@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.cjs
CHANGED
|
@@ -1,6 +1,408 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var lexicon = require('@hypercerts-org/lexicon');
|
|
3
|
+
var lexicon$1 = require('@hypercerts-org/lexicon');
|
|
4
|
+
var lexicon = require('@atproto/lexicon');
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Base error class for all SDK errors.
|
|
8
|
+
*
|
|
9
|
+
* All errors thrown by the Hypercerts SDK extend this class, making it easy
|
|
10
|
+
* to catch and handle SDK-specific errors.
|
|
11
|
+
*
|
|
12
|
+
* @example Catching all SDK errors
|
|
13
|
+
* ```typescript
|
|
14
|
+
* try {
|
|
15
|
+
* await sdk.authorize("user.bsky.social");
|
|
16
|
+
* } catch (error) {
|
|
17
|
+
* if (error instanceof ATProtoSDKError) {
|
|
18
|
+
* console.error(`SDK Error [${error.code}]: ${error.message}`);
|
|
19
|
+
* console.error(`HTTP Status: ${error.status}`);
|
|
20
|
+
* }
|
|
21
|
+
* }
|
|
22
|
+
* ```
|
|
23
|
+
*
|
|
24
|
+
* @example Checking error codes
|
|
25
|
+
* ```typescript
|
|
26
|
+
* try {
|
|
27
|
+
* await repo.records.get(collection, rkey);
|
|
28
|
+
* } catch (error) {
|
|
29
|
+
* if (error instanceof ATProtoSDKError) {
|
|
30
|
+
* switch (error.code) {
|
|
31
|
+
* case "AUTHENTICATION_ERROR":
|
|
32
|
+
* // Redirect to login
|
|
33
|
+
* break;
|
|
34
|
+
* case "VALIDATION_ERROR":
|
|
35
|
+
* // Show form errors
|
|
36
|
+
* break;
|
|
37
|
+
* case "NETWORK_ERROR":
|
|
38
|
+
* // Retry or show offline message
|
|
39
|
+
* break;
|
|
40
|
+
* }
|
|
41
|
+
* }
|
|
42
|
+
* }
|
|
43
|
+
* ```
|
|
44
|
+
*/
|
|
45
|
+
class ATProtoSDKError extends Error {
|
|
46
|
+
/**
|
|
47
|
+
* Creates a new SDK error.
|
|
48
|
+
*
|
|
49
|
+
* @param message - Human-readable error description
|
|
50
|
+
* @param code - Machine-readable error code for programmatic handling
|
|
51
|
+
* @param status - HTTP status code associated with this error type
|
|
52
|
+
* @param cause - The underlying error that caused this error, if any
|
|
53
|
+
*/
|
|
54
|
+
constructor(message, code, status, cause) {
|
|
55
|
+
super(message);
|
|
56
|
+
this.code = code;
|
|
57
|
+
this.status = status;
|
|
58
|
+
this.cause = cause;
|
|
59
|
+
this.name = "ATProtoSDKError";
|
|
60
|
+
Error.captureStackTrace?.(this, this.constructor);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Error thrown when input validation fails.
|
|
65
|
+
*
|
|
66
|
+
* This error indicates that provided data doesn't meet the required format
|
|
67
|
+
* or constraints. Common causes:
|
|
68
|
+
* - Missing required fields
|
|
69
|
+
* - Invalid URL formats
|
|
70
|
+
* - Invalid DID format
|
|
71
|
+
* - Schema validation failures for records
|
|
72
|
+
* - Invalid configuration values
|
|
73
|
+
*
|
|
74
|
+
* @example
|
|
75
|
+
* ```typescript
|
|
76
|
+
* try {
|
|
77
|
+
* await sdk.authorize(""); // Empty identifier
|
|
78
|
+
* } catch (error) {
|
|
79
|
+
* if (error instanceof ValidationError) {
|
|
80
|
+
* console.error("Invalid input:", error.message);
|
|
81
|
+
* // Show validation error to user
|
|
82
|
+
* }
|
|
83
|
+
* }
|
|
84
|
+
* ```
|
|
85
|
+
*
|
|
86
|
+
* @example With Zod validation cause
|
|
87
|
+
* ```typescript
|
|
88
|
+
* try {
|
|
89
|
+
* await repo.records.create(collection, record);
|
|
90
|
+
* } catch (error) {
|
|
91
|
+
* if (error instanceof ValidationError && error.cause) {
|
|
92
|
+
* // error.cause may be a ZodError with detailed field errors
|
|
93
|
+
* const zodError = error.cause as ZodError;
|
|
94
|
+
* zodError.errors.forEach(e => {
|
|
95
|
+
* console.error(`Field ${e.path.join(".")}: ${e.message}`);
|
|
96
|
+
* });
|
|
97
|
+
* }
|
|
98
|
+
* }
|
|
99
|
+
* ```
|
|
100
|
+
*/
|
|
101
|
+
class ValidationError extends ATProtoSDKError {
|
|
102
|
+
/**
|
|
103
|
+
* Creates a validation error.
|
|
104
|
+
*
|
|
105
|
+
* @param message - Description of what validation failed
|
|
106
|
+
* @param cause - The underlying validation error (e.g., ZodError)
|
|
107
|
+
*/
|
|
108
|
+
constructor(message, cause) {
|
|
109
|
+
super(message, "VALIDATION_ERROR", 400, cause);
|
|
110
|
+
this.name = "ValidationError";
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* LexiconRegistry - Manages custom lexicon registration and validation.
|
|
116
|
+
*
|
|
117
|
+
* This module provides a registry for AT Protocol lexicon schemas,
|
|
118
|
+
* allowing developers to register custom lexicons and validate records
|
|
119
|
+
* against registered schemas.
|
|
120
|
+
*
|
|
121
|
+
* @packageDocumentation
|
|
122
|
+
*/
|
|
123
|
+
/**
|
|
124
|
+
* Registry for managing AT Protocol lexicon schemas.
|
|
125
|
+
*
|
|
126
|
+
* The LexiconRegistry allows developers to:
|
|
127
|
+
* - Register custom lexicon definitions
|
|
128
|
+
* - Validate records against registered schemas
|
|
129
|
+
* - Query registered lexicons
|
|
130
|
+
* - Add lexicons to AT Protocol agents
|
|
131
|
+
*
|
|
132
|
+
* @example Basic usage
|
|
133
|
+
* ```typescript
|
|
134
|
+
* const registry = new LexiconRegistry();
|
|
135
|
+
*
|
|
136
|
+
* // Register a custom lexicon
|
|
137
|
+
* registry.register({
|
|
138
|
+
* lexicon: 1,
|
|
139
|
+
* id: "org.myapp.customRecord",
|
|
140
|
+
* defs: {
|
|
141
|
+
* main: {
|
|
142
|
+
* type: "record",
|
|
143
|
+
* key: "tid",
|
|
144
|
+
* record: {
|
|
145
|
+
* type: "object",
|
|
146
|
+
* required: ["$type", "title"],
|
|
147
|
+
* properties: {
|
|
148
|
+
* "$type": { type: "string", const: "org.myapp.customRecord" },
|
|
149
|
+
* title: { type: "string" }
|
|
150
|
+
* }
|
|
151
|
+
* }
|
|
152
|
+
* }
|
|
153
|
+
* }
|
|
154
|
+
* });
|
|
155
|
+
*
|
|
156
|
+
* // Validate a record
|
|
157
|
+
* const result = registry.validate("org.myapp.customRecord", {
|
|
158
|
+
* $type: "org.myapp.customRecord",
|
|
159
|
+
* title: "My Record"
|
|
160
|
+
* });
|
|
161
|
+
*
|
|
162
|
+
* if (!result.valid) {
|
|
163
|
+
* console.error(result.error);
|
|
164
|
+
* }
|
|
165
|
+
* ```
|
|
166
|
+
*/
|
|
167
|
+
class LexiconRegistry {
|
|
168
|
+
/**
|
|
169
|
+
* Creates a new LexiconRegistry instance.
|
|
170
|
+
*
|
|
171
|
+
* @param initialLexicons - Optional array of lexicons to register on initialization
|
|
172
|
+
*/
|
|
173
|
+
constructor(initialLexicons) {
|
|
174
|
+
this.lexicons = new lexicon.Lexicons();
|
|
175
|
+
this.registeredIds = new Set();
|
|
176
|
+
if (initialLexicons && initialLexicons.length > 0) {
|
|
177
|
+
this.registerMany(initialLexicons);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Registers a single lexicon definition.
|
|
182
|
+
*
|
|
183
|
+
* @param lexicon - The lexicon document to register
|
|
184
|
+
* @throws {Error} If the lexicon is invalid or already registered
|
|
185
|
+
*
|
|
186
|
+
* @example
|
|
187
|
+
* ```typescript
|
|
188
|
+
* registry.register({
|
|
189
|
+
* lexicon: 1,
|
|
190
|
+
* id: "org.myapp.customRecord",
|
|
191
|
+
* defs: { ... }
|
|
192
|
+
* });
|
|
193
|
+
* ```
|
|
194
|
+
*/
|
|
195
|
+
register(lexicon) {
|
|
196
|
+
if (!lexicon.id) {
|
|
197
|
+
throw new Error("Lexicon must have an id");
|
|
198
|
+
}
|
|
199
|
+
if (this.registeredIds.has(lexicon.id)) {
|
|
200
|
+
throw new Error(`Lexicon ${lexicon.id} is already registered`);
|
|
201
|
+
}
|
|
202
|
+
try {
|
|
203
|
+
// Check if the lexicon already exists in the internal store
|
|
204
|
+
// (e.g., after unregister which only removes from registeredIds)
|
|
205
|
+
const existingLexicon = this.lexicons.get(lexicon.id);
|
|
206
|
+
if (!existingLexicon) {
|
|
207
|
+
// Lexicon is truly new, add it to the store
|
|
208
|
+
this.lexicons.add(lexicon);
|
|
209
|
+
}
|
|
210
|
+
// Always add to registeredIds (re-enable if previously unregistered)
|
|
211
|
+
this.registeredIds.add(lexicon.id);
|
|
212
|
+
}
|
|
213
|
+
catch (error) {
|
|
214
|
+
throw new Error(`Failed to register lexicon ${lexicon.id}: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* Registers multiple lexicon definitions at once.
|
|
219
|
+
*
|
|
220
|
+
* @param lexicons - Array of lexicon documents to register
|
|
221
|
+
* @throws {Error} If any lexicon is invalid or already registered
|
|
222
|
+
*
|
|
223
|
+
* @example
|
|
224
|
+
* ```typescript
|
|
225
|
+
* registry.registerMany([lexicon1, lexicon2, lexicon3]);
|
|
226
|
+
* ```
|
|
227
|
+
*/
|
|
228
|
+
registerMany(lexicons) {
|
|
229
|
+
for (const lexicon of lexicons) {
|
|
230
|
+
this.register(lexicon);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* Registers a lexicon from a JSON object.
|
|
235
|
+
*
|
|
236
|
+
* This is a convenience method for registering lexicons loaded from JSON files.
|
|
237
|
+
*
|
|
238
|
+
* @param lexiconJson - The lexicon as a plain JavaScript object
|
|
239
|
+
* @throws {ValidationError} If the lexicon is not a valid object
|
|
240
|
+
* @throws {Error} If the lexicon is invalid or already registered
|
|
241
|
+
*
|
|
242
|
+
* @example
|
|
243
|
+
* ```typescript
|
|
244
|
+
* import customLexicon from "./custom-lexicon.json";
|
|
245
|
+
* registry.registerFromJSON(customLexicon);
|
|
246
|
+
* ```
|
|
247
|
+
*/
|
|
248
|
+
registerFromJSON(lexiconJson) {
|
|
249
|
+
// Validate that input is an object and not null
|
|
250
|
+
if (typeof lexiconJson !== "object" || lexiconJson === null) {
|
|
251
|
+
throw new ValidationError("Lexicon JSON must be a valid object");
|
|
252
|
+
}
|
|
253
|
+
// Now we can safely cast to LexiconDoc and register
|
|
254
|
+
this.register(lexiconJson);
|
|
255
|
+
}
|
|
256
|
+
/**
|
|
257
|
+
* Unregisters a lexicon by its NSID.
|
|
258
|
+
*
|
|
259
|
+
* @param nsid - The NSID of the lexicon to unregister
|
|
260
|
+
* @returns True if the lexicon was unregistered, false if it wasn't registered
|
|
261
|
+
*
|
|
262
|
+
* @example
|
|
263
|
+
* ```typescript
|
|
264
|
+
* registry.unregister("org.myapp.customRecord");
|
|
265
|
+
* ```
|
|
266
|
+
*/
|
|
267
|
+
unregister(nsid) {
|
|
268
|
+
if (!this.registeredIds.has(nsid)) {
|
|
269
|
+
return false;
|
|
270
|
+
}
|
|
271
|
+
this.registeredIds.delete(nsid);
|
|
272
|
+
// Note: Lexicons class doesn't have a remove method,
|
|
273
|
+
// so we can't actually remove from the internal store.
|
|
274
|
+
// We track removal in our Set for isRegistered checks.
|
|
275
|
+
return true;
|
|
276
|
+
}
|
|
277
|
+
/**
|
|
278
|
+
* Checks if a lexicon is registered.
|
|
279
|
+
*
|
|
280
|
+
* @param nsid - The NSID to check
|
|
281
|
+
* @returns True if the lexicon is registered
|
|
282
|
+
*
|
|
283
|
+
* @example
|
|
284
|
+
* ```typescript
|
|
285
|
+
* if (registry.isRegistered("org.myapp.customRecord")) {
|
|
286
|
+
* // Lexicon is available
|
|
287
|
+
* }
|
|
288
|
+
* ```
|
|
289
|
+
*/
|
|
290
|
+
isRegistered(nsid) {
|
|
291
|
+
return this.registeredIds.has(nsid);
|
|
292
|
+
}
|
|
293
|
+
/**
|
|
294
|
+
* Gets a lexicon definition by its NSID.
|
|
295
|
+
*
|
|
296
|
+
* @param nsid - The NSID of the lexicon to retrieve
|
|
297
|
+
* @returns The lexicon document, or undefined if not found
|
|
298
|
+
*
|
|
299
|
+
* @example
|
|
300
|
+
* ```typescript
|
|
301
|
+
* const lexicon = registry.get("org.myapp.customRecord");
|
|
302
|
+
* if (lexicon) {
|
|
303
|
+
* console.log(lexicon.defs);
|
|
304
|
+
* }
|
|
305
|
+
* ```
|
|
306
|
+
*/
|
|
307
|
+
get(nsid) {
|
|
308
|
+
if (!this.isRegistered(nsid)) {
|
|
309
|
+
return undefined;
|
|
310
|
+
}
|
|
311
|
+
return this.lexicons.get(nsid);
|
|
312
|
+
}
|
|
313
|
+
/**
|
|
314
|
+
* Gets all registered lexicon NSIDs.
|
|
315
|
+
*
|
|
316
|
+
* @returns Array of registered NSIDs
|
|
317
|
+
*
|
|
318
|
+
* @example
|
|
319
|
+
* ```typescript
|
|
320
|
+
* const registered = registry.getAll();
|
|
321
|
+
* console.log(`Registered lexicons: ${registered.join(", ")}`);
|
|
322
|
+
* ```
|
|
323
|
+
*/
|
|
324
|
+
getAll() {
|
|
325
|
+
return Array.from(this.registeredIds);
|
|
326
|
+
}
|
|
327
|
+
/**
|
|
328
|
+
* Validates a record against a registered lexicon.
|
|
329
|
+
*
|
|
330
|
+
* @param nsid - The collection NSID to validate against
|
|
331
|
+
* @param record - The record data to validate
|
|
332
|
+
* @returns Validation result with success status and optional error message
|
|
333
|
+
*
|
|
334
|
+
* @example
|
|
335
|
+
* ```typescript
|
|
336
|
+
* const result = registry.validate("org.myapp.customRecord", {
|
|
337
|
+
* $type: "org.myapp.customRecord",
|
|
338
|
+
* title: "My Record"
|
|
339
|
+
* });
|
|
340
|
+
*
|
|
341
|
+
* if (!result.valid) {
|
|
342
|
+
* console.error(`Validation failed: ${result.error}`);
|
|
343
|
+
* }
|
|
344
|
+
* ```
|
|
345
|
+
*/
|
|
346
|
+
validate(nsid, record) {
|
|
347
|
+
if (!this.isRegistered(nsid)) {
|
|
348
|
+
return {
|
|
349
|
+
valid: false,
|
|
350
|
+
error: `Lexicon ${nsid} is not registered`,
|
|
351
|
+
};
|
|
352
|
+
}
|
|
353
|
+
try {
|
|
354
|
+
this.lexicons.assertValidRecord(nsid, record);
|
|
355
|
+
return { valid: true };
|
|
356
|
+
}
|
|
357
|
+
catch (error) {
|
|
358
|
+
return {
|
|
359
|
+
valid: false,
|
|
360
|
+
error: error instanceof Error ? error.message : "Validation failed",
|
|
361
|
+
};
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
/**
|
|
365
|
+
* Adds all registered lexicons to an AT Protocol Agent.
|
|
366
|
+
*
|
|
367
|
+
* This method is currently a no-op as the AT Protocol Agent
|
|
368
|
+
* doesn't provide a public API for adding lexicons at runtime.
|
|
369
|
+
* Lexicons must be registered with the server.
|
|
370
|
+
*
|
|
371
|
+
* This method is kept for future compatibility if the API
|
|
372
|
+
* adds support for client-side lexicon registration.
|
|
373
|
+
*
|
|
374
|
+
* @param _agent - The AT Protocol Agent (currently unused)
|
|
375
|
+
*
|
|
376
|
+
* @example
|
|
377
|
+
* ```typescript
|
|
378
|
+
* const agent = new Agent(session);
|
|
379
|
+
* registry.addToAgent(agent);
|
|
380
|
+
* // Reserved for future use
|
|
381
|
+
* ```
|
|
382
|
+
*/
|
|
383
|
+
addToAgent(_agent) {
|
|
384
|
+
// No-op: AT Protocol Agent doesn't support client-side lexicon addition
|
|
385
|
+
// Lexicons are validated client-side via this registry,
|
|
386
|
+
// but server-side validation is performed by the PDS/SDS
|
|
387
|
+
}
|
|
388
|
+
/**
|
|
389
|
+
* Gets the underlying Lexicons instance.
|
|
390
|
+
*
|
|
391
|
+
* This provides direct access to the AT Protocol Lexicons object
|
|
392
|
+
* for advanced use cases.
|
|
393
|
+
*
|
|
394
|
+
* @returns The internal Lexicons instance
|
|
395
|
+
*
|
|
396
|
+
* @example
|
|
397
|
+
* ```typescript
|
|
398
|
+
* const lexicons = registry.getLexicons();
|
|
399
|
+
* // Use lexicons directly for advanced operations
|
|
400
|
+
* ```
|
|
401
|
+
*/
|
|
402
|
+
getLexicons() {
|
|
403
|
+
return this.lexicons;
|
|
404
|
+
}
|
|
405
|
+
}
|
|
4
406
|
|
|
5
407
|
/**
|
|
6
408
|
* Lexicons entrypoint - Lexicon definitions and registry.
|
|
@@ -66,22 +468,23 @@ var lexicon = require('@hypercerts-org/lexicon');
|
|
|
66
468
|
* This array contains all lexicon documents from the published package.
|
|
67
469
|
*/
|
|
68
470
|
const HYPERCERT_LEXICONS = [
|
|
69
|
-
lexicon.CERTIFIED_DEFS_LEXICON_JSON,
|
|
70
|
-
lexicon.LOCATION_LEXICON_JSON,
|
|
71
|
-
lexicon.
|
|
72
|
-
lexicon.HYPERCERTS_DEFS_LEXICON_JSON,
|
|
73
|
-
lexicon.ACTIVITY_LEXICON_JSON,
|
|
74
|
-
lexicon.COLLECTION_LEXICON_JSON,
|
|
75
|
-
lexicon.
|
|
76
|
-
lexicon.
|
|
77
|
-
lexicon.
|
|
78
|
-
lexicon.
|
|
79
|
-
lexicon.
|
|
80
|
-
lexicon.
|
|
81
|
-
lexicon.BADGE_AWARD_LEXICON_JSON,
|
|
82
|
-
lexicon.BADGE_DEFINITION_LEXICON_JSON,
|
|
83
|
-
lexicon.BADGE_RESPONSE_LEXICON_JSON,
|
|
84
|
-
lexicon.FUNDING_RECEIPT_LEXICON_JSON,
|
|
471
|
+
lexicon$1.CERTIFIED_DEFS_LEXICON_JSON,
|
|
472
|
+
lexicon$1.LOCATION_LEXICON_JSON,
|
|
473
|
+
lexicon$1.STRONG_REF_LEXICON_JSON,
|
|
474
|
+
lexicon$1.HYPERCERTS_DEFS_LEXICON_JSON,
|
|
475
|
+
lexicon$1.ACTIVITY_LEXICON_JSON,
|
|
476
|
+
lexicon$1.COLLECTION_LEXICON_JSON,
|
|
477
|
+
lexicon$1.CONTRIBUTION_DETAILS_LEXICON_JSON,
|
|
478
|
+
lexicon$1.CONTRIBUTOR_INFORMATION_LEXICON_JSON,
|
|
479
|
+
lexicon$1.EVALUATION_LEXICON_JSON,
|
|
480
|
+
lexicon$1.EVIDENCE_LEXICON_JSON,
|
|
481
|
+
lexicon$1.MEASUREMENT_LEXICON_JSON,
|
|
482
|
+
lexicon$1.RIGHTS_LEXICON_JSON,
|
|
483
|
+
lexicon$1.BADGE_AWARD_LEXICON_JSON,
|
|
484
|
+
lexicon$1.BADGE_DEFINITION_LEXICON_JSON,
|
|
485
|
+
lexicon$1.BADGE_RESPONSE_LEXICON_JSON,
|
|
486
|
+
lexicon$1.FUNDING_RECEIPT_LEXICON_JSON,
|
|
487
|
+
lexicon$1.WORK_SCOPE_TAG_LEXICON_JSON,
|
|
85
488
|
];
|
|
86
489
|
/**
|
|
87
490
|
* Collection NSIDs (Namespaced Identifiers) for hypercert records.
|
|
@@ -93,57 +496,66 @@ const HYPERCERT_COLLECTIONS = {
|
|
|
93
496
|
/**
|
|
94
497
|
* Main hypercert claim record collection.
|
|
95
498
|
*/
|
|
96
|
-
CLAIM: lexicon.ACTIVITY_NSID,
|
|
499
|
+
CLAIM: lexicon$1.ACTIVITY_NSID,
|
|
97
500
|
/**
|
|
98
501
|
* Rights record collection.
|
|
99
502
|
*/
|
|
100
|
-
RIGHTS: lexicon.RIGHTS_NSID,
|
|
503
|
+
RIGHTS: lexicon$1.RIGHTS_NSID,
|
|
101
504
|
/**
|
|
102
505
|
* Location record collection (shared certified lexicon).
|
|
103
506
|
*/
|
|
104
|
-
LOCATION: lexicon.LOCATION_NSID,
|
|
507
|
+
LOCATION: lexicon$1.LOCATION_NSID,
|
|
508
|
+
/**
|
|
509
|
+
* Contribution details record collection.
|
|
510
|
+
* For storing details about a specific contribution (role, description, timeframe).
|
|
511
|
+
*/
|
|
512
|
+
CONTRIBUTION_DETAILS: lexicon$1.CONTRIBUTION_DETAILS_NSID,
|
|
105
513
|
/**
|
|
106
|
-
*
|
|
514
|
+
* Contributor information record collection.
|
|
515
|
+
* For storing contributor profile information (identifier, displayName, image).
|
|
107
516
|
*/
|
|
108
|
-
|
|
517
|
+
CONTRIBUTOR_INFORMATION: lexicon$1.CONTRIBUTOR_INFORMATION_NSID,
|
|
109
518
|
/**
|
|
110
519
|
* Measurement record collection.
|
|
111
520
|
*/
|
|
112
|
-
MEASUREMENT: lexicon.MEASUREMENT_NSID,
|
|
521
|
+
MEASUREMENT: lexicon$1.MEASUREMENT_NSID,
|
|
113
522
|
/**
|
|
114
523
|
* Evaluation record collection.
|
|
115
524
|
*/
|
|
116
|
-
EVALUATION: lexicon.EVALUATION_NSID,
|
|
525
|
+
EVALUATION: lexicon$1.EVALUATION_NSID,
|
|
117
526
|
/**
|
|
118
527
|
* Evidence record collection.
|
|
119
528
|
*/
|
|
120
|
-
EVIDENCE: lexicon.EVIDENCE_NSID,
|
|
529
|
+
EVIDENCE: lexicon$1.EVIDENCE_NSID,
|
|
121
530
|
/**
|
|
122
531
|
* Collection record collection (groups of hypercerts).
|
|
532
|
+
* Projects are now collections with type='project'.
|
|
123
533
|
*/
|
|
124
|
-
COLLECTION: lexicon.COLLECTION_NSID,
|
|
125
|
-
/**
|
|
126
|
-
* Project record collection.
|
|
127
|
-
*/
|
|
128
|
-
PROJECT: lexicon.PROJECT_NSID,
|
|
534
|
+
COLLECTION: lexicon$1.COLLECTION_NSID,
|
|
129
535
|
/**
|
|
130
536
|
* Badge award record collection.
|
|
131
537
|
*/
|
|
132
|
-
BADGE_AWARD: lexicon.BADGE_AWARD_NSID,
|
|
538
|
+
BADGE_AWARD: lexicon$1.BADGE_AWARD_NSID,
|
|
133
539
|
/**
|
|
134
540
|
* Badge definition record collection.
|
|
135
541
|
*/
|
|
136
|
-
BADGE_DEFINITION: lexicon.BADGE_DEFINITION_NSID,
|
|
542
|
+
BADGE_DEFINITION: lexicon$1.BADGE_DEFINITION_NSID,
|
|
137
543
|
/**
|
|
138
544
|
* Badge response record collection.
|
|
139
545
|
*/
|
|
140
|
-
BADGE_RESPONSE: lexicon.BADGE_RESPONSE_NSID,
|
|
546
|
+
BADGE_RESPONSE: lexicon$1.BADGE_RESPONSE_NSID,
|
|
141
547
|
/**
|
|
142
548
|
* Funding receipt record collection.
|
|
143
549
|
*/
|
|
144
|
-
FUNDING_RECEIPT: lexicon.FUNDING_RECEIPT_NSID,
|
|
550
|
+
FUNDING_RECEIPT: lexicon$1.FUNDING_RECEIPT_NSID,
|
|
551
|
+
/**
|
|
552
|
+
* Work scope tag record collection.
|
|
553
|
+
* For defining reusable work scope atoms.
|
|
554
|
+
*/
|
|
555
|
+
WORK_SCOPE_TAG: lexicon$1.WORK_SCOPE_TAG_NSID,
|
|
145
556
|
};
|
|
146
557
|
|
|
147
558
|
exports.HYPERCERT_COLLECTIONS = HYPERCERT_COLLECTIONS;
|
|
148
559
|
exports.HYPERCERT_LEXICONS = HYPERCERT_LEXICONS;
|
|
560
|
+
exports.LexiconRegistry = LexiconRegistry;
|
|
149
561
|
//# sourceMappingURL=lexicons.cjs.map
|
package/dist/lexicons.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lexicons.cjs","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":["CERTIFIED_DEFS_LEXICON_JSON","LOCATION_LEXICON_JSON","STRONGREF_LEXICON_JSON","HYPERCERTS_DEFS_LEXICON_JSON","ACTIVITY_LEXICON_JSON","COLLECTION_LEXICON_JSON","CONTRIBUTION_LEXICON_JSON","EVALUATION_LEXICON_JSON","EVIDENCE_LEXICON_JSON","MEASUREMENT_LEXICON_JSON","RIGHTS_LEXICON_JSON","PROJECT_LEXICON_JSON","BADGE_AWARD_LEXICON_JSON","BADGE_DEFINITION_LEXICON_JSON","BADGE_RESPONSE_LEXICON_JSON","FUNDING_RECEIPT_LEXICON_JSON","ACTIVITY_NSID","RIGHTS_NSID","LOCATION_NSID","CONTRIBUTION_NSID","MEASUREMENT_NSID","EVALUATION_NSID","EVIDENCE_NSID","COLLECTION_NSID","PROJECT_NSID","BADGE_AWARD_NSID","BADGE_DEFINITION_NSID","BADGE_RESPONSE_NSID","FUNDING_RECEIPT_NSID"],"mappings":";;;;AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA0DG;AAqCH;;;AAGG;AACI,MAAM,kBAAkB,GAAiB;IAC9CA,mCAAyC;IACzCC,6BAAmC;IACnCC,8BAAoC;IACpCC,oCAA0C;IAC1CC,6BAAmC;IACnCC,+BAAqC;IACrCC,iCAAuC;IACvCC,+BAAqC;IACrCC,6BAAmC;IACnCC,gCAAsC;IACtCC,2BAAiC;IACjCC,4BAAkC;IAClCC,gCAAsC;IACtCC,qCAA2C;IAC3CC,mCAAyC;IACzCC,oCAA0C;;AAG5C;;;;;AAKG;AACI,MAAM,qBAAqB,GAAG;AACnC;;AAEG;AACH,IAAA,KAAK,EAAEC,qBAAa;AAEpB;;AAEG;AACH,IAAA,MAAM,EAAEC,mBAAW;AAEnB;;AAEG;AACH,IAAA,QAAQ,EAAEC,qBAAa;AAEvB;;AAEG;AACH,IAAA,YAAY,EAAEC,yBAAiB;AAE/B;;AAEG;AACH,IAAA,WAAW,EAAEC,wBAAgB;AAE7B;;AAEG;AACH,IAAA,UAAU,EAAEC,uBAAe;AAE3B;;AAEG;AACH,IAAA,QAAQ,EAAEC,qBAAa;AAEvB;;AAEG;AACH,IAAA,UAAU,EAAEC,uBAAe;AAE3B;;AAEG;AACH,IAAA,OAAO,EAAEC,oBAAY;AAErB;;AAEG;AACH,IAAA,WAAW,EAAEC,wBAAgB;AAE7B;;AAEG;AACH,IAAA,gBAAgB,EAAEC,6BAAqB;AAEvC;;AAEG;AACH,IAAA,cAAc,EAAEC,2BAAmB;AAEnC;;AAEG;AACH,IAAA,eAAe,EAAEC,4BAAoB;;;;;;"}
|
|
1
|
+
{"version":3,"file":"lexicons.cjs","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":["Lexicons","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","ACTIVITY_NSID","RIGHTS_NSID","LOCATION_NSID","CONTRIBUTION_DETAILS_NSID","CONTRIBUTOR_INFORMATION_NSID","MEASUREMENT_NSID","EVALUATION_NSID","EVIDENCE_NSID","COLLECTION_NSID","BADGE_AWARD_NSID","BADGE_DEFINITION_NSID","BADGE_RESPONSE_NSID","FUNDING_RECEIPT_NSID","WORK_SCOPE_TAG_NSID"],"mappings":";;;;;AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAsCG;AACG,MAAO,eAAgB,SAAQ,KAAK,CAAA;AACxC;;;;;;;AAOG;AACH,IAAA,WAAA,CACE,OAAe,EACR,IAAY,EACZ,MAAe,EACf,KAAe,EAAA;QAEtB,KAAK,CAAC,OAAO,CAAC;QAJP,IAAA,CAAA,IAAI,GAAJ,IAAI;QACJ,IAAA,CAAA,MAAM,GAAN,MAAM;QACN,IAAA,CAAA,KAAK,GAAL,KAAK;AAGZ,QAAA,IAAI,CAAC,IAAI,GAAG,iBAAiB;QAC7B,KAAK,CAAC,iBAAiB,GAAG,IAAI,EAAE,IAAI,CAAC,WAAW,CAAC;IACnD;AACD;AAyED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAqCG;AACG,MAAO,eAAgB,SAAQ,eAAe,CAAA;AAClD;;;;;AAKG;IACH,WAAA,CAAY,OAAe,EAAE,KAAe,EAAA;QAC1C,KAAK,CAAC,OAAO,EAAE,kBAAkB,EAAE,GAAG,EAAE,KAAK,CAAC;AAC9C,QAAA,IAAI,CAAC,IAAI,GAAG,iBAAiB;IAC/B;AACD;;ACpLD;;;;;;;;AAQG;AAsBH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2CG;MACU,eAAe,CAAA;AAI1B;;;;AAIG;AACH,IAAA,WAAA,CAAY,eAA8B,EAAA;AACxC,QAAA,IAAI,CAAC,QAAQ,GAAG,IAAIA,gBAAQ,EAAE;AAC9B,QAAA,IAAI,CAAC,aAAa,GAAG,IAAI,GAAG,EAAE;QAE9B,IAAI,eAAe,IAAI,eAAe,CAAC,MAAM,GAAG,CAAC,EAAE;AACjD,YAAA,IAAI,CAAC,YAAY,CAAC,eAAe,CAAC;QACpC;IACF;AAEA;;;;;;;;;;;;;;AAcG;AACH,IAAA,QAAQ,CAAC,OAAmB,EAAA;AAC1B,QAAA,IAAI,CAAC,OAAO,CAAC,EAAE,EAAE;AACf,YAAA,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC;QAC5C;QAEA,IAAI,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE;YACtC,MAAM,IAAI,KAAK,CAAC,CAAA,QAAA,EAAW,OAAO,CAAC,EAAE,CAAA,sBAAA,CAAwB,CAAC;QAChE;AAEA,QAAA,IAAI;;;AAGF,YAAA,MAAM,eAAe,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;YAErD,IAAI,CAAC,eAAe,EAAE;;AAEpB,gBAAA,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC;YAC5B;;YAGA,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;QACpC;QAAE,OAAO,KAAK,EAAE;YACd,MAAM,IAAI,KAAK,CACb,CAAA,2BAAA,EAA8B,OAAO,CAAC,EAAE,CAAA,EAAA,EAAK,KAAK,YAAY,KAAK,GAAG,KAAK,CAAC,OAAO,GAAG,eAAe,CAAA,CAAE,CACxG;QACH;IACF;AAEA;;;;;;;;;;AAUG;AACH,IAAA,YAAY,CAAC,QAAsB,EAAA;AACjC,QAAA,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE;AAC9B,YAAA,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC;QACxB;IACF;AAEA;;;;;;;;;;;;;;AAcG;AACH,IAAA,gBAAgB,CAAC,WAAoB,EAAA;;QAEnC,IAAI,OAAO,WAAW,KAAK,QAAQ,IAAI,WAAW,KAAK,IAAI,EAAE;AAC3D,YAAA,MAAM,IAAI,eAAe,CAAC,qCAAqC,CAAC;QAClE;;AAGA,QAAA,IAAI,CAAC,QAAQ,CAAC,WAAyB,CAAC;IAC1C;AAEA;;;;;;;;;;AAUG;AACH,IAAA,UAAU,CAAC,IAAY,EAAA;QACrB,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE;AACjC,YAAA,OAAO,KAAK;QACd;AAEA,QAAA,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC;;;;AAI/B,QAAA,OAAO,IAAI;IACb;AAEA;;;;;;;;;;;;AAYG;AACH,IAAA,YAAY,CAAC,IAAY,EAAA;QACvB,OAAO,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC;IACrC;AAEA;;;;;;;;;;;;;AAaG;AACH,IAAA,GAAG,CAAC,IAAY,EAAA;QACd,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE;AAC5B,YAAA,OAAO,SAAS;QAClB;QAEA,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC;IAChC;AAEA;;;;;;;;;;AAUG;IACH,MAAM,GAAA;QACJ,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC;IACvC;AAEA;;;;;;;;;;;;;;;;;;AAkBG;IACH,QAAQ,CAAC,IAAY,EAAE,MAAe,EAAA;QACpC,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE;YAC5B,OAAO;AACL,gBAAA,KAAK,EAAE,KAAK;gBACZ,KAAK,EAAE,CAAA,QAAA,EAAW,IAAI,CAAA,kBAAA,CAAoB;aAC3C;QACH;AAEA,QAAA,IAAI;YACF,IAAI,CAAC,QAAQ,CAAC,iBAAiB,CAAC,IAAI,EAAE,MAAM,CAAC;AAC7C,YAAA,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE;QACxB;QAAE,OAAO,KAAK,EAAE;YACd,OAAO;AACL,gBAAA,KAAK,EAAE,KAAK;AACZ,gBAAA,KAAK,EAAE,KAAK,YAAY,KAAK,GAAG,KAAK,CAAC,OAAO,GAAG,mBAAmB;aACpE;QACH;IACF;AAEA;;;;;;;;;;;;;;;;;;AAkBG;AACH,IAAA,UAAU,CAAC,MAAa,EAAA;;;;IAIxB;AAEA;;;;;;;;;;;;;AAaG;IACH,WAAW,GAAA;QACT,OAAO,IAAI,CAAC,QAAQ;IACtB;AACD;;AC9UD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA0DG;AA2CH;;;AAGG;AACI,MAAM,kBAAkB,GAAiB;IAC9CC,qCAAyC;IACzCC,+BAAmC;IACnCC,iCAAqC;IACrCC,sCAA0C;IAC1CC,+BAAmC;IACnCC,iCAAqC;IACrCC,2CAA+C;IAC/CC,8CAAkD;IAClDC,iCAAqC;IACrCC,+BAAmC;IACnCC,kCAAsC;IACtCC,6BAAiC;IACjCC,kCAAsC;IACtCC,uCAA2C;IAC3CC,qCAAyC;IACzCC,sCAA0C;IAC1CC,qCAAyC;;AAG3C;;;;;AAKG;AACI,MAAM,qBAAqB,GAAG;AACnC;;AAEG;AACH,IAAA,KAAK,EAAEC,uBAAa;AAEpB;;AAEG;AACH,IAAA,MAAM,EAAEC,qBAAW;AAEnB;;AAEG;AACH,IAAA,QAAQ,EAAEC,uBAAa;AAEvB;;;AAGG;AACH,IAAA,oBAAoB,EAAEC,mCAAyB;AAE/C;;;AAGG;AACH,IAAA,uBAAuB,EAAEC,sCAA4B;AAErD;;AAEG;AACH,IAAA,WAAW,EAAEC,0BAAgB;AAE7B;;AAEG;AACH,IAAA,UAAU,EAAEC,yBAAe;AAE3B;;AAEG;AACH,IAAA,QAAQ,EAAEC,uBAAa;AAEvB;;;AAGG;AACH,IAAA,UAAU,EAAEC,yBAAe;AAE3B;;AAEG;AACH,IAAA,WAAW,EAAEC,0BAAgB;AAE7B;;AAEG;AACH,IAAA,gBAAgB,EAAEC,+BAAqB;AAEvC;;AAEG;AACH,IAAA,cAAc,EAAEC,6BAAmB;AAEnC;;AAEG;AACH,IAAA,eAAe,EAAEC,8BAAoB;AAErC;;;AAGG;AACH,IAAA,cAAc,EAAEC,6BAAmB;;;;;;;"}
|