@hypercerts-org/sdk-core 0.4.0-beta.0 → 0.6.0-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. package/README.md +459 -79
  2. package/dist/index.cjs +128 -47
  3. package/dist/index.cjs.map +1 -1
  4. package/dist/index.d.ts +28 -9
  5. package/dist/index.mjs +128 -47
  6. package/dist/index.mjs.map +1 -1
  7. package/dist/types.cjs +3 -2
  8. package/dist/types.cjs.map +1 -1
  9. package/dist/types.d.ts +28 -9
  10. package/dist/types.mjs +3 -2
  11. package/dist/types.mjs.map +1 -1
  12. package/package.json +9 -5
  13. package/.turbo/turbo-build.log +0 -328
  14. package/.turbo/turbo-test.log +0 -118
  15. package/CHANGELOG.md +0 -22
  16. package/eslint.config.mjs +0 -22
  17. package/rollup.config.js +0 -75
  18. package/src/auth/OAuthClient.ts +0 -497
  19. package/src/core/SDK.ts +0 -410
  20. package/src/core/config.ts +0 -243
  21. package/src/core/errors.ts +0 -257
  22. package/src/core/interfaces.ts +0 -324
  23. package/src/core/types.ts +0 -281
  24. package/src/errors.ts +0 -57
  25. package/src/index.ts +0 -107
  26. package/src/lexicons.ts +0 -64
  27. package/src/repository/BlobOperationsImpl.ts +0 -199
  28. package/src/repository/CollaboratorOperationsImpl.ts +0 -396
  29. package/src/repository/HypercertOperationsImpl.ts +0 -1146
  30. package/src/repository/LexiconRegistry.ts +0 -332
  31. package/src/repository/OrganizationOperationsImpl.ts +0 -234
  32. package/src/repository/ProfileOperationsImpl.ts +0 -281
  33. package/src/repository/RecordOperationsImpl.ts +0 -340
  34. package/src/repository/Repository.ts +0 -482
  35. package/src/repository/interfaces.ts +0 -897
  36. package/src/repository/types.ts +0 -111
  37. package/src/services/hypercerts/types.ts +0 -87
  38. package/src/storage/InMemorySessionStore.ts +0 -127
  39. package/src/storage/InMemoryStateStore.ts +0 -146
  40. package/src/storage.ts +0 -63
  41. package/src/testing/index.ts +0 -67
  42. package/src/testing/mocks.ts +0 -142
  43. package/src/testing/stores.ts +0 -285
  44. package/src/testing.ts +0 -64
  45. package/src/types.ts +0 -86
  46. package/tests/auth/OAuthClient.test.ts +0 -164
  47. package/tests/core/SDK.test.ts +0 -176
  48. package/tests/core/errors.test.ts +0 -81
  49. package/tests/repository/BlobOperationsImpl.test.ts +0 -154
  50. package/tests/repository/CollaboratorOperationsImpl.test.ts +0 -438
  51. package/tests/repository/HypercertOperationsImpl.test.ts +0 -652
  52. package/tests/repository/LexiconRegistry.test.ts +0 -192
  53. package/tests/repository/OrganizationOperationsImpl.test.ts +0 -242
  54. package/tests/repository/ProfileOperationsImpl.test.ts +0 -254
  55. package/tests/repository/RecordOperationsImpl.test.ts +0 -375
  56. package/tests/repository/Repository.test.ts +0 -149
  57. package/tests/utils/fixtures.ts +0 -117
  58. package/tests/utils/mocks.ts +0 -109
  59. package/tests/utils/repository-fixtures.ts +0 -78
  60. package/tsconfig.json +0 -11
  61. package/tsconfig.tsbuildinfo +0 -1
  62. package/vitest.config.ts +0 -30
@@ -1,482 +0,0 @@
1
- /**
2
- * Repository - Unified fluent API for ATProto repository operations.
3
- *
4
- * This module provides the main interface for interacting with AT Protocol
5
- * data servers (PDS and SDS) through a consistent, fluent API.
6
- *
7
- * @packageDocumentation
8
- */
9
-
10
- import { Agent } from "@atproto/api";
11
- import { SDSRequiredError } from "../core/errors.js";
12
- import type { LoggerInterface } from "../core/interfaces.js";
13
- import type { Session } from "../core/types.js";
14
- import { HYPERCERT_LEXICONS } from "@hypercerts-org/lexicon";
15
- import type { LexiconRegistry } from "./LexiconRegistry.js";
16
-
17
- // Types
18
- export type {
19
- RepositoryOptions,
20
- CreateResult,
21
- UpdateResult,
22
- PaginatedList,
23
- ListParams,
24
- RepositoryRole,
25
- RepositoryAccessGrant,
26
- OrganizationInfo,
27
- ProgressStep,
28
- } from "./types.js";
29
-
30
- // Interfaces
31
- export type {
32
- RecordOperations,
33
- BlobOperations,
34
- ProfileOperations,
35
- HypercertOperations,
36
- HypercertEvents,
37
- CollaboratorOperations,
38
- OrganizationOperations,
39
- CreateHypercertParams,
40
- CreateHypercertResult,
41
- } from "./interfaces.js";
42
-
43
- // Implementations
44
- import { RecordOperationsImpl } from "./RecordOperationsImpl.js";
45
- import { BlobOperationsImpl } from "./BlobOperationsImpl.js";
46
- import { ProfileOperationsImpl } from "./ProfileOperationsImpl.js";
47
- import { HypercertOperationsImpl } from "./HypercertOperationsImpl.js";
48
- import { CollaboratorOperationsImpl } from "./CollaboratorOperationsImpl.js";
49
- import { OrganizationOperationsImpl } from "./OrganizationOperationsImpl.js";
50
-
51
- import type {
52
- RecordOperations,
53
- BlobOperations,
54
- ProfileOperations,
55
- HypercertOperations,
56
- CollaboratorOperations,
57
- OrganizationOperations,
58
- } from "./interfaces.js";
59
-
60
- /**
61
- * Repository provides a fluent API for AT Protocol data operations.
62
- *
63
- * This class is the primary interface for working with data in the AT Protocol
64
- * ecosystem. It provides organized access to:
65
- *
66
- * - **Records**: Low-level CRUD operations for any AT Protocol record type
67
- * - **Blobs**: Binary data upload and retrieval (images, files)
68
- * - **Profile**: User profile management
69
- * - **Hypercerts**: High-level hypercert creation and management
70
- * - **Collaborators**: Access control for shared repositories (SDS only)
71
- * - **Organizations**: Organization management (SDS only)
72
- *
73
- * @remarks
74
- * The Repository uses lazy initialization for operation handlers - they are
75
- * created only when first accessed. This improves performance when you only
76
- * need a subset of operations.
77
- *
78
- * **PDS vs SDS:**
79
- * - **PDS (Personal Data Server)**: User's own data storage. All operations
80
- * except collaborators and organizations are available.
81
- * - **SDS (Shared Data Server)**: Collaborative data storage with access
82
- * control. All operations including collaborators and organizations.
83
- *
84
- * @example Basic usage
85
- * ```typescript
86
- * // Get a repository from the SDK
87
- * const repo = sdk.repository(session);
88
- *
89
- * // Access user profile
90
- * const profile = await repo.profile.get();
91
- *
92
- * // Create a hypercert
93
- * const result = await repo.hypercerts.create({
94
- * title: "My Impact",
95
- * description: "Description of the impact",
96
- * workScope: "Climate Action",
97
- * workTimeframeFrom: "2024-01-01",
98
- * workTimeframeTo: "2024-12-31",
99
- * rights: {
100
- * name: "Attribution",
101
- * type: "license",
102
- * description: "CC-BY-4.0",
103
- * },
104
- * });
105
- * ```
106
- *
107
- * @example Working with a different user's repository
108
- * ```typescript
109
- * // Get the current user's repo
110
- * const myRepo = sdk.repository(session);
111
- *
112
- * // Get another user's repo (read-only for most operations)
113
- * const otherRepo = myRepo.repo("did:plc:other-user-did");
114
- * const theirProfile = await otherRepo.profile.get();
115
- * ```
116
- *
117
- * @example SDS operations
118
- * ```typescript
119
- * // Get SDS repository for collaborator features
120
- * const sdsRepo = sdk.repository(session, { server: "sds" });
121
- *
122
- * // Manage collaborators
123
- * await sdsRepo.collaborators.grant({
124
- * userDid: "did:plc:collaborator",
125
- * role: "editor",
126
- * });
127
- *
128
- * // List organizations
129
- * const orgs = await sdsRepo.organizations.list();
130
- * ```
131
- *
132
- * @see {@link ATProtoSDK.repository} for creating Repository instances
133
- */
134
- export class Repository {
135
- private session: Session;
136
- private serverUrl: string;
137
- private repoDid: string;
138
- private lexiconRegistry: LexiconRegistry;
139
- private logger?: LoggerInterface;
140
- private agent: Agent;
141
- private _isSDS: boolean;
142
-
143
- // Lazily initialized operations
144
- private _records?: RecordOperationsImpl;
145
- private _blobs?: BlobOperationsImpl;
146
- private _profile?: ProfileOperationsImpl;
147
- private _hypercerts?: HypercertOperationsImpl;
148
- private _collaborators?: CollaboratorOperationsImpl;
149
- private _organizations?: OrganizationOperationsImpl;
150
-
151
- /**
152
- * Creates a new Repository instance.
153
- *
154
- * @param session - Authenticated OAuth session
155
- * @param serverUrl - Base URL of the AT Protocol server
156
- * @param repoDid - DID of the repository to operate on
157
- * @param lexiconRegistry - Registry for lexicon validation
158
- * @param isSDS - Whether this is a Shared Data Server
159
- * @param logger - Optional logger for debugging
160
- *
161
- * @remarks
162
- * This constructor is typically not called directly. Use
163
- * {@link ATProtoSDK.repository} to create Repository instances.
164
- *
165
- * @internal
166
- */
167
- constructor(
168
- session: Session,
169
- serverUrl: string,
170
- repoDid: string,
171
- lexiconRegistry: LexiconRegistry,
172
- isSDS: boolean,
173
- logger?: LoggerInterface,
174
- ) {
175
- this.session = session;
176
- this.serverUrl = serverUrl;
177
- this.repoDid = repoDid;
178
- this.lexiconRegistry = lexiconRegistry;
179
- this._isSDS = isSDS;
180
- this.logger = logger;
181
-
182
- // Create Agent with OAuth session
183
- this.agent = new Agent(session);
184
- this.lexiconRegistry.addToAgent(this.agent);
185
-
186
- // Register hypercert lexicons
187
- this.lexiconRegistry.registerMany(HYPERCERT_LEXICONS);
188
- }
189
-
190
- /**
191
- * The DID (Decentralized Identifier) of this repository.
192
- *
193
- * This is the user or organization that owns the repository data.
194
- *
195
- * @example
196
- * ```typescript
197
- * console.log(`Working with repo: ${repo.did}`);
198
- * // Output: Working with repo: did:plc:abc123xyz...
199
- * ```
200
- */
201
- get did(): string {
202
- return this.repoDid;
203
- }
204
-
205
- /**
206
- * Whether this repository is on a Shared Data Server (SDS).
207
- *
208
- * SDS servers support additional features like collaborators and
209
- * organizations. Attempting to use these features on a PDS will
210
- * throw {@link SDSRequiredError}.
211
- *
212
- * @example
213
- * ```typescript
214
- * if (repo.isSDS) {
215
- * const collaborators = await repo.collaborators.list();
216
- * }
217
- * ```
218
- */
219
- get isSDS(): boolean {
220
- return this._isSDS;
221
- }
222
-
223
- /**
224
- * Gets the server URL this repository connects to.
225
- *
226
- * @returns The base URL of the AT Protocol server
227
- *
228
- * @example
229
- * ```typescript
230
- * console.log(repo.getServerUrl());
231
- * // Output: https://bsky.social or https://sds.hypercerts.org
232
- * ```
233
- */
234
- getServerUrl(): string {
235
- return this.serverUrl;
236
- }
237
-
238
- /**
239
- * Creates a Repository instance for a different DID on the same server.
240
- *
241
- * This allows you to read data from other users' repositories while
242
- * maintaining your authenticated session.
243
- *
244
- * @param did - The DID of the repository to access
245
- * @returns A new Repository instance for the specified DID
246
- *
247
- * @remarks
248
- * Write operations on another user's repository will typically fail
249
- * unless you have been granted collaborator access (SDS only).
250
- *
251
- * @example
252
- * ```typescript
253
- * // Read another user's profile
254
- * const otherRepo = repo.repo("did:plc:other-user");
255
- * const profile = await otherRepo.profile.get();
256
- *
257
- * // List their public hypercerts
258
- * const hypercerts = await otherRepo.hypercerts.list();
259
- * ```
260
- */
261
- repo(did: string): Repository {
262
- return new Repository(this.session, this.serverUrl, did, this.lexiconRegistry, this._isSDS, this.logger);
263
- }
264
-
265
- /**
266
- * Low-level record operations for CRUD on any AT Protocol record type.
267
- *
268
- * Use this for direct access to AT Protocol records when the high-level
269
- * APIs don't meet your needs.
270
- *
271
- * @returns {@link RecordOperations} interface for record CRUD
272
- *
273
- * @example
274
- * ```typescript
275
- * // Create a custom record
276
- * const result = await repo.records.create({
277
- * collection: "org.example.myRecord",
278
- * record: { foo: "bar" },
279
- * });
280
- *
281
- * // List records in a collection
282
- * const list = await repo.records.list({
283
- * collection: "org.example.myRecord",
284
- * limit: 50,
285
- * });
286
- *
287
- * // Get a specific record
288
- * const record = await repo.records.get({
289
- * collection: "org.example.myRecord",
290
- * rkey: "abc123",
291
- * });
292
- * ```
293
- */
294
- get records(): RecordOperations {
295
- if (!this._records) {
296
- this._records = new RecordOperationsImpl(this.agent, this.repoDid, this.lexiconRegistry);
297
- }
298
- return this._records;
299
- }
300
-
301
- /**
302
- * Blob operations for uploading and retrieving binary data.
303
- *
304
- * Blobs are used for images, files, and other binary content associated
305
- * with records.
306
- *
307
- * @returns {@link BlobOperations} interface for blob management
308
- *
309
- * @example
310
- * ```typescript
311
- * // Upload an image
312
- * const imageBlob = new Blob([imageData], { type: "image/png" });
313
- * const uploadResult = await repo.blobs.upload(imageBlob);
314
- *
315
- * // The ref can be used in records
316
- * console.log(uploadResult.ref.$link); // CID of the blob
317
- *
318
- * // Retrieve a blob by CID
319
- * const { data, mimeType } = await repo.blobs.get(cid);
320
- * ```
321
- */
322
- get blobs(): BlobOperations {
323
- if (!this._blobs) {
324
- this._blobs = new BlobOperationsImpl(this.agent, this.repoDid, this.serverUrl);
325
- }
326
- return this._blobs;
327
- }
328
-
329
- /**
330
- * Profile operations for managing user profiles.
331
- *
332
- * @returns {@link ProfileOperations} interface for profile management
333
- *
334
- * @example
335
- * ```typescript
336
- * // Get current profile
337
- * const profile = await repo.profile.get();
338
- * console.log(profile.displayName);
339
- *
340
- * // Update profile
341
- * await repo.profile.update({
342
- * displayName: "New Name",
343
- * description: "Updated bio",
344
- * avatar: avatarBlob, // Optional: update avatar image
345
- * });
346
- * ```
347
- */
348
- get profile(): ProfileOperations {
349
- if (!this._profile) {
350
- this._profile = new ProfileOperationsImpl(this.agent, this.repoDid, this.serverUrl);
351
- }
352
- return this._profile;
353
- }
354
-
355
- /**
356
- * High-level hypercert operations.
357
- *
358
- * Provides a convenient API for creating and managing hypercerts,
359
- * including related records like locations, contributions, and evidence.
360
- *
361
- * @returns {@link HypercertOperations} interface with EventEmitter capabilities
362
- *
363
- * @example Creating a hypercert
364
- * ```typescript
365
- * const result = await repo.hypercerts.create({
366
- * title: "Climate Action Project",
367
- * description: "Reduced carbon emissions by 1000 tons",
368
- * workScope: "Climate Action",
369
- * workTimeframeFrom: "2024-01-01",
370
- * workTimeframeTo: "2024-06-30",
371
- * rights: {
372
- * name: "Public Domain",
373
- * type: "license",
374
- * description: "CC0 - No Rights Reserved",
375
- * },
376
- * image: imageBlob, // Optional cover image
377
- * location: {
378
- * value: "San Francisco, CA",
379
- * name: "SF Bay Area",
380
- * },
381
- * });
382
- * console.log(`Created: ${result.hypercertUri}`);
383
- * ```
384
- *
385
- * @example Listening to events
386
- * ```typescript
387
- * repo.hypercerts.on("recordCreated", ({ uri, cid }) => {
388
- * console.log(`Record created: ${uri}`);
389
- * });
390
- * ```
391
- */
392
- get hypercerts(): HypercertOperations {
393
- if (!this._hypercerts) {
394
- this._hypercerts = new HypercertOperationsImpl(
395
- this.agent,
396
- this.repoDid,
397
- this.serverUrl,
398
- this.lexiconRegistry,
399
- this.logger,
400
- );
401
- }
402
- return this._hypercerts;
403
- }
404
-
405
- /**
406
- * Collaborator operations for managing repository access.
407
- *
408
- * **SDS Only**: This property throws {@link SDSRequiredError} if accessed
409
- * on a PDS repository.
410
- *
411
- * @returns {@link CollaboratorOperations} interface for access control
412
- * @throws {@link SDSRequiredError} if not connected to an SDS server
413
- *
414
- * @example
415
- * ```typescript
416
- * // Ensure we're on SDS
417
- * const sdsRepo = sdk.repository(session, { server: "sds" });
418
- *
419
- * // Grant editor access
420
- * await sdsRepo.collaborators.grant({
421
- * userDid: "did:plc:new-collaborator",
422
- * role: "editor",
423
- * });
424
- *
425
- * // List all collaborators
426
- * const collaborators = await sdsRepo.collaborators.list();
427
- *
428
- * // Check access
429
- * const hasAccess = await sdsRepo.collaborators.hasAccess("did:plc:someone");
430
- *
431
- * // Revoke access
432
- * await sdsRepo.collaborators.revoke({ userDid: "did:plc:former-collaborator" });
433
- * ```
434
- */
435
- get collaborators(): CollaboratorOperations {
436
- if (!this._isSDS) {
437
- throw new SDSRequiredError("Collaborator operations are only available on SDS servers");
438
- }
439
- if (!this._collaborators) {
440
- this._collaborators = new CollaboratorOperationsImpl(this.session, this.repoDid, this.serverUrl);
441
- }
442
- return this._collaborators;
443
- }
444
-
445
- /**
446
- * Organization operations for creating and managing organizations.
447
- *
448
- * **SDS Only**: This property throws {@link SDSRequiredError} if accessed
449
- * on a PDS repository.
450
- *
451
- * @returns {@link OrganizationOperations} interface for organization management
452
- * @throws {@link SDSRequiredError} if not connected to an SDS server
453
- *
454
- * @example
455
- * ```typescript
456
- * // Ensure we're on SDS
457
- * const sdsRepo = sdk.repository(session, { server: "sds" });
458
- *
459
- * // Create an organization
460
- * const org = await sdsRepo.organizations.create({
461
- * name: "My Organization",
462
- * description: "A team working on impact certificates",
463
- * handle: "my-org", // Optional custom handle
464
- * });
465
- *
466
- * // List organizations you have access to
467
- * const orgs = await sdsRepo.organizations.list();
468
- *
469
- * // Get specific organization
470
- * const orgInfo = await sdsRepo.organizations.get(org.did);
471
- * ```
472
- */
473
- get organizations(): OrganizationOperations {
474
- if (!this._isSDS) {
475
- throw new SDSRequiredError("Organization operations are only available on SDS servers");
476
- }
477
- if (!this._organizations) {
478
- this._organizations = new OrganizationOperationsImpl(this.session, this.repoDid, this.serverUrl, this.logger);
479
- }
480
- return this._organizations;
481
- }
482
- }