Encrypted, ephemeral, private memos on atproto

fix(lexicon): remove reliance on ambient types

graham.systems 44fbad70 bb102caf

verified
Changed files
+44 -42
packages
consumer
lexicon
src
types
app
cistern
producer
shared
+1 -2
deno.lock
··· 221 221 "dependencies": [ 222 222 "jsr:@puregarlic/randimal@^1.1.1", 223 223 "jsr:@std/expect@^1.0.17", 224 - "npm:@atcute/atproto@^3.1.9", 225 224 "npm:@atcute/client@^4.0.5", 226 225 "npm:@atcute/jetstream@^1.1.2", 227 226 "npm:@atcute/lexicons@^1.2.2", ··· 246 245 "packages/producer": { 247 246 "dependencies": [ 248 247 "jsr:@std/expect@^1.0.17", 249 - "npm:@atcute/atproto@^3.1.9", 250 248 "npm:@atcute/client@^4.0.5", 251 249 "npm:@atcute/lexicons@^1.2.2", 252 250 "npm:@atcute/tid@^1.0.3" ··· 254 252 }, 255 253 "packages/shared": { 256 254 "dependencies": [ 255 + "npm:@atcute/atproto@^3.1.9", 257 256 "npm:@atcute/client@^4.0.5", 258 257 "npm:@atcute/lexicons@^1.2.2" 259 258 ]
-1
packages/consumer/deno.jsonc
··· 9 9 "exclude": ["*.test.ts"] 10 10 }, 11 11 "imports": { 12 - "@atcute/atproto": "npm:@atcute/atproto@^3.1.9", 13 12 "@atcute/client": "npm:@atcute/client@^4.0.5", 14 13 "@atcute/jetstream": "npm:@atcute/jetstream@^1.1.2", 15 14 "@atcute/lexicons": "npm:@atcute/lexicons@^1.2.2",
+11 -10
packages/consumer/mod.test.ts
··· 6 6 import type { Did, Handle, ResourceUri } from "@atcute/lexicons"; 7 7 import { now } from "@atcute/tid"; 8 8 import type { AppCisternMemo } from "@cistern/lexicon"; 9 + import type { XRPCProcedures, XRPCQueries } from "@cistern/shared"; 9 10 10 11 // Helper to create a mock Consumer instance 11 12 function createMockConsumer( ··· 31 32 } 32 33 33 34 // Helper to create a mock RPC client 34 - function createMockRpcClient(): Client { 35 + function createMockRpcClient(): Client<XRPCQueries, XRPCProcedures> { 35 36 return { 36 37 get: () => { 37 38 throw new Error("Mock RPC get not implemented"); ··· 39 40 post: () => { 40 41 throw new Error("Mock RPC post not implemented"); 41 42 }, 42 - } as unknown as Client; 43 + } as unknown as Client<XRPCQueries, XRPCProcedures>; 43 44 } 44 45 45 46 Deno.test({ ··· 101 102 } 102 103 return Promise.resolve({ ok: false, status: 500, data: {} }); 103 104 }, 104 - } as unknown as Client; 105 + } as unknown as Client<XRPCQueries, XRPCProcedures>; 105 106 106 107 const consumer = createMockConsumer({ rpc: mockRpc }); 107 108 const keypair = await consumer.generateKeyPair(); ··· 152 153 status: 500, 153 154 data: { error: "Internal Server Error" }, 154 155 }), 155 - } as unknown as Client; 156 + } as unknown as Client<XRPCQueries, XRPCProcedures>; 156 157 157 158 const consumer = createMockConsumer({ rpc: mockRpc }); 158 159 ··· 210 211 } 211 212 return Promise.resolve({ ok: false, status: 500, data: {} }); 212 213 }, 213 - } as unknown as Client; 214 + } as unknown as Client<XRPCQueries, XRPCProcedures>; 214 215 215 216 const consumer = createMockConsumer({ 216 217 rpc: mockRpc, ··· 272 273 } 273 274 return Promise.resolve({ ok: false, status: 500, data: {} }); 274 275 }, 275 - } as unknown as Client; 276 + } as unknown as Client<XRPCQueries, XRPCProcedures>; 276 277 277 278 const consumer = createMockConsumer({ 278 279 rpc: mockRpc, ··· 363 364 } 364 365 return Promise.resolve({ ok: false, status: 500, data: {} }); 365 366 }, 366 - } as unknown as Client; 367 + } as unknown as Client<XRPCQueries, XRPCProcedures>; 367 368 368 369 const consumer = createMockConsumer({ 369 370 rpc: mockRpc, ··· 399 400 status: 401, 400 401 data: { error: "Unauthorized" }, 401 402 }), 402 - } as unknown as Client; 403 + } as unknown as Client<XRPCQueries, XRPCProcedures>; 403 404 404 405 const consumer = createMockConsumer({ 405 406 rpc: mockRpc, ··· 448 449 } 449 450 return Promise.resolve({ ok: false, status: 500, data: {} }); 450 451 }, 451 - } as unknown as Client; 452 + } as unknown as Client<XRPCQueries, XRPCProcedures>; 452 453 453 454 const consumer = createMockConsumer({ rpc: mockRpc }); 454 455 ··· 468 469 status: 404, 469 470 data: { error: "Not Found" }, 470 471 }), 471 - } as unknown as Client; 472 + } as unknown as Client<XRPCQueries, XRPCProcedures>; 472 473 473 474 const consumer = createMockConsumer({ rpc: mockRpc }); 474 475
+6 -4
packages/consumer/mod.ts
··· 1 - import { produceRequirements } from "@cistern/shared"; 1 + import { 2 + produceRequirements, 3 + type XRPCProcedures, 4 + type XRPCQueries, 5 + } from "@cistern/shared"; 2 6 import { decryptText, generateKeys } from "@cistern/crypto"; 3 7 import { generateRandomName } from "@puregarlic/randimal"; 4 8 import { is, parse, type RecordKey } from "@atcute/lexicons"; ··· 12 16 DecryptedMemo, 13 17 LocalKeyPair, 14 18 } from "./types.ts"; 15 - 16 - import type {} from "@atcute/atproto"; 17 19 18 20 export async function createConsumer( 19 21 options: ConsumerOptions, ··· 29 31 export class Consumer { 30 32 did: Did; 31 33 keypair?: LocalKeyPair; 32 - rpc: Client; 34 + rpc: Client<XRPCQueries, XRPCProcedures>; 33 35 manager: CredentialManager; 34 36 35 37 constructor(params: ConsumerParams) {
-7
packages/lexicon/src/types/app/cistern/memo.ts
··· 1 1 import type {} from "@atcute/lexicons"; 2 2 import * as v from "@atcute/lexicons/validations"; 3 - import type {} from "@atcute/lexicons/ambient"; 4 3 5 4 const _mainSchema = /*#__PURE__*/ v.record( 6 5 /*#__PURE__*/ v.string(), ··· 50 49 export const mainSchema = _mainSchema as mainSchema; 51 50 52 51 export interface Main extends v.InferInput<typeof mainSchema> {} 53 - 54 - declare module "@atcute/lexicons/ambient" { 55 - interface Records { 56 - "app.cistern.memo": mainSchema; 57 - } 58 - }
-7
packages/lexicon/src/types/app/cistern/pubkey.ts
··· 1 1 import type {} from "@atcute/lexicons"; 2 2 import * as v from "@atcute/lexicons/validations"; 3 - import type {} from "@atcute/lexicons/ambient"; 4 3 5 4 const _mainSchema = /*#__PURE__*/ v.record( 6 5 /*#__PURE__*/ v.string(), ··· 32 31 export const mainSchema = _mainSchema as mainSchema; 33 32 34 33 export interface Main extends v.InferInput<typeof mainSchema> {} 35 - 36 - declare module "@atcute/lexicons/ambient" { 37 - interface Records { 38 - "app.cistern.pubkey": mainSchema; 39 - } 40 - }
-1
packages/producer/deno.jsonc
··· 9 9 "exclude": ["*.test.ts"] 10 10 }, 11 11 "imports": { 12 - "@atcute/atproto": "npm:@atcute/atproto@^3.1.9", 13 12 "@atcute/client": "npm:@atcute/client@^4.0.5", 14 13 "@atcute/lexicons": "npm:@atcute/lexicons@^1.2.2", 15 14 "@atcute/tid": "npm:@atcute/tid@^1.0.3",
+8 -7
packages/producer/mod.test.ts
··· 5 5 import type { Client, CredentialManager } from "@atcute/client"; 6 6 import type { Did, Handle, ResourceUri } from "@atcute/lexicons"; 7 7 import type { AppCisternPubkey } from "@cistern/lexicon"; 8 + import type { XRPCProcedures, XRPCQueries } from "@cistern/shared"; 8 9 9 10 // Helper to create a mock Producer instance 10 11 function createMockProducer( ··· 30 31 } 31 32 32 33 // Helper to create a mock RPC client 33 - function createMockRpcClient(): Client { 34 + function createMockRpcClient(): Client<XRPCQueries, XRPCProcedures> { 34 35 return { 35 36 get: () => { 36 37 throw new Error("Mock RPC get not implemented"); ··· 38 39 post: () => { 39 40 throw new Error("Mock RPC post not implemented"); 40 41 }, 41 - } as unknown as Client; 42 + } as unknown as Client<XRPCQueries, XRPCProcedures>; 42 43 } 43 44 44 45 Deno.test({ ··· 98 99 } 99 100 return Promise.resolve({ ok: false, status: 500, data: {} }); 100 101 }, 101 - } as unknown as Client; 102 + } as unknown as Client<XRPCQueries, XRPCProcedures>; 102 103 103 104 const producer = createMockProducer({ 104 105 rpc: mockRpc, ··· 142 143 status: 500, 143 144 data: { error: "Internal Server Error" }, 144 145 }), 145 - } as unknown as Client; 146 + } as unknown as Client<XRPCQueries, XRPCProcedures>; 146 147 147 148 const producer = createMockProducer({ 148 149 rpc: mockRpc, ··· 196 197 } 197 198 return Promise.resolve({ ok: false, status: 500, data: {} }); 198 199 }, 199 - } as unknown as Client; 200 + } as unknown as Client<XRPCQueries, XRPCProcedures>; 200 201 201 202 const producer = createMockProducer({ rpc: mockRpc }); 202 203 ··· 262 263 } 263 264 return Promise.resolve({ ok: false, status: 500, data: {} }); 264 265 }, 265 - } as unknown as Client; 266 + } as unknown as Client<XRPCQueries, XRPCProcedures>; 266 267 267 268 const producer = createMockProducer({ rpc: mockRpc }); 268 269 ··· 288 289 status: 401, 289 290 data: { error: "Unauthorized" }, 290 291 }), 291 - } as unknown as Client; 292 + } as unknown as Client<XRPCQueries, XRPCProcedures>; 292 293 293 294 const producer = createMockProducer({ rpc: mockRpc }); 294 295
-2
packages/producer/mod.ts
··· 10 10 import { now } from "@atcute/tid"; 11 11 import { type AppCisternMemo, AppCisternPubkey } from "@cistern/lexicon"; 12 12 13 - import type {} from "@atcute/atproto"; 14 - 15 13 export async function createProducer( 16 14 { publicKey: rkey, ...opts }: ProducerOptions, 17 15 ): Promise<Producer> {
+1
packages/shared/deno.jsonc
··· 9 9 "exclude": ["*.test.ts"] 10 10 }, 11 11 "imports": { 12 + "@atcute/atproto": "npm:@atcute/atproto@^3.1.9", 12 13 "@atcute/client": "npm:@atcute/client@^4.0.5", 13 14 "@atcute/lexicons": "npm:@atcute/lexicons@^1.2.2" 14 15 }
+17 -1
packages/shared/types.ts
··· 1 1 import type { Did, Handle } from "@atcute/lexicons"; 2 2 import type { Client, CredentialManager } from "@atcute/client"; 3 + import type { 4 + ComAtprotoRepoCreateRecord, 5 + ComAtprotoRepoDeleteRecord, 6 + ComAtprotoRepoGetRecord, 7 + ComAtprotoRepoListRecords, 8 + } from "@atcute/atproto"; 3 9 4 10 export interface MiniDoc { 5 11 did: Did; ··· 13 19 appPassword: string; 14 20 } 15 21 22 + export interface XRPCQueries { 23 + "com.atproto.repo.getRecord": ComAtprotoRepoGetRecord.mainSchema; 24 + "com.atproto.repo.listRecords": ComAtprotoRepoListRecords.mainSchema; 25 + } 26 + 27 + export interface XRPCProcedures { 28 + "com.atproto.repo.createRecord": ComAtprotoRepoCreateRecord.mainSchema; 29 + "com.atproto.repo.deleteRecord": ComAtprotoRepoDeleteRecord.mainSchema; 30 + } 31 + 16 32 export interface ClientRequirements<Options extends BaseClientOptions> { 17 33 miniDoc: MiniDoc; 18 34 manager: CredentialManager; 19 - rpc: Client; 35 + rpc: Client<XRPCQueries, XRPCProcedures>; 20 36 options: Options; 21 37 }