@atproto/lex-resolver 0.0.22 → 0.1.0-next.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,40 @@
1
1
  # @atproto/lex-resolver
2
2
 
3
+ ## 0.1.0-next.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#4929](https://github.com/bluesky-social/atproto/pull/4929) [`bb7491c`](https://github.com/bluesky-social/atproto/commit/bb7491c29e06181e1d2f8cf6eb454f9bb8ab961b) Thanks [@devinivy](https://github.com/devinivy)! - **BREAKING:** Drop support for Node.js 18 and 20. Node.js 22 is now the minimum supported version. Docker images now use Node.js 24.
8
+
9
+ - [#4943](https://github.com/bluesky-social/atproto/pull/4943) [`07ae5d4`](https://github.com/bluesky-social/atproto/commit/07ae5d4452df51e045e0239da7a04cf0bc154028) Thanks [@devinivy](https://github.com/devinivy)! - **BREAKING:** Convert to pure ESM. All packages now ship `"type": "module"` with ES module output and Node16 module resolution.
10
+
11
+ Node.js 22's `require()` compatibility layer can still load these packages in CommonJS code.
12
+
13
+ - [#4930](https://github.com/bluesky-social/atproto/pull/4930) [`042df15`](https://github.com/bluesky-social/atproto/commit/042df15087c0e62cd1e715fcbf58852fab875af9) Thanks [@devinivy](https://github.com/devinivy)! - Build with TypeScript 6.0. Emitted `.d.ts` files now use TypeScript 6's stricter `Uint8Array<ArrayBuffer>` typing in places where Web/Node APIs require buffer-backed (not shared-memory) byte arrays. Consumers compiling against these types on older TypeScript should see no runtime impact, but may need to widen or cast in spots that previously relied on `Uint8Array` defaulting to `<ArrayBufferLike>`.
14
+
15
+ Internal: tsconfig `moduleResolution: "node"` is silenced via `ignoreDeprecations: "6.0"` for now; the proper migration to `node16`/`bundler` resolution is deferred.
16
+
17
+ ### Patch Changes
18
+
19
+ - Updated dependencies [[`bb7491c`](https://github.com/bluesky-social/atproto/commit/bb7491c29e06181e1d2f8cf6eb454f9bb8ab961b), [`07ae5d4`](https://github.com/bluesky-social/atproto/commit/07ae5d4452df51e045e0239da7a04cf0bc154028), [`042df15`](https://github.com/bluesky-social/atproto/commit/042df15087c0e62cd1e715fcbf58852fab875af9)]:
20
+ - @atproto/crypto@0.5.0-next.0
21
+ - @atproto/lex-client@0.1.0-next.0
22
+ - @atproto/lex-data@0.1.0-next.0
23
+ - @atproto/lex-document@0.1.0-next.0
24
+ - @atproto/lex-schema@0.1.0-next.0
25
+ - @atproto/repo@0.10.0-next.0
26
+ - @atproto/syntax@0.6.0-next.0
27
+ - @atproto-labs/did-resolver@0.3.0-next.0
28
+
29
+ ## 0.0.23
30
+
31
+ ### Patch Changes
32
+
33
+ - Updated dependencies [[`2fd8d62`](https://github.com/bluesky-social/atproto/commit/2fd8d62708dc23de6ed21cbcccfebab68b19f588), [`907edfa`](https://github.com/bluesky-social/atproto/commit/907edfa1d16b1074bab4dc617d0bd1a810f3da02)]:
34
+ - @atproto/lex-schema@0.0.20
35
+ - @atproto/lex-client@0.0.21
36
+ - @atproto/lex-document@0.0.21
37
+
3
38
  ## 0.0.22
4
39
 
5
40
  ### Patch Changes
package/dist/index.js CHANGED
@@ -1,6 +1,3 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const tslib_1 = require("tslib");
4
- tslib_1.__exportStar(require("./lex-resolver.js"), exports);
5
- tslib_1.__exportStar(require("./lex-resolver-error.js"), exports);
1
+ export * from './lex-resolver.js';
2
+ export * from './lex-resolver-error.js';
6
3
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,4DAAiC;AACjC,kEAAuC","sourcesContent":["export * from './lex-resolver.js'\nexport * from './lex-resolver-error.js'\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAA;AACjC,cAAc,yBAAyB,CAAA","sourcesContent":["export * from './lex-resolver.js'\nexport * from './lex-resolver-error.js'\n"]}
@@ -1,8 +1,5 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.LexResolverError = void 0;
4
- const lex_data_1 = require("@atproto/lex-data");
5
- const syntax_1 = require("@atproto/syntax");
1
+ import { LexError } from '@atproto/lex-data';
2
+ import { NSID } from '@atproto/syntax';
6
3
  /**
7
4
  * Error class for lexicon resolution failures.
8
5
  *
@@ -40,10 +37,7 @@ const syntax_1 = require("@atproto/syntax");
40
37
  * )
41
38
  * ```
42
39
  */
43
- class LexResolverError extends lex_data_1.LexError {
44
- nsid;
45
- description;
46
- name = 'LexResolverError';
40
+ export class LexResolverError extends LexError {
47
41
  /**
48
42
  * Creates a new LexResolverError instance.
49
43
  *
@@ -77,6 +71,7 @@ class LexResolverError extends lex_data_1.LexError {
77
71
  super('LexiconResolutionFailure', `${description} (${nsid})`, options);
78
72
  this.nsid = nsid;
79
73
  this.description = description;
74
+ this.name = 'LexResolverError';
80
75
  }
81
76
  /**
82
77
  * Factory method to create a LexResolverError from a string or NSID.
@@ -103,8 +98,7 @@ class LexResolverError extends lex_data_1.LexError {
103
98
  * ```
104
99
  */
105
100
  static from(nsid, description) {
106
- return new LexResolverError(typeof nsid === 'string' ? syntax_1.NSID.from(nsid) : nsid, description);
101
+ return new LexResolverError(typeof nsid === 'string' ? NSID.from(nsid) : nsid, description);
107
102
  }
108
103
  }
109
- exports.LexResolverError = LexResolverError;
110
104
  //# sourceMappingURL=lex-resolver-error.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"lex-resolver-error.js","sourceRoot":"","sources":["../src/lex-resolver-error.ts"],"names":[],"mappings":";;;AAAA,gDAA4C;AAC5C,4CAAsC;AAEtC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,MAAa,gBAAiB,SAAQ,mBAAQ;IA4B1B;IAIA;IA/BlB,IAAI,GAAG,kBAAkB,CAAA;IAEzB;;;;;;;;;;;;;;;;;;;;OAoBG;IACH;IACE;;OAEG;IACa,IAAU;IAC1B;;OAEG;IACa,cAAc,oCAAoC,EAClE,OAAsB;QAEtB,KAAK,CAAC,0BAA0B,EAAE,GAAG,WAAW,KAAK,IAAI,GAAG,EAAE,OAAO,CAAC,CAAA;QAPtD,SAAI,GAAJ,IAAI,CAAM;QAIV,gBAAW,GAAX,WAAW,CAAuC;IAIpE,CAAC;IAED;;;;;;;;;;;;;;;;;;;;;;;OAuBG;IACH,MAAM,CAAC,IAAI,CAAC,IAAmB,EAAE,WAAoB;QACnD,OAAO,IAAI,gBAAgB,CACzB,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,aAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,EACjD,WAAW,CACZ,CAAA;IACH,CAAC;CACF;AApED,4CAoEC","sourcesContent":["import { LexError } from '@atproto/lex-data'\nimport { NSID } from '@atproto/syntax'\n\n/**\n * Error class for lexicon resolution failures.\n *\n * This error is thrown when the {@link LexResolver} encounters issues during\n * the resolution process, such as DNS lookup failures, DID resolution errors,\n * invalid lexicon documents, or network failures.\n *\n * @example Catching resolution errors\n * ```typescript\n * import { LexResolver, LexResolverError } from '@atproto/lex-resolver'\n *\n * const resolver = new LexResolver({})\n *\n * try {\n * const result = await resolver.get('com.example.myLexicon')\n * } catch (error) {\n * if (error instanceof LexResolverError) {\n * console.error(`Failed to resolve ${error.nsid}: ${error.description}`)\n * // Access the original cause if available\n * if (error.cause) {\n * console.error('Caused by:', error.cause)\n * }\n * }\n * }\n * ```\n *\n * @example Creating errors with the factory method\n * ```typescript\n * import { LexResolverError } from '@atproto/lex-resolver'\n *\n * // Create from string NSID\n * const error = LexResolverError.from(\n * 'com.example.myLexicon',\n * 'Custom error description'\n * )\n * ```\n */\nexport class LexResolverError extends LexError {\n name = 'LexResolverError'\n\n /**\n * Creates a new LexResolverError instance.\n *\n * @param nsid - The NSID that failed to resolve\n * @param description - Human-readable description of the error. Defaults to\n * a generic message if not provided.\n * @param options - Standard error options including `cause` for error chaining\n *\n * @example\n * ```typescript\n * import { NSID } from '@atproto/syntax'\n * import { LexResolverError } from '@atproto/lex-resolver'\n *\n * const nsid = NSID.from('com.example.myLexicon')\n * const error = new LexResolverError(\n * nsid,\n * 'DNS lookup failed',\n * { cause: originalError }\n * )\n * ```\n */\n constructor(\n /**\n * The NSID that failed to resolve.\n */\n public readonly nsid: NSID,\n /**\n * Human-readable description of what went wrong during resolution.\n */\n public readonly description = `Could not resolve Lexicon for NSID`,\n options?: ErrorOptions,\n ) {\n super('LexiconResolutionFailure', `${description} (${nsid})`, options)\n }\n\n /**\n * Factory method to create a LexResolverError from a string or NSID.\n *\n * This is a convenience method that handles the conversion of string NSIDs\n * to NSID objects automatically.\n *\n * @param nsid - The NSID as a string or NSID object\n * @param description - Optional human-readable description of the error\n * @returns A new LexResolverError instance\n *\n * @example\n * ```typescript\n * import { LexResolverError } from '@atproto/lex-resolver'\n *\n * // Create from string\n * const error1 = LexResolverError.from('com.example.myLexicon')\n *\n * // Create with description\n * const error2 = LexResolverError.from(\n * 'com.example.myLexicon',\n * 'Authority not found in DNS'\n * )\n * ```\n */\n static from(nsid: NSID | string, description?: string) {\n return new LexResolverError(\n typeof nsid === 'string' ? NSID.from(nsid) : nsid,\n description,\n )\n }\n}\n"]}
1
+ {"version":3,"file":"lex-resolver-error.js","sourceRoot":"","sources":["../src/lex-resolver-error.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAA;AAC5C,OAAO,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAA;AAEtC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,MAAM,OAAO,gBAAiB,SAAQ,QAAQ;IAG5C;;;;;;;;;;;;;;;;;;;;OAoBG;IACH;IACE;;OAEG;IACa,IAAU;IAC1B;;OAEG;IACa,cAAc,oCAAoC,EAClE,OAAsB;QAEtB,KAAK,CAAC,0BAA0B,EAAE,GAAG,WAAW,KAAK,IAAI,GAAG,EAAE,OAAO,CAAC,CAAA;QAPtD,SAAI,GAAJ,IAAI,CAAM;QAIV,gBAAW,GAAX,WAAW,CAAuC;QA/BpE,SAAI,GAAG,kBAAkB,CAAA;IAmCzB,CAAC;IAED;;;;;;;;;;;;;;;;;;;;;;;OAuBG;IACH,MAAM,CAAC,IAAI,CAAC,IAAmB,EAAE,WAAoB;QACnD,OAAO,IAAI,gBAAgB,CACzB,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,EACjD,WAAW,CACZ,CAAA;IACH,CAAC;CACF","sourcesContent":["import { LexError } from '@atproto/lex-data'\nimport { NSID } from '@atproto/syntax'\n\n/**\n * Error class for lexicon resolution failures.\n *\n * This error is thrown when the {@link LexResolver} encounters issues during\n * the resolution process, such as DNS lookup failures, DID resolution errors,\n * invalid lexicon documents, or network failures.\n *\n * @example Catching resolution errors\n * ```typescript\n * import { LexResolver, LexResolverError } from '@atproto/lex-resolver'\n *\n * const resolver = new LexResolver({})\n *\n * try {\n * const result = await resolver.get('com.example.myLexicon')\n * } catch (error) {\n * if (error instanceof LexResolverError) {\n * console.error(`Failed to resolve ${error.nsid}: ${error.description}`)\n * // Access the original cause if available\n * if (error.cause) {\n * console.error('Caused by:', error.cause)\n * }\n * }\n * }\n * ```\n *\n * @example Creating errors with the factory method\n * ```typescript\n * import { LexResolverError } from '@atproto/lex-resolver'\n *\n * // Create from string NSID\n * const error = LexResolverError.from(\n * 'com.example.myLexicon',\n * 'Custom error description'\n * )\n * ```\n */\nexport class LexResolverError extends LexError {\n name = 'LexResolverError'\n\n /**\n * Creates a new LexResolverError instance.\n *\n * @param nsid - The NSID that failed to resolve\n * @param description - Human-readable description of the error. Defaults to\n * a generic message if not provided.\n * @param options - Standard error options including `cause` for error chaining\n *\n * @example\n * ```typescript\n * import { NSID } from '@atproto/syntax'\n * import { LexResolverError } from '@atproto/lex-resolver'\n *\n * const nsid = NSID.from('com.example.myLexicon')\n * const error = new LexResolverError(\n * nsid,\n * 'DNS lookup failed',\n * { cause: originalError }\n * )\n * ```\n */\n constructor(\n /**\n * The NSID that failed to resolve.\n */\n public readonly nsid: NSID,\n /**\n * Human-readable description of what went wrong during resolution.\n */\n public readonly description = `Could not resolve Lexicon for NSID`,\n options?: ErrorOptions,\n ) {\n super('LexiconResolutionFailure', `${description} (${nsid})`, options)\n }\n\n /**\n * Factory method to create a LexResolverError from a string or NSID.\n *\n * This is a convenience method that handles the conversion of string NSIDs\n * to NSID objects automatically.\n *\n * @param nsid - The NSID as a string or NSID object\n * @param description - Optional human-readable description of the error\n * @returns A new LexResolverError instance\n *\n * @example\n * ```typescript\n * import { LexResolverError } from '@atproto/lex-resolver'\n *\n * // Create from string\n * const error1 = LexResolverError.from('com.example.myLexicon')\n *\n * // Create with description\n * const error2 = LexResolverError.from(\n * 'com.example.myLexicon',\n * 'Authority not found in DNS'\n * )\n * ```\n */\n static from(nsid: NSID | string, description?: string) {\n return new LexResolverError(\n typeof nsid === 'string' ? NSID.from(nsid) : nsid,\n description,\n )\n }\n}\n"]}
@@ -1,18 +1,13 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.LexResolver = exports.NSID = exports.AtUri = void 0;
4
- const tslib_1 = require("tslib");
5
- const promises_1 = require("node:dns/promises");
6
- const crypto = tslib_1.__importStar(require("@atproto/crypto"));
7
- const lex_client_1 = require("@atproto/lex-client");
8
- const lex_document_1 = require("@atproto/lex-document");
9
- const repo_1 = require("@atproto/repo");
10
- const syntax_1 = require("@atproto/syntax");
11
- Object.defineProperty(exports, "AtUri", { enumerable: true, get: function () { return syntax_1.AtUri; } });
12
- Object.defineProperty(exports, "NSID", { enumerable: true, get: function () { return syntax_1.NSID; } });
13
- const did_resolver_1 = require("@atproto-labs/did-resolver");
14
- const lex_resolver_error_js_1 = require("./lex-resolver-error.js");
15
- const index_js_1 = require("./lexicons/index.js");
1
+ import { resolveTxt } from 'node:dns/promises';
2
+ import * as crypto from '@atproto/crypto';
3
+ import { buildAgent, xrpc } from '@atproto/lex-client';
4
+ import { lexiconDocumentSchema } from '@atproto/lex-document';
5
+ import { MST, MemoryBlockstore, def as repoDef, readCarWithRoot, verifyCommitSig, } from '@atproto/repo';
6
+ import { AtUri, NSID } from '@atproto/syntax';
7
+ import { assertDid, createDidResolver, extractAtprotoData, } from '@atproto-labs/did-resolver';
8
+ import { LexResolverError } from './lex-resolver-error.js';
9
+ import { com } from './lexicons/index.js';
10
+ export { AtUri, NSID };
16
11
  /**
17
12
  * Resolves Lexicon documents from the AT Protocol network.
18
13
  *
@@ -87,12 +82,10 @@ const index_js_1 = require("./lexicons/index.js");
87
82
  * }
88
83
  * ```
89
84
  */
90
- class LexResolver {
91
- options;
92
- didResolver;
85
+ export class LexResolver {
93
86
  constructor(options) {
94
87
  this.options = options;
95
- this.didResolver = (0, did_resolver_1.createDidResolver)(options);
88
+ this.didResolver = createDidResolver(options);
96
89
  }
97
90
  /**
98
91
  * Gets a lexicon document by its NSID.
@@ -155,7 +148,7 @@ class LexResolver {
155
148
  * ```
156
149
  */
157
150
  async resolve(nsidStr) {
158
- const nsid = syntax_1.NSID.from(nsidStr);
151
+ const nsid = NSID.from(nsidStr);
159
152
  const did = (await this.options.hooks?.onResolveAuthority?.({ nsid })) ??
160
153
  (await this.resolveLexiconAuthority(nsid).then(async (did) => {
161
154
  await this.options.hooks?.onResolveAuthorityResult?.({ nsid, did });
@@ -164,7 +157,7 @@ class LexResolver {
164
157
  await this.options.hooks?.onResolveAuthorityError?.({ nsid, err });
165
158
  throw err;
166
159
  }));
167
- return syntax_1.AtUri.make(did, 'com.atproto.lexicon.schema', nsid.toString());
160
+ return AtUri.make(did, 'com.atproto.lexicon.schema', nsid.toString());
168
161
  }
169
162
  // @TODO This class could be made compatible with browsers by making the
170
163
  // following method abstract and/or by allowing the caller to inject a DNS
@@ -175,7 +168,7 @@ class LexResolver {
175
168
  return await getDomainTxtDid(`_lexicon.${nsid.authority}`);
176
169
  }
177
170
  catch (cause) {
178
- throw new lex_resolver_error_js_1.LexResolverError(nsid, `Failed to resolve lexicon DID authority for ${nsid}`, { cause });
171
+ throw new LexResolverError(nsid, `Failed to resolve lexicon DID authority for ${nsid}`, { cause });
179
172
  }
180
173
  }
181
174
  /**
@@ -212,7 +205,7 @@ class LexResolver {
212
205
  * ```
213
206
  */
214
207
  async fetch(uriStr, options) {
215
- const uri = typeof uriStr === 'string' ? new syntax_1.AtUri(uriStr) : uriStr;
208
+ const uri = typeof uriStr === 'string' ? new AtUri(uriStr) : uriStr;
216
209
  const { lexicon, cid } = (await this.options.hooks?.onFetch?.({ uri })) ??
217
210
  (await this.fetchLexiconUri(uri, options).then(async (res) => {
218
211
  await this.options.hooks?.onFetchResult?.({ uri, ...res });
@@ -227,65 +220,64 @@ class LexResolver {
227
220
  const { did, nsid } = parseLexiconUri(uri);
228
221
  const { pds, key } = await this.didResolver
229
222
  .resolve(did, options)
230
- .then(did_resolver_1.extractAtprotoData)
223
+ .then(extractAtprotoData)
231
224
  .catch((cause) => {
232
- throw new lex_resolver_error_js_1.LexResolverError(nsid, `Failed to resolve DID document for ${did}`, { cause });
225
+ throw new LexResolverError(nsid, `Failed to resolve DID document for ${did}`, { cause });
233
226
  });
234
227
  if (!key || !pds || !URL.canParse(pds.serviceEndpoint)) {
235
- throw new lex_resolver_error_js_1.LexResolverError(nsid, `No atproto PDS service endpoint or signing key found in ${did} DID document`);
228
+ throw new LexResolverError(nsid, `No atproto PDS service endpoint or signing key found in ${did} DID document`);
236
229
  }
237
- const agent = (0, lex_client_1.buildAgent)({
230
+ const agent = buildAgent({
238
231
  service: pds.serviceEndpoint,
239
232
  fetch: this.options.fetch,
240
233
  });
241
234
  const collection = 'com.atproto.lexicon.schema';
242
235
  const rkey = nsid.toString();
243
- const { cid, record } = await (0, lex_client_1.xrpc)(agent, index_js_1.com.atproto.sync.getRecord, {
236
+ const { cid, record } = await xrpc(agent, com.atproto.sync.getRecord, {
244
237
  signal: options?.signal,
245
238
  headers: options?.noCache ? { 'Cache-Control': 'no-cache' } : undefined,
246
239
  params: { did, collection, rkey },
247
240
  }).then(({ body }) => {
248
241
  return verifyRecordProof(body, did, key, collection, rkey).catch((cause) => {
249
- throw new lex_resolver_error_js_1.LexResolverError(nsid, `Failed to verify Lexicon record proof at ${uri}`, { cause });
242
+ throw new LexResolverError(nsid, `Failed to verify Lexicon record proof at ${uri}`, { cause });
250
243
  });
251
244
  }, (cause) => {
252
- throw new lex_resolver_error_js_1.LexResolverError(nsid, `Failed to fetch Record ${uri}`, {
245
+ throw new LexResolverError(nsid, `Failed to fetch Record ${uri}`, {
253
246
  cause,
254
247
  });
255
248
  });
256
- const validationResult = lex_document_1.lexiconDocumentSchema.safeParse(record);
249
+ const validationResult = lexiconDocumentSchema.safeParse(record);
257
250
  if (!validationResult.success) {
258
- throw new lex_resolver_error_js_1.LexResolverError(nsid, `Invalid Lexicon document at ${uri}`, {
251
+ throw new LexResolverError(nsid, `Invalid Lexicon document at ${uri}`, {
259
252
  cause: validationResult.reason,
260
253
  });
261
254
  }
262
255
  const lexicon = validationResult.value;
263
256
  if (lexicon.id !== uri.rkey) {
264
- throw new lex_resolver_error_js_1.LexResolverError(nsid, `Invalid document id "${lexicon.id}" at ${uri}`);
257
+ throw new LexResolverError(nsid, `Invalid document id "${lexicon.id}" at ${uri}`);
265
258
  }
266
259
  return { lexicon, cid };
267
260
  }
268
261
  }
269
- exports.LexResolver = LexResolver;
270
262
  function parseLexiconUri(uri) {
271
263
  // Validate input URI
272
- const nsid = syntax_1.NSID.from(uri.rkey);
264
+ const nsid = NSID.from(uri.rkey);
273
265
  try {
274
266
  const did = uri.host;
275
- (0, did_resolver_1.assertDid)(did);
267
+ assertDid(did);
276
268
  return { did, nsid };
277
269
  }
278
270
  catch (cause) {
279
- throw new lex_resolver_error_js_1.LexResolverError(nsid, `URI host is not a DID ${uri}`, { cause });
271
+ throw new LexResolverError(nsid, `URI host is not a DID ${uri}`, { cause });
280
272
  }
281
273
  }
282
274
  async function getDomainTxtDid(domain) {
283
- const didLines = (await (0, promises_1.resolveTxt)(domain))
275
+ const didLines = (await resolveTxt(domain))
284
276
  .map((chunks) => chunks.join(''))
285
277
  .filter((i) => i.startsWith('did='));
286
278
  if (didLines.length === 1) {
287
279
  const did = didLines[0].slice(4);
288
- (0, did_resolver_1.assertDid)(did);
280
+ assertDid(did);
289
281
  return did;
290
282
  }
291
283
  throw didLines.length > 1
@@ -293,18 +285,18 @@ async function getDomainTxtDid(domain) {
293
285
  : new Error('No DID found in DNS TXT records');
294
286
  }
295
287
  async function verifyRecordProof(car, did, key, collection, rkey) {
296
- const { root, blocks } = await (0, repo_1.readCarWithRoot)(car);
297
- const blockstore = new repo_1.MemoryBlockstore(blocks);
298
- const commit = await blockstore.readObj(root, repo_1.def.commit);
288
+ const { root, blocks } = await readCarWithRoot(car);
289
+ const blockstore = new MemoryBlockstore(blocks);
290
+ const commit = await blockstore.readObj(root, repoDef.commit);
299
291
  if (commit.did !== did) {
300
292
  throw new Error(`Invalid repo did: ${commit.did}`);
301
293
  }
302
294
  const signingKey = getDidKeyFromMultibase(key);
303
- const validSig = await (0, repo_1.verifyCommitSig)(commit, signingKey);
295
+ const validSig = await verifyCommitSig(commit, signingKey);
304
296
  if (!validSig) {
305
297
  throw new Error(`Invalid signature on commit: ${root.toString()}`);
306
298
  }
307
- const mst = repo_1.MST.load(blockstore, commit.data);
299
+ const mst = MST.load(blockstore, commit.data);
308
300
  const cid = await mst.get(`${collection}/${rkey}`);
309
301
  if (!cid)
310
302
  throw new Error('Record not found in proof');
@@ -1 +1 @@
1
- {"version":3,"file":"lex-resolver.js","sourceRoot":"","sources":["../src/lex-resolver.ts"],"names":[],"mappings":"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","sourcesContent":["import { resolveTxt } from 'node:dns/promises'\nimport * as crypto from '@atproto/crypto'\nimport { buildAgent, xrpc } from '@atproto/lex-client'\nimport { Cid } from '@atproto/lex-data'\nimport { LexiconDocument, lexiconDocumentSchema } from '@atproto/lex-document'\nimport {\n MST,\n MemoryBlockstore,\n def as repoDef,\n readCarWithRoot,\n verifyCommitSig,\n} from '@atproto/repo'\nimport { AtUri, NSID, NsidString } from '@atproto/syntax'\nimport {\n AtprotoVerificationMethod,\n CreateDidResolverOptions,\n Did,\n DidResolver,\n ResolveDidOptions,\n assertDid,\n createDidResolver,\n extractAtprotoData,\n} from '@atproto-labs/did-resolver'\nimport { LexResolverError } from './lex-resolver-error.js'\nimport { com } from './lexicons/index.js'\n\n/**\n * Result returned when successfully resolving a lexicon document.\n *\n * Contains the full AT URI where the lexicon was found, the content-addressed\n * identifier (CID) for integrity verification, and the parsed lexicon document.\n */\nexport type LexResolverResult = {\n /** The AT URI where the lexicon document was found */\n uri: AtUri\n /** Content identifier (CID) of the lexicon record for integrity verification */\n cid: Cid\n /** The parsed and validated lexicon document */\n lexicon: LexiconDocument\n}\n\n/**\n * Result returned when fetching a lexicon document from a specific URI.\n *\n * This is a subset of {@link LexResolverResult} used internally and by hooks,\n * containing only the CID and lexicon document (without the URI, which is\n * already known from the fetch request).\n */\nexport type LexResolverFetchResult = {\n /** Content identifier (CID) of the lexicon record */\n cid: Cid\n /** The parsed and validated lexicon document */\n lexicon: LexiconDocument\n}\n\nexport type Awaitable<T> = T | Promise<T>\n\n/**\n * Callback hooks for customizing the lexicon resolution process.\n *\n * Hooks allow you to intercept, cache, or override the default resolution\n * behavior at various stages. Each hook can be synchronous or asynchronous.\n *\n * @example Implementing a cache with hooks\n * ```typescript\n * import { LexResolver, LexResolverHooks, LexResolverFetchResult } from '@atproto/lex-resolver'\n * import { AtUri } from '@atproto/syntax'\n *\n * const cache = new Map<string, LexResolverFetchResult>()\n *\n * const hooks: LexResolverHooks = {\n * // Return cached result if available, bypassing network fetch\n * onFetch({ uri }) {\n * return cache.get(uri.toString())\n * },\n * // Cache successful fetches\n * onFetchResult({ uri, cid, lexicon }) {\n * cache.set(uri.toString(), { cid, lexicon })\n * },\n * // Log errors for monitoring\n * onFetchError({ uri, err }) {\n * console.error(`Failed to fetch ${uri}:`, err)\n * }\n * }\n *\n * const resolver = new LexResolver({ hooks })\n * ```\n *\n * @example Overriding authority resolution for testing\n * ```typescript\n * const hooks: LexResolverHooks = {\n * // Always resolve to a test DID\n * onResolveAuthority({ nsid }) {\n * if (nsid.authority === 'test.example') {\n * return 'did:plc:test123'\n * }\n * // Return undefined to use default resolution\n * }\n * }\n * ```\n */\nexport type LexResolverHooks = {\n /**\n * Hook called before resolving a lexicon authority DID. If a DID is returned,\n * it will be used instead of performing the default resolution. In that case,\n * the `onResolveAuthorityResult` and `onResolveAuthorityError` hooks will\n * not be called.\n *\n * @param data - Object containing the NSID being resolved\n * @returns A DID to use instead of default resolution, or void/undefined to proceed normally\n */\n onResolveAuthority?(data: { nsid: NSID }): Awaitable<void | Did>\n\n /**\n * Hook called after successfully resolving a lexicon authority DID.\n *\n * @param data - Object containing the NSID and resolved DID\n */\n onResolveAuthorityResult?(data: { nsid: NSID; did: Did }): Awaitable<void>\n\n /**\n * Hook called when authority resolution fails.\n *\n * @param data - Object containing the NSID and error that occurred\n */\n onResolveAuthorityError?(data: { nsid: NSID; err: unknown }): Awaitable<void>\n\n /**\n * Hook called before fetching a lexicon URI. If a result is returned, it will\n * be used instead of performing the default fetch. In that case, the\n * `onFetchResult` and `onFetchError` hooks will not be called.\n *\n * @param data - Object containing the URI being fetched\n * @returns A fetch result to use instead of default fetch, or void/undefined to proceed normally\n */\n onFetch?(data: { uri: AtUri }): Awaitable<void | LexResolverFetchResult>\n\n /**\n * Hook called after successfully fetching a lexicon document.\n *\n * @param data - Object containing the URI, CID, and parsed lexicon document\n */\n onFetchResult?(data: {\n uri: AtUri\n cid: Cid\n lexicon: LexiconDocument\n }): Awaitable<void>\n\n /**\n * Hook called when fetching fails.\n *\n * @param data - Object containing the URI and error that occurred\n */\n onFetchError?(data: { uri: AtUri; err: unknown }): Awaitable<void>\n}\n\n/**\n * Configuration options for the {@link LexResolver}.\n *\n * Extends DID resolver options with lexicon-specific hooks for customizing\n * the resolution process.\n *\n * @see {@link CreateDidResolverOptions} for DID resolver configuration\n */\nexport type LexResolverOptions = CreateDidResolverOptions & {\n /**\n * Optional hooks for customizing the resolution process.\n * See {@link LexResolverHooks} for available callbacks.\n */\n hooks?: LexResolverHooks\n}\n\nexport { AtUri, type Cid, NSID }\nexport type { LexiconDocument, ResolveDidOptions }\n\n/**\n * Resolves Lexicon documents from the AT Protocol network.\n *\n * The {@link LexResolver} handles the complete process of resolving a lexicon\n * by NSID:\n * 1. **Authority Resolution**: Looks up the `_lexicon.<authority>` DNS TXT record\n * to find the DID that controls lexicons for that namespace\n * 2. **DID Resolution**: Resolves the DID document to find the PDS endpoint and\n * signing key\n * 3. **Record Fetch**: Fetches the lexicon record from the PDS with cryptographic\n * proof verification\n * 4. **Validation**: Validates the lexicon document structure\n *\n * @example Basic usage - resolve a lexicon by NSID\n * ```typescript\n * import { LexResolver } from '@atproto/lex-resolver'\n *\n * const resolver = new LexResolver({})\n *\n * // Get a lexicon document by its NSID\n * const result = await resolver.get('app.bsky.feed.post')\n * console.log(result.lexicon) // The parsed lexicon document\n * console.log(result.uri) // AT URI where it was found\n * console.log(result.cid) // Content identifier for verification\n * ```\n *\n * @example Two-step resolution for more control\n * ```typescript\n * import { LexResolver } from '@atproto/lex-resolver'\n *\n * const resolver = new LexResolver({})\n *\n * // Step 1: Resolve the authority to get the AT URI\n * const uri = await resolver.resolve('app.bsky.feed.post')\n * console.log(uri.toString()) // 'at://did:plc:xxx/com.atproto.lexicon.schema/app.bsky.feed.post'\n *\n * // Step 2: Fetch the lexicon from the URI\n * const result = await resolver.fetch(uri)\n * console.log(result.lexicon)\n * ```\n *\n * @example Using hooks for caching\n * ```typescript\n * import { LexResolver, LexResolverFetchResult } from '@atproto/lex-resolver'\n *\n * const cache = new Map<string, LexResolverFetchResult>()\n *\n * const resolver = new LexResolver({\n * hooks: {\n * onFetch({ uri }) {\n * return cache.get(uri.toString())\n * },\n * onFetchResult({ uri, cid, lexicon }) {\n * cache.set(uri.toString(), { cid, lexicon })\n * }\n * }\n * })\n * ```\n *\n * @example Error handling\n * ```typescript\n * import { LexResolver, LexResolverError } from '@atproto/lex-resolver'\n *\n * const resolver = new LexResolver({})\n *\n * try {\n * const result = await resolver.get('com.example.unknown')\n * } catch (error) {\n * if (error instanceof LexResolverError) {\n * console.error(`Failed to resolve ${error.nsid}: ${error.description}`)\n * }\n * }\n * ```\n */\nexport class LexResolver {\n protected readonly didResolver: DidResolver<'plc' | 'web'>\n\n constructor(protected readonly options: LexResolverOptions) {\n this.didResolver = createDidResolver(options)\n }\n\n /**\n * Gets a lexicon document by its NSID.\n *\n * This is the primary method for resolving lexicons. It combines\n * {@link resolve} and {@link fetch} into a single operation, handling\n * authority resolution, DID lookup, and record fetching.\n *\n * @param nsidStr - The NSID to resolve, either as a string or NSID object\n * @param options - Optional DID resolution options (e.g., signal for cancellation)\n * @returns The resolved lexicon result containing URI, CID, and lexicon document\n * @throws {LexResolverError} If resolution fails at any stage\n *\n * @example\n * ```typescript\n * // Resolve using string NSID\n * const result = await resolver.get('app.bsky.feed.post')\n *\n * // Resolve using NSID object\n * import { NSID } from '@atproto/syntax'\n * const nsid = NSID.from('app.bsky.feed.post')\n * const result = await resolver.get(nsid)\n *\n * // With abort signal for cancellation\n * const controller = new AbortController()\n * const result = await resolver.get('app.bsky.feed.post', {\n * signal: controller.signal\n * })\n * ```\n */\n async get(\n nsidStr: NSID | string,\n options?: ResolveDidOptions,\n ): Promise<LexResolverResult> {\n const uri = await this.resolve(nsidStr)\n return this.fetch(uri, options)\n }\n\n /**\n * Resolves the authority for an NSID and returns the AT URI for the lexicon.\n *\n * This method performs the first stage of lexicon resolution:\n * 1. Parses the NSID to extract the authority domain\n * 2. Looks up the `_lexicon.<authority>` DNS TXT record\n * 3. Extracts the DID from the TXT record (format: `did=<did>`)\n * 4. Constructs the AT URI for the lexicon record\n *\n * Use this when you need the URI without fetching the actual document,\n * or when you want to implement custom fetching logic.\n *\n * @param nsidStr - The NSID to resolve, either as a string or NSID object\n * @returns The AT URI pointing to the lexicon record\n * @throws {LexResolverError} If authority resolution fails (e.g., DNS lookup fails)\n *\n * @example\n * ```typescript\n * // Resolve to get the AT URI\n * const uri = await resolver.resolve('app.bsky.feed.post')\n * console.log(uri.toString())\n * // Output: 'at://did:plc:z72i7hdynmk6r22z27h6tvur/com.atproto.lexicon.schema/app.bsky.feed.post'\n *\n * // The URI can then be used with fetch() or stored for later use\n * const result = await resolver.fetch(uri)\n * ```\n */\n async resolve(nsidStr: NSID | string): Promise<AtUri> {\n const nsid = NSID.from(nsidStr)\n\n const did =\n (await this.options.hooks?.onResolveAuthority?.({ nsid })) ??\n (await this.resolveLexiconAuthority(nsid).then(\n async (did) => {\n await this.options.hooks?.onResolveAuthorityResult?.({ nsid, did })\n return did\n },\n async (err) => {\n await this.options.hooks?.onResolveAuthorityError?.({ nsid, err })\n throw err\n },\n ))\n\n return AtUri.make(did, 'com.atproto.lexicon.schema', nsid.toString())\n }\n\n // @TODO This class could be made compatible with browsers by making the\n // following method abstract and/or by allowing the caller to inject a DNS\n // resolver implementation (based on DNS-over-HTTPS or similar), instead of\n // using the Node.js built-in resolver.\n protected async resolveLexiconAuthority(nsid: NSID): Promise<Did> {\n try {\n return await getDomainTxtDid(`_lexicon.${nsid.authority}`)\n } catch (cause) {\n throw new LexResolverError(\n nsid,\n `Failed to resolve lexicon DID authority for ${nsid}`,\n { cause },\n )\n }\n }\n\n /**\n * Fetches a lexicon document from a specific AT URI.\n *\n * This method performs the second stage of lexicon resolution:\n * 1. Resolves the DID from the URI to find the PDS endpoint\n * 2. Fetches the record from the PDS using `com.atproto.sync.getRecord`\n * 3. Verifies the cryptographic proof (commit signature)\n * 4. Validates the lexicon document structure\n * 5. Ensures the document ID matches the URI rkey\n *\n * Use this when you already have an AT URI (e.g., from {@link resolve})\n * and want to fetch the lexicon document.\n *\n * @param uriStr - The AT URI to fetch, either as a string or AtUri object\n * @param options - Optional DID resolution options (e.g., signal for cancellation, noCache)\n * @returns The resolved lexicon result containing URI, CID, and lexicon document\n * @throws {LexResolverError} If fetching or validation fails\n *\n * @example\n * ```typescript\n * // Fetch from a known URI\n * const result = await resolver.fetch(\n * 'at://did:plc:xyz/com.atproto.lexicon.schema/app.bsky.feed.post'\n * )\n *\n * // Fetch with no-cache to bypass any upstream caching\n * const result = await resolver.fetch(uri, { noCache: true })\n *\n * // Fetch with abort signal\n * const controller = new AbortController()\n * const result = await resolver.fetch(uri, { signal: controller.signal })\n * ```\n */\n async fetch(\n uriStr: AtUri | string,\n options?: ResolveDidOptions,\n ): Promise<LexResolverResult> {\n const uri = typeof uriStr === 'string' ? new AtUri(uriStr) : uriStr\n\n const { lexicon, cid } =\n (await this.options.hooks?.onFetch?.({ uri })) ??\n (await this.fetchLexiconUri(uri, options).then(\n async (res) => {\n await this.options.hooks?.onFetchResult?.({ uri, ...res })\n return res\n },\n async (err) => {\n await this.options.hooks?.onFetchError?.({ uri, err })\n throw err\n },\n ))\n\n return { uri, cid, lexicon }\n }\n\n protected async fetchLexiconUri(\n uri: AtUri,\n options?: ResolveDidOptions,\n ): Promise<LexResolverFetchResult> {\n const { did, nsid } = parseLexiconUri(uri)\n\n const { pds, key } = await this.didResolver\n .resolve(did, options)\n .then(extractAtprotoData)\n .catch((cause) => {\n throw new LexResolverError(\n nsid,\n `Failed to resolve DID document for ${did}`,\n { cause },\n )\n })\n\n if (!key || !pds || !URL.canParse(pds.serviceEndpoint)) {\n throw new LexResolverError(\n nsid,\n `No atproto PDS service endpoint or signing key found in ${did} DID document`,\n )\n }\n\n const agent = buildAgent({\n service: pds.serviceEndpoint,\n fetch: this.options.fetch,\n })\n\n const collection = 'com.atproto.lexicon.schema'\n const rkey = nsid.toString()\n\n const { cid, record } = await xrpc(agent, com.atproto.sync.getRecord, {\n signal: options?.signal,\n headers: options?.noCache ? { 'Cache-Control': 'no-cache' } : undefined,\n params: { did, collection, rkey },\n }).then(\n ({ body }) => {\n return verifyRecordProof(body, did, key, collection, rkey).catch(\n (cause) => {\n throw new LexResolverError(\n nsid,\n `Failed to verify Lexicon record proof at ${uri}`,\n { cause },\n )\n },\n )\n },\n (cause) => {\n throw new LexResolverError(nsid, `Failed to fetch Record ${uri}`, {\n cause,\n })\n },\n )\n\n const validationResult = lexiconDocumentSchema.safeParse(record)\n if (!validationResult.success) {\n throw new LexResolverError(nsid, `Invalid Lexicon document at ${uri}`, {\n cause: validationResult.reason,\n })\n }\n\n const lexicon = validationResult.value\n if (lexicon.id !== uri.rkey) {\n throw new LexResolverError(\n nsid,\n `Invalid document id \"${lexicon.id}\" at ${uri}`,\n )\n }\n\n return { lexicon, cid }\n }\n}\n\nfunction parseLexiconUri(uri: AtUri): {\n did: Did\n nsid: NSID\n} {\n // Validate input URI\n const nsid = NSID.from(uri.rkey)\n try {\n const did = uri.host\n assertDid(did)\n return { did, nsid }\n } catch (cause) {\n throw new LexResolverError(nsid, `URI host is not a DID ${uri}`, { cause })\n }\n}\n\nasync function getDomainTxtDid(domain: string): Promise<Did> {\n const didLines = (await resolveTxt(domain))\n .map((chunks) => chunks.join(''))\n .filter((i) => i.startsWith('did='))\n\n if (didLines.length === 1) {\n const did = didLines[0].slice(4)\n assertDid(did)\n return did\n }\n\n throw didLines.length > 1\n ? new Error('Multiple DIDs found in DNS TXT records')\n : new Error('No DID found in DNS TXT records')\n}\n\nasync function verifyRecordProof(\n car: Uint8Array,\n did: Did,\n key: AtprotoVerificationMethod,\n collection: NsidString,\n rkey: string,\n) {\n const { root, blocks } = await readCarWithRoot(car)\n const blockstore = new MemoryBlockstore(blocks)\n\n const commit = await blockstore.readObj(root, repoDef.commit)\n if (commit.did !== did) {\n throw new Error(`Invalid repo did: ${commit.did}`)\n }\n\n const signingKey = getDidKeyFromMultibase(key)\n const validSig = await verifyCommitSig(commit, signingKey)\n if (!validSig) {\n throw new Error(`Invalid signature on commit: ${root.toString()}`)\n }\n\n const mst = MST.load(blockstore, commit.data)\n\n const cid = await mst.get(`${collection}/${rkey}`)\n if (!cid) throw new Error('Record not found in proof')\n\n const record = await blockstore.readRecord(cid)\n if (record?.$type !== collection) {\n throw new Error(\n `Invalid record type: expected ${collection}, got ${record?.$type}`,\n )\n }\n\n return { cid, record }\n}\n\nfunction getDidKeyFromMultibase(key: AtprotoVerificationMethod) {\n switch (key.type) {\n case 'EcdsaSecp256r1VerificationKey2019': {\n const keyBytes = crypto.multibaseToBytes(key.publicKeyMultibase)\n return crypto.formatDidKey(crypto.P256_JWT_ALG, keyBytes)\n }\n case 'EcdsaSecp256k1VerificationKey2019': {\n const keyBytes = crypto.multibaseToBytes(key.publicKeyMultibase)\n return crypto.formatDidKey(crypto.SECP256K1_JWT_ALG, keyBytes)\n }\n case 'Multikey': {\n const { jwtAlg, keyBytes } = crypto.parseMultikey(key.publicKeyMultibase)\n return crypto.formatDidKey(jwtAlg, keyBytes)\n }\n default: {\n // Should never happen\n throw new Error(`Unsupported verification method type: ${key.type}`)\n }\n }\n}\n"]}
1
+ {"version":3,"file":"lex-resolver.js","sourceRoot":"","sources":["../src/lex-resolver.ts"],"names":[],"mappings":"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","sourcesContent":["import { resolveTxt } from 'node:dns/promises'\nimport * as crypto from '@atproto/crypto'\nimport { buildAgent, xrpc } from '@atproto/lex-client'\nimport { Cid } from '@atproto/lex-data'\nimport { LexiconDocument, lexiconDocumentSchema } from '@atproto/lex-document'\nimport {\n MST,\n MemoryBlockstore,\n def as repoDef,\n readCarWithRoot,\n verifyCommitSig,\n} from '@atproto/repo'\nimport { AtUri, NSID, NsidString } from '@atproto/syntax'\nimport {\n AtprotoVerificationMethod,\n CreateDidResolverOptions,\n Did,\n DidResolver,\n ResolveDidOptions,\n assertDid,\n createDidResolver,\n extractAtprotoData,\n} from '@atproto-labs/did-resolver'\nimport { LexResolverError } from './lex-resolver-error.js'\nimport { com } from './lexicons/index.js'\n\n/**\n * Result returned when successfully resolving a lexicon document.\n *\n * Contains the full AT URI where the lexicon was found, the content-addressed\n * identifier (CID) for integrity verification, and the parsed lexicon document.\n */\nexport type LexResolverResult = {\n /** The AT URI where the lexicon document was found */\n uri: AtUri\n /** Content identifier (CID) of the lexicon record for integrity verification */\n cid: Cid\n /** The parsed and validated lexicon document */\n lexicon: LexiconDocument\n}\n\n/**\n * Result returned when fetching a lexicon document from a specific URI.\n *\n * This is a subset of {@link LexResolverResult} used internally and by hooks,\n * containing only the CID and lexicon document (without the URI, which is\n * already known from the fetch request).\n */\nexport type LexResolverFetchResult = {\n /** Content identifier (CID) of the lexicon record */\n cid: Cid\n /** The parsed and validated lexicon document */\n lexicon: LexiconDocument\n}\n\nexport type Awaitable<T> = T | Promise<T>\n\n/**\n * Callback hooks for customizing the lexicon resolution process.\n *\n * Hooks allow you to intercept, cache, or override the default resolution\n * behavior at various stages. Each hook can be synchronous or asynchronous.\n *\n * @example Implementing a cache with hooks\n * ```typescript\n * import { LexResolver, LexResolverHooks, LexResolverFetchResult } from '@atproto/lex-resolver'\n * import { AtUri } from '@atproto/syntax'\n *\n * const cache = new Map<string, LexResolverFetchResult>()\n *\n * const hooks: LexResolverHooks = {\n * // Return cached result if available, bypassing network fetch\n * onFetch({ uri }) {\n * return cache.get(uri.toString())\n * },\n * // Cache successful fetches\n * onFetchResult({ uri, cid, lexicon }) {\n * cache.set(uri.toString(), { cid, lexicon })\n * },\n * // Log errors for monitoring\n * onFetchError({ uri, err }) {\n * console.error(`Failed to fetch ${uri}:`, err)\n * }\n * }\n *\n * const resolver = new LexResolver({ hooks })\n * ```\n *\n * @example Overriding authority resolution for testing\n * ```typescript\n * const hooks: LexResolverHooks = {\n * // Always resolve to a test DID\n * onResolveAuthority({ nsid }) {\n * if (nsid.authority === 'test.example') {\n * return 'did:plc:test123'\n * }\n * // Return undefined to use default resolution\n * }\n * }\n * ```\n */\nexport type LexResolverHooks = {\n /**\n * Hook called before resolving a lexicon authority DID. If a DID is returned,\n * it will be used instead of performing the default resolution. In that case,\n * the `onResolveAuthorityResult` and `onResolveAuthorityError` hooks will\n * not be called.\n *\n * @param data - Object containing the NSID being resolved\n * @returns A DID to use instead of default resolution, or void/undefined to proceed normally\n */\n onResolveAuthority?(data: { nsid: NSID }): Awaitable<void | Did>\n\n /**\n * Hook called after successfully resolving a lexicon authority DID.\n *\n * @param data - Object containing the NSID and resolved DID\n */\n onResolveAuthorityResult?(data: { nsid: NSID; did: Did }): Awaitable<void>\n\n /**\n * Hook called when authority resolution fails.\n *\n * @param data - Object containing the NSID and error that occurred\n */\n onResolveAuthorityError?(data: { nsid: NSID; err: unknown }): Awaitable<void>\n\n /**\n * Hook called before fetching a lexicon URI. If a result is returned, it will\n * be used instead of performing the default fetch. In that case, the\n * `onFetchResult` and `onFetchError` hooks will not be called.\n *\n * @param data - Object containing the URI being fetched\n * @returns A fetch result to use instead of default fetch, or void/undefined to proceed normally\n */\n onFetch?(data: { uri: AtUri }): Awaitable<void | LexResolverFetchResult>\n\n /**\n * Hook called after successfully fetching a lexicon document.\n *\n * @param data - Object containing the URI, CID, and parsed lexicon document\n */\n onFetchResult?(data: {\n uri: AtUri\n cid: Cid\n lexicon: LexiconDocument\n }): Awaitable<void>\n\n /**\n * Hook called when fetching fails.\n *\n * @param data - Object containing the URI and error that occurred\n */\n onFetchError?(data: { uri: AtUri; err: unknown }): Awaitable<void>\n}\n\n/**\n * Configuration options for the {@link LexResolver}.\n *\n * Extends DID resolver options with lexicon-specific hooks for customizing\n * the resolution process.\n *\n * @see {@link CreateDidResolverOptions} for DID resolver configuration\n */\nexport type LexResolverOptions = CreateDidResolverOptions & {\n /**\n * Optional hooks for customizing the resolution process.\n * See {@link LexResolverHooks} for available callbacks.\n */\n hooks?: LexResolverHooks\n}\n\nexport { AtUri, type Cid, NSID }\nexport type { LexiconDocument, ResolveDidOptions }\n\n/**\n * Resolves Lexicon documents from the AT Protocol network.\n *\n * The {@link LexResolver} handles the complete process of resolving a lexicon\n * by NSID:\n * 1. **Authority Resolution**: Looks up the `_lexicon.<authority>` DNS TXT record\n * to find the DID that controls lexicons for that namespace\n * 2. **DID Resolution**: Resolves the DID document to find the PDS endpoint and\n * signing key\n * 3. **Record Fetch**: Fetches the lexicon record from the PDS with cryptographic\n * proof verification\n * 4. **Validation**: Validates the lexicon document structure\n *\n * @example Basic usage - resolve a lexicon by NSID\n * ```typescript\n * import { LexResolver } from '@atproto/lex-resolver'\n *\n * const resolver = new LexResolver({})\n *\n * // Get a lexicon document by its NSID\n * const result = await resolver.get('app.bsky.feed.post')\n * console.log(result.lexicon) // The parsed lexicon document\n * console.log(result.uri) // AT URI where it was found\n * console.log(result.cid) // Content identifier for verification\n * ```\n *\n * @example Two-step resolution for more control\n * ```typescript\n * import { LexResolver } from '@atproto/lex-resolver'\n *\n * const resolver = new LexResolver({})\n *\n * // Step 1: Resolve the authority to get the AT URI\n * const uri = await resolver.resolve('app.bsky.feed.post')\n * console.log(uri.toString()) // 'at://did:plc:xxx/com.atproto.lexicon.schema/app.bsky.feed.post'\n *\n * // Step 2: Fetch the lexicon from the URI\n * const result = await resolver.fetch(uri)\n * console.log(result.lexicon)\n * ```\n *\n * @example Using hooks for caching\n * ```typescript\n * import { LexResolver, LexResolverFetchResult } from '@atproto/lex-resolver'\n *\n * const cache = new Map<string, LexResolverFetchResult>()\n *\n * const resolver = new LexResolver({\n * hooks: {\n * onFetch({ uri }) {\n * return cache.get(uri.toString())\n * },\n * onFetchResult({ uri, cid, lexicon }) {\n * cache.set(uri.toString(), { cid, lexicon })\n * }\n * }\n * })\n * ```\n *\n * @example Error handling\n * ```typescript\n * import { LexResolver, LexResolverError } from '@atproto/lex-resolver'\n *\n * const resolver = new LexResolver({})\n *\n * try {\n * const result = await resolver.get('com.example.unknown')\n * } catch (error) {\n * if (error instanceof LexResolverError) {\n * console.error(`Failed to resolve ${error.nsid}: ${error.description}`)\n * }\n * }\n * ```\n */\nexport class LexResolver {\n protected readonly didResolver: DidResolver<'plc' | 'web'>\n\n constructor(protected readonly options: LexResolverOptions) {\n this.didResolver = createDidResolver(options)\n }\n\n /**\n * Gets a lexicon document by its NSID.\n *\n * This is the primary method for resolving lexicons. It combines\n * {@link resolve} and {@link fetch} into a single operation, handling\n * authority resolution, DID lookup, and record fetching.\n *\n * @param nsidStr - The NSID to resolve, either as a string or NSID object\n * @param options - Optional DID resolution options (e.g., signal for cancellation)\n * @returns The resolved lexicon result containing URI, CID, and lexicon document\n * @throws {LexResolverError} If resolution fails at any stage\n *\n * @example\n * ```typescript\n * // Resolve using string NSID\n * const result = await resolver.get('app.bsky.feed.post')\n *\n * // Resolve using NSID object\n * import { NSID } from '@atproto/syntax'\n * const nsid = NSID.from('app.bsky.feed.post')\n * const result = await resolver.get(nsid)\n *\n * // With abort signal for cancellation\n * const controller = new AbortController()\n * const result = await resolver.get('app.bsky.feed.post', {\n * signal: controller.signal\n * })\n * ```\n */\n async get(\n nsidStr: NSID | string,\n options?: ResolveDidOptions,\n ): Promise<LexResolverResult> {\n const uri = await this.resolve(nsidStr)\n return this.fetch(uri, options)\n }\n\n /**\n * Resolves the authority for an NSID and returns the AT URI for the lexicon.\n *\n * This method performs the first stage of lexicon resolution:\n * 1. Parses the NSID to extract the authority domain\n * 2. Looks up the `_lexicon.<authority>` DNS TXT record\n * 3. Extracts the DID from the TXT record (format: `did=<did>`)\n * 4. Constructs the AT URI for the lexicon record\n *\n * Use this when you need the URI without fetching the actual document,\n * or when you want to implement custom fetching logic.\n *\n * @param nsidStr - The NSID to resolve, either as a string or NSID object\n * @returns The AT URI pointing to the lexicon record\n * @throws {LexResolverError} If authority resolution fails (e.g., DNS lookup fails)\n *\n * @example\n * ```typescript\n * // Resolve to get the AT URI\n * const uri = await resolver.resolve('app.bsky.feed.post')\n * console.log(uri.toString())\n * // Output: 'at://did:plc:z72i7hdynmk6r22z27h6tvur/com.atproto.lexicon.schema/app.bsky.feed.post'\n *\n * // The URI can then be used with fetch() or stored for later use\n * const result = await resolver.fetch(uri)\n * ```\n */\n async resolve(nsidStr: NSID | string): Promise<AtUri> {\n const nsid = NSID.from(nsidStr)\n\n const did =\n (await this.options.hooks?.onResolveAuthority?.({ nsid })) ??\n (await this.resolveLexiconAuthority(nsid).then(\n async (did) => {\n await this.options.hooks?.onResolveAuthorityResult?.({ nsid, did })\n return did\n },\n async (err) => {\n await this.options.hooks?.onResolveAuthorityError?.({ nsid, err })\n throw err\n },\n ))\n\n return AtUri.make(did, 'com.atproto.lexicon.schema', nsid.toString())\n }\n\n // @TODO This class could be made compatible with browsers by making the\n // following method abstract and/or by allowing the caller to inject a DNS\n // resolver implementation (based on DNS-over-HTTPS or similar), instead of\n // using the Node.js built-in resolver.\n protected async resolveLexiconAuthority(nsid: NSID): Promise<Did> {\n try {\n return await getDomainTxtDid(`_lexicon.${nsid.authority}`)\n } catch (cause) {\n throw new LexResolverError(\n nsid,\n `Failed to resolve lexicon DID authority for ${nsid}`,\n { cause },\n )\n }\n }\n\n /**\n * Fetches a lexicon document from a specific AT URI.\n *\n * This method performs the second stage of lexicon resolution:\n * 1. Resolves the DID from the URI to find the PDS endpoint\n * 2. Fetches the record from the PDS using `com.atproto.sync.getRecord`\n * 3. Verifies the cryptographic proof (commit signature)\n * 4. Validates the lexicon document structure\n * 5. Ensures the document ID matches the URI rkey\n *\n * Use this when you already have an AT URI (e.g., from {@link resolve})\n * and want to fetch the lexicon document.\n *\n * @param uriStr - The AT URI to fetch, either as a string or AtUri object\n * @param options - Optional DID resolution options (e.g., signal for cancellation, noCache)\n * @returns The resolved lexicon result containing URI, CID, and lexicon document\n * @throws {LexResolverError} If fetching or validation fails\n *\n * @example\n * ```typescript\n * // Fetch from a known URI\n * const result = await resolver.fetch(\n * 'at://did:plc:xyz/com.atproto.lexicon.schema/app.bsky.feed.post'\n * )\n *\n * // Fetch with no-cache to bypass any upstream caching\n * const result = await resolver.fetch(uri, { noCache: true })\n *\n * // Fetch with abort signal\n * const controller = new AbortController()\n * const result = await resolver.fetch(uri, { signal: controller.signal })\n * ```\n */\n async fetch(\n uriStr: AtUri | string,\n options?: ResolveDidOptions,\n ): Promise<LexResolverResult> {\n const uri = typeof uriStr === 'string' ? new AtUri(uriStr) : uriStr\n\n const { lexicon, cid } =\n (await this.options.hooks?.onFetch?.({ uri })) ??\n (await this.fetchLexiconUri(uri, options).then(\n async (res) => {\n await this.options.hooks?.onFetchResult?.({ uri, ...res })\n return res\n },\n async (err) => {\n await this.options.hooks?.onFetchError?.({ uri, err })\n throw err\n },\n ))\n\n return { uri, cid, lexicon }\n }\n\n protected async fetchLexiconUri(\n uri: AtUri,\n options?: ResolveDidOptions,\n ): Promise<LexResolverFetchResult> {\n const { did, nsid } = parseLexiconUri(uri)\n\n const { pds, key } = await this.didResolver\n .resolve(did, options)\n .then(extractAtprotoData)\n .catch((cause) => {\n throw new LexResolverError(\n nsid,\n `Failed to resolve DID document for ${did}`,\n { cause },\n )\n })\n\n if (!key || !pds || !URL.canParse(pds.serviceEndpoint)) {\n throw new LexResolverError(\n nsid,\n `No atproto PDS service endpoint or signing key found in ${did} DID document`,\n )\n }\n\n const agent = buildAgent({\n service: pds.serviceEndpoint,\n fetch: this.options.fetch,\n })\n\n const collection = 'com.atproto.lexicon.schema'\n const rkey = nsid.toString()\n\n const { cid, record } = await xrpc(agent, com.atproto.sync.getRecord, {\n signal: options?.signal,\n headers: options?.noCache ? { 'Cache-Control': 'no-cache' } : undefined,\n params: { did, collection, rkey },\n }).then(\n ({ body }) => {\n return verifyRecordProof(body, did, key, collection, rkey).catch(\n (cause) => {\n throw new LexResolverError(\n nsid,\n `Failed to verify Lexicon record proof at ${uri}`,\n { cause },\n )\n },\n )\n },\n (cause) => {\n throw new LexResolverError(nsid, `Failed to fetch Record ${uri}`, {\n cause,\n })\n },\n )\n\n const validationResult = lexiconDocumentSchema.safeParse(record)\n if (!validationResult.success) {\n throw new LexResolverError(nsid, `Invalid Lexicon document at ${uri}`, {\n cause: validationResult.reason,\n })\n }\n\n const lexicon = validationResult.value\n if (lexicon.id !== uri.rkey) {\n throw new LexResolverError(\n nsid,\n `Invalid document id \"${lexicon.id}\" at ${uri}`,\n )\n }\n\n return { lexicon, cid }\n }\n}\n\nfunction parseLexiconUri(uri: AtUri): {\n did: Did\n nsid: NSID\n} {\n // Validate input URI\n const nsid = NSID.from(uri.rkey)\n try {\n const did = uri.host\n assertDid(did)\n return { did, nsid }\n } catch (cause) {\n throw new LexResolverError(nsid, `URI host is not a DID ${uri}`, { cause })\n }\n}\n\nasync function getDomainTxtDid(domain: string): Promise<Did> {\n const didLines = (await resolveTxt(domain))\n .map((chunks) => chunks.join(''))\n .filter((i) => i.startsWith('did='))\n\n if (didLines.length === 1) {\n const did = didLines[0].slice(4)\n assertDid(did)\n return did\n }\n\n throw didLines.length > 1\n ? new Error('Multiple DIDs found in DNS TXT records')\n : new Error('No DID found in DNS TXT records')\n}\n\nasync function verifyRecordProof(\n car: Uint8Array,\n did: Did,\n key: AtprotoVerificationMethod,\n collection: NsidString,\n rkey: string,\n) {\n const { root, blocks } = await readCarWithRoot(car)\n const blockstore = new MemoryBlockstore(blocks)\n\n const commit = await blockstore.readObj(root, repoDef.commit)\n if (commit.did !== did) {\n throw new Error(`Invalid repo did: ${commit.did}`)\n }\n\n const signingKey = getDidKeyFromMultibase(key)\n const validSig = await verifyCommitSig(commit, signingKey)\n if (!validSig) {\n throw new Error(`Invalid signature on commit: ${root.toString()}`)\n }\n\n const mst = MST.load(blockstore, commit.data)\n\n const cid = await mst.get(`${collection}/${rkey}`)\n if (!cid) throw new Error('Record not found in proof')\n\n const record = await blockstore.readRecord(cid)\n if (record?.$type !== collection) {\n throw new Error(\n `Invalid record type: expected ${collection}, got ${record?.$type}`,\n )\n }\n\n return { cid, record }\n}\n\nfunction getDidKeyFromMultibase(key: AtprotoVerificationMethod) {\n switch (key.type) {\n case 'EcdsaSecp256r1VerificationKey2019': {\n const keyBytes = crypto.multibaseToBytes(key.publicKeyMultibase)\n return crypto.formatDidKey(crypto.P256_JWT_ALG, keyBytes)\n }\n case 'EcdsaSecp256k1VerificationKey2019': {\n const keyBytes = crypto.multibaseToBytes(key.publicKeyMultibase)\n return crypto.formatDidKey(crypto.SECP256K1_JWT_ALG, keyBytes)\n }\n case 'Multikey': {\n const { jwtAlg, keyBytes } = crypto.parseMultikey(key.publicKeyMultibase)\n return crypto.formatDidKey(jwtAlg, keyBytes)\n }\n default: {\n // Should never happen\n throw new Error(`Unsupported verification method type: ${key.type}`)\n }\n }\n}\n"]}
@@ -1,28 +1,25 @@
1
- "use strict";
2
1
  /*
3
2
  * THIS FILE WAS GENERATED BY "@atproto/lex". DO NOT EDIT.
4
3
  */
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.$output = exports.$params = exports.$lxm = exports.main = exports.$nsid = void 0;
7
- const lex_schema_1 = require("@atproto/lex-schema");
4
+ import { l } from '@atproto/lex-schema';
8
5
  const $nsid = 'com.atproto.sync.getRecord';
9
- exports.$nsid = $nsid;
6
+ export { $nsid };
10
7
  /** Get data blocks needed to prove the existence or non-existence of record in the current version of repo. Does not require auth. */
11
8
  const main =
12
9
  /*#__PURE__*/
13
- lex_schema_1.l.query($nsid,
14
- /*#__PURE__*/ lex_schema_1.l.params({
15
- did: /*#__PURE__*/ lex_schema_1.l.string({ format: 'did' }),
16
- collection: /*#__PURE__*/ lex_schema_1.l.string({ format: 'nsid' }),
17
- rkey: /*#__PURE__*/ lex_schema_1.l.string({ format: 'record-key' }),
10
+ l.query($nsid,
11
+ /*#__PURE__*/ l.params({
12
+ did: /*#__PURE__*/ l.string({ format: 'did' }),
13
+ collection: /*#__PURE__*/ l.string({ format: 'nsid' }),
14
+ rkey: /*#__PURE__*/ l.string({ format: 'record-key' }),
18
15
  }),
19
- /*#__PURE__*/ lex_schema_1.l.payload('application/vnd.ipld.car'), [
16
+ /*#__PURE__*/ l.payload('application/vnd.ipld.car'), [
20
17
  'RecordNotFound',
21
18
  'RepoNotFound',
22
19
  'RepoTakendown',
23
20
  'RepoSuspended',
24
21
  'RepoDeactivated',
25
22
  ]);
26
- exports.main = main;
27
- exports.$lxm = main.nsid, exports.$params = main.parameters, exports.$output = main.output;
23
+ export { main };
24
+ export const $lxm = /*#__PURE__*/ main.nsid, $params = main.parameters, $output = main.output;
28
25
  //# sourceMappingURL=getRecord.defs.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"getRecord.defs.js","sourceRoot":"","sources":["../../../../../src/lexicons/com/atproto/sync/getRecord.defs.ts"],"names":[],"mappings":";AAAA;;GAEG;;;AAEH,oDAAuC;AAEvC,MAAM,KAAK,GAAG,4BAA4B,CAAA;AAEjC,sBAAK;AAEd,sIAAsI;AACtI,MAAM,IAAI;AACR,aAAa;AACb,cAAC,CAAC,KAAK,CACL,KAAK;AACL,aAAa,CAAC,cAAC,CAAC,MAAM,CAAC;IACrB,GAAG,EAAE,aAAa,CAAC,cAAC,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;IAC9C,UAAU,EAAE,aAAa,CAAC,cAAC,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;IACtD,IAAI,EAAE,aAAa,CAAC,cAAC,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,YAAY,EAAE,CAAC;CACvD,CAAC;AACF,aAAa,CAAC,cAAC,CAAC,OAAO,CAAC,0BAA0B,CAAC,EACnD;IACE,gBAAgB;IAChB,cAAc;IACd,eAAe;IACf,eAAe;IACf,iBAAiB;CAClB,CACF,CAAA;AACM,oBAAI;AASA,QAAA,IAAI,GAAiB,IAAI,CAAC,IAAI,EACzC,QAAA,OAAO,GAAG,IAAI,CAAC,UAAU,EACzB,QAAA,OAAO,GAAG,IAAI,CAAC,MAAM,CAAA","sourcesContent":["/*\n * THIS FILE WAS GENERATED BY \"@atproto/lex\". DO NOT EDIT.\n */\n\nimport { l } from '@atproto/lex-schema'\n\nconst $nsid = 'com.atproto.sync.getRecord'\n\nexport { $nsid }\n\n/** Get data blocks needed to prove the existence or non-existence of record in the current version of repo. Does not require auth. */\nconst main =\n /*#__PURE__*/\n l.query(\n $nsid,\n /*#__PURE__*/ l.params({\n did: /*#__PURE__*/ l.string({ format: 'did' }),\n collection: /*#__PURE__*/ l.string({ format: 'nsid' }),\n rkey: /*#__PURE__*/ l.string({ format: 'record-key' }),\n }),\n /*#__PURE__*/ l.payload('application/vnd.ipld.car'),\n [\n 'RecordNotFound',\n 'RepoNotFound',\n 'RepoTakendown',\n 'RepoSuspended',\n 'RepoDeactivated',\n ],\n )\nexport { main }\n\nexport type $Params = l.InferMethodParams<typeof main>\nexport type $Output<B = l.BinaryData> = l.InferMethodOutput<typeof main, B>\nexport type $OutputBody<B = l.BinaryData> = l.InferMethodOutputBody<\n typeof main,\n B\n>\n\nexport const $lxm = /*#__PURE__*/ main.nsid,\n $params = main.parameters,\n $output = main.output\n"]}
1
+ {"version":3,"file":"getRecord.defs.js","sourceRoot":"","sources":["../../../../../src/lexicons/com/atproto/sync/getRecord.defs.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,qBAAqB,CAAA;AAEvC,MAAM,KAAK,GAAG,4BAA4B,CAAA;AAE1C,OAAO,EAAE,KAAK,EAAE,CAAA;AAEhB,sIAAsI;AACtI,MAAM,IAAI;AACR,aAAa;AACb,CAAC,CAAC,KAAK,CACL,KAAK;AACL,aAAa,CAAC,CAAC,CAAC,MAAM,CAAC;IACrB,GAAG,EAAE,aAAa,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;IAC9C,UAAU,EAAE,aAAa,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;IACtD,IAAI,EAAE,aAAa,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,YAAY,EAAE,CAAC;CACvD,CAAC;AACF,aAAa,CAAC,CAAC,CAAC,OAAO,CAAC,0BAA0B,CAAC,EACnD;IACE,gBAAgB;IAChB,cAAc;IACd,eAAe;IACf,eAAe;IACf,iBAAiB;CAClB,CACF,CAAA;AACH,OAAO,EAAE,IAAI,EAAE,CAAA;AASf,MAAM,CAAC,MAAM,IAAI,GAAG,aAAa,CAAC,IAAI,CAAC,IAAI,EACzC,OAAO,GAAG,IAAI,CAAC,UAAU,EACzB,OAAO,GAAG,IAAI,CAAC,MAAM,CAAA","sourcesContent":["/*\n * THIS FILE WAS GENERATED BY \"@atproto/lex\". DO NOT EDIT.\n */\n\nimport { l } from '@atproto/lex-schema'\n\nconst $nsid = 'com.atproto.sync.getRecord'\n\nexport { $nsid }\n\n/** Get data blocks needed to prove the existence or non-existence of record in the current version of repo. Does not require auth. */\nconst main =\n /*#__PURE__*/\n l.query(\n $nsid,\n /*#__PURE__*/ l.params({\n did: /*#__PURE__*/ l.string({ format: 'did' }),\n collection: /*#__PURE__*/ l.string({ format: 'nsid' }),\n rkey: /*#__PURE__*/ l.string({ format: 'record-key' }),\n }),\n /*#__PURE__*/ l.payload('application/vnd.ipld.car'),\n [\n 'RecordNotFound',\n 'RepoNotFound',\n 'RepoTakendown',\n 'RepoSuspended',\n 'RepoDeactivated',\n ],\n )\nexport { main }\n\nexport type $Params = l.InferMethodParams<typeof main>\nexport type $Output<B = l.BinaryData> = l.InferMethodOutput<typeof main, B>\nexport type $OutputBody<B = l.BinaryData> = l.InferMethodOutputBody<\n typeof main,\n B\n>\n\nexport const $lxm = /*#__PURE__*/ main.nsid,\n $params = main.parameters,\n $output = main.output\n"]}
@@ -1,10 +1,6 @@
1
- "use strict";
2
1
  /*
3
2
  * THIS FILE WAS GENERATED BY "@atproto/lex". DO NOT EDIT.
4
3
  */
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.$defs = void 0;
7
- const tslib_1 = require("tslib");
8
- tslib_1.__exportStar(require("./getRecord.defs.js"), exports);
9
- exports.$defs = tslib_1.__importStar(require("./getRecord.defs.js"));
4
+ export * from './getRecord.defs.js';
5
+ export * as $defs from './getRecord.defs.js';
10
6
  //# sourceMappingURL=getRecord.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"getRecord.js","sourceRoot":"","sources":["../../../../../src/lexicons/com/atproto/sync/getRecord.ts"],"names":[],"mappings":";AAAA;;GAEG;;;;AAEH,8DAAmC;AACnC,qEAA4C","sourcesContent":["/*\n * THIS FILE WAS GENERATED BY \"@atproto/lex\". DO NOT EDIT.\n */\n\nexport * from './getRecord.defs.js'\nexport * as $defs from './getRecord.defs.js'\n"]}
1
+ {"version":3,"file":"getRecord.js","sourceRoot":"","sources":["../../../../../src/lexicons/com/atproto/sync/getRecord.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,qBAAqB,CAAA;AACnC,OAAO,KAAK,KAAK,MAAM,qBAAqB,CAAA","sourcesContent":["/*\n * THIS FILE WAS GENERATED BY \"@atproto/lex\". DO NOT EDIT.\n */\n\nexport * from './getRecord.defs.js'\nexport * as $defs from './getRecord.defs.js'\n"]}
@@ -1,9 +1,5 @@
1
- "use strict";
2
1
  /*
3
2
  * THIS FILE WAS GENERATED BY "@atproto/lex". DO NOT EDIT.
4
3
  */
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.getRecord = void 0;
7
- const tslib_1 = require("tslib");
8
- exports.getRecord = tslib_1.__importStar(require("./sync/getRecord.js"));
4
+ export * as getRecord from './sync/getRecord.js';
9
5
  //# sourceMappingURL=sync.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"sync.js","sourceRoot":"","sources":["../../../../src/lexicons/com/atproto/sync.ts"],"names":[],"mappings":";AAAA;;GAEG;;;;AAEH,yEAAgD","sourcesContent":["/*\n * THIS FILE WAS GENERATED BY \"@atproto/lex\". DO NOT EDIT.\n */\n\nexport * as getRecord from './sync/getRecord.js'\n"]}
1
+ {"version":3,"file":"sync.js","sourceRoot":"","sources":["../../../../src/lexicons/com/atproto/sync.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,SAAS,MAAM,qBAAqB,CAAA","sourcesContent":["/*\n * THIS FILE WAS GENERATED BY \"@atproto/lex\". DO NOT EDIT.\n */\n\nexport * as getRecord from './sync/getRecord.js'\n"]}
@@ -1,9 +1,5 @@
1
- "use strict";
2
1
  /*
3
2
  * THIS FILE WAS GENERATED BY "@atproto/lex". DO NOT EDIT.
4
3
  */
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.sync = void 0;
7
- const tslib_1 = require("tslib");
8
- exports.sync = tslib_1.__importStar(require("./atproto/sync.js"));
4
+ export * as sync from './atproto/sync.js';
9
5
  //# sourceMappingURL=atproto.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"atproto.js","sourceRoot":"","sources":["../../../src/lexicons/com/atproto.ts"],"names":[],"mappings":";AAAA;;GAEG;;;;AAEH,kEAAyC","sourcesContent":["/*\n * THIS FILE WAS GENERATED BY \"@atproto/lex\". DO NOT EDIT.\n */\n\nexport * as sync from './atproto/sync.js'\n"]}
1
+ {"version":3,"file":"atproto.js","sourceRoot":"","sources":["../../../src/lexicons/com/atproto.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,IAAI,MAAM,mBAAmB,CAAA","sourcesContent":["/*\n * THIS FILE WAS GENERATED BY \"@atproto/lex\". DO NOT EDIT.\n */\n\nexport * as sync from './atproto/sync.js'\n"]}
@@ -1,9 +1,5 @@
1
- "use strict";
2
1
  /*
3
2
  * THIS FILE WAS GENERATED BY "@atproto/lex". DO NOT EDIT.
4
3
  */
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.atproto = void 0;
7
- const tslib_1 = require("tslib");
8
- exports.atproto = tslib_1.__importStar(require("./com/atproto.js"));
4
+ export * as atproto from './com/atproto.js';
9
5
  //# sourceMappingURL=com.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"com.js","sourceRoot":"","sources":["../../src/lexicons/com.ts"],"names":[],"mappings":";AAAA;;GAEG;;;;AAEH,oEAA2C","sourcesContent":["/*\n * THIS FILE WAS GENERATED BY \"@atproto/lex\". DO NOT EDIT.\n */\n\nexport * as atproto from './com/atproto.js'\n"]}
1
+ {"version":3,"file":"com.js","sourceRoot":"","sources":["../../src/lexicons/com.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,OAAO,MAAM,kBAAkB,CAAA","sourcesContent":["/*\n * THIS FILE WAS GENERATED BY \"@atproto/lex\". DO NOT EDIT.\n */\n\nexport * as atproto from './com/atproto.js'\n"]}
@@ -1,9 +1,5 @@
1
- "use strict";
2
1
  /*
3
2
  * THIS FILE WAS GENERATED BY "@atproto/lex". DO NOT EDIT.
4
3
  */
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.com = void 0;
7
- const tslib_1 = require("tslib");
8
- exports.com = tslib_1.__importStar(require("./com.js"));
4
+ export * as com from './com.js';
9
5
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/lexicons/index.ts"],"names":[],"mappings":";AAAA;;GAEG;;;;AAEH,wDAA+B","sourcesContent":["/*\n * THIS FILE WAS GENERATED BY \"@atproto/lex\". DO NOT EDIT.\n */\n\nexport * as com from './com.js'\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/lexicons/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,GAAG,MAAM,UAAU,CAAA","sourcesContent":["/*\n * THIS FILE WAS GENERATED BY \"@atproto/lex\". DO NOT EDIT.\n */\n\nexport * as com from './com.js'\n"]}
package/package.json CHANGED
@@ -1,6 +1,9 @@
1
1
  {
2
2
  "name": "@atproto/lex-resolver",
3
- "version": "0.0.22",
3
+ "version": "0.1.0-next.0",
4
+ "engines": {
5
+ "node": ">=22"
6
+ },
4
7
  "license": "MIT",
5
8
  "description": "Lexicon document resolver utility for AT Lexicons",
6
9
  "keywords": [
@@ -24,31 +27,27 @@
24
27
  "./CHANGELOG.md"
25
28
  ],
26
29
  "sideEffects": false,
27
- "type": "commonjs",
28
- "main": "./dist/index.js",
29
- "types": "./dist/index.d.ts",
30
+ "type": "module",
30
31
  "exports": {
31
32
  ".": {
32
33
  "types": "./dist/index.d.ts",
33
- "browser": "./dist/index.js",
34
- "import": "./dist/index.js",
35
34
  "default": "./dist/index.js"
36
35
  }
37
36
  },
38
37
  "dependencies": {
39
38
  "tslib": "^2.8.1",
40
- "@atproto-labs/did-resolver": "^0.2.6",
41
- "@atproto/crypto": "^0.4.5",
42
- "@atproto/lex-client": "^0.0.20",
43
- "@atproto/lex-data": "^0.0.15",
44
- "@atproto/lex-schema": "^0.0.19",
45
- "@atproto/repo": "^0.9.1",
46
- "@atproto/syntax": "^0.5.4",
47
- "@atproto/lex-document": "^0.0.20"
39
+ "@atproto/lex-client": "^0.1.0-next.0",
40
+ "@atproto/lex-data": "^0.1.0-next.0",
41
+ "@atproto/lex-document": "^0.1.0-next.0",
42
+ "@atproto/syntax": "^0.6.0-next.0",
43
+ "@atproto-labs/did-resolver": "^0.3.0-next.0",
44
+ "@atproto/lex-schema": "^0.1.0-next.0",
45
+ "@atproto/crypto": "^0.5.0-next.0",
46
+ "@atproto/repo": "^0.10.0-next.0"
48
47
  },
49
48
  "devDependencies": {
50
49
  "vitest": "^4.0.16",
51
- "@atproto/lex-builder": "^0.0.22"
50
+ "@atproto/lex-builder": "^0.1.0-next.0"
52
51
  },
53
52
  "scripts": {
54
53
  "prebuild": "node ./scripts/lex-build.mjs",