Encrypted, ephemeral, private memos on atproto

fix(lexicon): remove reliance on ambient types

graham.systems 44fbad70 bb102caf

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