@atproto/lex-builder 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,33 @@
1
1
  # @atproto/lex-builder
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/lex-document@0.1.0-next.0
21
+ - @atproto/lex-schema@0.1.0-next.0
22
+
23
+ ## 0.0.23
24
+
25
+ ### Patch Changes
26
+
27
+ - Updated dependencies [[`2fd8d62`](https://github.com/bluesky-social/atproto/commit/2fd8d62708dc23de6ed21cbcccfebab68b19f588)]:
28
+ - @atproto/lex-schema@0.0.20
29
+ - @atproto/lex-document@0.0.21
30
+
3
31
  ## 0.0.22
4
32
 
5
33
  ### Patch Changes
package/dist/filter.js CHANGED
@@ -1,6 +1,3 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.buildFilter = buildFilter;
4
1
  /**
5
2
  * Builds a filter function from include/exclude patterns.
6
3
  *
@@ -23,7 +20,7 @@ exports.buildFilter = buildFilter;
23
20
  * filter('com.atproto.repo') // false (not included)
24
21
  * ```
25
22
  */
26
- function buildFilter(options) {
23
+ export function buildFilter(options) {
27
24
  const include = createMatcher(options.include, () => true);
28
25
  const exclude = createMatcher(options.exclude, () => false);
29
26
  return (id) => include(id) && !exclude(id);
@@ -1 +1 @@
1
- {"version":3,"file":"filter.js","sourceRoot":"","sources":["../src/filter.ts"],"names":[],"mappings":";;AA8DA,kCAKC;AA3BD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,SAAgB,WAAW,CAAC,OAA2B;IACrD,MAAM,OAAO,GAAG,aAAa,CAAC,OAAO,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,CAAA;IAC1D,MAAM,OAAO,GAAG,aAAa,CAAC,OAAO,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,CAAA;IAE3D,OAAO,CAAC,EAAE,EAAE,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAA;AAC5C,CAAC;AAED,SAAS,aAAa,CACpB,OAAsC,EACtC,QAAgB;IAEhB,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,CAAC;QACrB,OAAO,QAAQ,CAAA;IACjB,CAAC;SAAM,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;QAClC,OAAO,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,MAAM,CAAC,cAAc,CAAC,CAAA;IACzD,CAAC;SAAM,CAAC;QACN,OAAO,YAAY,CAAC,OAAO,CAAC,CAAA;IAC9B,CAAC;AACH,CAAC;AAED,SAAS,cAAc,CAAC,CAAS,EAAE,CAAS;IAC1C,OAAO,CAAC,KAAa,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAA;AAChD,CAAC;AAED,SAAS,YAAY,CAAC,OAAe;IACnC,IAAI,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QAC1B,MAAM,KAAK,GAAG,IAAI,MAAM,CACtB,IAAI,OAAO,CAAC,UAAU,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,UAAU,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAC5D,CAAA;QACD,OAAO,CAAC,KAAa,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;IAC7C,CAAC;IAED,OAAO,CAAC,KAAa,EAAE,EAAE,CAAC,OAAO,KAAK,KAAK,CAAA;AAC7C,CAAC","sourcesContent":["/**\n * Options for building a filter function to include/exclude lexicon documents.\n */\nexport type BuildFilterOptions = {\n /**\n * Pattern(s) for lexicon NSIDs to include.\n *\n * Supports glob patterns with `*` as a wildcard that matches one or more\n * characters. If not specified, all lexicons are included by default.\n *\n * @example\n * ```ts\n * { include: 'app.bsky.*' } // Include all app.bsky lexicons\n * { include: ['com.atproto.*', 'app.bsky.*'] } // Include multiple patterns\n * ```\n */\n include?: string | string[]\n /**\n * Pattern(s) for lexicon NSIDs to exclude.\n *\n * Supports glob patterns with `*` as a wildcard. Exclusions are applied\n * after inclusions.\n *\n * @example\n * ```ts\n * { exclude: '*.internal.*' } // Exclude internal lexicons\n * { exclude: ['*.test', '*.mock'] } // Exclude test and mock lexicons\n * ```\n */\n exclude?: string | string[]\n}\n\n/**\n * A function that tests whether a lexicon NSID should be included.\n *\n * @param input - The lexicon NSID to test\n * @returns `true` if the NSID passes the filter, `false` otherwise\n */\nexport type Filter = (input: string) => boolean\n\n/**\n * Builds a filter function from include/exclude patterns.\n *\n * The returned filter returns `true` for NSIDs that match any include pattern\n * (or all NSIDs if no include patterns are specified) AND do not match any\n * exclude pattern.\n *\n * @param options - The filter options containing include/exclude patterns\n * @returns A filter function that can be applied to lexicon NSIDs\n *\n * @example\n * ```ts\n * const filter = buildFilter({\n * include: 'app.bsky.*',\n * exclude: '*.internal.*',\n * })\n *\n * filter('app.bsky.feed.post') // true\n * filter('app.bsky.internal.foo') // false\n * filter('com.atproto.repo') // false (not included)\n * ```\n */\nexport function buildFilter(options: BuildFilterOptions): Filter {\n const include = createMatcher(options.include, () => true)\n const exclude = createMatcher(options.exclude, () => false)\n\n return (id) => include(id) && !exclude(id)\n}\n\nfunction createMatcher(\n pattern: undefined | string | string[],\n fallback: Filter,\n): Filter {\n if (!pattern?.length) {\n return fallback\n } else if (Array.isArray(pattern)) {\n return pattern.map(buildMatcher).reduce(combineFilters)\n } else {\n return buildMatcher(pattern)\n }\n}\n\nfunction combineFilters(a: Filter, b: Filter): Filter {\n return (input: string) => a(input) || b(input)\n}\n\nfunction buildMatcher(pattern: string): Filter {\n if (pattern.includes('*')) {\n const regex = new RegExp(\n `^${pattern.replaceAll('.', '\\\\.').replaceAll('*', '.+')}$`,\n )\n return (input: string) => regex.test(input)\n }\n\n return (input: string) => pattern === input\n}\n"]}
1
+ {"version":3,"file":"filter.js","sourceRoot":"","sources":["../src/filter.ts"],"names":[],"mappings":"AAwCA;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,UAAU,WAAW,CAAC,OAA2B;IACrD,MAAM,OAAO,GAAG,aAAa,CAAC,OAAO,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,CAAA;IAC1D,MAAM,OAAO,GAAG,aAAa,CAAC,OAAO,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,CAAA;IAE3D,OAAO,CAAC,EAAE,EAAE,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAA;AAC5C,CAAC;AAED,SAAS,aAAa,CACpB,OAAsC,EACtC,QAAgB;IAEhB,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,CAAC;QACrB,OAAO,QAAQ,CAAA;IACjB,CAAC;SAAM,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;QAClC,OAAO,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,MAAM,CAAC,cAAc,CAAC,CAAA;IACzD,CAAC;SAAM,CAAC;QACN,OAAO,YAAY,CAAC,OAAO,CAAC,CAAA;IAC9B,CAAC;AACH,CAAC;AAED,SAAS,cAAc,CAAC,CAAS,EAAE,CAAS;IAC1C,OAAO,CAAC,KAAa,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAA;AAChD,CAAC;AAED,SAAS,YAAY,CAAC,OAAe;IACnC,IAAI,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QAC1B,MAAM,KAAK,GAAG,IAAI,MAAM,CACtB,IAAI,OAAO,CAAC,UAAU,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,UAAU,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAC5D,CAAA;QACD,OAAO,CAAC,KAAa,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;IAC7C,CAAC;IAED,OAAO,CAAC,KAAa,EAAE,EAAE,CAAC,OAAO,KAAK,KAAK,CAAA;AAC7C,CAAC","sourcesContent":["/**\n * Options for building a filter function to include/exclude lexicon documents.\n */\nexport type BuildFilterOptions = {\n /**\n * Pattern(s) for lexicon NSIDs to include.\n *\n * Supports glob patterns with `*` as a wildcard that matches one or more\n * characters. If not specified, all lexicons are included by default.\n *\n * @example\n * ```ts\n * { include: 'app.bsky.*' } // Include all app.bsky lexicons\n * { include: ['com.atproto.*', 'app.bsky.*'] } // Include multiple patterns\n * ```\n */\n include?: string | string[]\n /**\n * Pattern(s) for lexicon NSIDs to exclude.\n *\n * Supports glob patterns with `*` as a wildcard. Exclusions are applied\n * after inclusions.\n *\n * @example\n * ```ts\n * { exclude: '*.internal.*' } // Exclude internal lexicons\n * { exclude: ['*.test', '*.mock'] } // Exclude test and mock lexicons\n * ```\n */\n exclude?: string | string[]\n}\n\n/**\n * A function that tests whether a lexicon NSID should be included.\n *\n * @param input - The lexicon NSID to test\n * @returns `true` if the NSID passes the filter, `false` otherwise\n */\nexport type Filter = (input: string) => boolean\n\n/**\n * Builds a filter function from include/exclude patterns.\n *\n * The returned filter returns `true` for NSIDs that match any include pattern\n * (or all NSIDs if no include patterns are specified) AND do not match any\n * exclude pattern.\n *\n * @param options - The filter options containing include/exclude patterns\n * @returns A filter function that can be applied to lexicon NSIDs\n *\n * @example\n * ```ts\n * const filter = buildFilter({\n * include: 'app.bsky.*',\n * exclude: '*.internal.*',\n * })\n *\n * filter('app.bsky.feed.post') // true\n * filter('app.bsky.internal.foo') // false\n * filter('com.atproto.repo') // false (not included)\n * ```\n */\nexport function buildFilter(options: BuildFilterOptions): Filter {\n const include = createMatcher(options.include, () => true)\n const exclude = createMatcher(options.exclude, () => false)\n\n return (id) => include(id) && !exclude(id)\n}\n\nfunction createMatcher(\n pattern: undefined | string | string[],\n fallback: Filter,\n): Filter {\n if (!pattern?.length) {\n return fallback\n } else if (Array.isArray(pattern)) {\n return pattern.map(buildMatcher).reduce(combineFilters)\n } else {\n return buildMatcher(pattern)\n }\n}\n\nfunction combineFilters(a: Filter, b: Filter): Filter {\n return (input: string) => a(input) || b(input)\n}\n\nfunction buildMatcher(pattern: string): Filter {\n if (pattern.includes('*')) {\n const regex = new RegExp(\n `^${pattern.replaceAll('.', '\\\\.').replaceAll('*', '.+')}$`,\n )\n return (input: string) => regex.test(input)\n }\n\n return (input: string) => pattern === input\n}\n"]}
@@ -1,19 +1,14 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.FilteredIndexer = void 0;
4
1
  /**
5
2
  * A lexicon indexer that filters documents based on a provided filter.
6
3
  *
7
4
  * If a document was filtered out but later requested via `get()`, the filter
8
5
  * will be bypassed for that document.
9
6
  */
10
- class FilteredIndexer {
11
- indexer;
12
- filter;
13
- returned = new Set();
7
+ export class FilteredIndexer {
14
8
  constructor(indexer, filter) {
15
9
  this.indexer = indexer;
16
10
  this.filter = filter;
11
+ this.returned = new Set();
17
12
  }
18
13
  async get(id) {
19
14
  this.returned.add(id);
@@ -52,5 +47,4 @@ class FilteredIndexer {
52
47
  await this.indexer[Symbol.asyncDispose]?.();
53
48
  }
54
49
  }
55
- exports.FilteredIndexer = FilteredIndexer;
56
50
  //# sourceMappingURL=filtered-indexer.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"filtered-indexer.js","sourceRoot":"","sources":["../src/filtered-indexer.ts"],"names":[],"mappings":";;;AAGA;;;;;GAKG;AACH,MAAa,eAAe;IAIf;IACA;IAJQ,QAAQ,GAAG,IAAI,GAAG,EAAU,CAAA;IAE/C,YACW,OAAwD,EACxD,MAAc;QADd,YAAO,GAAP,OAAO,CAAiD;QACxD,WAAM,GAAN,MAAM,CAAQ;IACtB,CAAC;IAEJ,KAAK,CAAC,GAAG,CAAC,EAAU;QAClB,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;QACrB,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;IAC7B,CAAC;IAED,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC;QAC3B,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAU,CAAA;QAElC,IAAI,KAAK,EAAE,MAAM,GAAG,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACrC,IAAI,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;gBACzB,sBAAsB;gBACtB,MAAM,IAAI,KAAK,CAAC,kCAAkC,GAAG,CAAC,EAAE,EAAE,CAAC,CAAA;YAC7D,CAAC;YAED,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;gBACrD,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;gBACzB,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;gBACpB,MAAM,GAAG,CAAA;YACX,CAAC;QACH,CAAC;QAED,2EAA2E;QAC3E,wEAAwE;QACxE,4EAA4E;QAC5E,uDAAuD;QAEvD,IAAI,WAAoB,CAAA;QACxB,GAAG,CAAC;YACF,WAAW,GAAG,KAAK,CAAA;YACnB,KAAK,MAAM,EAAE,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;gBAC/B,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;oBACtB,MAAM,MAAM,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;oBAChC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;oBAChB,WAAW,GAAG,IAAI,CAAA;gBACpB,CAAC;YACH,CAAC;QACH,CAAC,QAAQ,WAAW,EAAC;IACvB,CAAC;IAED,KAAK,CAAC,CAAC,MAAM,CAAC,YAAY,CAAC;QACzB,MAAM,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,YAAY,CAAC,EAAE,EAAE,CAAA;IAC7C,CAAC;CACF;AAlDD,0CAkDC","sourcesContent":["import { LexiconDocument, LexiconIndexer } from '@atproto/lex-document'\nimport { Filter } from './filter.js'\n\n/**\n * A lexicon indexer that filters documents based on a provided filter.\n *\n * If a document was filtered out but later requested via `get()`, the filter\n * will be bypassed for that document.\n */\nexport class FilteredIndexer implements LexiconIndexer, AsyncDisposable {\n protected readonly returned = new Set<string>()\n\n constructor(\n readonly indexer: LexiconIndexer & AsyncIterable<LexiconDocument>,\n readonly filter: Filter,\n ) {}\n\n async get(id: string): Promise<LexiconDocument> {\n this.returned.add(id)\n return this.indexer.get(id)\n }\n\n async *[Symbol.asyncIterator]() {\n const returned = new Set<string>()\n\n for await (const doc of this.indexer) {\n if (returned.has(doc.id)) {\n // Should never happen\n throw new Error(`Duplicate lexicon document id: ${doc.id}`)\n }\n\n if (this.returned.has(doc.id) || this.filter(doc.id)) {\n this.returned.add(doc.id)\n returned.add(doc.id)\n yield doc\n }\n }\n\n // When we yield control back to the caller, there may be requests (.get())\n // for documents that were initially ignored (filtered out). We won't be\n // done iterating until every document that may have been requested when the\n // control was yielded to the caller has been returned.\n\n let returnedAny: boolean\n do {\n returnedAny = false\n for (const id of this.returned) {\n if (!returned.has(id)) {\n yield await this.indexer.get(id)\n returned.add(id)\n returnedAny = true\n }\n }\n } while (returnedAny)\n }\n\n async [Symbol.asyncDispose](): Promise<void> {\n await this.indexer[Symbol.asyncDispose]?.()\n }\n}\n"]}
1
+ {"version":3,"file":"filtered-indexer.js","sourceRoot":"","sources":["../src/filtered-indexer.ts"],"names":[],"mappings":"AAGA;;;;;GAKG;AACH,MAAM,OAAO,eAAe;IAG1B,YACW,OAAwD,EACxD,MAAc;QADd,YAAO,GAAP,OAAO,CAAiD;QACxD,WAAM,GAAN,MAAM,CAAQ;QAJN,aAAQ,GAAG,IAAI,GAAG,EAAU,CAAA;IAK5C,CAAC;IAEJ,KAAK,CAAC,GAAG,CAAC,EAAU;QAClB,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;QACrB,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;IAC7B,CAAC;IAED,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC;QAC3B,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAU,CAAA;QAElC,IAAI,KAAK,EAAE,MAAM,GAAG,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACrC,IAAI,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;gBACzB,sBAAsB;gBACtB,MAAM,IAAI,KAAK,CAAC,kCAAkC,GAAG,CAAC,EAAE,EAAE,CAAC,CAAA;YAC7D,CAAC;YAED,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;gBACrD,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;gBACzB,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;gBACpB,MAAM,GAAG,CAAA;YACX,CAAC;QACH,CAAC;QAED,2EAA2E;QAC3E,wEAAwE;QACxE,4EAA4E;QAC5E,uDAAuD;QAEvD,IAAI,WAAoB,CAAA;QACxB,GAAG,CAAC;YACF,WAAW,GAAG,KAAK,CAAA;YACnB,KAAK,MAAM,EAAE,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;gBAC/B,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;oBACtB,MAAM,MAAM,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;oBAChC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;oBAChB,WAAW,GAAG,IAAI,CAAA;gBACpB,CAAC;YACH,CAAC;QACH,CAAC,QAAQ,WAAW,EAAC;IACvB,CAAC;IAED,KAAK,CAAC,CAAC,MAAM,CAAC,YAAY,CAAC;QACzB,MAAM,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,YAAY,CAAC,EAAE,EAAE,CAAA;IAC7C,CAAC;CACF","sourcesContent":["import { LexiconDocument, LexiconIndexer } from '@atproto/lex-document'\nimport { Filter } from './filter.js'\n\n/**\n * A lexicon indexer that filters documents based on a provided filter.\n *\n * If a document was filtered out but later requested via `get()`, the filter\n * will be bypassed for that document.\n */\nexport class FilteredIndexer implements LexiconIndexer, AsyncDisposable {\n protected readonly returned = new Set<string>()\n\n constructor(\n readonly indexer: LexiconIndexer & AsyncIterable<LexiconDocument>,\n readonly filter: Filter,\n ) {}\n\n async get(id: string): Promise<LexiconDocument> {\n this.returned.add(id)\n return this.indexer.get(id)\n }\n\n async *[Symbol.asyncIterator]() {\n const returned = new Set<string>()\n\n for await (const doc of this.indexer) {\n if (returned.has(doc.id)) {\n // Should never happen\n throw new Error(`Duplicate lexicon document id: ${doc.id}`)\n }\n\n if (this.returned.has(doc.id) || this.filter(doc.id)) {\n this.returned.add(doc.id)\n returned.add(doc.id)\n yield doc\n }\n }\n\n // When we yield control back to the caller, there may be requests (.get())\n // for documents that were initially ignored (filtered out). We won't be\n // done iterating until every document that may have been requested when the\n // control was yielded to the caller has been returned.\n\n let returnedAny: boolean\n do {\n returnedAny = false\n for (const id of this.returned) {\n if (!returned.has(id)) {\n yield await this.indexer.get(id)\n returned.add(id)\n returnedAny = true\n }\n }\n } while (returnedAny)\n }\n\n async [Symbol.asyncDispose](): Promise<void> {\n await this.indexer[Symbol.asyncDispose]?.()\n }\n}\n"]}
package/dist/formatter.js CHANGED
@@ -1,7 +1,4 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.Formatter = void 0;
4
- const prettier_1 = require("prettier");
1
+ import { format as prettierFormat } from 'prettier';
5
2
  const DEFAULT_FORMAT_OPTIONS = {
6
3
  parser: 'typescript',
7
4
  tabWidth: 2,
@@ -22,11 +19,7 @@ const DEFAULT_BANNER = `/*
22
19
  * const formatted = await formatter.format(generatedCode)
23
20
  * ```
24
21
  */
25
- class Formatter {
26
- /** The banner comment to prepend to formatted code. */
27
- banner;
28
- /** Prettier options, or `null` if formatting is disabled. */
29
- prettierOptions;
22
+ export class Formatter {
30
23
  /**
31
24
  * Creates a new Formatter instance.
32
25
  *
@@ -50,10 +43,9 @@ class Formatter {
50
43
  async format(code) {
51
44
  const bannerPadding = this.banner && !this.banner.endsWith('\n') ? '\n\n' : '';
52
45
  const codePretty = this.prettierOptions
53
- ? await (0, prettier_1.format)(code, this.prettierOptions)
46
+ ? await prettierFormat(code, this.prettierOptions)
54
47
  : code;
55
48
  return `${this.banner}${bannerPadding}${codePretty}`;
56
49
  }
57
50
  }
58
- exports.Formatter = Formatter;
59
51
  //# sourceMappingURL=formatter.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"formatter.js","sourceRoot":"","sources":["../src/formatter.ts"],"names":[],"mappings":";;;AAAA,uCAA+E;AAE/E,MAAM,sBAAsB,GAAoB;IAC9C,MAAM,EAAE,YAAY;IACpB,QAAQ,EAAE,CAAC;IACX,IAAI,EAAE,KAAK;IACX,WAAW,EAAE,IAAI;IACjB,aAAa,EAAE,KAAK;CACrB,CAAA;AAED,MAAM,cAAc,GAAG;;IAEnB,CAAA;AAwBJ;;;;;;;;;GASG;AACH,MAAa,SAAS;IACpB,uDAAuD;IAC9C,MAAM,CAAQ;IACvB,6DAA6D;IACpD,eAAe,CAAwB;IAEhD;;;;OAIG;IACH,YAAY,UAA4B,EAAE;QACxC,IAAI,CAAC,MAAM,GAAG,OAAO,EAAE,MAAM,IAAI,cAAc,CAAA;QAE/C,IAAI,CAAC,eAAe;YAClB,OAAO,EAAE,MAAM,KAAK,IAAI;gBACtB,CAAC,CAAC,sBAAsB;gBACxB,CAAC,CAAC,OAAO,EAAE,MAAM,IAAI,IAAI,CAAA;IAC/B,CAAC;IAED;;;;;;;OAOG;IACH,KAAK,CAAC,MAAM,CAAC,IAAY;QACvB,MAAM,aAAa,GACjB,IAAI,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAA;QAC1D,MAAM,UAAU,GAAG,IAAI,CAAC,eAAe;YACrC,CAAC,CAAC,MAAM,IAAA,iBAAc,EAAC,IAAI,EAAE,IAAI,CAAC,eAAe,CAAC;YAClD,CAAC,CAAC,IAAI,CAAA;QACR,OAAO,GAAG,IAAI,CAAC,MAAM,GAAG,aAAa,GAAG,UAAU,EAAE,CAAA;IACtD,CAAC;CACF;AApCD,8BAoCC","sourcesContent":["import { Options as PrettierOptions, format as prettierFormat } from 'prettier'\n\nconst DEFAULT_FORMAT_OPTIONS: PrettierOptions = {\n parser: 'typescript',\n tabWidth: 2,\n semi: false,\n singleQuote: true,\n trailingComma: 'all',\n}\n\nconst DEFAULT_BANNER = `/*\n * THIS FILE WAS GENERATED BY \"@atproto/lex\". DO NOT EDIT.\n */`\n\n/**\n * Options for configuring the code formatter.\n */\nexport type FormatterOptions = {\n /**\n * Whether to format the generated code with Prettier.\n *\n * - `false`: No formatting (default)\n * - `true`: Format with default Prettier options\n * - `PrettierOptions`: Format with custom Prettier configuration\n *\n * @default false\n */\n pretty?: boolean | PrettierOptions\n /**\n * A banner comment to prepend to each generated file.\n *\n * @default '/* THIS FILE WAS GENERATED BY \"@atproto/lex\". DO NOT EDIT. *\\/'\n */\n banner?: string\n}\n\n/**\n * Formats generated TypeScript code with optional Prettier formatting\n * and banner comments.\n *\n * @example\n * ```ts\n * const formatter = new Formatter({ pretty: true })\n * const formatted = await formatter.format(generatedCode)\n * ```\n */\nexport class Formatter {\n /** The banner comment to prepend to formatted code. */\n readonly banner: string\n /** Prettier options, or `null` if formatting is disabled. */\n readonly prettierOptions: PrettierOptions | null\n\n /**\n * Creates a new Formatter instance.\n *\n * @param options - Formatting configuration options\n */\n constructor(options: FormatterOptions = {}) {\n this.banner = options?.banner ?? DEFAULT_BANNER\n\n this.prettierOptions =\n options?.pretty === true\n ? DEFAULT_FORMAT_OPTIONS\n : options?.pretty || null\n }\n\n /**\n * Formats the given code string.\n *\n * Applies Prettier formatting if enabled, and prepends the banner comment.\n *\n * @param code - The TypeScript code to format\n * @returns The formatted code with banner\n */\n async format(code: string) {\n const bannerPadding =\n this.banner && !this.banner.endsWith('\\n') ? '\\n\\n' : ''\n const codePretty = this.prettierOptions\n ? await prettierFormat(code, this.prettierOptions)\n : code\n return `${this.banner}${bannerPadding}${codePretty}`\n }\n}\n"]}
1
+ {"version":3,"file":"formatter.js","sourceRoot":"","sources":["../src/formatter.ts"],"names":[],"mappings":"AAAA,OAAO,EAA8B,MAAM,IAAI,cAAc,EAAE,MAAM,UAAU,CAAA;AAE/E,MAAM,sBAAsB,GAAoB;IAC9C,MAAM,EAAE,YAAY;IACpB,QAAQ,EAAE,CAAC;IACX,IAAI,EAAE,KAAK;IACX,WAAW,EAAE,IAAI;IACjB,aAAa,EAAE,KAAK;CACrB,CAAA;AAED,MAAM,cAAc,GAAG;;IAEnB,CAAA;AAwBJ;;;;;;;;;GASG;AACH,MAAM,OAAO,SAAS;IAMpB;;;;OAIG;IACH,YAAY,UAA4B,EAAE;QACxC,IAAI,CAAC,MAAM,GAAG,OAAO,EAAE,MAAM,IAAI,cAAc,CAAA;QAE/C,IAAI,CAAC,eAAe;YAClB,OAAO,EAAE,MAAM,KAAK,IAAI;gBACtB,CAAC,CAAC,sBAAsB;gBACxB,CAAC,CAAC,OAAO,EAAE,MAAM,IAAI,IAAI,CAAA;IAC/B,CAAC;IAED;;;;;;;OAOG;IACH,KAAK,CAAC,MAAM,CAAC,IAAY;QACvB,MAAM,aAAa,GACjB,IAAI,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAA;QAC1D,MAAM,UAAU,GAAG,IAAI,CAAC,eAAe;YACrC,CAAC,CAAC,MAAM,cAAc,CAAC,IAAI,EAAE,IAAI,CAAC,eAAe,CAAC;YAClD,CAAC,CAAC,IAAI,CAAA;QACR,OAAO,GAAG,IAAI,CAAC,MAAM,GAAG,aAAa,GAAG,UAAU,EAAE,CAAA;IACtD,CAAC;CACF","sourcesContent":["import { Options as PrettierOptions, format as prettierFormat } from 'prettier'\n\nconst DEFAULT_FORMAT_OPTIONS: PrettierOptions = {\n parser: 'typescript',\n tabWidth: 2,\n semi: false,\n singleQuote: true,\n trailingComma: 'all',\n}\n\nconst DEFAULT_BANNER = `/*\n * THIS FILE WAS GENERATED BY \"@atproto/lex\". DO NOT EDIT.\n */`\n\n/**\n * Options for configuring the code formatter.\n */\nexport type FormatterOptions = {\n /**\n * Whether to format the generated code with Prettier.\n *\n * - `false`: No formatting (default)\n * - `true`: Format with default Prettier options\n * - `PrettierOptions`: Format with custom Prettier configuration\n *\n * @default false\n */\n pretty?: boolean | PrettierOptions\n /**\n * A banner comment to prepend to each generated file.\n *\n * @default '/* THIS FILE WAS GENERATED BY \"@atproto/lex\". DO NOT EDIT. *\\/'\n */\n banner?: string\n}\n\n/**\n * Formats generated TypeScript code with optional Prettier formatting\n * and banner comments.\n *\n * @example\n * ```ts\n * const formatter = new Formatter({ pretty: true })\n * const formatted = await formatter.format(generatedCode)\n * ```\n */\nexport class Formatter {\n /** The banner comment to prepend to formatted code. */\n readonly banner: string\n /** Prettier options, or `null` if formatting is disabled. */\n readonly prettierOptions: PrettierOptions | null\n\n /**\n * Creates a new Formatter instance.\n *\n * @param options - Formatting configuration options\n */\n constructor(options: FormatterOptions = {}) {\n this.banner = options?.banner ?? DEFAULT_BANNER\n\n this.prettierOptions =\n options?.pretty === true\n ? DEFAULT_FORMAT_OPTIONS\n : options?.pretty || null\n }\n\n /**\n * Formats the given code string.\n *\n * Applies Prettier formatting if enabled, and prepends the banner comment.\n *\n * @param code - The TypeScript code to format\n * @returns The formatted code with banner\n */\n async format(code: string) {\n const bannerPadding =\n this.banner && !this.banner.endsWith('\\n') ? '\\n\\n' : ''\n const codePretty = this.prettierOptions\n ? await prettierFormat(code, this.prettierOptions)\n : code\n return `${this.banner}${bannerPadding}${codePretty}`\n }\n}\n"]}
package/dist/index.js CHANGED
@@ -1,13 +1,9 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.build = build;
4
- const tslib_1 = require("tslib");
5
1
  // Must be first
6
- require("./polyfill.js");
7
- const lex_builder_js_1 = require("./lex-builder.js");
8
- tslib_1.__exportStar(require("./lex-builder.js"), exports);
9
- tslib_1.__exportStar(require("./lex-def-builder.js"), exports);
10
- tslib_1.__exportStar(require("./lexicon-directory-indexer.js"), exports);
2
+ import './polyfill.js';
3
+ import { LexBuilder, } from './lex-builder.js';
4
+ export * from './lex-builder.js';
5
+ export * from './lex-def-builder.js';
6
+ export * from './lexicon-directory-indexer.js';
11
7
  /**
12
8
  * Builds TypeScript schemas from Lexicon documents.
13
9
  *
@@ -31,8 +27,8 @@ tslib_1.__exportStar(require("./lexicon-directory-indexer.js"), exports);
31
27
  * })
32
28
  * ```
33
29
  */
34
- async function build(options) {
35
- const builder = new lex_builder_js_1.LexBuilder(options);
30
+ export async function build(options) {
31
+ const builder = new LexBuilder(options);
36
32
  await builder.load(options);
37
33
  await builder.save(options);
38
34
  }
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;AAmDA,sBAIC;;AAvDD,gBAAgB;AAChB,yBAAsB;AAEtB,qDAKyB;AAEzB,2DAAgC;AAChC,+DAAoC;AACpC,yEAA8C;AAgB9C;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACI,KAAK,UAAU,KAAK,CAAC,OAA8B;IACxD,MAAM,OAAO,GAAG,IAAI,2BAAU,CAAC,OAAO,CAAC,CAAA;IACvC,MAAM,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;IAC3B,MAAM,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;AAC7B,CAAC","sourcesContent":["// Must be first\nimport './polyfill.js'\n\nimport {\n LexBuilder,\n LexBuilderLoadOptions,\n LexBuilderOptions,\n LexBuilderSaveOptions,\n} from './lex-builder.js'\n\nexport * from './lex-builder.js'\nexport * from './lex-def-builder.js'\nexport * from './lexicon-directory-indexer.js'\n\n/**\n * Combined options for building a TypeScript project from Lexicon documents.\n *\n * This type merges all configuration options needed for the complete build\n * process, including builder configuration, loading options, and save options.\n *\n * @see {@link LexBuilderOptions} for builder configuration\n * @see {@link LexBuilderLoadOptions} for lexicon loading options\n * @see {@link LexBuilderSaveOptions} for output save options\n */\nexport type TsProjectBuildOptions = LexBuilderOptions &\n LexBuilderLoadOptions &\n LexBuilderSaveOptions\n\n/**\n * Builds TypeScript schemas from Lexicon documents.\n *\n * This is the main entry point for programmatic usage of the lex-builder\n * package. It creates a new {@link LexBuilder} instance, loads lexicon\n * documents from the specified directory, and saves the generated TypeScript\n * files to the output directory.\n *\n * @param options - Combined build options including source directory, output\n * directory, and generation settings\n *\n * @example\n * ```ts\n * import { build } from '@atproto/lex-builder'\n *\n * await build({\n * lexicons: './lexicons',\n * out: './src/generated',\n * pretty: true,\n * clear: true,\n * })\n * ```\n */\nexport async function build(options: TsProjectBuildOptions) {\n const builder = new LexBuilder(options)\n await builder.load(options)\n await builder.save(options)\n}\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,gBAAgB;AAChB,OAAO,eAAe,CAAA;AAEtB,OAAO,EACL,UAAU,GAIX,MAAM,kBAAkB,CAAA;AAEzB,cAAc,kBAAkB,CAAA;AAChC,cAAc,sBAAsB,CAAA;AACpC,cAAc,gCAAgC,CAAA;AAgB9C;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,CAAC,KAAK,UAAU,KAAK,CAAC,OAA8B;IACxD,MAAM,OAAO,GAAG,IAAI,UAAU,CAAC,OAAO,CAAC,CAAA;IACvC,MAAM,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;IAC3B,MAAM,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;AAC7B,CAAC","sourcesContent":["// Must be first\nimport './polyfill.js'\n\nimport {\n LexBuilder,\n LexBuilderLoadOptions,\n LexBuilderOptions,\n LexBuilderSaveOptions,\n} from './lex-builder.js'\n\nexport * from './lex-builder.js'\nexport * from './lex-def-builder.js'\nexport * from './lexicon-directory-indexer.js'\n\n/**\n * Combined options for building a TypeScript project from Lexicon documents.\n *\n * This type merges all configuration options needed for the complete build\n * process, including builder configuration, loading options, and save options.\n *\n * @see {@link LexBuilderOptions} for builder configuration\n * @see {@link LexBuilderLoadOptions} for lexicon loading options\n * @see {@link LexBuilderSaveOptions} for output save options\n */\nexport type TsProjectBuildOptions = LexBuilderOptions &\n LexBuilderLoadOptions &\n LexBuilderSaveOptions\n\n/**\n * Builds TypeScript schemas from Lexicon documents.\n *\n * This is the main entry point for programmatic usage of the lex-builder\n * package. It creates a new {@link LexBuilder} instance, loads lexicon\n * documents from the specified directory, and saves the generated TypeScript\n * files to the output directory.\n *\n * @param options - Combined build options including source directory, output\n * directory, and generation settings\n *\n * @example\n * ```ts\n * import { build } from '@atproto/lex-builder'\n *\n * await build({\n * lexicons: './lexicons',\n * out: './src/generated',\n * pretty: true,\n * clear: true,\n * })\n * ```\n */\nexport async function build(options: TsProjectBuildOptions) {\n const builder = new LexBuilder(options)\n await builder.load(options)\n await builder.save(options)\n}\n"]}
@@ -1,17 +1,14 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.LexBuilder = void 0;
4
- const tslib_1 = require("tslib");
5
- const node_assert_1 = tslib_1.__importDefault(require("node:assert"));
6
- const promises_1 = require("node:fs/promises");
7
- const node_path_1 = require("node:path");
8
- const ts_morph_1 = require("ts-morph");
9
- const filter_js_1 = require("./filter.js");
10
- const filtered_indexer_js_1 = require("./filtered-indexer.js");
11
- const formatter_js_1 = require("./formatter.js");
12
- const lex_def_builder_js_1 = require("./lex-def-builder.js");
13
- const lexicon_directory_indexer_js_1 = require("./lexicon-directory-indexer.js");
14
- const ts_lang_js_1 = require("./ts-lang.js");
1
+ import { __addDisposableResource, __disposeResources } from "tslib";
2
+ import assert from 'node:assert';
3
+ import { mkdir, rm, stat, writeFile } from 'node:fs/promises';
4
+ import { join, resolve } from 'node:path';
5
+ import { IndentationText, Project } from 'ts-morph';
6
+ import { buildFilter } from './filter.js';
7
+ import { FilteredIndexer } from './filtered-indexer.js';
8
+ import { Formatter } from './formatter.js';
9
+ import { LexDefBuilder } from './lex-def-builder.js';
10
+ import { LexiconDirectoryIndexer, } from './lexicon-directory-indexer.js';
11
+ import { asNamespaceExport } from './ts-lang.js';
15
12
  /**
16
13
  * Main builder class for generating TypeScript schemas from Lexicon documents.
17
14
  *
@@ -32,12 +29,11 @@ const ts_lang_js_1 = require("./ts-lang.js");
32
29
  * await builder.save({ out: './src/generated', clear: true })
33
30
  * ```
34
31
  */
35
- class LexBuilder {
36
- options;
32
+ export class LexBuilder {
37
33
  #imported = new Set();
38
- #project = new ts_morph_1.Project({
34
+ #project = new Project({
39
35
  useInMemoryFileSystem: true,
40
- manipulationSettings: { indentationText: ts_morph_1.IndentationText.TwoSpaces },
36
+ manipulationSettings: { indentationText: IndentationText.TwoSpaces },
41
37
  });
42
38
  constructor(options = {}) {
43
39
  this.options = options;
@@ -51,7 +47,7 @@ class LexBuilder {
51
47
  async load(options) {
52
48
  const env_1 = { stack: [], error: void 0, hasError: false };
53
49
  try {
54
- const indexer = tslib_1.__addDisposableResource(env_1, new filtered_indexer_js_1.FilteredIndexer(new lexicon_directory_indexer_js_1.LexiconDirectoryIndexer(options), (0, filter_js_1.buildFilter)(options)), true);
50
+ const indexer = __addDisposableResource(env_1, new FilteredIndexer(new LexiconDirectoryIndexer(options), buildFilter(options)), true);
55
51
  for await (const doc of indexer) {
56
52
  if (!this.#imported.has(doc.id)) {
57
53
  this.#imported.add(doc.id);
@@ -68,27 +64,27 @@ class LexBuilder {
68
64
  env_1.hasError = true;
69
65
  }
70
66
  finally {
71
- const result_1 = tslib_1.__disposeResources(env_1);
67
+ const result_1 = __disposeResources(env_1);
72
68
  if (result_1)
73
69
  await result_1;
74
70
  }
75
71
  }
76
72
  async save(options) {
77
73
  const files = this.#project.getSourceFiles();
78
- const destination = (0, node_path_1.resolve)(options.out);
74
+ const destination = resolve(options.out);
79
75
  if (options.clear) {
80
- await (0, promises_1.rm)(destination, { recursive: true, force: true });
76
+ await rm(destination, { recursive: true, force: true });
81
77
  }
82
78
  else if (!options.override) {
83
- await Promise.all(files.map(async (f) => assertNotFileExists((0, node_path_1.join)(destination, f.getFilePath()))));
79
+ await Promise.all(files.map(async (f) => assertNotFileExists(join(destination, f.getFilePath()))));
84
80
  }
85
- const formatter = new formatter_js_1.Formatter(options);
81
+ const formatter = new Formatter(options);
86
82
  await Promise.all(Array.from(files, async (file) => {
87
- const filePath = (0, node_path_1.join)(destination, file.getFilePath());
83
+ const filePath = join(destination, file.getFilePath());
88
84
  const content = await formatter.format(file.getFullText());
89
- await (0, promises_1.mkdir)((0, node_path_1.join)(filePath, '..'), { recursive: true });
90
- await (0, promises_1.rm)(filePath, { recursive: true, force: true });
91
- await (0, promises_1.writeFile)(filePath, content, 'utf8');
85
+ await mkdir(join(filePath, '..'), { recursive: true });
86
+ await rm(filePath, { recursive: true, force: true });
87
+ await writeFile(filePath, content, 'utf8');
92
88
  }));
93
89
  }
94
90
  createFile(path) {
@@ -102,12 +98,12 @@ class LexBuilder {
102
98
  if (this.options.indexFile) {
103
99
  const indexFile = this.getFile(`/index${this.fileExt}`);
104
100
  const tldNs = namespaces[0];
105
- (0, node_assert_1.default)(tldNs !== 'index', 'The "indexFile" options cannot be used with namespaces using a ".index" tld.');
101
+ assert(tldNs !== 'index', 'The "indexFile" options cannot be used with namespaces using a ".index" tld.');
106
102
  const tldNsSpecifier = `./${tldNs}${this.importExt}`;
107
103
  if (!indexFile.getExportDeclaration(tldNsSpecifier)) {
108
104
  indexFile.addExportDeclaration({
109
105
  moduleSpecifier: tldNsSpecifier,
110
- namespaceExport: (0, ts_lang_js_1.asNamespaceExport)(tldNs),
106
+ namespaceExport: asNamespaceExport(tldNs),
111
107
  });
112
108
  }
113
109
  }
@@ -115,26 +111,26 @@ class LexBuilder {
115
111
  for (let i = 0; i < namespaces.length - 1; i++) {
116
112
  const currentNs = namespaces[i];
117
113
  const childNs = namespaces[i + 1];
118
- const path = (0, node_path_1.join)('/', ...namespaces.slice(0, i + 1));
114
+ const path = join('/', ...namespaces.slice(0, i + 1));
119
115
  const file = this.getFile(`${path}${this.fileExt}`);
120
116
  const childModuleSpecifier = `./${currentNs}/${childNs}${this.importExt}`;
121
117
  const dec = file.getExportDeclaration(childModuleSpecifier);
122
118
  if (!dec) {
123
119
  file.addExportDeclaration({
124
120
  moduleSpecifier: childModuleSpecifier,
125
- namespaceExport: (0, ts_lang_js_1.asNamespaceExport)(childNs),
121
+ namespaceExport: asNamespaceExport(childNs),
126
122
  });
127
123
  }
128
124
  }
129
125
  // The child file exports the schemas (as *)
130
- const path = (0, node_path_1.join)('/', ...namespaces);
126
+ const path = join('/', ...namespaces);
131
127
  const file = this.getFile(`${path}${this.fileExt}`);
132
128
  file.addExportDeclaration({
133
129
  moduleSpecifier: `./${namespaces.at(-1)}.defs${this.importExt}`,
134
130
  });
135
131
  // @NOTE Individual exports exports from the defs file might conflict with
136
132
  // child namespaces. For this reason, we also add a namespace export for the
137
- // defs (export * as $defs from './xyz.defs'). This is an escape hatch
133
+ // defs (export * as $defs from './xyz.defs.js'). This is an escape hatch
138
134
  // allowing to still access the definitions if a hash get shadowed by a
139
135
  // child namespace.
140
136
  file.addExportDeclaration({
@@ -143,16 +139,15 @@ class LexBuilder {
143
139
  });
144
140
  }
145
141
  async createDefsFile(doc, indexer) {
146
- const path = (0, node_path_1.join)('/', ...doc.id.split('.'));
142
+ const path = join('/', ...doc.id.split('.'));
147
143
  const file = this.createFile(`${path}.defs${this.fileExt}`);
148
- const fileBuilder = new lex_def_builder_js_1.LexDefBuilder(this.options, file, doc, indexer);
144
+ const fileBuilder = new LexDefBuilder(this.options, file, doc, indexer);
149
145
  await fileBuilder.build();
150
146
  }
151
147
  }
152
- exports.LexBuilder = LexBuilder;
153
148
  async function assertNotFileExists(file) {
154
149
  try {
155
- await (0, promises_1.stat)(file);
150
+ await stat(file);
156
151
  throw new Error(`File already exists: ${file}`);
157
152
  }
158
153
  catch (err) {
@@ -1 +1 @@
1
- {"version":3,"file":"lex-builder.js","sourceRoot":"","sources":["../src/lex-builder.ts"],"names":[],"mappings":"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","sourcesContent":["import assert from 'node:assert'\nimport { mkdir, rm, stat, writeFile } from 'node:fs/promises'\nimport { join, resolve } from 'node:path'\nimport { IndentationText, Project } from 'ts-morph'\nimport { LexiconDocument, LexiconIndexer } from '@atproto/lex-document'\nimport { BuildFilterOptions, buildFilter } from './filter.js'\nimport { FilteredIndexer } from './filtered-indexer.js'\nimport { Formatter, FormatterOptions } from './formatter.js'\nimport { LexDefBuilder, LexDefBuilderOptions } from './lex-def-builder.js'\nimport {\n LexiconDirectoryIndexer,\n LexiconDirectoryIndexerOptions,\n} from './lexicon-directory-indexer.js'\nimport { asNamespaceExport } from './ts-lang.js'\n\n/**\n * Configuration options for the {@link LexBuilder} class.\n *\n * Extends {@link LexDefBuilderOptions} with additional settings for\n * controlling the generated TypeScript project structure.\n *\n * @see {@link LexDefBuilderOptions} for definition generation options\n */\nexport type LexBuilderOptions = LexDefBuilderOptions & {\n /**\n * Whether to generate an index file at the root exporting all top-level\n * namespaces.\n *\n * @note This could theoretically cause name conflicts if a\n * @default false\n */\n indexFile?: boolean\n /**\n * The file extension to use for import specifiers in the generated code.\n *\n * @default '.js'\n */\n importExt?: string\n /**\n * The file extension to use for generated TypeScript files.\n *\n * @default '.ts'\n */\n fileExt?: string\n}\n\n/**\n * Options for loading lexicon documents into the builder.\n *\n * Combines directory indexing options with filtering options to control\n * which lexicon documents are processed.\n *\n * @see {@link LexiconDirectoryIndexerOptions} for directory scanning options\n * @see {@link BuildFilterOptions} for include/exclude filtering\n */\nexport type LexBuilderLoadOptions = LexiconDirectoryIndexerOptions &\n BuildFilterOptions\n\n/**\n * Options for saving generated TypeScript files.\n *\n * Combines formatting options with output directory configuration.\n */\nexport type LexBuilderSaveOptions = FormatterOptions & {\n /**\n * The output directory path where generated TypeScript files will be written.\n */\n out: string\n /**\n * Whether to clear the output directory before writing files.\n *\n * When `true`, the entire output directory is deleted before writing new files.\n *\n * @default false\n */\n clear?: boolean\n /**\n * Whether to allow overwriting existing files.\n *\n * When `false`, an error is thrown if any output file already exists.\n *\n * @default false\n */\n override?: boolean\n}\n\n/**\n * Main builder class for generating TypeScript schemas from Lexicon documents.\n *\n * The LexBuilder orchestrates the entire code generation process:\n * 1. Loading and indexing lexicon documents from the filesystem\n * 2. Generating TypeScript type definitions and runtime schemas\n * 3. Creating namespace export trees for convenient imports\n * 4. Saving formatted output files\n *\n * @example\n * ```ts\n * const builder = new LexBuilder({ indexFile: true, pretty: true })\n *\n * // Load lexicons from a directory\n * await builder.load({ lexicons: './lexicons' })\n *\n * // Save generated TypeScript to output directory\n * await builder.save({ out: './src/generated', clear: true })\n * ```\n */\nexport class LexBuilder {\n readonly #imported = new Set<string>()\n readonly #project = new Project({\n useInMemoryFileSystem: true,\n manipulationSettings: { indentationText: IndentationText.TwoSpaces },\n })\n\n constructor(private readonly options: LexBuilderOptions = {}) {}\n\n get fileExt() {\n return this.options.fileExt ?? '.ts'\n }\n\n get importExt() {\n return this.options.importExt ?? '.js'\n }\n\n public async load(options: LexBuilderLoadOptions) {\n await using indexer = new FilteredIndexer(\n new LexiconDirectoryIndexer(options),\n buildFilter(options),\n )\n\n for await (const doc of indexer) {\n if (!this.#imported.has(doc.id)) {\n this.#imported.add(doc.id)\n } else {\n throw new Error(`Duplicate lexicon document id: ${doc.id}`)\n }\n\n await this.createDefsFile(doc, indexer)\n await this.createExportTree(doc)\n }\n }\n\n public async save(options: LexBuilderSaveOptions) {\n const files = this.#project.getSourceFiles()\n\n const destination = resolve(options.out)\n\n if (options.clear) {\n await rm(destination, { recursive: true, force: true })\n } else if (!options.override) {\n await Promise.all(\n files.map(async (f) =>\n assertNotFileExists(join(destination, f.getFilePath())),\n ),\n )\n }\n\n const formatter = new Formatter(options)\n\n await Promise.all(\n Array.from(files, async (file) => {\n const filePath = join(destination, file.getFilePath())\n const content = await formatter.format(file.getFullText())\n await mkdir(join(filePath, '..'), { recursive: true })\n await rm(filePath, { recursive: true, force: true })\n await writeFile(filePath, content, 'utf8')\n }),\n )\n }\n\n private createFile(path: string) {\n return this.#project.createSourceFile(path)\n }\n\n private getFile(path: string) {\n return this.#project.getSourceFile(path) || this.createFile(path)\n }\n\n private async createExportTree(doc: LexiconDocument) {\n const namespaces = doc.id.split('.')\n\n if (this.options.indexFile) {\n const indexFile = this.getFile(`/index${this.fileExt}`)\n\n const tldNs = namespaces[0]!\n assert(\n tldNs !== 'index',\n 'The \"indexFile\" options cannot be used with namespaces using a \".index\" tld.',\n )\n const tldNsSpecifier = `./${tldNs}${this.importExt}`\n if (!indexFile.getExportDeclaration(tldNsSpecifier)) {\n indexFile.addExportDeclaration({\n moduleSpecifier: tldNsSpecifier,\n namespaceExport: asNamespaceExport(tldNs),\n })\n }\n }\n\n // First create the parent namespaces\n for (let i = 0; i < namespaces.length - 1; i++) {\n const currentNs = namespaces[i]\n const childNs = namespaces[i + 1]\n\n const path = join('/', ...namespaces.slice(0, i + 1))\n const file = this.getFile(`${path}${this.fileExt}`)\n\n const childModuleSpecifier = `./${currentNs}/${childNs}${this.importExt}`\n const dec = file.getExportDeclaration(childModuleSpecifier)\n if (!dec) {\n file.addExportDeclaration({\n moduleSpecifier: childModuleSpecifier,\n namespaceExport: asNamespaceExport(childNs),\n })\n }\n }\n\n // The child file exports the schemas (as *)\n const path = join('/', ...namespaces)\n const file = this.getFile(`${path}${this.fileExt}`)\n\n file.addExportDeclaration({\n moduleSpecifier: `./${namespaces.at(-1)}.defs${this.importExt}`,\n })\n\n // @NOTE Individual exports exports from the defs file might conflict with\n // child namespaces. For this reason, we also add a namespace export for the\n // defs (export * as $defs from './xyz.defs'). This is an escape hatch\n // allowing to still access the definitions if a hash get shadowed by a\n // child namespace.\n file.addExportDeclaration({\n moduleSpecifier: `./${namespaces.at(-1)}.defs${this.importExt}`,\n namespaceExport: '$defs',\n })\n }\n\n private async createDefsFile(\n doc: LexiconDocument,\n indexer: LexiconIndexer,\n ): Promise<void> {\n const path = join('/', ...doc.id.split('.'))\n const file = this.createFile(`${path}.defs${this.fileExt}`)\n\n const fileBuilder = new LexDefBuilder(this.options, file, doc, indexer)\n await fileBuilder.build()\n }\n}\n\nasync function assertNotFileExists(file: string): Promise<void> {\n try {\n await stat(file)\n throw new Error(`File already exists: ${file}`)\n } catch (err) {\n if (err instanceof Error && 'code' in err && err.code === 'ENOENT') return\n throw err\n }\n}\n"]}
1
+ {"version":3,"file":"lex-builder.js","sourceRoot":"","sources":["../src/lex-builder.ts"],"names":[],"mappings":"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","sourcesContent":["import assert from 'node:assert'\nimport { mkdir, rm, stat, writeFile } from 'node:fs/promises'\nimport { join, resolve } from 'node:path'\nimport { IndentationText, Project } from 'ts-morph'\nimport { LexiconDocument, LexiconIndexer } from '@atproto/lex-document'\nimport { BuildFilterOptions, buildFilter } from './filter.js'\nimport { FilteredIndexer } from './filtered-indexer.js'\nimport { Formatter, FormatterOptions } from './formatter.js'\nimport { LexDefBuilder, LexDefBuilderOptions } from './lex-def-builder.js'\nimport {\n LexiconDirectoryIndexer,\n LexiconDirectoryIndexerOptions,\n} from './lexicon-directory-indexer.js'\nimport { asNamespaceExport } from './ts-lang.js'\n\n/**\n * Configuration options for the {@link LexBuilder} class.\n *\n * Extends {@link LexDefBuilderOptions} with additional settings for\n * controlling the generated TypeScript project structure.\n *\n * @see {@link LexDefBuilderOptions} for definition generation options\n */\nexport type LexBuilderOptions = LexDefBuilderOptions & {\n /**\n * Whether to generate an index file at the root exporting all top-level\n * namespaces.\n *\n * @note This could theoretically cause name conflicts if a\n * @default false\n */\n indexFile?: boolean\n /**\n * The file extension to use for import specifiers in the generated code.\n *\n * @default '.js'\n */\n importExt?: string\n /**\n * The file extension to use for generated TypeScript files.\n *\n * @default '.ts'\n */\n fileExt?: string\n}\n\n/**\n * Options for loading lexicon documents into the builder.\n *\n * Combines directory indexing options with filtering options to control\n * which lexicon documents are processed.\n *\n * @see {@link LexiconDirectoryIndexerOptions} for directory scanning options\n * @see {@link BuildFilterOptions} for include/exclude filtering\n */\nexport type LexBuilderLoadOptions = LexiconDirectoryIndexerOptions &\n BuildFilterOptions\n\n/**\n * Options for saving generated TypeScript files.\n *\n * Combines formatting options with output directory configuration.\n */\nexport type LexBuilderSaveOptions = FormatterOptions & {\n /**\n * The output directory path where generated TypeScript files will be written.\n */\n out: string\n /**\n * Whether to clear the output directory before writing files.\n *\n * When `true`, the entire output directory is deleted before writing new files.\n *\n * @default false\n */\n clear?: boolean\n /**\n * Whether to allow overwriting existing files.\n *\n * When `false`, an error is thrown if any output file already exists.\n *\n * @default false\n */\n override?: boolean\n}\n\n/**\n * Main builder class for generating TypeScript schemas from Lexicon documents.\n *\n * The LexBuilder orchestrates the entire code generation process:\n * 1. Loading and indexing lexicon documents from the filesystem\n * 2. Generating TypeScript type definitions and runtime schemas\n * 3. Creating namespace export trees for convenient imports\n * 4. Saving formatted output files\n *\n * @example\n * ```ts\n * const builder = new LexBuilder({ indexFile: true, pretty: true })\n *\n * // Load lexicons from a directory\n * await builder.load({ lexicons: './lexicons' })\n *\n * // Save generated TypeScript to output directory\n * await builder.save({ out: './src/generated', clear: true })\n * ```\n */\nexport class LexBuilder {\n readonly #imported = new Set<string>()\n readonly #project = new Project({\n useInMemoryFileSystem: true,\n manipulationSettings: { indentationText: IndentationText.TwoSpaces },\n })\n\n constructor(private readonly options: LexBuilderOptions = {}) {}\n\n get fileExt() {\n return this.options.fileExt ?? '.ts'\n }\n\n get importExt() {\n return this.options.importExt ?? '.js'\n }\n\n public async load(options: LexBuilderLoadOptions) {\n await using indexer = new FilteredIndexer(\n new LexiconDirectoryIndexer(options),\n buildFilter(options),\n )\n\n for await (const doc of indexer) {\n if (!this.#imported.has(doc.id)) {\n this.#imported.add(doc.id)\n } else {\n throw new Error(`Duplicate lexicon document id: ${doc.id}`)\n }\n\n await this.createDefsFile(doc, indexer)\n await this.createExportTree(doc)\n }\n }\n\n public async save(options: LexBuilderSaveOptions) {\n const files = this.#project.getSourceFiles()\n\n const destination = resolve(options.out)\n\n if (options.clear) {\n await rm(destination, { recursive: true, force: true })\n } else if (!options.override) {\n await Promise.all(\n files.map(async (f) =>\n assertNotFileExists(join(destination, f.getFilePath())),\n ),\n )\n }\n\n const formatter = new Formatter(options)\n\n await Promise.all(\n Array.from(files, async (file) => {\n const filePath = join(destination, file.getFilePath())\n const content = await formatter.format(file.getFullText())\n await mkdir(join(filePath, '..'), { recursive: true })\n await rm(filePath, { recursive: true, force: true })\n await writeFile(filePath, content, 'utf8')\n }),\n )\n }\n\n private createFile(path: string) {\n return this.#project.createSourceFile(path)\n }\n\n private getFile(path: string) {\n return this.#project.getSourceFile(path) || this.createFile(path)\n }\n\n private async createExportTree(doc: LexiconDocument) {\n const namespaces = doc.id.split('.')\n\n if (this.options.indexFile) {\n const indexFile = this.getFile(`/index${this.fileExt}`)\n\n const tldNs = namespaces[0]!\n assert(\n tldNs !== 'index',\n 'The \"indexFile\" options cannot be used with namespaces using a \".index\" tld.',\n )\n const tldNsSpecifier = `./${tldNs}${this.importExt}`\n if (!indexFile.getExportDeclaration(tldNsSpecifier)) {\n indexFile.addExportDeclaration({\n moduleSpecifier: tldNsSpecifier,\n namespaceExport: asNamespaceExport(tldNs),\n })\n }\n }\n\n // First create the parent namespaces\n for (let i = 0; i < namespaces.length - 1; i++) {\n const currentNs = namespaces[i]\n const childNs = namespaces[i + 1]\n\n const path = join('/', ...namespaces.slice(0, i + 1))\n const file = this.getFile(`${path}${this.fileExt}`)\n\n const childModuleSpecifier = `./${currentNs}/${childNs}${this.importExt}`\n const dec = file.getExportDeclaration(childModuleSpecifier)\n if (!dec) {\n file.addExportDeclaration({\n moduleSpecifier: childModuleSpecifier,\n namespaceExport: asNamespaceExport(childNs),\n })\n }\n }\n\n // The child file exports the schemas (as *)\n const path = join('/', ...namespaces)\n const file = this.getFile(`${path}${this.fileExt}`)\n\n file.addExportDeclaration({\n moduleSpecifier: `./${namespaces.at(-1)}.defs${this.importExt}`,\n })\n\n // @NOTE Individual exports exports from the defs file might conflict with\n // child namespaces. For this reason, we also add a namespace export for the\n // defs (export * as $defs from './xyz.defs.js'). This is an escape hatch\n // allowing to still access the definitions if a hash get shadowed by a\n // child namespace.\n file.addExportDeclaration({\n moduleSpecifier: `./${namespaces.at(-1)}.defs${this.importExt}`,\n namespaceExport: '$defs',\n })\n }\n\n private async createDefsFile(\n doc: LexiconDocument,\n indexer: LexiconIndexer,\n ): Promise<void> {\n const path = join('/', ...doc.id.split('.'))\n const file = this.createFile(`${path}.defs${this.fileExt}`)\n\n const fileBuilder = new LexDefBuilder(this.options, file, doc, indexer)\n await fileBuilder.build()\n }\n}\n\nasync function assertNotFileExists(file: string): Promise<void> {\n try {\n await stat(file)\n throw new Error(`File already exists: ${file}`)\n } catch (err) {\n if (err instanceof Error && 'code' in err && err.code === 'ENOENT') return\n throw err\n }\n}\n"]}
@@ -1,10 +1,7 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.LexDefBuilder = void 0;
4
- const ts_morph_1 = require("ts-morph");
5
- const lex_schema_1 = require("@atproto/lex-schema");
6
- const ref_resolver_js_1 = require("./ref-resolver.js");
7
- const ts_lang_js_1 = require("./ts-lang.js");
1
+ import { VariableDeclarationKind, } from 'ts-morph';
2
+ import { l } from '@atproto/lex-schema';
3
+ import { RefResolver, getPublicIdentifiers, } from './ref-resolver.js';
4
+ import { asNamespaceExport } from './ts-lang.js';
8
5
  /**
9
6
  * Builds TypeScript type definitions and runtime schemas from a single
10
7
  * Lexicon document.
@@ -18,23 +15,19 @@ const ts_lang_js_1 = require("./ts-lang.js");
18
15
  * Each lexicon definition type (record, object, query, procedure, etc.)
19
16
  * is handled with specialized code generation logic.
20
17
  */
21
- class LexDefBuilder {
22
- options;
23
- file;
24
- doc;
25
- refResolver;
18
+ export class LexDefBuilder {
26
19
  constructor(options, file, doc, indexer) {
27
20
  this.options = options;
28
21
  this.file = file;
29
22
  this.doc = doc;
30
- this.refResolver = new ref_resolver_js_1.RefResolver(doc, file, indexer, options);
23
+ this.refResolver = new RefResolver(doc, file, indexer, options);
31
24
  }
32
25
  pure(code) {
33
26
  return this.options.pureAnnotations ? markPure(code) : code;
34
27
  }
35
28
  async build() {
36
29
  this.file.addVariableStatement({
37
- declarationKind: ts_morph_1.VariableDeclarationKind.Const,
30
+ declarationKind: VariableDeclarationKind.Const,
38
31
  declarations: [
39
32
  { name: '$nsid', initializer: JSON.stringify(this.doc.id) },
40
33
  ],
@@ -58,7 +51,7 @@ class LexDefBuilder {
58
51
  if (entries.length) {
59
52
  this.file.addVariableStatement({
60
53
  isExported: true,
61
- declarationKind: ts_morph_1.VariableDeclarationKind.Const,
54
+ declarationKind: VariableDeclarationKind.Const,
62
55
  declarations: entries.map(([name, initializer]) => ({
63
56
  name,
64
57
  initializer,
@@ -229,7 +222,7 @@ class LexDefBuilder {
229
222
  const key = JSON.stringify(def.key ?? 'any');
230
223
  const objectSchema = await this.compileObjectSchema(def.record);
231
224
  const properties = await this.compilePropertiesTypes(def.record);
232
- properties.unshift(`$type: ${JSON.stringify(lex_schema_1.l.$type(this.doc.id, hash))}`);
225
+ properties.unshift(`$type: ${JSON.stringify(l.$type(this.doc.id, hash))}`);
233
226
  await this.addSchema(hash, def, {
234
227
  type: `{ ${properties.join(';')} }`,
235
228
  schema: (ref) => this.pure(`l.record<${key}, ${ref.typeName}>(${key}, $nsid, ${objectSchema})`),
@@ -240,7 +233,7 @@ class LexDefBuilder {
240
233
  async addObject(hash, def) {
241
234
  const objectSchema = await this.compileObjectSchema(def);
242
235
  const properties = await this.compilePropertiesTypes(def);
243
- properties.unshift(`$type?: ${JSON.stringify(lex_schema_1.l.$type(this.doc.id, hash))}`);
236
+ properties.unshift(`$type?: ${JSON.stringify(l.$type(this.doc.id, hash))}`);
244
237
  await this.addSchema(hash, def, {
245
238
  type: `{ ${properties.join(';')} }`,
246
239
  schema: (ref) => this.pure(`l.typedObject<${ref.typeName}>($nsid, ${JSON.stringify(hash)}, ${objectSchema})`),
@@ -251,7 +244,7 @@ class LexDefBuilder {
251
244
  async addToken(hash, def) {
252
245
  await this.addSchema(hash, def, {
253
246
  schema: this.pure(`l.token($nsid, ${JSON.stringify(hash)})`),
254
- type: JSON.stringify(lex_schema_1.l.$type(this.doc.id, hash)),
247
+ type: JSON.stringify(l.$type(this.doc.id, hash)),
255
248
  validationUtils: true,
256
249
  });
257
250
  }
@@ -274,7 +267,7 @@ class LexDefBuilder {
274
267
  }
275
268
  async addSchema(hash, def, { type, schema, objectUtils, validationUtils, }) {
276
269
  const ref = await this.refResolver.resolveLocal(hash);
277
- const pub = (0, ref_resolver_js_1.getPublicIdentifiers)(hash);
270
+ const pub = getPublicIdentifiers(hash);
278
271
  if (type) {
279
272
  this.file.addTypeAlias({
280
273
  name: ref.typeName,
@@ -288,14 +281,14 @@ class LexDefBuilder {
288
281
  name: ref.typeName,
289
282
  alias: ref.typeName === pub.typeName
290
283
  ? undefined
291
- : (0, ts_lang_js_1.asNamespaceExport)(pub.typeName),
284
+ : asNamespaceExport(pub.typeName),
292
285
  },
293
286
  ],
294
287
  });
295
288
  }
296
289
  if (schema) {
297
290
  this.file.addVariableStatement({
298
- declarationKind: ts_morph_1.VariableDeclarationKind.Const,
291
+ declarationKind: VariableDeclarationKind.Const,
299
292
  declarations: [
300
293
  {
301
294
  name: ref.varName,
@@ -310,7 +303,7 @@ class LexDefBuilder {
310
303
  name: ref.varName,
311
304
  alias: ref.varName === pub.varName
312
305
  ? undefined
313
- : (0, ts_lang_js_1.asNamespaceExport)(pub.varName),
306
+ : asNamespaceExport(pub.varName),
314
307
  },
315
308
  ],
316
309
  });
@@ -496,7 +489,7 @@ class LexDefBuilder {
496
489
  return this.pure(`l.withDefault(${schema}, ${JSON.stringify(defaultValue)})`);
497
490
  }
498
491
  async compileBooleanSchema(def) {
499
- const schema = lex_schema_1.l.boolean();
492
+ const schema = l.boolean();
500
493
  if (def.default !== undefined) {
501
494
  schema.check(def.default);
502
495
  }
@@ -510,7 +503,7 @@ class LexDefBuilder {
510
503
  return 'boolean';
511
504
  }
512
505
  async compileIntegerSchema(def) {
513
- const schema = lex_schema_1.l.integer(def);
506
+ const schema = l.integer(def);
514
507
  if (hasConst(def)) {
515
508
  schema.check(def.const);
516
509
  }
@@ -539,7 +532,7 @@ class LexDefBuilder {
539
532
  return 'number';
540
533
  }
541
534
  async compileStringSchema(def) {
542
- const schema = lex_schema_1.l.string(def);
535
+ const schema = l.string(def);
543
536
  if (hasConst(def)) {
544
537
  schema.check(def.const);
545
538
  }
@@ -698,7 +691,6 @@ class LexDefBuilder {
698
691
  return def.enum.map((v) => JSON.stringify(v)).join(' | ') || 'never';
699
692
  }
700
693
  }
701
- exports.LexDefBuilder = LexDefBuilder;
702
694
  function parseDescription(description) {
703
695
  if (/deprecated/i.test(description)) {
704
696
  const deprecationMatch = description.match(/(\s*deprecated\s*(?:--?|:)?\s*([^-]*)(?:-+)?)/i);