Fork of github.com/did-method-plc/did-method-plc
1import { cidForCbor } from '@atproto/common'
2import * as plc from '@did-plc/lib'
3import { ServerError } from '../error'
4import { PlcDatabase } from './types'
5
6type Contents = Record<string, plc.IndexedOperation[]>
7
8export class MockDatabase implements PlcDatabase {
9 contents: Contents = {}
10
11 async close(): Promise<void> {}
12 async healthCheck(): Promise<void> {}
13
14 async validateAndAddOp(
15 did: string,
16 proposed: plc.OpOrTombstone,
17 ): Promise<void> {
18 this.contents[did] ??= []
19 const opsBefore = this.contents[did]
20 // throws if invalid
21 const { nullified } = await plc.assureValidNextOp(did, opsBefore, proposed)
22 const cid = await cidForCbor(proposed)
23 if (this.contents[did] !== opsBefore) {
24 throw new ServerError(
25 409,
26 `Proposed prev does not match the most recent operation`,
27 )
28 }
29 this.contents[did].push({
30 did,
31 operation: proposed,
32 cid,
33 nullified: false,
34 createdAt: new Date(),
35 })
36
37 if (nullified.length > 0) {
38 for (let i = 0; i < this.contents[did].length; i++) {
39 const cid = this.contents[did][i].cid
40 for (const toCheck of nullified) {
41 if (toCheck.equals(cid)) {
42 this.contents[did][i].nullified = true
43 }
44 }
45 }
46 }
47 }
48
49 async opsForDid(did: string): Promise<plc.CompatibleOpOrTombstone[]> {
50 const ops = await this.indexedOpsForDid(did)
51 return ops.map((op) => op.operation)
52 }
53
54 async indexedOpsForDid(
55 did: string,
56 includeNull = false,
57 ): Promise<plc.IndexedOperation[]> {
58 const ops = this.contents[did] ?? []
59 if (includeNull) {
60 return ops
61 }
62 return ops.filter((op) => op.nullified === false)
63 }
64
65 async lastOpForDid(did: string): Promise<plc.CompatibleOpOrTombstone | null> {
66 const op = this.contents[did]?.at(-1)
67
68 if (!op) return null
69 return op.operation
70 }
71
72 // disabled in mocks
73 async exportOps(_count: number, _after?: Date): Promise<plc.ExportedOp[]> {
74 return []
75 }
76}
77
78export default MockDatabase