import { z } from 'zod' import { Cid, LexMap, ifCid } from '@atproto/lex-data' import { NsidString, RecordKeyString } from '@atproto/syntax' import { BlockMap } from './block-map' import { CidSet } from './cid-set' // Repo nodes // --------------- const cidSchema = z.unknown().transform((input, ctx): Cid => { const cid = ifCid(input) if (cid) return cid ctx.addIssue({ code: z.ZodIssueCode.custom, message: 'Not a valid CID', }) return z.NEVER }) const unsignedCommit = z.object({ did: z.string(), version: z.literal(3), data: cidSchema, rev: z.string(), // `prev` added for backwards compatibility with v2, no requirement of keeping around history prev: cidSchema.nullable(), }) export type UnsignedCommit = z.infer & { sig?: never } const commit = z.object({ did: z.string(), version: z.literal(3), data: cidSchema, rev: z.string(), prev: cidSchema.nullable(), sig: z.instanceof(Uint8Array), }) export type Commit = z.infer const legacyV2Commit = z.object({ did: z.string(), version: z.literal(2), data: cidSchema, rev: z.string().optional(), prev: cidSchema.nullable(), sig: z.instanceof(Uint8Array), }) export type LegacyV2Commit = z.infer const versionedCommit = z.discriminatedUnion('version', [ commit, legacyV2Commit, ]) export type VersionedCommit = z.infer export const schema = { cid: cidSchema, carHeader: z.object({ version: z.literal(1), roots: z.array(cidSchema), }), bytes: z.instanceof(Uint8Array), string: z.string(), array: z.array(z.unknown()), map: z.record(z.string(), z.unknown()), unknown: z.unknown(), commit, legacyV2Commit, versionedCommit, } export const def = { cid: { name: 'cid', schema: schema.cid, }, carHeader: { name: 'CAR header', schema: schema.carHeader, }, bytes: { name: 'bytes', schema: schema.bytes, }, string: { name: 'string', schema: schema.string, }, map: { name: 'map', schema: schema.map, }, unknown: { name: 'unknown', schema: schema.unknown, }, commit: { name: 'commit', schema: schema.commit, }, versionedCommit: { name: 'versioned_commit', schema: schema.versionedCommit, }, } // Repo Operations // --------------- export enum WriteOpAction { Create = 'create', Update = 'update', Delete = 'delete', } export type RecordCreateOp = { action: WriteOpAction.Create collection: NsidString rkey: RecordKeyString record: LexMap } export type RecordUpdateOp = { action: WriteOpAction.Update collection: NsidString rkey: RecordKeyString record: LexMap } export type RecordDeleteOp = { action: WriteOpAction.Delete collection: NsidString rkey: RecordKeyString } export type RecordWriteOp = RecordCreateOp | RecordUpdateOp | RecordDeleteOp export type RecordCreateDescript = { action: WriteOpAction.Create collection: NsidString rkey: RecordKeyString cid: Cid } export type RecordUpdateDescript = { action: WriteOpAction.Update collection: NsidString rkey: RecordKeyString prev: Cid cid: Cid } export type RecordDeleteDescript = { action: WriteOpAction.Delete collection: NsidString rkey: RecordKeyString cid: Cid } export type RecordWriteDescript = | RecordCreateDescript | RecordUpdateDescript | RecordDeleteDescript export type WriteLog = RecordWriteDescript[][] // Updates/Commits // --------------- export type CommitData = { cid: Cid rev: string since: string | null prev: Cid | null newBlocks: BlockMap relevantBlocks: BlockMap removedCids: CidSet } export type RepoUpdate = CommitData & { ops: RecordWriteOp[] } export type CollectionContents = Record export type RepoContents = Record export type RepoRecordWithCid = { cid: Cid; value: LexMap } export type CollectionContentsWithCids = Record export type RepoContentsWithCids = Record export type DatastoreContents = Record export type RecordPath = { collection: string rkey: string } export type RecordCidClaim = { collection: string rkey: string cid: Cid | null } export type RecordClaim = { collection: string rkey: string record: LexMap | null } // Sync // --------------- export type VerifiedDiff = { writes: RecordWriteDescript[] commit: CommitData } export type VerifiedRepo = { creates: RecordCreateDescript[] commit: CommitData } export type CarBlock = { cid: Cid bytes: Uint8Array }