@hypercerts-org/sdk-core 0.10.0-beta.4 → 0.10.0-beta.5
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.
- package/CHANGELOG.md +153 -0
- package/README.md +131 -6
- package/dist/index.cjs +2597 -320
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +1900 -169
- package/dist/index.mjs +3588 -1341
- package/dist/index.mjs.map +1 -1
- package/dist/lexicons.cjs +446 -34
- package/dist/lexicons.cjs.map +1 -1
- package/dist/lexicons.d.ts +248 -8
- package/dist/lexicons.mjs +422 -11
- package/dist/lexicons.mjs.map +1 -1
- package/dist/testing.d.ts +56 -9
- package/dist/types.cjs +89 -9
- package/dist/types.cjs.map +1 -1
- package/dist/types.d.ts +358 -66
- package/dist/types.mjs +89 -9
- package/dist/types.mjs.map +1 -1
- package/package.json +3 -3
package/dist/lexicons.mjs
CHANGED
|
@@ -1,4 +1,406 @@
|
|
|
1
|
-
import { CERTIFIED_DEFS_LEXICON_JSON, LOCATION_LEXICON_JSON,
|
|
1
|
+
import { CERTIFIED_DEFS_LEXICON_JSON, LOCATION_LEXICON_JSON, STRONG_REF_LEXICON_JSON, HYPERCERTS_DEFS_LEXICON_JSON, ACTIVITY_LEXICON_JSON, COLLECTION_LEXICON_JSON, CONTRIBUTION_DETAILS_LEXICON_JSON, CONTRIBUTOR_INFORMATION_LEXICON_JSON, EVALUATION_LEXICON_JSON, EVIDENCE_LEXICON_JSON, MEASUREMENT_LEXICON_JSON, RIGHTS_LEXICON_JSON, BADGE_AWARD_LEXICON_JSON, BADGE_DEFINITION_LEXICON_JSON, BADGE_RESPONSE_LEXICON_JSON, FUNDING_RECEIPT_LEXICON_JSON, WORK_SCOPE_TAG_LEXICON_JSON, WORK_SCOPE_TAG_NSID, FUNDING_RECEIPT_NSID, BADGE_RESPONSE_NSID, BADGE_DEFINITION_NSID, BADGE_AWARD_NSID, COLLECTION_NSID, EVIDENCE_NSID, EVALUATION_NSID, MEASUREMENT_NSID, CONTRIBUTOR_INFORMATION_NSID, CONTRIBUTION_DETAILS_NSID, LOCATION_NSID, RIGHTS_NSID, ACTIVITY_NSID } from '@hypercerts-org/lexicon';
|
|
2
|
+
import { Lexicons } from '@atproto/lexicon';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Base error class for all SDK errors.
|
|
6
|
+
*
|
|
7
|
+
* All errors thrown by the Hypercerts SDK extend this class, making it easy
|
|
8
|
+
* to catch and handle SDK-specific errors.
|
|
9
|
+
*
|
|
10
|
+
* @example Catching all SDK errors
|
|
11
|
+
* ```typescript
|
|
12
|
+
* try {
|
|
13
|
+
* await sdk.authorize("user.bsky.social");
|
|
14
|
+
* } catch (error) {
|
|
15
|
+
* if (error instanceof ATProtoSDKError) {
|
|
16
|
+
* console.error(`SDK Error [${error.code}]: ${error.message}`);
|
|
17
|
+
* console.error(`HTTP Status: ${error.status}`);
|
|
18
|
+
* }
|
|
19
|
+
* }
|
|
20
|
+
* ```
|
|
21
|
+
*
|
|
22
|
+
* @example Checking error codes
|
|
23
|
+
* ```typescript
|
|
24
|
+
* try {
|
|
25
|
+
* await repo.records.get(collection, rkey);
|
|
26
|
+
* } catch (error) {
|
|
27
|
+
* if (error instanceof ATProtoSDKError) {
|
|
28
|
+
* switch (error.code) {
|
|
29
|
+
* case "AUTHENTICATION_ERROR":
|
|
30
|
+
* // Redirect to login
|
|
31
|
+
* break;
|
|
32
|
+
* case "VALIDATION_ERROR":
|
|
33
|
+
* // Show form errors
|
|
34
|
+
* break;
|
|
35
|
+
* case "NETWORK_ERROR":
|
|
36
|
+
* // Retry or show offline message
|
|
37
|
+
* break;
|
|
38
|
+
* }
|
|
39
|
+
* }
|
|
40
|
+
* }
|
|
41
|
+
* ```
|
|
42
|
+
*/
|
|
43
|
+
class ATProtoSDKError extends Error {
|
|
44
|
+
/**
|
|
45
|
+
* Creates a new SDK error.
|
|
46
|
+
*
|
|
47
|
+
* @param message - Human-readable error description
|
|
48
|
+
* @param code - Machine-readable error code for programmatic handling
|
|
49
|
+
* @param status - HTTP status code associated with this error type
|
|
50
|
+
* @param cause - The underlying error that caused this error, if any
|
|
51
|
+
*/
|
|
52
|
+
constructor(message, code, status, cause) {
|
|
53
|
+
super(message);
|
|
54
|
+
this.code = code;
|
|
55
|
+
this.status = status;
|
|
56
|
+
this.cause = cause;
|
|
57
|
+
this.name = "ATProtoSDKError";
|
|
58
|
+
Error.captureStackTrace?.(this, this.constructor);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Error thrown when input validation fails.
|
|
63
|
+
*
|
|
64
|
+
* This error indicates that provided data doesn't meet the required format
|
|
65
|
+
* or constraints. Common causes:
|
|
66
|
+
* - Missing required fields
|
|
67
|
+
* - Invalid URL formats
|
|
68
|
+
* - Invalid DID format
|
|
69
|
+
* - Schema validation failures for records
|
|
70
|
+
* - Invalid configuration values
|
|
71
|
+
*
|
|
72
|
+
* @example
|
|
73
|
+
* ```typescript
|
|
74
|
+
* try {
|
|
75
|
+
* await sdk.authorize(""); // Empty identifier
|
|
76
|
+
* } catch (error) {
|
|
77
|
+
* if (error instanceof ValidationError) {
|
|
78
|
+
* console.error("Invalid input:", error.message);
|
|
79
|
+
* // Show validation error to user
|
|
80
|
+
* }
|
|
81
|
+
* }
|
|
82
|
+
* ```
|
|
83
|
+
*
|
|
84
|
+
* @example With Zod validation cause
|
|
85
|
+
* ```typescript
|
|
86
|
+
* try {
|
|
87
|
+
* await repo.records.create(collection, record);
|
|
88
|
+
* } catch (error) {
|
|
89
|
+
* if (error instanceof ValidationError && error.cause) {
|
|
90
|
+
* // error.cause may be a ZodError with detailed field errors
|
|
91
|
+
* const zodError = error.cause as ZodError;
|
|
92
|
+
* zodError.errors.forEach(e => {
|
|
93
|
+
* console.error(`Field ${e.path.join(".")}: ${e.message}`);
|
|
94
|
+
* });
|
|
95
|
+
* }
|
|
96
|
+
* }
|
|
97
|
+
* ```
|
|
98
|
+
*/
|
|
99
|
+
class ValidationError extends ATProtoSDKError {
|
|
100
|
+
/**
|
|
101
|
+
* Creates a validation error.
|
|
102
|
+
*
|
|
103
|
+
* @param message - Description of what validation failed
|
|
104
|
+
* @param cause - The underlying validation error (e.g., ZodError)
|
|
105
|
+
*/
|
|
106
|
+
constructor(message, cause) {
|
|
107
|
+
super(message, "VALIDATION_ERROR", 400, cause);
|
|
108
|
+
this.name = "ValidationError";
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* LexiconRegistry - Manages custom lexicon registration and validation.
|
|
114
|
+
*
|
|
115
|
+
* This module provides a registry for AT Protocol lexicon schemas,
|
|
116
|
+
* allowing developers to register custom lexicons and validate records
|
|
117
|
+
* against registered schemas.
|
|
118
|
+
*
|
|
119
|
+
* @packageDocumentation
|
|
120
|
+
*/
|
|
121
|
+
/**
|
|
122
|
+
* Registry for managing AT Protocol lexicon schemas.
|
|
123
|
+
*
|
|
124
|
+
* The LexiconRegistry allows developers to:
|
|
125
|
+
* - Register custom lexicon definitions
|
|
126
|
+
* - Validate records against registered schemas
|
|
127
|
+
* - Query registered lexicons
|
|
128
|
+
* - Add lexicons to AT Protocol agents
|
|
129
|
+
*
|
|
130
|
+
* @example Basic usage
|
|
131
|
+
* ```typescript
|
|
132
|
+
* const registry = new LexiconRegistry();
|
|
133
|
+
*
|
|
134
|
+
* // Register a custom lexicon
|
|
135
|
+
* registry.register({
|
|
136
|
+
* lexicon: 1,
|
|
137
|
+
* id: "org.myapp.customRecord",
|
|
138
|
+
* defs: {
|
|
139
|
+
* main: {
|
|
140
|
+
* type: "record",
|
|
141
|
+
* key: "tid",
|
|
142
|
+
* record: {
|
|
143
|
+
* type: "object",
|
|
144
|
+
* required: ["$type", "title"],
|
|
145
|
+
* properties: {
|
|
146
|
+
* "$type": { type: "string", const: "org.myapp.customRecord" },
|
|
147
|
+
* title: { type: "string" }
|
|
148
|
+
* }
|
|
149
|
+
* }
|
|
150
|
+
* }
|
|
151
|
+
* }
|
|
152
|
+
* });
|
|
153
|
+
*
|
|
154
|
+
* // Validate a record
|
|
155
|
+
* const result = registry.validate("org.myapp.customRecord", {
|
|
156
|
+
* $type: "org.myapp.customRecord",
|
|
157
|
+
* title: "My Record"
|
|
158
|
+
* });
|
|
159
|
+
*
|
|
160
|
+
* if (!result.valid) {
|
|
161
|
+
* console.error(result.error);
|
|
162
|
+
* }
|
|
163
|
+
* ```
|
|
164
|
+
*/
|
|
165
|
+
class LexiconRegistry {
|
|
166
|
+
/**
|
|
167
|
+
* Creates a new LexiconRegistry instance.
|
|
168
|
+
*
|
|
169
|
+
* @param initialLexicons - Optional array of lexicons to register on initialization
|
|
170
|
+
*/
|
|
171
|
+
constructor(initialLexicons) {
|
|
172
|
+
this.lexicons = new Lexicons();
|
|
173
|
+
this.registeredIds = new Set();
|
|
174
|
+
if (initialLexicons && initialLexicons.length > 0) {
|
|
175
|
+
this.registerMany(initialLexicons);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Registers a single lexicon definition.
|
|
180
|
+
*
|
|
181
|
+
* @param lexicon - The lexicon document to register
|
|
182
|
+
* @throws {Error} If the lexicon is invalid or already registered
|
|
183
|
+
*
|
|
184
|
+
* @example
|
|
185
|
+
* ```typescript
|
|
186
|
+
* registry.register({
|
|
187
|
+
* lexicon: 1,
|
|
188
|
+
* id: "org.myapp.customRecord",
|
|
189
|
+
* defs: { ... }
|
|
190
|
+
* });
|
|
191
|
+
* ```
|
|
192
|
+
*/
|
|
193
|
+
register(lexicon) {
|
|
194
|
+
if (!lexicon.id) {
|
|
195
|
+
throw new Error("Lexicon must have an id");
|
|
196
|
+
}
|
|
197
|
+
if (this.registeredIds.has(lexicon.id)) {
|
|
198
|
+
throw new Error(`Lexicon ${lexicon.id} is already registered`);
|
|
199
|
+
}
|
|
200
|
+
try {
|
|
201
|
+
// Check if the lexicon already exists in the internal store
|
|
202
|
+
// (e.g., after unregister which only removes from registeredIds)
|
|
203
|
+
const existingLexicon = this.lexicons.get(lexicon.id);
|
|
204
|
+
if (!existingLexicon) {
|
|
205
|
+
// Lexicon is truly new, add it to the store
|
|
206
|
+
this.lexicons.add(lexicon);
|
|
207
|
+
}
|
|
208
|
+
// Always add to registeredIds (re-enable if previously unregistered)
|
|
209
|
+
this.registeredIds.add(lexicon.id);
|
|
210
|
+
}
|
|
211
|
+
catch (error) {
|
|
212
|
+
throw new Error(`Failed to register lexicon ${lexicon.id}: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* Registers multiple lexicon definitions at once.
|
|
217
|
+
*
|
|
218
|
+
* @param lexicons - Array of lexicon documents to register
|
|
219
|
+
* @throws {Error} If any lexicon is invalid or already registered
|
|
220
|
+
*
|
|
221
|
+
* @example
|
|
222
|
+
* ```typescript
|
|
223
|
+
* registry.registerMany([lexicon1, lexicon2, lexicon3]);
|
|
224
|
+
* ```
|
|
225
|
+
*/
|
|
226
|
+
registerMany(lexicons) {
|
|
227
|
+
for (const lexicon of lexicons) {
|
|
228
|
+
this.register(lexicon);
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
/**
|
|
232
|
+
* Registers a lexicon from a JSON object.
|
|
233
|
+
*
|
|
234
|
+
* This is a convenience method for registering lexicons loaded from JSON files.
|
|
235
|
+
*
|
|
236
|
+
* @param lexiconJson - The lexicon as a plain JavaScript object
|
|
237
|
+
* @throws {ValidationError} If the lexicon is not a valid object
|
|
238
|
+
* @throws {Error} If the lexicon is invalid or already registered
|
|
239
|
+
*
|
|
240
|
+
* @example
|
|
241
|
+
* ```typescript
|
|
242
|
+
* import customLexicon from "./custom-lexicon.json";
|
|
243
|
+
* registry.registerFromJSON(customLexicon);
|
|
244
|
+
* ```
|
|
245
|
+
*/
|
|
246
|
+
registerFromJSON(lexiconJson) {
|
|
247
|
+
// Validate that input is an object and not null
|
|
248
|
+
if (typeof lexiconJson !== "object" || lexiconJson === null) {
|
|
249
|
+
throw new ValidationError("Lexicon JSON must be a valid object");
|
|
250
|
+
}
|
|
251
|
+
// Now we can safely cast to LexiconDoc and register
|
|
252
|
+
this.register(lexiconJson);
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* Unregisters a lexicon by its NSID.
|
|
256
|
+
*
|
|
257
|
+
* @param nsid - The NSID of the lexicon to unregister
|
|
258
|
+
* @returns True if the lexicon was unregistered, false if it wasn't registered
|
|
259
|
+
*
|
|
260
|
+
* @example
|
|
261
|
+
* ```typescript
|
|
262
|
+
* registry.unregister("org.myapp.customRecord");
|
|
263
|
+
* ```
|
|
264
|
+
*/
|
|
265
|
+
unregister(nsid) {
|
|
266
|
+
if (!this.registeredIds.has(nsid)) {
|
|
267
|
+
return false;
|
|
268
|
+
}
|
|
269
|
+
this.registeredIds.delete(nsid);
|
|
270
|
+
// Note: Lexicons class doesn't have a remove method,
|
|
271
|
+
// so we can't actually remove from the internal store.
|
|
272
|
+
// We track removal in our Set for isRegistered checks.
|
|
273
|
+
return true;
|
|
274
|
+
}
|
|
275
|
+
/**
|
|
276
|
+
* Checks if a lexicon is registered.
|
|
277
|
+
*
|
|
278
|
+
* @param nsid - The NSID to check
|
|
279
|
+
* @returns True if the lexicon is registered
|
|
280
|
+
*
|
|
281
|
+
* @example
|
|
282
|
+
* ```typescript
|
|
283
|
+
* if (registry.isRegistered("org.myapp.customRecord")) {
|
|
284
|
+
* // Lexicon is available
|
|
285
|
+
* }
|
|
286
|
+
* ```
|
|
287
|
+
*/
|
|
288
|
+
isRegistered(nsid) {
|
|
289
|
+
return this.registeredIds.has(nsid);
|
|
290
|
+
}
|
|
291
|
+
/**
|
|
292
|
+
* Gets a lexicon definition by its NSID.
|
|
293
|
+
*
|
|
294
|
+
* @param nsid - The NSID of the lexicon to retrieve
|
|
295
|
+
* @returns The lexicon document, or undefined if not found
|
|
296
|
+
*
|
|
297
|
+
* @example
|
|
298
|
+
* ```typescript
|
|
299
|
+
* const lexicon = registry.get("org.myapp.customRecord");
|
|
300
|
+
* if (lexicon) {
|
|
301
|
+
* console.log(lexicon.defs);
|
|
302
|
+
* }
|
|
303
|
+
* ```
|
|
304
|
+
*/
|
|
305
|
+
get(nsid) {
|
|
306
|
+
if (!this.isRegistered(nsid)) {
|
|
307
|
+
return undefined;
|
|
308
|
+
}
|
|
309
|
+
return this.lexicons.get(nsid);
|
|
310
|
+
}
|
|
311
|
+
/**
|
|
312
|
+
* Gets all registered lexicon NSIDs.
|
|
313
|
+
*
|
|
314
|
+
* @returns Array of registered NSIDs
|
|
315
|
+
*
|
|
316
|
+
* @example
|
|
317
|
+
* ```typescript
|
|
318
|
+
* const registered = registry.getAll();
|
|
319
|
+
* console.log(`Registered lexicons: ${registered.join(", ")}`);
|
|
320
|
+
* ```
|
|
321
|
+
*/
|
|
322
|
+
getAll() {
|
|
323
|
+
return Array.from(this.registeredIds);
|
|
324
|
+
}
|
|
325
|
+
/**
|
|
326
|
+
* Validates a record against a registered lexicon.
|
|
327
|
+
*
|
|
328
|
+
* @param nsid - The collection NSID to validate against
|
|
329
|
+
* @param record - The record data to validate
|
|
330
|
+
* @returns Validation result with success status and optional error message
|
|
331
|
+
*
|
|
332
|
+
* @example
|
|
333
|
+
* ```typescript
|
|
334
|
+
* const result = registry.validate("org.myapp.customRecord", {
|
|
335
|
+
* $type: "org.myapp.customRecord",
|
|
336
|
+
* title: "My Record"
|
|
337
|
+
* });
|
|
338
|
+
*
|
|
339
|
+
* if (!result.valid) {
|
|
340
|
+
* console.error(`Validation failed: ${result.error}`);
|
|
341
|
+
* }
|
|
342
|
+
* ```
|
|
343
|
+
*/
|
|
344
|
+
validate(nsid, record) {
|
|
345
|
+
if (!this.isRegistered(nsid)) {
|
|
346
|
+
return {
|
|
347
|
+
valid: false,
|
|
348
|
+
error: `Lexicon ${nsid} is not registered`,
|
|
349
|
+
};
|
|
350
|
+
}
|
|
351
|
+
try {
|
|
352
|
+
this.lexicons.assertValidRecord(nsid, record);
|
|
353
|
+
return { valid: true };
|
|
354
|
+
}
|
|
355
|
+
catch (error) {
|
|
356
|
+
return {
|
|
357
|
+
valid: false,
|
|
358
|
+
error: error instanceof Error ? error.message : "Validation failed",
|
|
359
|
+
};
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
/**
|
|
363
|
+
* Adds all registered lexicons to an AT Protocol Agent.
|
|
364
|
+
*
|
|
365
|
+
* This method is currently a no-op as the AT Protocol Agent
|
|
366
|
+
* doesn't provide a public API for adding lexicons at runtime.
|
|
367
|
+
* Lexicons must be registered with the server.
|
|
368
|
+
*
|
|
369
|
+
* This method is kept for future compatibility if the API
|
|
370
|
+
* adds support for client-side lexicon registration.
|
|
371
|
+
*
|
|
372
|
+
* @param _agent - The AT Protocol Agent (currently unused)
|
|
373
|
+
*
|
|
374
|
+
* @example
|
|
375
|
+
* ```typescript
|
|
376
|
+
* const agent = new Agent(session);
|
|
377
|
+
* registry.addToAgent(agent);
|
|
378
|
+
* // Reserved for future use
|
|
379
|
+
* ```
|
|
380
|
+
*/
|
|
381
|
+
addToAgent(_agent) {
|
|
382
|
+
// No-op: AT Protocol Agent doesn't support client-side lexicon addition
|
|
383
|
+
// Lexicons are validated client-side via this registry,
|
|
384
|
+
// but server-side validation is performed by the PDS/SDS
|
|
385
|
+
}
|
|
386
|
+
/**
|
|
387
|
+
* Gets the underlying Lexicons instance.
|
|
388
|
+
*
|
|
389
|
+
* This provides direct access to the AT Protocol Lexicons object
|
|
390
|
+
* for advanced use cases.
|
|
391
|
+
*
|
|
392
|
+
* @returns The internal Lexicons instance
|
|
393
|
+
*
|
|
394
|
+
* @example
|
|
395
|
+
* ```typescript
|
|
396
|
+
* const lexicons = registry.getLexicons();
|
|
397
|
+
* // Use lexicons directly for advanced operations
|
|
398
|
+
* ```
|
|
399
|
+
*/
|
|
400
|
+
getLexicons() {
|
|
401
|
+
return this.lexicons;
|
|
402
|
+
}
|
|
403
|
+
}
|
|
2
404
|
|
|
3
405
|
/**
|
|
4
406
|
* Lexicons entrypoint - Lexicon definitions and registry.
|
|
@@ -66,20 +468,21 @@ import { CERTIFIED_DEFS_LEXICON_JSON, LOCATION_LEXICON_JSON, STRONGREF_LEXICON_J
|
|
|
66
468
|
const HYPERCERT_LEXICONS = [
|
|
67
469
|
CERTIFIED_DEFS_LEXICON_JSON,
|
|
68
470
|
LOCATION_LEXICON_JSON,
|
|
69
|
-
|
|
471
|
+
STRONG_REF_LEXICON_JSON,
|
|
70
472
|
HYPERCERTS_DEFS_LEXICON_JSON,
|
|
71
473
|
ACTIVITY_LEXICON_JSON,
|
|
72
474
|
COLLECTION_LEXICON_JSON,
|
|
73
|
-
|
|
475
|
+
CONTRIBUTION_DETAILS_LEXICON_JSON,
|
|
476
|
+
CONTRIBUTOR_INFORMATION_LEXICON_JSON,
|
|
74
477
|
EVALUATION_LEXICON_JSON,
|
|
75
478
|
EVIDENCE_LEXICON_JSON,
|
|
76
479
|
MEASUREMENT_LEXICON_JSON,
|
|
77
480
|
RIGHTS_LEXICON_JSON,
|
|
78
|
-
PROJECT_LEXICON_JSON,
|
|
79
481
|
BADGE_AWARD_LEXICON_JSON,
|
|
80
482
|
BADGE_DEFINITION_LEXICON_JSON,
|
|
81
483
|
BADGE_RESPONSE_LEXICON_JSON,
|
|
82
484
|
FUNDING_RECEIPT_LEXICON_JSON,
|
|
485
|
+
WORK_SCOPE_TAG_LEXICON_JSON,
|
|
83
486
|
];
|
|
84
487
|
/**
|
|
85
488
|
* Collection NSIDs (Namespaced Identifiers) for hypercert records.
|
|
@@ -101,9 +504,15 @@ const HYPERCERT_COLLECTIONS = {
|
|
|
101
504
|
*/
|
|
102
505
|
LOCATION: LOCATION_NSID,
|
|
103
506
|
/**
|
|
104
|
-
* Contribution record collection.
|
|
507
|
+
* Contribution details record collection.
|
|
508
|
+
* For storing details about a specific contribution (role, description, timeframe).
|
|
509
|
+
*/
|
|
510
|
+
CONTRIBUTION_DETAILS: CONTRIBUTION_DETAILS_NSID,
|
|
511
|
+
/**
|
|
512
|
+
* Contributor information record collection.
|
|
513
|
+
* For storing contributor profile information (identifier, displayName, image).
|
|
105
514
|
*/
|
|
106
|
-
|
|
515
|
+
CONTRIBUTOR_INFORMATION: CONTRIBUTOR_INFORMATION_NSID,
|
|
107
516
|
/**
|
|
108
517
|
* Measurement record collection.
|
|
109
518
|
*/
|
|
@@ -118,12 +527,9 @@ const HYPERCERT_COLLECTIONS = {
|
|
|
118
527
|
EVIDENCE: EVIDENCE_NSID,
|
|
119
528
|
/**
|
|
120
529
|
* Collection record collection (groups of hypercerts).
|
|
530
|
+
* Projects are now collections with type='project'.
|
|
121
531
|
*/
|
|
122
532
|
COLLECTION: COLLECTION_NSID,
|
|
123
|
-
/**
|
|
124
|
-
* Project record collection.
|
|
125
|
-
*/
|
|
126
|
-
PROJECT: PROJECT_NSID,
|
|
127
533
|
/**
|
|
128
534
|
* Badge award record collection.
|
|
129
535
|
*/
|
|
@@ -140,7 +546,12 @@ const HYPERCERT_COLLECTIONS = {
|
|
|
140
546
|
* Funding receipt record collection.
|
|
141
547
|
*/
|
|
142
548
|
FUNDING_RECEIPT: FUNDING_RECEIPT_NSID,
|
|
549
|
+
/**
|
|
550
|
+
* Work scope tag record collection.
|
|
551
|
+
* For defining reusable work scope atoms.
|
|
552
|
+
*/
|
|
553
|
+
WORK_SCOPE_TAG: WORK_SCOPE_TAG_NSID,
|
|
143
554
|
};
|
|
144
555
|
|
|
145
|
-
export { HYPERCERT_COLLECTIONS, HYPERCERT_LEXICONS };
|
|
556
|
+
export { HYPERCERT_COLLECTIONS, HYPERCERT_LEXICONS, LexiconRegistry };
|
|
146
557
|
//# sourceMappingURL=lexicons.mjs.map
|
package/dist/lexicons.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lexicons.mjs","sources":["../src/lexicons.ts"],"sourcesContent":["/**\n * Lexicons entrypoint - Lexicon definitions and registry.\n *\n * This sub-entrypoint exports the lexicon registry and hypercert\n * lexicon constants for working with AT Protocol record schemas.\n *\n * @remarks\n * Import from `@hypercerts-org/sdk/lexicons`:\n *\n * ```typescript\n * import {\n * LexiconRegistry,\n * HYPERCERT_LEXICONS,\n * HYPERCERT_COLLECTIONS,\n * } from \"@hypercerts-org/sdk/lexicons\";\n * ```\n *\n * **Exports**:\n * - {@link LexiconRegistry} - Registry for managing and validating lexicons\n * - {@link HYPERCERT_LEXICONS} - Array of all hypercert lexicon documents\n * - {@link HYPERCERT_COLLECTIONS} - Constants for collection NSIDs\n *\n * @example Using collection constants\n * ```typescript\n * import { HYPERCERT_COLLECTIONS } from \"@hypercerts-org/sdk/lexicons\";\n *\n * // List hypercerts using the correct collection name\n * const records = await repo.records.list({\n * collection: HYPERCERT_COLLECTIONS.RECORD,\n * });\n *\n * // List contributions\n * const contributions = await repo.records.list({\n * collection: HYPERCERT_COLLECTIONS.CONTRIBUTION,\n * });\n * ```\n *\n * @example Custom lexicon registration\n * ```typescript\n * import { LexiconRegistry } from \"@hypercerts-org/sdk/lexicons\";\n *\n * const registry = sdk.getLexiconRegistry();\n *\n * // Register custom lexicon\n * registry.register({\n * lexicon: 1,\n * id: \"org.myapp.customRecord\",\n * defs: { ... },\n * });\n *\n * // Validate a record\n * const result = registry.validate(\"org.myapp.customRecord\", record);\n * if (!result.valid) {\n * console.error(result.error);\n * }\n * ```\n *\n * @packageDocumentation\n */\n\n// Import lexicon JSON files and constants from the published package\nimport type { LexiconDoc } from \"@atproto/lexicon\";\nimport {\n CERTIFIED_DEFS_LEXICON_JSON,\n LOCATION_LEXICON_JSON,\n STRONGREF_LEXICON_JSON,\n HYPERCERTS_DEFS_LEXICON_JSON,\n ACTIVITY_LEXICON_JSON,\n COLLECTION_LEXICON_JSON,\n CONTRIBUTION_LEXICON_JSON,\n EVALUATION_LEXICON_JSON,\n EVIDENCE_LEXICON_JSON,\n MEASUREMENT_LEXICON_JSON,\n RIGHTS_LEXICON_JSON,\n PROJECT_LEXICON_JSON,\n BADGE_AWARD_LEXICON_JSON,\n BADGE_DEFINITION_LEXICON_JSON,\n BADGE_RESPONSE_LEXICON_JSON,\n FUNDING_RECEIPT_LEXICON_JSON,\n // NSID constants\n ACTIVITY_NSID,\n RIGHTS_NSID,\n LOCATION_NSID,\n CONTRIBUTION_NSID,\n MEASUREMENT_NSID,\n EVALUATION_NSID,\n EVIDENCE_NSID,\n COLLECTION_NSID,\n PROJECT_NSID,\n BADGE_AWARD_NSID,\n BADGE_DEFINITION_NSID,\n BADGE_RESPONSE_NSID,\n FUNDING_RECEIPT_NSID,\n} from \"@hypercerts-org/lexicon\";\n\n/**\n * All hypercert-related lexicons for registration with AT Protocol Agent.\n * This array contains all lexicon documents from the published package.\n */\nexport const HYPERCERT_LEXICONS: LexiconDoc[] = [\n CERTIFIED_DEFS_LEXICON_JSON as LexiconDoc,\n LOCATION_LEXICON_JSON as LexiconDoc,\n STRONGREF_LEXICON_JSON as LexiconDoc,\n HYPERCERTS_DEFS_LEXICON_JSON as LexiconDoc,\n ACTIVITY_LEXICON_JSON as LexiconDoc,\n COLLECTION_LEXICON_JSON as LexiconDoc,\n CONTRIBUTION_LEXICON_JSON as LexiconDoc,\n EVALUATION_LEXICON_JSON as LexiconDoc,\n EVIDENCE_LEXICON_JSON as LexiconDoc,\n MEASUREMENT_LEXICON_JSON as LexiconDoc,\n RIGHTS_LEXICON_JSON as LexiconDoc,\n PROJECT_LEXICON_JSON as LexiconDoc,\n BADGE_AWARD_LEXICON_JSON as LexiconDoc,\n BADGE_DEFINITION_LEXICON_JSON as LexiconDoc,\n BADGE_RESPONSE_LEXICON_JSON as LexiconDoc,\n FUNDING_RECEIPT_LEXICON_JSON as LexiconDoc,\n];\n\n/**\n * Collection NSIDs (Namespaced Identifiers) for hypercert records.\n *\n * Use these constants when performing record operations to ensure\n * correct collection names.\n */\nexport const HYPERCERT_COLLECTIONS = {\n /**\n * Main hypercert claim record collection.\n */\n CLAIM: ACTIVITY_NSID,\n\n /**\n * Rights record collection.\n */\n RIGHTS: RIGHTS_NSID,\n\n /**\n * Location record collection (shared certified lexicon).\n */\n LOCATION: LOCATION_NSID,\n\n /**\n * Contribution record collection.\n */\n CONTRIBUTION: CONTRIBUTION_NSID,\n\n /**\n * Measurement record collection.\n */\n MEASUREMENT: MEASUREMENT_NSID,\n\n /**\n * Evaluation record collection.\n */\n EVALUATION: EVALUATION_NSID,\n\n /**\n * Evidence record collection.\n */\n EVIDENCE: EVIDENCE_NSID,\n\n /**\n * Collection record collection (groups of hypercerts).\n */\n COLLECTION: COLLECTION_NSID,\n\n /**\n * Project record collection.\n */\n PROJECT: PROJECT_NSID,\n\n /**\n * Badge award record collection.\n */\n BADGE_AWARD: BADGE_AWARD_NSID,\n\n /**\n * Badge definition record collection.\n */\n BADGE_DEFINITION: BADGE_DEFINITION_NSID,\n\n /**\n * Badge response record collection.\n */\n BADGE_RESPONSE: BADGE_RESPONSE_NSID,\n\n /**\n * Funding receipt record collection.\n */\n FUNDING_RECEIPT: FUNDING_RECEIPT_NSID,\n} as const;\n"],"names":[],"mappings":";;AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA0DG;AAqCH;;;AAGG;AACI,MAAM,kBAAkB,GAAiB;IAC9C,2BAAyC;IACzC,qBAAmC;IACnC,sBAAoC;IACpC,4BAA0C;IAC1C,qBAAmC;IACnC,uBAAqC;IACrC,yBAAuC;IACvC,uBAAqC;IACrC,qBAAmC;IACnC,wBAAsC;IACtC,mBAAiC;IACjC,oBAAkC;IAClC,wBAAsC;IACtC,6BAA2C;IAC3C,2BAAyC;IACzC,4BAA0C;;AAG5C;;;;;AAKG;AACI,MAAM,qBAAqB,GAAG;AACnC;;AAEG;AACH,IAAA,KAAK,EAAE,aAAa;AAEpB;;AAEG;AACH,IAAA,MAAM,EAAE,WAAW;AAEnB;;AAEG;AACH,IAAA,QAAQ,EAAE,aAAa;AAEvB;;AAEG;AACH,IAAA,YAAY,EAAE,iBAAiB;AAE/B;;AAEG;AACH,IAAA,WAAW,EAAE,gBAAgB;AAE7B;;AAEG;AACH,IAAA,UAAU,EAAE,eAAe;AAE3B;;AAEG;AACH,IAAA,QAAQ,EAAE,aAAa;AAEvB;;AAEG;AACH,IAAA,UAAU,EAAE,eAAe;AAE3B;;AAEG;AACH,IAAA,OAAO,EAAE,YAAY;AAErB;;AAEG;AACH,IAAA,WAAW,EAAE,gBAAgB;AAE7B;;AAEG;AACH,IAAA,gBAAgB,EAAE,qBAAqB;AAEvC;;AAEG;AACH,IAAA,cAAc,EAAE,mBAAmB;AAEnC;;AAEG;AACH,IAAA,eAAe,EAAE,oBAAoB;;;;;"}
|
|
1
|
+
{"version":3,"file":"lexicons.mjs","sources":["../src/core/errors.ts","../src/repository/LexiconRegistry.ts","../src/lexicons.ts"],"sourcesContent":["/**\n * Base error class for all SDK errors.\n *\n * All errors thrown by the Hypercerts SDK extend this class, making it easy\n * to catch and handle SDK-specific errors.\n *\n * @example Catching all SDK errors\n * ```typescript\n * try {\n * await sdk.authorize(\"user.bsky.social\");\n * } catch (error) {\n * if (error instanceof ATProtoSDKError) {\n * console.error(`SDK Error [${error.code}]: ${error.message}`);\n * console.error(`HTTP Status: ${error.status}`);\n * }\n * }\n * ```\n *\n * @example Checking error codes\n * ```typescript\n * try {\n * await repo.records.get(collection, rkey);\n * } catch (error) {\n * if (error instanceof ATProtoSDKError) {\n * switch (error.code) {\n * case \"AUTHENTICATION_ERROR\":\n * // Redirect to login\n * break;\n * case \"VALIDATION_ERROR\":\n * // Show form errors\n * break;\n * case \"NETWORK_ERROR\":\n * // Retry or show offline message\n * break;\n * }\n * }\n * }\n * ```\n */\nexport class ATProtoSDKError extends Error {\n /**\n * Creates a new SDK error.\n *\n * @param message - Human-readable error description\n * @param code - Machine-readable error code for programmatic handling\n * @param status - HTTP status code associated with this error type\n * @param cause - The underlying error that caused this error, if any\n */\n constructor(\n message: string,\n public code: string,\n public status?: number,\n public cause?: unknown,\n ) {\n super(message);\n this.name = \"ATProtoSDKError\";\n Error.captureStackTrace?.(this, this.constructor);\n }\n}\n\n/**\n * Error thrown when authentication fails.\n *\n * This error indicates problems with the OAuth flow, invalid credentials,\n * or failed token exchanges. Common causes:\n * - Invalid authorization code\n * - Expired or invalid state parameter\n * - Revoked or invalid tokens\n * - User denied authorization\n *\n * @example\n * ```typescript\n * try {\n * const session = await sdk.callback(params);\n * } catch (error) {\n * if (error instanceof AuthenticationError) {\n * // Clear any stored state and redirect to login\n * console.error(\"Authentication failed:\", error.message);\n * }\n * }\n * ```\n */\nexport class AuthenticationError extends ATProtoSDKError {\n /**\n * Creates an authentication error.\n *\n * @param message - Description of what went wrong during authentication\n * @param cause - The underlying error (e.g., from the OAuth client)\n */\n constructor(message: string, cause?: unknown) {\n super(message, \"AUTHENTICATION_ERROR\", 401, cause);\n this.name = \"AuthenticationError\";\n }\n}\n\n/**\n * Error thrown when a session has expired and cannot be refreshed.\n *\n * This typically occurs when:\n * - The refresh token has expired (usually after extended inactivity)\n * - The user has revoked access to your application\n * - The PDS has invalidated all sessions for the user\n *\n * When this error occurs, the user must re-authenticate.\n *\n * @example\n * ```typescript\n * try {\n * const session = await sdk.restoreSession(did);\n * } catch (error) {\n * if (error instanceof SessionExpiredError) {\n * // Clear stored session and prompt user to log in again\n * localStorage.removeItem(\"userDid\");\n * window.location.href = \"/login\";\n * }\n * }\n * ```\n */\nexport class SessionExpiredError extends ATProtoSDKError {\n /**\n * Creates a session expired error.\n *\n * @param message - Description of why the session expired\n * @param cause - The underlying error from the token refresh attempt\n */\n constructor(message: string = \"Session expired\", cause?: unknown) {\n super(message, \"SESSION_EXPIRED\", 401, cause);\n this.name = \"SessionExpiredError\";\n }\n}\n\n/**\n * Error thrown when input validation fails.\n *\n * This error indicates that provided data doesn't meet the required format\n * or constraints. Common causes:\n * - Missing required fields\n * - Invalid URL formats\n * - Invalid DID format\n * - Schema validation failures for records\n * - Invalid configuration values\n *\n * @example\n * ```typescript\n * try {\n * await sdk.authorize(\"\"); // Empty identifier\n * } catch (error) {\n * if (error instanceof ValidationError) {\n * console.error(\"Invalid input:\", error.message);\n * // Show validation error to user\n * }\n * }\n * ```\n *\n * @example With Zod validation cause\n * ```typescript\n * try {\n * await repo.records.create(collection, record);\n * } catch (error) {\n * if (error instanceof ValidationError && error.cause) {\n * // error.cause may be a ZodError with detailed field errors\n * const zodError = error.cause as ZodError;\n * zodError.errors.forEach(e => {\n * console.error(`Field ${e.path.join(\".\")}: ${e.message}`);\n * });\n * }\n * }\n * ```\n */\nexport class ValidationError extends ATProtoSDKError {\n /**\n * Creates a validation error.\n *\n * @param message - Description of what validation failed\n * @param cause - The underlying validation error (e.g., ZodError)\n */\n constructor(message: string, cause?: unknown) {\n super(message, \"VALIDATION_ERROR\", 400, cause);\n this.name = \"ValidationError\";\n }\n}\n\n/**\n * Error thrown when a network request fails.\n *\n * This error indicates connectivity issues or server unavailability.\n * Common causes:\n * - No internet connection\n * - DNS resolution failure\n * - Server timeout\n * - Server returned 5xx error\n * - TLS/SSL errors\n *\n * These errors are typically transient and may succeed on retry.\n *\n * @example\n * ```typescript\n * try {\n * await repo.records.list(collection);\n * } catch (error) {\n * if (error instanceof NetworkError) {\n * // Implement retry logic or show offline indicator\n * console.error(\"Network error:\", error.message);\n * await retryWithBackoff(() => repo.records.list(collection));\n * }\n * }\n * ```\n */\nexport class NetworkError extends ATProtoSDKError {\n /**\n * Creates a network error.\n *\n * @param message - Description of the network failure\n * @param cause - The underlying error (e.g., fetch error, timeout)\n */\n constructor(message: string, cause?: unknown) {\n super(message, \"NETWORK_ERROR\", 503, cause);\n this.name = \"NetworkError\";\n }\n}\n\n/**\n * Error thrown when an SDS-only operation is attempted on a PDS.\n *\n * Certain operations are only available on Shared Data Servers (SDS),\n * such as collaborator management and organization operations.\n * This error is thrown when these operations are attempted on a\n * Personal Data Server (PDS).\n *\n * @example\n * ```typescript\n * const pdsRepo = sdk.repository(session); // Default is PDS\n *\n * try {\n * // This will throw SDSRequiredError\n * await pdsRepo.collaborators.list();\n * } catch (error) {\n * if (error instanceof SDSRequiredError) {\n * // Switch to SDS for this operation\n * const sdsRepo = sdk.repository(session, { server: \"sds\" });\n * const collaborators = await sdsRepo.collaborators.list();\n * }\n * }\n * ```\n */\nexport class SDSRequiredError extends ATProtoSDKError {\n /**\n * Creates an SDS required error.\n *\n * @param message - Description of which operation requires SDS\n * @param cause - Any underlying error\n */\n constructor(message: string = \"This operation requires a Shared Data Server (SDS)\", cause?: unknown) {\n super(message, \"SDS_REQUIRED\", 400, cause);\n this.name = \"SDSRequiredError\";\n }\n}\n","/**\n * LexiconRegistry - Manages custom lexicon registration and validation.\n *\n * This module provides a registry for AT Protocol lexicon schemas,\n * allowing developers to register custom lexicons and validate records\n * against registered schemas.\n *\n * @packageDocumentation\n */\n\nimport type { LexiconDoc } from \"@atproto/lexicon\";\nimport { Lexicons } from \"@atproto/lexicon\";\nimport type { Agent } from \"@atproto/api\";\nimport { ValidationError } from \"../errors.js\";\n\n/**\n * Validation result from lexicon validation.\n */\nexport interface ValidationResult {\n /**\n * Whether the record is valid according to the lexicon.\n */\n valid: boolean;\n\n /**\n * Error message if validation failed.\n */\n error?: string;\n}\n\n/**\n * Registry for managing AT Protocol lexicon schemas.\n *\n * The LexiconRegistry allows developers to:\n * - Register custom lexicon definitions\n * - Validate records against registered schemas\n * - Query registered lexicons\n * - Add lexicons to AT Protocol agents\n *\n * @example Basic usage\n * ```typescript\n * const registry = new LexiconRegistry();\n *\n * // Register a custom lexicon\n * registry.register({\n * lexicon: 1,\n * id: \"org.myapp.customRecord\",\n * defs: {\n * main: {\n * type: \"record\",\n * key: \"tid\",\n * record: {\n * type: \"object\",\n * required: [\"$type\", \"title\"],\n * properties: {\n * \"$type\": { type: \"string\", const: \"org.myapp.customRecord\" },\n * title: { type: \"string\" }\n * }\n * }\n * }\n * }\n * });\n *\n * // Validate a record\n * const result = registry.validate(\"org.myapp.customRecord\", {\n * $type: \"org.myapp.customRecord\",\n * title: \"My Record\"\n * });\n *\n * if (!result.valid) {\n * console.error(result.error);\n * }\n * ```\n */\nexport class LexiconRegistry {\n private lexicons: Lexicons;\n private registeredIds: Set<string>;\n\n /**\n * Creates a new LexiconRegistry instance.\n *\n * @param initialLexicons - Optional array of lexicons to register on initialization\n */\n constructor(initialLexicons?: LexiconDoc[]) {\n this.lexicons = new Lexicons();\n this.registeredIds = new Set();\n\n if (initialLexicons && initialLexicons.length > 0) {\n this.registerMany(initialLexicons);\n }\n }\n\n /**\n * Registers a single lexicon definition.\n *\n * @param lexicon - The lexicon document to register\n * @throws {Error} If the lexicon is invalid or already registered\n *\n * @example\n * ```typescript\n * registry.register({\n * lexicon: 1,\n * id: \"org.myapp.customRecord\",\n * defs: { ... }\n * });\n * ```\n */\n register(lexicon: LexiconDoc): void {\n if (!lexicon.id) {\n throw new Error(\"Lexicon must have an id\");\n }\n\n if (this.registeredIds.has(lexicon.id)) {\n throw new Error(`Lexicon ${lexicon.id} is already registered`);\n }\n\n try {\n // Check if the lexicon already exists in the internal store\n // (e.g., after unregister which only removes from registeredIds)\n const existingLexicon = this.lexicons.get(lexicon.id);\n\n if (!existingLexicon) {\n // Lexicon is truly new, add it to the store\n this.lexicons.add(lexicon);\n }\n\n // Always add to registeredIds (re-enable if previously unregistered)\n this.registeredIds.add(lexicon.id);\n } catch (error) {\n throw new Error(\n `Failed to register lexicon ${lexicon.id}: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n );\n }\n }\n\n /**\n * Registers multiple lexicon definitions at once.\n *\n * @param lexicons - Array of lexicon documents to register\n * @throws {Error} If any lexicon is invalid or already registered\n *\n * @example\n * ```typescript\n * registry.registerMany([lexicon1, lexicon2, lexicon3]);\n * ```\n */\n registerMany(lexicons: LexiconDoc[]): void {\n for (const lexicon of lexicons) {\n this.register(lexicon);\n }\n }\n\n /**\n * Registers a lexicon from a JSON object.\n *\n * This is a convenience method for registering lexicons loaded from JSON files.\n *\n * @param lexiconJson - The lexicon as a plain JavaScript object\n * @throws {ValidationError} If the lexicon is not a valid object\n * @throws {Error} If the lexicon is invalid or already registered\n *\n * @example\n * ```typescript\n * import customLexicon from \"./custom-lexicon.json\";\n * registry.registerFromJSON(customLexicon);\n * ```\n */\n registerFromJSON(lexiconJson: unknown): void {\n // Validate that input is an object and not null\n if (typeof lexiconJson !== \"object\" || lexiconJson === null) {\n throw new ValidationError(\"Lexicon JSON must be a valid object\");\n }\n\n // Now we can safely cast to LexiconDoc and register\n this.register(lexiconJson as LexiconDoc);\n }\n\n /**\n * Unregisters a lexicon by its NSID.\n *\n * @param nsid - The NSID of the lexicon to unregister\n * @returns True if the lexicon was unregistered, false if it wasn't registered\n *\n * @example\n * ```typescript\n * registry.unregister(\"org.myapp.customRecord\");\n * ```\n */\n unregister(nsid: string): boolean {\n if (!this.registeredIds.has(nsid)) {\n return false;\n }\n\n this.registeredIds.delete(nsid);\n // Note: Lexicons class doesn't have a remove method,\n // so we can't actually remove from the internal store.\n // We track removal in our Set for isRegistered checks.\n return true;\n }\n\n /**\n * Checks if a lexicon is registered.\n *\n * @param nsid - The NSID to check\n * @returns True if the lexicon is registered\n *\n * @example\n * ```typescript\n * if (registry.isRegistered(\"org.myapp.customRecord\")) {\n * // Lexicon is available\n * }\n * ```\n */\n isRegistered(nsid: string): boolean {\n return this.registeredIds.has(nsid);\n }\n\n /**\n * Gets a lexicon definition by its NSID.\n *\n * @param nsid - The NSID of the lexicon to retrieve\n * @returns The lexicon document, or undefined if not found\n *\n * @example\n * ```typescript\n * const lexicon = registry.get(\"org.myapp.customRecord\");\n * if (lexicon) {\n * console.log(lexicon.defs);\n * }\n * ```\n */\n get(nsid: string): LexiconDoc | undefined {\n if (!this.isRegistered(nsid)) {\n return undefined;\n }\n\n return this.lexicons.get(nsid);\n }\n\n /**\n * Gets all registered lexicon NSIDs.\n *\n * @returns Array of registered NSIDs\n *\n * @example\n * ```typescript\n * const registered = registry.getAll();\n * console.log(`Registered lexicons: ${registered.join(\", \")}`);\n * ```\n */\n getAll(): string[] {\n return Array.from(this.registeredIds);\n }\n\n /**\n * Validates a record against a registered lexicon.\n *\n * @param nsid - The collection NSID to validate against\n * @param record - The record data to validate\n * @returns Validation result with success status and optional error message\n *\n * @example\n * ```typescript\n * const result = registry.validate(\"org.myapp.customRecord\", {\n * $type: \"org.myapp.customRecord\",\n * title: \"My Record\"\n * });\n *\n * if (!result.valid) {\n * console.error(`Validation failed: ${result.error}`);\n * }\n * ```\n */\n validate(nsid: string, record: unknown): ValidationResult {\n if (!this.isRegistered(nsid)) {\n return {\n valid: false,\n error: `Lexicon ${nsid} is not registered`,\n };\n }\n\n try {\n this.lexicons.assertValidRecord(nsid, record);\n return { valid: true };\n } catch (error) {\n return {\n valid: false,\n error: error instanceof Error ? error.message : \"Validation failed\",\n };\n }\n }\n\n /**\n * Adds all registered lexicons to an AT Protocol Agent.\n *\n * This method is currently a no-op as the AT Protocol Agent\n * doesn't provide a public API for adding lexicons at runtime.\n * Lexicons must be registered with the server.\n *\n * This method is kept for future compatibility if the API\n * adds support for client-side lexicon registration.\n *\n * @param _agent - The AT Protocol Agent (currently unused)\n *\n * @example\n * ```typescript\n * const agent = new Agent(session);\n * registry.addToAgent(agent);\n * // Reserved for future use\n * ```\n */\n addToAgent(_agent: Agent): void {\n // No-op: AT Protocol Agent doesn't support client-side lexicon addition\n // Lexicons are validated client-side via this registry,\n // but server-side validation is performed by the PDS/SDS\n }\n\n /**\n * Gets the underlying Lexicons instance.\n *\n * This provides direct access to the AT Protocol Lexicons object\n * for advanced use cases.\n *\n * @returns The internal Lexicons instance\n *\n * @example\n * ```typescript\n * const lexicons = registry.getLexicons();\n * // Use lexicons directly for advanced operations\n * ```\n */\n getLexicons(): Lexicons {\n return this.lexicons;\n }\n}\n","/**\n * Lexicons entrypoint - Lexicon definitions and registry.\n *\n * This sub-entrypoint exports the lexicon registry and hypercert\n * lexicon constants for working with AT Protocol record schemas.\n *\n * @remarks\n * Import from `@hypercerts-org/sdk/lexicons`:\n *\n * ```typescript\n * import {\n * LexiconRegistry,\n * HYPERCERT_LEXICONS,\n * HYPERCERT_COLLECTIONS,\n * } from \"@hypercerts-org/sdk/lexicons\";\n * ```\n *\n * **Exports**:\n * - {@link LexiconRegistry} - Registry for managing and validating lexicons\n * - {@link HYPERCERT_LEXICONS} - Array of all hypercert lexicon documents\n * - {@link HYPERCERT_COLLECTIONS} - Constants for collection NSIDs\n *\n * @example Using collection constants\n * ```typescript\n * import { HYPERCERT_COLLECTIONS } from \"@hypercerts-org/sdk/lexicons\";\n *\n * // List hypercerts using the correct collection name\n * const records = await repo.records.list({\n * collection: HYPERCERT_COLLECTIONS.RECORD,\n * });\n *\n * // List contributions\n * const contributions = await repo.records.list({\n * collection: HYPERCERT_COLLECTIONS.CONTRIBUTION,\n * });\n * ```\n *\n * @example Custom lexicon registration\n * ```typescript\n * import { LexiconRegistry } from \"@hypercerts-org/sdk/lexicons\";\n *\n * const registry = sdk.getLexiconRegistry();\n *\n * // Register custom lexicon\n * registry.register({\n * lexicon: 1,\n * id: \"org.myapp.customRecord\",\n * defs: { ... },\n * });\n *\n * // Validate a record\n * const result = registry.validate(\"org.myapp.customRecord\", record);\n * if (!result.valid) {\n * console.error(result.error);\n * }\n * ```\n *\n * @packageDocumentation\n */\n\n// Import lexicon JSON files and constants from the published package\nimport type { LexiconDoc } from \"@atproto/lexicon\";\nimport {\n CERTIFIED_DEFS_LEXICON_JSON,\n LOCATION_LEXICON_JSON,\n STRONG_REF_LEXICON_JSON,\n HYPERCERTS_DEFS_LEXICON_JSON,\n ACTIVITY_LEXICON_JSON,\n COLLECTION_LEXICON_JSON,\n CONTRIBUTION_DETAILS_LEXICON_JSON,\n CONTRIBUTOR_INFORMATION_LEXICON_JSON,\n EVALUATION_LEXICON_JSON,\n EVIDENCE_LEXICON_JSON,\n MEASUREMENT_LEXICON_JSON,\n RIGHTS_LEXICON_JSON,\n BADGE_AWARD_LEXICON_JSON,\n BADGE_DEFINITION_LEXICON_JSON,\n BADGE_RESPONSE_LEXICON_JSON,\n FUNDING_RECEIPT_LEXICON_JSON,\n WORK_SCOPE_TAG_LEXICON_JSON,\n // NSID constants\n ACTIVITY_NSID,\n RIGHTS_NSID,\n LOCATION_NSID,\n CONTRIBUTION_DETAILS_NSID,\n CONTRIBUTOR_INFORMATION_NSID,\n MEASUREMENT_NSID,\n EVALUATION_NSID,\n EVIDENCE_NSID,\n COLLECTION_NSID,\n BADGE_AWARD_NSID,\n BADGE_DEFINITION_NSID,\n BADGE_RESPONSE_NSID,\n FUNDING_RECEIPT_NSID,\n WORK_SCOPE_TAG_NSID,\n} from \"@hypercerts-org/lexicon\";\n\n// Export LexiconRegistry for custom lexicon management\nexport { LexiconRegistry } from \"./repository/LexiconRegistry.js\";\nexport type { ValidationResult } from \"./repository/LexiconRegistry.js\";\n\n/**\n * All hypercert-related lexicons for registration with AT Protocol Agent.\n * This array contains all lexicon documents from the published package.\n */\nexport const HYPERCERT_LEXICONS: LexiconDoc[] = [\n CERTIFIED_DEFS_LEXICON_JSON as LexiconDoc,\n LOCATION_LEXICON_JSON as LexiconDoc,\n STRONG_REF_LEXICON_JSON as LexiconDoc,\n HYPERCERTS_DEFS_LEXICON_JSON as LexiconDoc,\n ACTIVITY_LEXICON_JSON as LexiconDoc,\n COLLECTION_LEXICON_JSON as LexiconDoc,\n CONTRIBUTION_DETAILS_LEXICON_JSON as LexiconDoc,\n CONTRIBUTOR_INFORMATION_LEXICON_JSON as LexiconDoc,\n EVALUATION_LEXICON_JSON as LexiconDoc,\n EVIDENCE_LEXICON_JSON as LexiconDoc,\n MEASUREMENT_LEXICON_JSON as LexiconDoc,\n RIGHTS_LEXICON_JSON as LexiconDoc,\n BADGE_AWARD_LEXICON_JSON as LexiconDoc,\n BADGE_DEFINITION_LEXICON_JSON as LexiconDoc,\n BADGE_RESPONSE_LEXICON_JSON as LexiconDoc,\n FUNDING_RECEIPT_LEXICON_JSON as LexiconDoc,\n WORK_SCOPE_TAG_LEXICON_JSON as LexiconDoc,\n];\n\n/**\n * Collection NSIDs (Namespaced Identifiers) for hypercert records.\n *\n * Use these constants when performing record operations to ensure\n * correct collection names.\n */\nexport const HYPERCERT_COLLECTIONS = {\n /**\n * Main hypercert claim record collection.\n */\n CLAIM: ACTIVITY_NSID,\n\n /**\n * Rights record collection.\n */\n RIGHTS: RIGHTS_NSID,\n\n /**\n * Location record collection (shared certified lexicon).\n */\n LOCATION: LOCATION_NSID,\n\n /**\n * Contribution details record collection.\n * For storing details about a specific contribution (role, description, timeframe).\n */\n CONTRIBUTION_DETAILS: CONTRIBUTION_DETAILS_NSID,\n\n /**\n * Contributor information record collection.\n * For storing contributor profile information (identifier, displayName, image).\n */\n CONTRIBUTOR_INFORMATION: CONTRIBUTOR_INFORMATION_NSID,\n\n /**\n * Measurement record collection.\n */\n MEASUREMENT: MEASUREMENT_NSID,\n\n /**\n * Evaluation record collection.\n */\n EVALUATION: EVALUATION_NSID,\n\n /**\n * Evidence record collection.\n */\n EVIDENCE: EVIDENCE_NSID,\n\n /**\n * Collection record collection (groups of hypercerts).\n * Projects are now collections with type='project'.\n */\n COLLECTION: COLLECTION_NSID,\n\n /**\n * Badge award record collection.\n */\n BADGE_AWARD: BADGE_AWARD_NSID,\n\n /**\n * Badge definition record collection.\n */\n BADGE_DEFINITION: BADGE_DEFINITION_NSID,\n\n /**\n * Badge response record collection.\n */\n BADGE_RESPONSE: BADGE_RESPONSE_NSID,\n\n /**\n * Funding receipt record collection.\n */\n FUNDING_RECEIPT: FUNDING_RECEIPT_NSID,\n\n /**\n * Work scope tag record collection.\n * For defining reusable work scope atoms.\n */\n WORK_SCOPE_TAG: WORK_SCOPE_TAG_NSID,\n} as const;\n"],"names":[],"mappings":"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"}
|
package/dist/testing.d.ts
CHANGED
|
@@ -348,22 +348,28 @@ interface LoggerInterface {
|
|
|
348
348
|
* Zod schema for OAuth configuration validation.
|
|
349
349
|
*
|
|
350
350
|
* @remarks
|
|
351
|
-
* All URLs must be valid and use HTTPS in production.
|
|
352
|
-
*
|
|
351
|
+
* All URLs must be valid and use HTTPS in production. For local development,
|
|
352
|
+
* HTTP loopback URLs (localhost, 127.0.0.1, [::1]) are allowed.
|
|
353
|
+
* The `jwkPrivate` field should contain the private key in JWK (JSON Web Key) format as a string.
|
|
353
354
|
*/
|
|
354
355
|
declare const OAuthConfigSchema: z.ZodObject<{
|
|
355
356
|
/**
|
|
356
357
|
* URL to the OAuth client metadata JSON document.
|
|
357
358
|
* This document describes your application to the authorization server.
|
|
358
359
|
*
|
|
360
|
+
* For local development, you can use `http://localhost/` as a loopback client.
|
|
361
|
+
*
|
|
359
362
|
* @see https://atproto.com/specs/oauth#client-metadata
|
|
360
363
|
*/
|
|
361
|
-
clientId: z.ZodString
|
|
364
|
+
clientId: z.ZodEffects<z.ZodString, string, string>;
|
|
362
365
|
/**
|
|
363
366
|
* URL where users are redirected after authentication.
|
|
364
367
|
* Must match one of the redirect URIs in your client metadata.
|
|
368
|
+
*
|
|
369
|
+
* For local development, you can use HTTP loopback URLs like
|
|
370
|
+
* `http://127.0.0.1:3000/callback` or `http://localhost:3000/callback`.
|
|
365
371
|
*/
|
|
366
|
-
redirectUri: z.ZodString
|
|
372
|
+
redirectUri: z.ZodEffects<z.ZodString, string, string>;
|
|
367
373
|
/**
|
|
368
374
|
* OAuth scopes to request, space-separated.
|
|
369
375
|
*
|
|
@@ -397,8 +403,11 @@ declare const OAuthConfigSchema: z.ZodObject<{
|
|
|
397
403
|
/**
|
|
398
404
|
* URL to your public JWKS (JSON Web Key Set) endpoint.
|
|
399
405
|
* Used by the authorization server to verify your client's signatures.
|
|
406
|
+
*
|
|
407
|
+
* For local development, you can serve JWKS from a loopback URL like
|
|
408
|
+
* `http://127.0.0.1:3000/.well-known/jwks.json`.
|
|
400
409
|
*/
|
|
401
|
-
jwksUri: z.ZodString
|
|
410
|
+
jwksUri: z.ZodEffects<z.ZodString, string, string>;
|
|
402
411
|
/**
|
|
403
412
|
* Private JWK (JSON Web Key) as a JSON string.
|
|
404
413
|
* Used for signing DPoP proofs and client assertions.
|
|
@@ -408,40 +417,78 @@ declare const OAuthConfigSchema: z.ZodObject<{
|
|
|
408
417
|
* Typically loaded from environment variables or a secrets manager.
|
|
409
418
|
*/
|
|
410
419
|
jwkPrivate: z.ZodString;
|
|
420
|
+
/**
|
|
421
|
+
* Enable development mode features (optional).
|
|
422
|
+
*
|
|
423
|
+
* When true, suppresses warnings about using HTTP loopback URLs.
|
|
424
|
+
* Should be set to true for local development to reduce console noise.
|
|
425
|
+
*
|
|
426
|
+
* @default false
|
|
427
|
+
*
|
|
428
|
+
* @example
|
|
429
|
+
* ```typescript
|
|
430
|
+
* oauth: {
|
|
431
|
+
* clientId: "http://localhost/",
|
|
432
|
+
* redirectUri: "http://127.0.0.1:3000/callback",
|
|
433
|
+
* // ... other config
|
|
434
|
+
* developmentMode: true, // Suppress loopback warnings
|
|
435
|
+
* }
|
|
436
|
+
* ```
|
|
437
|
+
*/
|
|
438
|
+
developmentMode: z.ZodOptional<z.ZodBoolean>;
|
|
411
439
|
}, "strip", z.ZodTypeAny, {
|
|
412
440
|
clientId: string;
|
|
413
441
|
redirectUri: string;
|
|
414
442
|
scope: string;
|
|
415
443
|
jwksUri: string;
|
|
416
444
|
jwkPrivate: string;
|
|
445
|
+
developmentMode?: boolean | undefined;
|
|
417
446
|
}, {
|
|
418
447
|
clientId: string;
|
|
419
448
|
redirectUri: string;
|
|
420
449
|
scope: string;
|
|
421
450
|
jwksUri: string;
|
|
422
451
|
jwkPrivate: string;
|
|
452
|
+
developmentMode?: boolean | undefined;
|
|
423
453
|
}>;
|
|
424
454
|
/**
|
|
425
455
|
* Zod schema for server URL configuration.
|
|
426
456
|
*
|
|
427
457
|
* @remarks
|
|
428
458
|
* At least one server (PDS or SDS) should be configured for the SDK to be useful.
|
|
459
|
+
* For local development, HTTP loopback URLs are allowed.
|
|
429
460
|
*/
|
|
430
461
|
declare const ServerConfigSchema: z.ZodObject<{
|
|
431
462
|
/**
|
|
432
463
|
* Personal Data Server URL - the user's own AT Protocol server.
|
|
433
464
|
* This is the primary server for user data operations.
|
|
434
465
|
*
|
|
435
|
-
* @example
|
|
466
|
+
* @example Production
|
|
467
|
+
* ```typescript
|
|
468
|
+
* pds: "https://bsky.social"
|
|
469
|
+
* ```
|
|
470
|
+
*
|
|
471
|
+
* @example Local development
|
|
472
|
+
* ```typescript
|
|
473
|
+
* pds: "http://localhost:2583"
|
|
474
|
+
* ```
|
|
436
475
|
*/
|
|
437
|
-
pds: z.ZodOptional<z.ZodString
|
|
476
|
+
pds: z.ZodOptional<z.ZodEffects<z.ZodString, string, string>>;
|
|
438
477
|
/**
|
|
439
478
|
* Shared Data Server URL - for collaborative data storage.
|
|
440
479
|
* Required for collaborator and organization operations.
|
|
441
480
|
*
|
|
442
|
-
* @example
|
|
481
|
+
* @example Production
|
|
482
|
+
* ```typescript
|
|
483
|
+
* sds: "https://sds.hypercerts.org"
|
|
484
|
+
* ```
|
|
485
|
+
*
|
|
486
|
+
* @example Local development
|
|
487
|
+
* ```typescript
|
|
488
|
+
* sds: "http://127.0.0.1:2584"
|
|
489
|
+
* ```
|
|
443
490
|
*/
|
|
444
|
-
sds: z.ZodOptional<z.ZodString
|
|
491
|
+
sds: z.ZodOptional<z.ZodEffects<z.ZodString, string, string>>;
|
|
445
492
|
}, "strip", z.ZodTypeAny, {
|
|
446
493
|
pds?: string | undefined;
|
|
447
494
|
sds?: string | undefined;
|