@atproto/lex-builder 0.0.7 → 0.0.9

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,31 @@
1
1
  # @atproto/lex-builder
2
2
 
3
+ ## 0.0.9
4
+
5
+ ### Patch Changes
6
+
7
+ - [#4501](https://github.com/bluesky-social/atproto/pull/4501) [`2f78893`](https://github.com/bluesky-social/atproto/commit/2f78893ace3bbf14d4bac36837820ddb46658c98) Thanks [@matthieusieben](https://github.com/matthieusieben)! - Better prevent use of conflicting identifiers in generated code
8
+
9
+ - [#4501](https://github.com/bluesky-social/atproto/pull/4501) [`2f78893`](https://github.com/bluesky-social/atproto/commit/2f78893ace3bbf14d4bac36837820ddb46658c98) Thanks [@matthieusieben](https://github.com/matthieusieben)! - Add an `indexFile` option that allows generating an "index.ts" file that re-exports every tld namespaces.
10
+
11
+ - [#4501](https://github.com/bluesky-social/atproto/pull/4501) [`2f78893`](https://github.com/bluesky-social/atproto/commit/2f78893ace3bbf14d4bac36837820ddb46658c98) Thanks [@matthieusieben](https://github.com/matthieusieben)! - Ensure generated "import" identifiers start with a lower case letter
12
+
13
+ - [#4501](https://github.com/bluesky-social/atproto/pull/4501) [`2f78893`](https://github.com/bluesky-social/atproto/commit/2f78893ace3bbf14d4bac36837820ddb46658c98) Thanks [@matthieusieben](https://github.com/matthieusieben)! - Avoid escaping export identifier when it is a known global
14
+
15
+ - Updated dependencies [[`2f78893`](https://github.com/bluesky-social/atproto/commit/2f78893ace3bbf14d4bac36837820ddb46658c98)]:
16
+ - @atproto/lex-schema@0.0.7
17
+ - @atproto/lex-document@0.0.8
18
+
19
+ ## 0.0.8
20
+
21
+ ### Patch Changes
22
+
23
+ - [#4443](https://github.com/bluesky-social/atproto/pull/4443) [`9af7a2d`](https://github.com/bluesky-social/atproto/commit/9af7a2d12240e91248610ce4fe7d93387733c59c) Thanks [@matthieusieben](https://github.com/matthieusieben)! - Use `jsonPayload` for json payloads
24
+
25
+ - Updated dependencies [[`9af7a2d`](https://github.com/bluesky-social/atproto/commit/9af7a2d12240e91248610ce4fe7d93387733c59c), [`9af7a2d`](https://github.com/bluesky-social/atproto/commit/9af7a2d12240e91248610ce4fe7d93387733c59c), [`9af7a2d`](https://github.com/bluesky-social/atproto/commit/9af7a2d12240e91248610ce4fe7d93387733c59c), [`9af7a2d`](https://github.com/bluesky-social/atproto/commit/9af7a2d12240e91248610ce4fe7d93387733c59c), [`9af7a2d`](https://github.com/bluesky-social/atproto/commit/9af7a2d12240e91248610ce4fe7d93387733c59c), [`9af7a2d`](https://github.com/bluesky-social/atproto/commit/9af7a2d12240e91248610ce4fe7d93387733c59c), [`9af7a2d`](https://github.com/bluesky-social/atproto/commit/9af7a2d12240e91248610ce4fe7d93387733c59c), [`9af7a2d`](https://github.com/bluesky-social/atproto/commit/9af7a2d12240e91248610ce4fe7d93387733c59c)]:
26
+ - @atproto/lex-schema@0.0.6
27
+ - @atproto/lex-document@0.0.7
28
+
3
29
  ## 0.0.7
4
30
 
5
31
  ### Patch Changes
@@ -3,6 +3,14 @@ import { FormatterOptions } from './formatter.js';
3
3
  import { LexDefBuilderOptions } from './lex-def-builder.js';
4
4
  import { LexiconDirectoryIndexerOptions } from './lexicon-directory-indexer.js';
5
5
  export type LexBuilderOptions = LexDefBuilderOptions & {
6
+ /**
7
+ * Whether to generate an index file at the root exporting all top-level
8
+ * namespaces.
9
+ *
10
+ * @note This could theoretically cause name conflicts if a
11
+ * @default false
12
+ */
13
+ indexFile?: boolean;
6
14
  importExt?: string;
7
15
  fileExt?: string;
8
16
  };
@@ -1 +1 @@
1
- {"version":3,"file":"lex-builder.d.ts","sourceRoot":"","sources":["../src/lex-builder.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,kBAAkB,EAAe,MAAM,aAAa,CAAA;AAE7D,OAAO,EAAa,gBAAgB,EAAE,MAAM,gBAAgB,CAAA;AAC5D,OAAO,EAAiB,oBAAoB,EAAE,MAAM,sBAAsB,CAAA;AAC1E,OAAO,EAEL,8BAA8B,EAC/B,MAAM,gCAAgC,CAAA;AAGvC,MAAM,MAAM,iBAAiB,GAAG,oBAAoB,GAAG;IACrD,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB,CAAA;AAED,MAAM,MAAM,qBAAqB,GAAG,8BAA8B,GAChE,kBAAkB,CAAA;AAEpB,MAAM,MAAM,qBAAqB,GAAG,gBAAgB,GAAG;IACrD,GAAG,EAAE,MAAM,CAAA;IACX,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,QAAQ,CAAC,EAAE,OAAO,CAAA;CACnB,CAAA;AAED,qBAAa,UAAU;;IAOT,OAAO,CAAC,QAAQ,CAAC,OAAO;gBAAP,OAAO,GAAE,iBAAsB;IAE5D,IAAI,OAAO,WAEV;IAED,IAAI,SAAS,WAEZ;IAEY,IAAI,CAAC,OAAO,EAAE,qBAAqB;IAkBnC,IAAI,CAAC,OAAO,EAAE,qBAAqB;IA4BhD,OAAO,CAAC,UAAU;IAIlB,OAAO,CAAC,OAAO;YAID,gBAAgB;YA0ChB,cAAc;CAU7B"}
1
+ {"version":3,"file":"lex-builder.d.ts","sourceRoot":"","sources":["../src/lex-builder.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,kBAAkB,EAAe,MAAM,aAAa,CAAA;AAE7D,OAAO,EAAa,gBAAgB,EAAE,MAAM,gBAAgB,CAAA;AAC5D,OAAO,EAAiB,oBAAoB,EAAE,MAAM,sBAAsB,CAAA;AAC1E,OAAO,EAEL,8BAA8B,EAC/B,MAAM,gCAAgC,CAAA;AAGvC,MAAM,MAAM,iBAAiB,GAAG,oBAAoB,GAAG;IACrD;;;;;;OAMG;IACH,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB,CAAA;AAED,MAAM,MAAM,qBAAqB,GAAG,8BAA8B,GAChE,kBAAkB,CAAA;AAEpB,MAAM,MAAM,qBAAqB,GAAG,gBAAgB,GAAG;IACrD,GAAG,EAAE,MAAM,CAAA;IACX,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,QAAQ,CAAC,EAAE,OAAO,CAAA;CACnB,CAAA;AAED,qBAAa,UAAU;;IAOT,OAAO,CAAC,QAAQ,CAAC,OAAO;gBAAP,OAAO,GAAE,iBAAsB;IAE5D,IAAI,OAAO,WAEV;IAED,IAAI,SAAS,WAEZ;IAEY,IAAI,CAAC,OAAO,EAAE,qBAAqB;IAkBnC,IAAI,CAAC,OAAO,EAAE,qBAAqB;IA4BhD,OAAO,CAAC,UAAU;IAIlB,OAAO,CAAC,OAAO;YAID,gBAAgB;YAyDhB,cAAc;CAU7B"}
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.LexBuilder = void 0;
4
4
  const tslib_1 = require("tslib");
5
+ const node_assert_1 = tslib_1.__importDefault(require("node:assert"));
5
6
  const promises_1 = require("node:fs/promises");
6
7
  const node_path_1 = require("node:path");
7
8
  const ts_morph_1 = require("ts-morph");
@@ -78,6 +79,18 @@ class LexBuilder {
78
79
  }
79
80
  async createExportTree(doc) {
80
81
  const namespaces = doc.id.split('.');
82
+ if (this.options.indexFile) {
83
+ const indexFile = this.getFile(`/index${this.fileExt}`);
84
+ const tldNs = namespaces[0];
85
+ (0, node_assert_1.default)(tldNs !== 'index', 'The "indexFile" options cannot be used with namespaces using a ".index" tld.');
86
+ const tldNsSpecifier = `./${tldNs}${this.importExt}`;
87
+ if (!indexFile.getExportDeclaration(tldNsSpecifier)) {
88
+ indexFile.addExportDeclaration({
89
+ moduleSpecifier: tldNsSpecifier,
90
+ namespaceExport: (0, ts_lang_js_1.asNamespaceExport)(tldNs),
91
+ });
92
+ }
93
+ }
81
94
  // First create the parent namespaces
82
95
  for (let i = 0; i < namespaces.length - 1; i++) {
83
96
  const currentNs = namespaces[i];
@@ -89,9 +102,7 @@ class LexBuilder {
89
102
  if (!dec) {
90
103
  file.addExportDeclaration({
91
104
  moduleSpecifier: childModuleSpecifier,
92
- namespaceExport: (0, ts_lang_js_1.isSafeIdentifier)(childNs)
93
- ? childNs
94
- : JSON.stringify(childNs),
105
+ namespaceExport: (0, ts_lang_js_1.asNamespaceExport)(childNs),
95
106
  });
96
107
  }
97
108
  }
@@ -1 +1 @@
1
- {"version":3,"file":"lex-builder.js","sourceRoot":"","sources":["../src/lex-builder.ts"],"names":[],"mappings":"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","sourcesContent":["import { 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 { isSafeIdentifier } from './ts-lang.js'\n\nexport type LexBuilderOptions = LexDefBuilderOptions & {\n importExt?: string\n fileExt?: string\n}\n\nexport type LexBuilderLoadOptions = LexiconDirectoryIndexerOptions &\n BuildFilterOptions\n\nexport type LexBuilderSaveOptions = FormatterOptions & {\n out: string\n clear?: boolean\n override?: boolean\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 // 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: isSafeIdentifier(childNs)\n ? childNs\n : JSON.stringify(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\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 importExt?: string\n fileExt?: string\n}\n\nexport type LexBuilderLoadOptions = LexiconDirectoryIndexerOptions &\n BuildFilterOptions\n\nexport type LexBuilderSaveOptions = FormatterOptions & {\n out: string\n clear?: boolean\n override?: boolean\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 +1 @@
1
- {"version":3,"file":"lex-def-builder.d.ts","sourceRoot":"","sources":["../src/lex-def-builder.ts"],"names":[],"mappings":"AACA,OAAO,EAGL,UAAU,EAEX,MAAM,UAAU,CAAA;AACjB,OAAO,EAOL,eAAe,EAEf,cAAc,EAMd,gBAAgB,EAChB,YAAY,EAKZ,mBAAmB,EAGpB,MAAM,uBAAuB,CAAA;AAE9B,OAAO,EAEL,kBAAkB,EAClB,WAAW,EAEZ,MAAM,mBAAmB,CAAA;AAG1B,MAAM,MAAM,oBAAoB,GAAG,kBAAkB,GAAG;IACtD,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,gBAAgB,CAAC,EAAE,OAAO,CAAA;IAC1B,eAAe,CAAC,EAAE,OAAO,CAAA;CAC1B,CAAA;AAED;;GAEG;AACH,qBAAa,aAAa;IAItB,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,IAAI;IACrB,OAAO,CAAC,QAAQ,CAAC,GAAG;IALtB,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAa;gBAGtB,OAAO,EAAE,oBAAoB,EAC7B,IAAI,EAAE,UAAU,EAChB,GAAG,EAAE,eAAe,EACrC,OAAO,EAAE,cAAc;IAKzB,OAAO,CAAC,IAAI;IAIN,KAAK;IAyBX,OAAO,CAAC,QAAQ;YAgBF,MAAM;YA8BN,gBAAgB;YAsBhB,YAAY;YA4BZ,QAAQ;YA0BR,eAAe;IA0B7B,kBAAkB,CAChB,GAAG,EAAE,WAAW,EAChB,GAAG,EAAE,gBAAgB,GAAG,YAAY,GAAG,mBAAmB;YAmD9C,SAAS;YAsBT,SAAS;YAiBT,QAAQ;YAQR,QAAQ;YAuBR,SAAS;YAyFT,cAAc;YAYd,iBAAiB;YAQjB,mBAAmB;YAOnB,aAAa;YAKb,mBAAmB;YAKnB,wBAAwB;YAsBxB,sBAAsB;YAYtB,0BAA0B;YAuB1B,wBAAwB;YAoBxB,sBAAsB;YA8BtB,oBAAoB;YA8BpB,kBAAkB;YASlB,gBAAgB;YAIhB,oBAAoB;YAIpB,kBAAkB;YAIlB,oBAAoB;YASpB,kBAAkB;YAKlB,oBAAoB;YAsBpB,kBAAkB;YAOlB,mBAAmB;YAuBnB,iBAAiB;YA2CjB,kBAAkB;YAQlB,gBAAgB;YAIhB,iBAAiB;YAUjB,eAAe;YAMf,oBAAoB;YAIpB,kBAAkB;YAIlB,gBAAgB;YAOhB,cAAc;YAKd,qBAAqB;YAmBrB,mBAAmB;YAWnB,kBAAkB;YAalB,gBAAgB;YAShB,iBAAiB;YAgBjB,eAAe;CAK9B"}
1
+ {"version":3,"file":"lex-def-builder.d.ts","sourceRoot":"","sources":["../src/lex-def-builder.ts"],"names":[],"mappings":"AACA,OAAO,EAGL,UAAU,EAEX,MAAM,UAAU,CAAA;AACjB,OAAO,EAOL,eAAe,EAEf,cAAc,EAMd,gBAAgB,EAChB,YAAY,EAKZ,mBAAmB,EAGpB,MAAM,uBAAuB,CAAA;AAE9B,OAAO,EAEL,kBAAkB,EAClB,WAAW,EAEZ,MAAM,mBAAmB,CAAA;AAG1B,MAAM,MAAM,oBAAoB,GAAG,kBAAkB,GAAG;IACtD,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,gBAAgB,CAAC,EAAE,OAAO,CAAA;IAC1B,eAAe,CAAC,EAAE,OAAO,CAAA;CAC1B,CAAA;AAED;;GAEG;AACH,qBAAa,aAAa;IAItB,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,IAAI;IACrB,OAAO,CAAC,QAAQ,CAAC,GAAG;IALtB,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAa;gBAGtB,OAAO,EAAE,oBAAoB,EAC7B,IAAI,EAAE,UAAU,EAChB,GAAG,EAAE,eAAe,EACrC,OAAO,EAAE,cAAc;IAKzB,OAAO,CAAC,IAAI;IAIN,KAAK;IAyBX,OAAO,CAAC,QAAQ;YAgBF,MAAM;YA8BN,gBAAgB;YAsBhB,YAAY;YA4BZ,QAAQ;YA0BR,eAAe;IA0B7B,kBAAkB,CAChB,GAAG,EAAE,WAAW,EAChB,GAAG,EAAE,gBAAgB,GAAG,YAAY,GAAG,mBAAmB;YAmD9C,SAAS;YAsBT,SAAS;YAiBT,QAAQ;YAQR,QAAQ;YAuBR,SAAS;YAyFT,cAAc;YAkBd,iBAAiB;YAQjB,mBAAmB;YAOnB,aAAa;YAKb,mBAAmB;YAKnB,wBAAwB;YAsBxB,sBAAsB;YAYtB,0BAA0B;YAuB1B,wBAAwB;YAoBxB,sBAAsB;YA8BtB,oBAAoB;YA8BpB,kBAAkB;YASlB,gBAAgB;YAIhB,oBAAoB;YAIpB,kBAAkB;YAIlB,oBAAoB;YASpB,kBAAkB;YAKlB,oBAAoB;YAsBpB,kBAAkB;YAOlB,mBAAmB;YAuBnB,iBAAiB;YA2CjB,kBAAkB;YAQlB,gBAAgB;YAIhB,iBAAiB;YAUjB,eAAe;YAMf,oBAAoB;YAIpB,kBAAkB;YAIlB,gBAAgB;YAOhB,cAAc;YAKd,qBAAqB;YAmBrB,mBAAmB;YAWnB,kBAAkB;YAalB,gBAAgB;YAShB,iBAAiB;YAgBjB,eAAe;CAK9B"}
@@ -332,6 +332,11 @@ class LexDefBuilder {
332
332
  async compilePayload(def) {
333
333
  if (!def)
334
334
  return this.pure(`l.payload()`);
335
+ // Special case for JSON object payloads
336
+ if (def.encoding === 'application/json' && def.schema?.type === 'object') {
337
+ const properties = await this.compilePropertiesSchemas(def.schema);
338
+ return this.pure(`l.jsonPayload({${properties.join(',')}})`);
339
+ }
335
340
  const encodedEncoding = JSON.stringify(def.encoding);
336
341
  if (def.schema) {
337
342
  const bodySchema = await this.compileBodySchema(def.schema);
@@ -350,7 +355,7 @@ class LexDefBuilder {
350
355
  }
351
356
  async compileParamsSchema(def) {
352
357
  if (!def)
353
- return this.pure(`l.params({})`);
358
+ return this.pure(`l.params()`);
354
359
  const properties = await this.compilePropertiesSchemas(def);
355
360
  return this.pure(`l.params({${properties.join(',')}})`);
356
361
  }
@@ -1 +1 @@
1
- {"version":3,"file":"lex-def-builder.js","sourceRoot":"","sources":["../src/lex-def-builder.ts"],"names":[],"mappings":"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","sourcesContent":["import assert from 'node:assert'\nimport {\n JSDocStructure,\n OptionalKind,\n SourceFile,\n VariableDeclarationKind,\n} from 'ts-morph'\nimport {\n LexiconArray,\n LexiconArrayItems,\n LexiconBlob,\n LexiconBoolean,\n LexiconBytes,\n LexiconCid,\n LexiconDocument,\n LexiconError,\n LexiconIndexer,\n LexiconInteger,\n LexiconObject,\n LexiconParameters,\n LexiconPayload,\n LexiconPermissionSet,\n LexiconProcedure,\n LexiconQuery,\n LexiconRecord,\n LexiconRef,\n LexiconRefUnion,\n LexiconString,\n LexiconSubscription,\n LexiconToken,\n LexiconUnknown,\n} from '@atproto/lex-document'\nimport { l } from '@atproto/lex-schema'\nimport {\n RefResolver,\n RefResolverOptions,\n ResolvedRef,\n getPublicIdentifiers,\n} from './ref-resolver.js'\nimport { isSafeIdentifier } from './ts-lang.js'\n\nexport type LexDefBuilderOptions = RefResolverOptions & {\n lib?: string\n allowLegacyBlobs?: boolean\n pureAnnotations?: boolean\n}\n\n/**\n * Utility class to build a TypeScript source file from a lexicon document.\n */\nexport class LexDefBuilder {\n private readonly refResolver: RefResolver\n\n constructor(\n private readonly options: LexDefBuilderOptions,\n private readonly file: SourceFile,\n private readonly doc: LexiconDocument,\n indexer: LexiconIndexer,\n ) {\n this.refResolver = new RefResolver(doc, file, indexer, options)\n }\n\n private pure(code: string) {\n return this.options.pureAnnotations ? markPure(code) : code\n }\n\n async build() {\n this.file.addVariableStatement({\n declarationKind: VariableDeclarationKind.Const,\n declarations: [\n { name: '$nsid', initializer: JSON.stringify(this.doc.id) },\n ],\n })\n\n this.file.addExportDeclaration({\n namedExports: [{ name: '$nsid' }],\n })\n\n const defs = Object.keys(this.doc.defs)\n if (defs.length) {\n const moduleSpecifier = this.options?.lib ?? '@atproto/lex-schema'\n this.file\n .addImportDeclaration({ moduleSpecifier })\n .addNamedImports([{ name: 'l' }])\n\n for (const hash of defs) {\n await this.addDef(hash)\n }\n }\n }\n\n private addUtils(definitions: Record<string, undefined | string>) {\n const entries = Object.entries(definitions).filter(\n (e): e is [(typeof e)[0], NonNullable<(typeof e)[1]>] => e[1] != null,\n )\n if (entries.length) {\n this.file.addVariableStatement({\n isExported: true,\n declarationKind: VariableDeclarationKind.Const,\n declarations: entries.map(([name, initializer]) => ({\n name,\n initializer,\n })),\n })\n }\n }\n\n private async addDef(hash: string) {\n const def = Object.hasOwn(this.doc.defs, hash) ? this.doc.defs[hash] : null\n if (def == null) return\n\n switch (def.type) {\n case 'permission-set':\n return this.addPermissionSet(hash, def)\n case 'procedure':\n return this.addProcedure(hash, def)\n case 'query':\n return this.addQuery(hash, def)\n case 'subscription':\n return this.addSubscription(hash, def)\n case 'record':\n return this.addRecord(hash, def)\n case 'token':\n return this.addToken(hash, def)\n case 'object':\n return this.addObject(hash, def)\n case 'array':\n return this.addArray(hash, def)\n default:\n await this.addSchema(hash, def, {\n type: await this.compileContainedType(def),\n schema: await this.compileContainedSchema(def),\n validationUtils: true,\n })\n }\n }\n\n private async addPermissionSet(hash: string, def: LexiconPermissionSet) {\n const permission = def.permissions.map((def) => {\n const options = stringifyOptions(def, undefined, ['resource', 'type'])\n return this.pure(\n `l.permission(${JSON.stringify(def.resource)}, ${options})`,\n )\n })\n\n const options = stringifyOptions(def, [\n 'title',\n 'title:lang',\n 'detail',\n 'detail:lang',\n ] satisfies (keyof l.PermissionSetOptions)[])\n\n await this.addSchema(hash, def, {\n schema: this.pure(\n `l.permissionSet($nsid, [${permission.join(',')}], ${options})`,\n ),\n })\n }\n\n private async addProcedure(hash: string, def: LexiconProcedure) {\n if (hash !== 'main') {\n throw new Error(`Definition ${hash} cannot be of type ${def.type}`)\n }\n\n // @TODO Build the types instead of using an inferred type.\n\n const ref = await this.addSchema(hash, def, {\n schema: this.pure(`\n l.procedure(\n $nsid,\n ${await this.compileParamsSchema(def.parameters)},\n ${await this.compilePayload(def.input)},\n ${await this.compilePayload(def.output)},\n ${await this.compileErrors(def.errors)}\n )\n `),\n })\n\n this.addMethodTypeUtils(ref, def)\n this.addUtils({\n $lxm: this.pure(`${ref.varName}.nsid`),\n $params: this.pure(`${ref.varName}.parameters`),\n $input: this.pure(`${ref.varName}.input`),\n $output: this.pure(`${ref.varName}.output`),\n })\n }\n\n private async addQuery(hash: string, def: LexiconQuery) {\n if (hash !== 'main') {\n throw new Error(`Definition ${hash} cannot be of type ${def.type}`)\n }\n\n // @TODO Build the types instead of using an inferred type.\n\n const ref = await this.addSchema(hash, def, {\n schema: this.pure(`\n l.query(\n $nsid,\n ${await this.compileParamsSchema(def.parameters)},\n ${await this.compilePayload(def.output)},\n ${await this.compileErrors(def.errors)}\n )\n `),\n })\n\n this.addMethodTypeUtils(ref, def)\n this.addUtils({\n $lxm: this.pure(`${ref.varName}.nsid`),\n $params: `${ref.varName}.parameters`,\n $output: `${ref.varName}.output`,\n })\n }\n\n private async addSubscription(hash: string, def: LexiconSubscription) {\n if (hash !== 'main') {\n throw new Error(`Definition ${hash} cannot be of type ${def.type}`)\n }\n\n // @TODO Build the types instead of using an inferred type.\n\n const ref = await this.addSchema(hash, def, {\n schema: this.pure(`\n l.subscription(\n $nsid,\n ${await this.compileParamsSchema(def.parameters)},\n ${await this.compileBodySchema(def.message?.schema)},\n ${await this.compileErrors(def.errors)}\n )\n `),\n })\n\n this.addMethodTypeUtils(ref, def)\n this.addUtils({\n $lxm: this.pure(`${ref.varName}.nsid`),\n $params: `${ref.varName}.parameters`,\n $message: `${ref.varName}.message`,\n })\n }\n\n addMethodTypeUtils(\n ref: ResolvedRef,\n def: LexiconProcedure | LexiconQuery | LexiconSubscription,\n ) {\n this.file.addTypeAlias({\n isExported: true,\n name: 'Params',\n type: `l.InferMethodParams<typeof ${ref.varName}>`,\n docs: compileDocs(def.parameters?.description),\n })\n\n if (def.type === 'procedure') {\n this.file.addTypeAlias({\n isExported: true,\n name: 'Input',\n type: `l.InferMethodInput<typeof ${ref.varName}>`,\n docs: compileDocs(def.input?.description),\n })\n\n this.file.addTypeAlias({\n isExported: true,\n name: 'InputBody',\n type: `l.InferMethodInputBody<typeof ${ref.varName}>`,\n docs: compileDocs(def.input?.description),\n })\n }\n\n if (def.type === 'procedure' || def.type === 'query') {\n this.file.addTypeAlias({\n isExported: true,\n name: 'Output',\n type: `l.InferMethodOutput<typeof ${ref.varName}>`,\n docs: compileDocs(def.output?.description),\n })\n\n this.file.addTypeAlias({\n isExported: true,\n name: 'OutputBody',\n type: `l.InferMethodOutputBody<typeof ${ref.varName}>`,\n docs: compileDocs(def.output?.description),\n })\n }\n\n if (def.type === 'subscription') {\n this.file.addTypeAlias({\n isExported: true,\n name: 'Message',\n type: `l.InferSubscriptionMessage<typeof ${ref.varName}>`,\n docs: compileDocs(def.message?.description),\n })\n }\n }\n\n private async addRecord(hash: string, def: LexiconRecord) {\n if (hash !== 'main') {\n throw new Error(`Definition ${hash} cannot be of type ${def.type}`)\n }\n\n const key = JSON.stringify(def.key ?? 'any')\n const objectSchema = await this.compileObjectSchema(def.record)\n\n const properties = await this.compilePropertiesTypes(def.record)\n properties.unshift(`$type: ${JSON.stringify(l.$type(this.doc.id, hash))}`)\n\n await this.addSchema(hash, def, {\n type: `{ ${properties.join(';')} }`,\n schema: (ref) =>\n this.pure(\n `l.record<${key}, ${ref.typeName}>(${key}, $nsid, ${objectSchema})`,\n ),\n objectUtils: true,\n validationUtils: true,\n })\n }\n\n private async addObject(hash: string, def: LexiconObject) {\n const objectSchema = await this.compileObjectSchema(def)\n\n const properties = await this.compilePropertiesTypes(def)\n properties.unshift(`$type?: ${JSON.stringify(l.$type(this.doc.id, hash))}`)\n\n await this.addSchema(hash, def, {\n type: `{ ${properties.join(';')} }`,\n schema: (ref) =>\n this.pure(\n `l.typedObject<${ref.typeName}>($nsid, ${JSON.stringify(hash)}, ${objectSchema})`,\n ),\n objectUtils: true,\n validationUtils: true,\n })\n }\n\n private async addToken(hash: string, def: LexiconToken) {\n await this.addSchema(hash, def, {\n schema: this.pure(`l.token($nsid, ${JSON.stringify(hash)})`),\n type: JSON.stringify(l.$type(this.doc.id, hash)),\n validationUtils: true,\n })\n }\n\n private async addArray(hash: string, def: LexiconArray) {\n // @TODO It could be nice to expose the array item type as a separate type.\n // This was not done (yet) as there is no easy way to name it to avoid\n // collisions.\n\n const itemSchema = await this.compileContainedSchema(def.items)\n const options = stringifyOptions(def, [\n 'minLength',\n 'maxLength',\n ] satisfies (keyof l.ArraySchemaOptions)[])\n\n await this.addSchema(hash, def, {\n type: `(${await this.compileContainedType(def.items)})[]`,\n // @NOTE Not using compileArraySchema to allow specifying the generic\n // parameter to l.array<>.\n schema: (ref) =>\n this.pure(\n `l.array<${ref.typeName}[number]>(${itemSchema}, ${options})`,\n ),\n validationUtils: true,\n })\n }\n\n private async addSchema(\n hash: string,\n def: { description?: string },\n {\n type,\n schema,\n objectUtils,\n validationUtils,\n }: {\n type?: string | ((ref: ResolvedRef) => string)\n schema?: string | ((ref: ResolvedRef) => string)\n objectUtils?: boolean\n validationUtils?: boolean\n },\n ): Promise<ResolvedRef> {\n const ref = await this.refResolver.resolveLocal(hash)\n const pub = getPublicIdentifiers(hash)\n\n // Fool-proofing\n assert(isSafeIdentifier(ref.varName), 'Expected safe type identifier')\n assert(isSafeIdentifier(ref.typeName), 'Expected safe type identifier')\n assert(isSafeIdentifier(pub.typeName), 'Expected safe type identifier')\n\n if (type) {\n this.file.addTypeAlias({\n name: ref.typeName,\n type: typeof type === 'function' ? type(ref) : type,\n docs: compileDocs(def.description),\n })\n\n this.file.addExportDeclaration({\n isTypeOnly: true,\n namedExports: [\n {\n name: ref.typeName,\n alias: ref.typeName === pub.typeName ? undefined : pub.typeName,\n },\n ],\n })\n }\n\n if (schema) {\n this.file.addVariableStatement({\n declarationKind: VariableDeclarationKind.Const,\n declarations: [\n {\n name: ref.varName,\n initializer: typeof schema === 'function' ? schema(ref) : schema,\n },\n ],\n docs: compileDocs(def.description),\n })\n\n this.file.addExportDeclaration({\n namedExports: [\n {\n name: ref.varName,\n alias:\n ref.varName === pub.varName\n ? undefined\n : isSafeIdentifier(pub.varName)\n ? pub.varName\n : JSON.stringify(pub.varName),\n },\n ],\n })\n }\n\n if (hash === 'main' && objectUtils) {\n this.addUtils({\n $isTypeOf: markPure(`${ref.varName}.isTypeOf.bind(${ref.varName})`),\n $build: markPure(`${ref.varName}.build.bind(${ref.varName})`),\n $type: markPure(`${ref.varName}.$type`),\n })\n }\n\n if (hash === 'main' && validationUtils) {\n this.addUtils({\n $assert: markPure(`${ref.varName}.assert.bind(${ref.varName})`),\n $ifMatches: markPure(`${ref.varName}.ifMatches.bind(${ref.varName})`),\n $matches: markPure(`${ref.varName}.matches.bind(${ref.varName})`),\n $parse: markPure(`${ref.varName}.parse.bind(${ref.varName})`),\n $safeParse: markPure(`${ref.varName}.safeParse.bind(${ref.varName})`),\n })\n }\n\n return ref\n }\n\n private async compilePayload(def: LexiconPayload | undefined) {\n if (!def) return this.pure(`l.payload()`)\n\n const encodedEncoding = JSON.stringify(def.encoding)\n if (def.schema) {\n const bodySchema = await this.compileBodySchema(def.schema)\n return this.pure(`l.payload(${encodedEncoding}, ${bodySchema})`)\n } else {\n return this.pure(`l.payload(${encodedEncoding})`)\n }\n }\n\n private async compileBodySchema(\n def?: LexiconRef | LexiconRefUnion | LexiconObject,\n ): Promise<string> {\n if (!def) return 'undefined'\n if (def.type === 'object') return this.compileObjectSchema(def)\n return this.compileContainedSchema(def)\n }\n\n private async compileParamsSchema(def: undefined | LexiconParameters) {\n if (!def) return this.pure(`l.params({})`)\n\n const properties = await this.compilePropertiesSchemas(def)\n return this.pure(`l.params({${properties.join(',')}})`)\n }\n\n private async compileErrors(defs?: readonly LexiconError[]) {\n if (!defs?.length) return ''\n return JSON.stringify(defs.map((d) => d.name))\n }\n\n private async compileObjectSchema(def: LexiconObject): Promise<string> {\n const properties = await this.compilePropertiesSchemas(def)\n return this.pure(`l.object({${properties.join(',')}})`)\n }\n\n private async compilePropertiesSchemas(options: {\n properties: Record<string, LexiconArray | LexiconArrayItems>\n required?: readonly string[]\n nullable?: readonly string[]\n }): Promise<string[]> {\n for (const opt of ['required', 'nullable'] as const) {\n if (options[opt]) {\n for (const prop of options[opt]) {\n if (!Object.hasOwn(options.properties, prop)) {\n throw new Error(`No schema found for ${opt} property \"${prop}\"`)\n }\n }\n }\n }\n\n return Promise.all(\n Object.entries(options.properties).map((entry) => {\n return this.compilePropertyEntrySchema(entry, options)\n }),\n )\n }\n\n private async compilePropertiesTypes(options: {\n properties: Record<string, LexiconArray | LexiconArrayItems>\n required?: readonly string[]\n nullable?: readonly string[]\n }) {\n return Promise.all(\n Object.entries(options.properties).map((entry) => {\n return this.compilePropertyEntryType(entry, options)\n }),\n )\n }\n\n private async compilePropertyEntrySchema(\n [key, def]: [string, LexiconArray | LexiconArrayItems],\n options: {\n required?: readonly string[]\n nullable?: readonly string[]\n },\n ) {\n const isNullable = options.nullable?.includes(key)\n const isRequired = options.required?.includes(key)\n\n let schema = await this.compileContainedSchema(def)\n\n if (isNullable) {\n schema = this.pure(`l.nullable(${schema})`)\n }\n\n if (!isRequired) {\n schema = this.pure(`l.optional(${schema})`)\n }\n\n return `${JSON.stringify(key)}:${schema}`\n }\n\n private async compilePropertyEntryType(\n [key, def]: [string, LexiconArray | LexiconArrayItems],\n options: {\n required?: readonly string[]\n nullable?: readonly string[]\n },\n ) {\n const isNullable = options.nullable?.includes(key)\n const isRequired = options.required?.includes(key)\n\n const optional = isRequired ? '' : '?'\n const append = isNullable ? ' | null' : ''\n\n const jsDoc = compileLeadingTrivia(def.description) || ''\n const name = JSON.stringify(key)\n const type = await this.compileContainedType(def)\n\n return `${jsDoc}${name}${optional}:${type}${append}`\n }\n\n private async compileContainedSchema(\n def: LexiconArray | LexiconArrayItems,\n ): Promise<string> {\n switch (def.type) {\n case 'unknown':\n return this.compileUnknownSchema(def)\n case 'boolean':\n return this.compileBooleanSchema(def)\n case 'integer':\n return this.compileIntegerSchema(def)\n case 'string':\n return this.compileStringSchema(def)\n case 'bytes':\n return this.compileBytesSchema(def)\n case 'blob':\n return this.compileBlobSchema(def)\n case 'cid-link':\n return this.compileCidLinkSchema(def)\n case 'ref':\n return this.compileRefSchema(def)\n case 'union':\n return this.compileRefUnionSchema(def)\n case 'array':\n return this.compileArraySchema(def)\n default:\n // @ts-expect-error\n throw new Error(`Unsupported def type: ${def.type}`)\n }\n }\n\n private async compileContainedType(\n def: LexiconArray | LexiconArrayItems,\n ): Promise<string> {\n switch (def.type) {\n case 'unknown':\n return this.compileUnknownType(def)\n case 'boolean':\n return this.compileBooleanType(def)\n case 'integer':\n return this.compileIntegerType(def)\n case 'string':\n return this.compileStringType(def)\n case 'bytes':\n return this.compileBytesType(def)\n case 'blob':\n return this.compileBlobType(def)\n case 'cid-link':\n return this.compileCidLinkType(def)\n case 'ref':\n return this.compileRefType(def)\n case 'union':\n return this.compileRefUnionType(def)\n case 'array':\n return this.compileArrayType(def)\n default:\n // @ts-expect-error\n throw new Error(`Unsupported def type: ${def.type}`)\n }\n }\n\n private async compileArraySchema(def: LexiconArray): Promise<string> {\n const itemSchema = await this.compileContainedSchema(def.items)\n const options = stringifyOptions(def, [\n 'minLength',\n 'maxLength',\n ] satisfies (keyof l.ArraySchemaOptions)[])\n return this.pure(`l.array(${itemSchema}, ${options})`)\n }\n\n private async compileArrayType(def: LexiconArray): Promise<string> {\n return `(${await this.compileContainedType(def.items)})[]`\n }\n\n private async compileUnknownSchema(_def: LexiconUnknown): Promise<string> {\n return this.pure(`l.unknownObject()`)\n }\n\n private async compileUnknownType(_def: LexiconUnknown): Promise<string> {\n return `l.UnknownObject`\n }\n\n private async compileBooleanSchema(def: LexiconBoolean): Promise<string> {\n if (hasConst(def)) return this.compileConstSchema(def)\n\n const options = stringifyOptions(def, [\n 'default',\n ] satisfies (keyof l.BooleanSchemaOptions)[])\n return this.pure(`l.boolean(${options})`)\n }\n\n private async compileBooleanType(def: LexiconBoolean): Promise<string> {\n if (hasConst(def)) return this.compileConstType(def)\n return 'boolean'\n }\n\n private async compileIntegerSchema(def: LexiconInteger): Promise<string> {\n if (hasConst(def)) {\n const schema: l.IntegerSchema = l.integer(def)\n schema.assert(def.const)\n }\n\n if (hasEnum(def)) {\n const schema: l.IntegerSchema = l.integer(def)\n for (const val of def.enum) schema.assert(val)\n }\n\n if (hasConst(def)) return this.compileConstSchema(def)\n if (hasEnum(def)) return this.compileEnumSchema(def)\n\n const options = stringifyOptions(def, [\n 'default',\n 'maximum',\n 'minimum',\n ] satisfies (keyof l.IntegerSchemaOptions)[])\n return this.pure(`l.integer(${options})`)\n }\n\n private async compileIntegerType(def: LexiconInteger): Promise<string> {\n if (hasConst(def)) return this.compileConstType(def)\n if (hasEnum(def)) return this.compileEnumType(def)\n\n return 'number'\n }\n\n private async compileStringSchema(def: LexiconString): Promise<string> {\n if (hasConst(def)) {\n const schema: l.StringSchema = l.string(def)\n schema.assert(def.const)\n } else if (hasEnum(def)) {\n const schema: l.StringSchema = l.string(def)\n for (const val of def.enum) schema.assert(val)\n }\n\n if (hasConst(def)) return this.compileConstSchema(def)\n if (hasEnum(def)) return this.compileEnumSchema(def)\n\n const options = stringifyOptions(def, [\n 'default',\n 'format',\n 'maxGraphemes',\n 'minGraphemes',\n 'maxLength',\n 'minLength',\n ] satisfies (keyof l.StringSchemaOptions)[])\n return this.pure(`l.string(${options})`)\n }\n\n private async compileStringType(def: LexiconString): Promise<string> {\n if (hasConst(def)) return this.compileConstType(def)\n if (hasEnum(def)) return this.compileEnumType(def)\n\n switch (def.format) {\n case undefined:\n break\n case 'datetime':\n return 'l.DatetimeString'\n case 'uri':\n return 'l.UriString'\n case 'at-uri':\n return 'l.AtUriString'\n case 'did':\n return 'l.DidString'\n case 'handle':\n return 'l.HandleString'\n case 'at-identifier':\n return 'l.AtIdentifierString'\n case 'nsid':\n return 'l.NsidString'\n case 'tid':\n return 'l.TidString'\n case 'cid':\n return 'l.CidString'\n case 'language':\n return 'l.LanguageString'\n case 'record-key':\n return 'l.RecordKeyString'\n default:\n throw new Error(`Unknown string format: ${def.format}`)\n }\n\n if (def.knownValues?.length) {\n return (\n def.knownValues.map((v) => JSON.stringify(v)).join(' | ') +\n ' | l.UnknownString'\n )\n }\n\n return 'string'\n }\n\n private async compileBytesSchema(def: LexiconBytes): Promise<string> {\n const options = stringifyOptions(def, [\n 'minLength',\n 'maxLength',\n ] satisfies (keyof l.BytesSchemaOptions)[])\n return this.pure(`l.bytes(${options})`)\n }\n\n private async compileBytesType(_def: LexiconBytes): Promise<string> {\n return 'Uint8Array'\n }\n\n private async compileBlobSchema(def: LexiconBlob): Promise<string> {\n const opts = { ...def, allowLegacy: this.options.allowLegacyBlobs === true }\n const options = stringifyOptions(opts, [\n 'maxSize',\n 'accept',\n 'allowLegacy',\n ] satisfies (keyof l.BlobSchemaOptions)[])\n return this.pure(`l.blob(${options})`)\n }\n\n private async compileBlobType(_def: LexiconBlob): Promise<string> {\n return this.options.allowLegacyBlobs\n ? 'l.BlobRef | l.LegacyBlobRef'\n : 'l.BlobRef'\n }\n\n private async compileCidLinkSchema(_def: LexiconCid): Promise<string> {\n return this.pure(`l.cidLink()`)\n }\n\n private async compileCidLinkType(_def: LexiconCid): Promise<string> {\n return 'l.Cid'\n }\n\n private async compileRefSchema(def: LexiconRef): Promise<string> {\n const { varName, typeName } = await this.refResolver.resolve(def.ref)\n // @NOTE \"as any\" is needed in schemas with circular refs as TypeScript\n // cannot infer the type of a value that depends on its initializer type\n return this.pure(`l.ref<${typeName}>((() => ${varName}) as any)`)\n }\n\n private async compileRefType(def: LexiconRef): Promise<string> {\n const ref = await this.refResolver.resolve(def.ref)\n return ref.typeName\n }\n\n private async compileRefUnionSchema(def: LexiconRefUnion): Promise<string> {\n if (def.refs.length === 0 && def.closed) {\n return this.pure(`l.never()`)\n }\n\n const refs = await Promise.all(\n def.refs.map(async (ref: string) => {\n const { varName, typeName } = await this.refResolver.resolve(ref)\n // @NOTE \"as any\" is needed in schemas with circular refs as TypeScript\n // cannot infer the type of a value that depends on its initializer type\n return this.pure(`l.typedRef<${typeName}>((() => ${varName}) as any)`)\n }),\n )\n\n return this.pure(\n `l.typedUnion([${refs.join(',')}], ${def.closed ?? false})`,\n )\n }\n\n private async compileRefUnionType(def: LexiconRefUnion): Promise<string> {\n const types = await Promise.all(\n def.refs.map(async (ref) => {\n const { typeName } = await this.refResolver.resolve(ref)\n return `l.TypedRef<${typeName}>`\n }),\n )\n if (!def.closed) types.push('l.TypedObject')\n return types.join(' | ') || 'never'\n }\n\n private async compileConstSchema<\n T extends null | number | string | boolean,\n >(def: { const: T; enum?: readonly T[]; default?: T }): Promise<string> {\n if (hasEnum(def) && !def.enum.includes(def.const)) {\n return this.pure(`l.never()`)\n }\n\n const options = stringifyOptions(def, [\n 'default',\n ] satisfies (keyof l.LiteralSchemaOptions<any>)[])\n return this.pure(`l.literal(${JSON.stringify(def.const)}, ${options})`)\n }\n\n private async compileConstType<\n T extends null | number | string | boolean,\n >(def: { const: T; enum?: readonly T[] }): Promise<string> {\n if (hasEnum(def) && !def.enum.includes(def.const)) {\n return 'never'\n }\n return JSON.stringify(def.const)\n }\n\n private async compileEnumSchema<T extends null | number | string>(def: {\n enum: readonly T[]\n default?: T\n }): Promise<string> {\n if (def.enum.length === 0) {\n return this.pure(`l.never()`)\n }\n if (def.enum.length === 1 && def.default === undefined) {\n return this.pure(`l.literal(${JSON.stringify(def.enum[0])})`)\n }\n const options = stringifyOptions(def, [\n 'default',\n ] satisfies (keyof l.EnumSchemaOptions<any>)[])\n return this.pure(`l.enum(${JSON.stringify(def.enum)}, ${options})`)\n }\n\n private async compileEnumType<T extends null | number | string>(def: {\n enum: readonly T[]\n }): Promise<string> {\n return def.enum.map((v) => JSON.stringify(v)).join(' | ') || 'never'\n }\n}\n\ntype ParsedDescription = OptionalKind<JSDocStructure> & {\n description?: string\n tags?: { tagName: string; text?: string }[]\n}\n\nfunction parseDescription(description: string): ParsedDescription {\n if (/deprecated/i.test(description)) {\n const deprecationMatch = description.match(\n /(\\s*deprecated\\s*(?:--?|:)?\\s*([^-]*)(?:-+)?)/i,\n )\n if (deprecationMatch) {\n const { 1: match, 2: deprecationNotice } = deprecationMatch\n return {\n description: description.replace(match, '').trim() || undefined,\n tags: [{ tagName: 'deprecated', text: deprecationNotice?.trim() }],\n }\n } else {\n return {\n description: description.trim() || undefined,\n tags: [{ tagName: 'deprecated' }],\n }\n }\n }\n\n return {\n description: description.trim() || undefined,\n }\n}\n\nfunction compileLeadingTrivia(description?: string) {\n if (!description) return undefined\n const parsed = parseDescription(description)\n if (!parsed.description && !parsed.tags?.length) return undefined\n const tags = parsed.tags\n ?.map(({ tagName, text }) => (text ? `@${tagName} ${text}` : `@${tagName}`))\n ?.join('\\n')\n const text = `\\n${[parsed.description, tags].filter(Boolean).join('\\n\\n')}`\n return `\\n\\n/**${text.replaceAll('\\n', '\\n * ')}\\n */\\n`\n}\n\nfunction compileDocs(description?: string) {\n if (!description) return undefined\n return [parseDescription(description)]\n}\n\nfunction stringifyOptions<O extends Record<string, unknown>>(\n obj: O,\n include?: (keyof O)[],\n exclude?: (keyof O)[],\n) {\n const filtered = Object.entries(obj).filter(\n ([k]) => (!include || include.includes(k)) && !exclude?.includes(k),\n )\n return filtered.length ? JSON.stringify(Object.fromEntries(filtered)) : ''\n}\n\nfunction hasConst<T extends { const?: unknown }>(\n def: T,\n): def is T & { const: NonNullable<T['const']> } {\n return def.const != null\n}\n\nfunction hasEnum<T extends { enum?: readonly unknown[] }>(\n def: T,\n): def is T & { enum: unknown[] } {\n return def.enum != null\n}\n\nfunction markPure<T extends string>(v: T): `/*#__PURE__*/ ${T}` {\n return `/*#__PURE__*/ ${v}`\n}\n"]}
1
+ {"version":3,"file":"lex-def-builder.js","sourceRoot":"","sources":["../src/lex-def-builder.ts"],"names":[],"mappings":"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","sourcesContent":["import assert from 'node:assert'\nimport {\n JSDocStructure,\n OptionalKind,\n SourceFile,\n VariableDeclarationKind,\n} from 'ts-morph'\nimport {\n LexiconArray,\n LexiconArrayItems,\n LexiconBlob,\n LexiconBoolean,\n LexiconBytes,\n LexiconCid,\n LexiconDocument,\n LexiconError,\n LexiconIndexer,\n LexiconInteger,\n LexiconObject,\n LexiconParameters,\n LexiconPayload,\n LexiconPermissionSet,\n LexiconProcedure,\n LexiconQuery,\n LexiconRecord,\n LexiconRef,\n LexiconRefUnion,\n LexiconString,\n LexiconSubscription,\n LexiconToken,\n LexiconUnknown,\n} from '@atproto/lex-document'\nimport { l } from '@atproto/lex-schema'\nimport {\n RefResolver,\n RefResolverOptions,\n ResolvedRef,\n getPublicIdentifiers,\n} from './ref-resolver.js'\nimport { isSafeIdentifier } from './ts-lang.js'\n\nexport type LexDefBuilderOptions = RefResolverOptions & {\n lib?: string\n allowLegacyBlobs?: boolean\n pureAnnotations?: boolean\n}\n\n/**\n * Utility class to build a TypeScript source file from a lexicon document.\n */\nexport class LexDefBuilder {\n private readonly refResolver: RefResolver\n\n constructor(\n private readonly options: LexDefBuilderOptions,\n private readonly file: SourceFile,\n private readonly doc: LexiconDocument,\n indexer: LexiconIndexer,\n ) {\n this.refResolver = new RefResolver(doc, file, indexer, options)\n }\n\n private pure(code: string) {\n return this.options.pureAnnotations ? markPure(code) : code\n }\n\n async build() {\n this.file.addVariableStatement({\n declarationKind: VariableDeclarationKind.Const,\n declarations: [\n { name: '$nsid', initializer: JSON.stringify(this.doc.id) },\n ],\n })\n\n this.file.addExportDeclaration({\n namedExports: [{ name: '$nsid' }],\n })\n\n const defs = Object.keys(this.doc.defs)\n if (defs.length) {\n const moduleSpecifier = this.options?.lib ?? '@atproto/lex-schema'\n this.file\n .addImportDeclaration({ moduleSpecifier })\n .addNamedImports([{ name: 'l' }])\n\n for (const hash of defs) {\n await this.addDef(hash)\n }\n }\n }\n\n private addUtils(definitions: Record<string, undefined | string>) {\n const entries = Object.entries(definitions).filter(\n (e): e is [(typeof e)[0], NonNullable<(typeof e)[1]>] => e[1] != null,\n )\n if (entries.length) {\n this.file.addVariableStatement({\n isExported: true,\n declarationKind: VariableDeclarationKind.Const,\n declarations: entries.map(([name, initializer]) => ({\n name,\n initializer,\n })),\n })\n }\n }\n\n private async addDef(hash: string) {\n const def = Object.hasOwn(this.doc.defs, hash) ? this.doc.defs[hash] : null\n if (def == null) return\n\n switch (def.type) {\n case 'permission-set':\n return this.addPermissionSet(hash, def)\n case 'procedure':\n return this.addProcedure(hash, def)\n case 'query':\n return this.addQuery(hash, def)\n case 'subscription':\n return this.addSubscription(hash, def)\n case 'record':\n return this.addRecord(hash, def)\n case 'token':\n return this.addToken(hash, def)\n case 'object':\n return this.addObject(hash, def)\n case 'array':\n return this.addArray(hash, def)\n default:\n await this.addSchema(hash, def, {\n type: await this.compileContainedType(def),\n schema: await this.compileContainedSchema(def),\n validationUtils: true,\n })\n }\n }\n\n private async addPermissionSet(hash: string, def: LexiconPermissionSet) {\n const permission = def.permissions.map((def) => {\n const options = stringifyOptions(def, undefined, ['resource', 'type'])\n return this.pure(\n `l.permission(${JSON.stringify(def.resource)}, ${options})`,\n )\n })\n\n const options = stringifyOptions(def, [\n 'title',\n 'title:lang',\n 'detail',\n 'detail:lang',\n ] satisfies (keyof l.PermissionSetOptions)[])\n\n await this.addSchema(hash, def, {\n schema: this.pure(\n `l.permissionSet($nsid, [${permission.join(',')}], ${options})`,\n ),\n })\n }\n\n private async addProcedure(hash: string, def: LexiconProcedure) {\n if (hash !== 'main') {\n throw new Error(`Definition ${hash} cannot be of type ${def.type}`)\n }\n\n // @TODO Build the types instead of using an inferred type.\n\n const ref = await this.addSchema(hash, def, {\n schema: this.pure(`\n l.procedure(\n $nsid,\n ${await this.compileParamsSchema(def.parameters)},\n ${await this.compilePayload(def.input)},\n ${await this.compilePayload(def.output)},\n ${await this.compileErrors(def.errors)}\n )\n `),\n })\n\n this.addMethodTypeUtils(ref, def)\n this.addUtils({\n $lxm: this.pure(`${ref.varName}.nsid`),\n $params: this.pure(`${ref.varName}.parameters`),\n $input: this.pure(`${ref.varName}.input`),\n $output: this.pure(`${ref.varName}.output`),\n })\n }\n\n private async addQuery(hash: string, def: LexiconQuery) {\n if (hash !== 'main') {\n throw new Error(`Definition ${hash} cannot be of type ${def.type}`)\n }\n\n // @TODO Build the types instead of using an inferred type.\n\n const ref = await this.addSchema(hash, def, {\n schema: this.pure(`\n l.query(\n $nsid,\n ${await this.compileParamsSchema(def.parameters)},\n ${await this.compilePayload(def.output)},\n ${await this.compileErrors(def.errors)}\n )\n `),\n })\n\n this.addMethodTypeUtils(ref, def)\n this.addUtils({\n $lxm: this.pure(`${ref.varName}.nsid`),\n $params: `${ref.varName}.parameters`,\n $output: `${ref.varName}.output`,\n })\n }\n\n private async addSubscription(hash: string, def: LexiconSubscription) {\n if (hash !== 'main') {\n throw new Error(`Definition ${hash} cannot be of type ${def.type}`)\n }\n\n // @TODO Build the types instead of using an inferred type.\n\n const ref = await this.addSchema(hash, def, {\n schema: this.pure(`\n l.subscription(\n $nsid,\n ${await this.compileParamsSchema(def.parameters)},\n ${await this.compileBodySchema(def.message?.schema)},\n ${await this.compileErrors(def.errors)}\n )\n `),\n })\n\n this.addMethodTypeUtils(ref, def)\n this.addUtils({\n $lxm: this.pure(`${ref.varName}.nsid`),\n $params: `${ref.varName}.parameters`,\n $message: `${ref.varName}.message`,\n })\n }\n\n addMethodTypeUtils(\n ref: ResolvedRef,\n def: LexiconProcedure | LexiconQuery | LexiconSubscription,\n ) {\n this.file.addTypeAlias({\n isExported: true,\n name: 'Params',\n type: `l.InferMethodParams<typeof ${ref.varName}>`,\n docs: compileDocs(def.parameters?.description),\n })\n\n if (def.type === 'procedure') {\n this.file.addTypeAlias({\n isExported: true,\n name: 'Input',\n type: `l.InferMethodInput<typeof ${ref.varName}>`,\n docs: compileDocs(def.input?.description),\n })\n\n this.file.addTypeAlias({\n isExported: true,\n name: 'InputBody',\n type: `l.InferMethodInputBody<typeof ${ref.varName}>`,\n docs: compileDocs(def.input?.description),\n })\n }\n\n if (def.type === 'procedure' || def.type === 'query') {\n this.file.addTypeAlias({\n isExported: true,\n name: 'Output',\n type: `l.InferMethodOutput<typeof ${ref.varName}>`,\n docs: compileDocs(def.output?.description),\n })\n\n this.file.addTypeAlias({\n isExported: true,\n name: 'OutputBody',\n type: `l.InferMethodOutputBody<typeof ${ref.varName}>`,\n docs: compileDocs(def.output?.description),\n })\n }\n\n if (def.type === 'subscription') {\n this.file.addTypeAlias({\n isExported: true,\n name: 'Message',\n type: `l.InferSubscriptionMessage<typeof ${ref.varName}>`,\n docs: compileDocs(def.message?.description),\n })\n }\n }\n\n private async addRecord(hash: string, def: LexiconRecord) {\n if (hash !== 'main') {\n throw new Error(`Definition ${hash} cannot be of type ${def.type}`)\n }\n\n const key = JSON.stringify(def.key ?? 'any')\n const objectSchema = await this.compileObjectSchema(def.record)\n\n const properties = await this.compilePropertiesTypes(def.record)\n properties.unshift(`$type: ${JSON.stringify(l.$type(this.doc.id, hash))}`)\n\n await this.addSchema(hash, def, {\n type: `{ ${properties.join(';')} }`,\n schema: (ref) =>\n this.pure(\n `l.record<${key}, ${ref.typeName}>(${key}, $nsid, ${objectSchema})`,\n ),\n objectUtils: true,\n validationUtils: true,\n })\n }\n\n private async addObject(hash: string, def: LexiconObject) {\n const objectSchema = await this.compileObjectSchema(def)\n\n const properties = await this.compilePropertiesTypes(def)\n properties.unshift(`$type?: ${JSON.stringify(l.$type(this.doc.id, hash))}`)\n\n await this.addSchema(hash, def, {\n type: `{ ${properties.join(';')} }`,\n schema: (ref) =>\n this.pure(\n `l.typedObject<${ref.typeName}>($nsid, ${JSON.stringify(hash)}, ${objectSchema})`,\n ),\n objectUtils: true,\n validationUtils: true,\n })\n }\n\n private async addToken(hash: string, def: LexiconToken) {\n await this.addSchema(hash, def, {\n schema: this.pure(`l.token($nsid, ${JSON.stringify(hash)})`),\n type: JSON.stringify(l.$type(this.doc.id, hash)),\n validationUtils: true,\n })\n }\n\n private async addArray(hash: string, def: LexiconArray) {\n // @TODO It could be nice to expose the array item type as a separate type.\n // This was not done (yet) as there is no easy way to name it to avoid\n // collisions.\n\n const itemSchema = await this.compileContainedSchema(def.items)\n const options = stringifyOptions(def, [\n 'minLength',\n 'maxLength',\n ] satisfies (keyof l.ArraySchemaOptions)[])\n\n await this.addSchema(hash, def, {\n type: `(${await this.compileContainedType(def.items)})[]`,\n // @NOTE Not using compileArraySchema to allow specifying the generic\n // parameter to l.array<>.\n schema: (ref) =>\n this.pure(\n `l.array<${ref.typeName}[number]>(${itemSchema}, ${options})`,\n ),\n validationUtils: true,\n })\n }\n\n private async addSchema(\n hash: string,\n def: { description?: string },\n {\n type,\n schema,\n objectUtils,\n validationUtils,\n }: {\n type?: string | ((ref: ResolvedRef) => string)\n schema?: string | ((ref: ResolvedRef) => string)\n objectUtils?: boolean\n validationUtils?: boolean\n },\n ): Promise<ResolvedRef> {\n const ref = await this.refResolver.resolveLocal(hash)\n const pub = getPublicIdentifiers(hash)\n\n // Fool-proofing\n assert(isSafeIdentifier(ref.varName), 'Expected safe type identifier')\n assert(isSafeIdentifier(ref.typeName), 'Expected safe type identifier')\n assert(isSafeIdentifier(pub.typeName), 'Expected safe type identifier')\n\n if (type) {\n this.file.addTypeAlias({\n name: ref.typeName,\n type: typeof type === 'function' ? type(ref) : type,\n docs: compileDocs(def.description),\n })\n\n this.file.addExportDeclaration({\n isTypeOnly: true,\n namedExports: [\n {\n name: ref.typeName,\n alias: ref.typeName === pub.typeName ? undefined : pub.typeName,\n },\n ],\n })\n }\n\n if (schema) {\n this.file.addVariableStatement({\n declarationKind: VariableDeclarationKind.Const,\n declarations: [\n {\n name: ref.varName,\n initializer: typeof schema === 'function' ? schema(ref) : schema,\n },\n ],\n docs: compileDocs(def.description),\n })\n\n this.file.addExportDeclaration({\n namedExports: [\n {\n name: ref.varName,\n alias:\n ref.varName === pub.varName\n ? undefined\n : isSafeIdentifier(pub.varName)\n ? pub.varName\n : JSON.stringify(pub.varName),\n },\n ],\n })\n }\n\n if (hash === 'main' && objectUtils) {\n this.addUtils({\n $isTypeOf: markPure(`${ref.varName}.isTypeOf.bind(${ref.varName})`),\n $build: markPure(`${ref.varName}.build.bind(${ref.varName})`),\n $type: markPure(`${ref.varName}.$type`),\n })\n }\n\n if (hash === 'main' && validationUtils) {\n this.addUtils({\n $assert: markPure(`${ref.varName}.assert.bind(${ref.varName})`),\n $ifMatches: markPure(`${ref.varName}.ifMatches.bind(${ref.varName})`),\n $matches: markPure(`${ref.varName}.matches.bind(${ref.varName})`),\n $parse: markPure(`${ref.varName}.parse.bind(${ref.varName})`),\n $safeParse: markPure(`${ref.varName}.safeParse.bind(${ref.varName})`),\n })\n }\n\n return ref\n }\n\n private async compilePayload(def: LexiconPayload | undefined) {\n if (!def) return this.pure(`l.payload()`)\n\n // Special case for JSON object payloads\n if (def.encoding === 'application/json' && def.schema?.type === 'object') {\n const properties = await this.compilePropertiesSchemas(def.schema)\n return this.pure(`l.jsonPayload({${properties.join(',')}})`)\n }\n\n const encodedEncoding = JSON.stringify(def.encoding)\n if (def.schema) {\n const bodySchema = await this.compileBodySchema(def.schema)\n return this.pure(`l.payload(${encodedEncoding}, ${bodySchema})`)\n } else {\n return this.pure(`l.payload(${encodedEncoding})`)\n }\n }\n\n private async compileBodySchema(\n def?: LexiconRef | LexiconRefUnion | LexiconObject,\n ): Promise<string> {\n if (!def) return 'undefined'\n if (def.type === 'object') return this.compileObjectSchema(def)\n return this.compileContainedSchema(def)\n }\n\n private async compileParamsSchema(def: undefined | LexiconParameters) {\n if (!def) return this.pure(`l.params()`)\n\n const properties = await this.compilePropertiesSchemas(def)\n return this.pure(`l.params({${properties.join(',')}})`)\n }\n\n private async compileErrors(defs?: readonly LexiconError[]) {\n if (!defs?.length) return ''\n return JSON.stringify(defs.map((d) => d.name))\n }\n\n private async compileObjectSchema(def: LexiconObject): Promise<string> {\n const properties = await this.compilePropertiesSchemas(def)\n return this.pure(`l.object({${properties.join(',')}})`)\n }\n\n private async compilePropertiesSchemas(options: {\n properties: Record<string, LexiconArray | LexiconArrayItems>\n required?: readonly string[]\n nullable?: readonly string[]\n }): Promise<string[]> {\n for (const opt of ['required', 'nullable'] as const) {\n if (options[opt]) {\n for (const prop of options[opt]) {\n if (!Object.hasOwn(options.properties, prop)) {\n throw new Error(`No schema found for ${opt} property \"${prop}\"`)\n }\n }\n }\n }\n\n return Promise.all(\n Object.entries(options.properties).map((entry) => {\n return this.compilePropertyEntrySchema(entry, options)\n }),\n )\n }\n\n private async compilePropertiesTypes(options: {\n properties: Record<string, LexiconArray | LexiconArrayItems>\n required?: readonly string[]\n nullable?: readonly string[]\n }) {\n return Promise.all(\n Object.entries(options.properties).map((entry) => {\n return this.compilePropertyEntryType(entry, options)\n }),\n )\n }\n\n private async compilePropertyEntrySchema(\n [key, def]: [string, LexiconArray | LexiconArrayItems],\n options: {\n required?: readonly string[]\n nullable?: readonly string[]\n },\n ) {\n const isNullable = options.nullable?.includes(key)\n const isRequired = options.required?.includes(key)\n\n let schema = await this.compileContainedSchema(def)\n\n if (isNullable) {\n schema = this.pure(`l.nullable(${schema})`)\n }\n\n if (!isRequired) {\n schema = this.pure(`l.optional(${schema})`)\n }\n\n return `${JSON.stringify(key)}:${schema}`\n }\n\n private async compilePropertyEntryType(\n [key, def]: [string, LexiconArray | LexiconArrayItems],\n options: {\n required?: readonly string[]\n nullable?: readonly string[]\n },\n ) {\n const isNullable = options.nullable?.includes(key)\n const isRequired = options.required?.includes(key)\n\n const optional = isRequired ? '' : '?'\n const append = isNullable ? ' | null' : ''\n\n const jsDoc = compileLeadingTrivia(def.description) || ''\n const name = JSON.stringify(key)\n const type = await this.compileContainedType(def)\n\n return `${jsDoc}${name}${optional}:${type}${append}`\n }\n\n private async compileContainedSchema(\n def: LexiconArray | LexiconArrayItems,\n ): Promise<string> {\n switch (def.type) {\n case 'unknown':\n return this.compileUnknownSchema(def)\n case 'boolean':\n return this.compileBooleanSchema(def)\n case 'integer':\n return this.compileIntegerSchema(def)\n case 'string':\n return this.compileStringSchema(def)\n case 'bytes':\n return this.compileBytesSchema(def)\n case 'blob':\n return this.compileBlobSchema(def)\n case 'cid-link':\n return this.compileCidLinkSchema(def)\n case 'ref':\n return this.compileRefSchema(def)\n case 'union':\n return this.compileRefUnionSchema(def)\n case 'array':\n return this.compileArraySchema(def)\n default:\n // @ts-expect-error\n throw new Error(`Unsupported def type: ${def.type}`)\n }\n }\n\n private async compileContainedType(\n def: LexiconArray | LexiconArrayItems,\n ): Promise<string> {\n switch (def.type) {\n case 'unknown':\n return this.compileUnknownType(def)\n case 'boolean':\n return this.compileBooleanType(def)\n case 'integer':\n return this.compileIntegerType(def)\n case 'string':\n return this.compileStringType(def)\n case 'bytes':\n return this.compileBytesType(def)\n case 'blob':\n return this.compileBlobType(def)\n case 'cid-link':\n return this.compileCidLinkType(def)\n case 'ref':\n return this.compileRefType(def)\n case 'union':\n return this.compileRefUnionType(def)\n case 'array':\n return this.compileArrayType(def)\n default:\n // @ts-expect-error\n throw new Error(`Unsupported def type: ${def.type}`)\n }\n }\n\n private async compileArraySchema(def: LexiconArray): Promise<string> {\n const itemSchema = await this.compileContainedSchema(def.items)\n const options = stringifyOptions(def, [\n 'minLength',\n 'maxLength',\n ] satisfies (keyof l.ArraySchemaOptions)[])\n return this.pure(`l.array(${itemSchema}, ${options})`)\n }\n\n private async compileArrayType(def: LexiconArray): Promise<string> {\n return `(${await this.compileContainedType(def.items)})[]`\n }\n\n private async compileUnknownSchema(_def: LexiconUnknown): Promise<string> {\n return this.pure(`l.unknownObject()`)\n }\n\n private async compileUnknownType(_def: LexiconUnknown): Promise<string> {\n return `l.UnknownObject`\n }\n\n private async compileBooleanSchema(def: LexiconBoolean): Promise<string> {\n if (hasConst(def)) return this.compileConstSchema(def)\n\n const options = stringifyOptions(def, [\n 'default',\n ] satisfies (keyof l.BooleanSchemaOptions)[])\n return this.pure(`l.boolean(${options})`)\n }\n\n private async compileBooleanType(def: LexiconBoolean): Promise<string> {\n if (hasConst(def)) return this.compileConstType(def)\n return 'boolean'\n }\n\n private async compileIntegerSchema(def: LexiconInteger): Promise<string> {\n if (hasConst(def)) {\n const schema: l.IntegerSchema = l.integer(def)\n schema.assert(def.const)\n }\n\n if (hasEnum(def)) {\n const schema: l.IntegerSchema = l.integer(def)\n for (const val of def.enum) schema.assert(val)\n }\n\n if (hasConst(def)) return this.compileConstSchema(def)\n if (hasEnum(def)) return this.compileEnumSchema(def)\n\n const options = stringifyOptions(def, [\n 'default',\n 'maximum',\n 'minimum',\n ] satisfies (keyof l.IntegerSchemaOptions)[])\n return this.pure(`l.integer(${options})`)\n }\n\n private async compileIntegerType(def: LexiconInteger): Promise<string> {\n if (hasConst(def)) return this.compileConstType(def)\n if (hasEnum(def)) return this.compileEnumType(def)\n\n return 'number'\n }\n\n private async compileStringSchema(def: LexiconString): Promise<string> {\n if (hasConst(def)) {\n const schema: l.StringSchema = l.string(def)\n schema.assert(def.const)\n } else if (hasEnum(def)) {\n const schema: l.StringSchema = l.string(def)\n for (const val of def.enum) schema.assert(val)\n }\n\n if (hasConst(def)) return this.compileConstSchema(def)\n if (hasEnum(def)) return this.compileEnumSchema(def)\n\n const options = stringifyOptions(def, [\n 'default',\n 'format',\n 'maxGraphemes',\n 'minGraphemes',\n 'maxLength',\n 'minLength',\n ] satisfies (keyof l.StringSchemaOptions)[])\n return this.pure(`l.string(${options})`)\n }\n\n private async compileStringType(def: LexiconString): Promise<string> {\n if (hasConst(def)) return this.compileConstType(def)\n if (hasEnum(def)) return this.compileEnumType(def)\n\n switch (def.format) {\n case undefined:\n break\n case 'datetime':\n return 'l.DatetimeString'\n case 'uri':\n return 'l.UriString'\n case 'at-uri':\n return 'l.AtUriString'\n case 'did':\n return 'l.DidString'\n case 'handle':\n return 'l.HandleString'\n case 'at-identifier':\n return 'l.AtIdentifierString'\n case 'nsid':\n return 'l.NsidString'\n case 'tid':\n return 'l.TidString'\n case 'cid':\n return 'l.CidString'\n case 'language':\n return 'l.LanguageString'\n case 'record-key':\n return 'l.RecordKeyString'\n default:\n throw new Error(`Unknown string format: ${def.format}`)\n }\n\n if (def.knownValues?.length) {\n return (\n def.knownValues.map((v) => JSON.stringify(v)).join(' | ') +\n ' | l.UnknownString'\n )\n }\n\n return 'string'\n }\n\n private async compileBytesSchema(def: LexiconBytes): Promise<string> {\n const options = stringifyOptions(def, [\n 'minLength',\n 'maxLength',\n ] satisfies (keyof l.BytesSchemaOptions)[])\n return this.pure(`l.bytes(${options})`)\n }\n\n private async compileBytesType(_def: LexiconBytes): Promise<string> {\n return 'Uint8Array'\n }\n\n private async compileBlobSchema(def: LexiconBlob): Promise<string> {\n const opts = { ...def, allowLegacy: this.options.allowLegacyBlobs === true }\n const options = stringifyOptions(opts, [\n 'maxSize',\n 'accept',\n 'allowLegacy',\n ] satisfies (keyof l.BlobSchemaOptions)[])\n return this.pure(`l.blob(${options})`)\n }\n\n private async compileBlobType(_def: LexiconBlob): Promise<string> {\n return this.options.allowLegacyBlobs\n ? 'l.BlobRef | l.LegacyBlobRef'\n : 'l.BlobRef'\n }\n\n private async compileCidLinkSchema(_def: LexiconCid): Promise<string> {\n return this.pure(`l.cidLink()`)\n }\n\n private async compileCidLinkType(_def: LexiconCid): Promise<string> {\n return 'l.Cid'\n }\n\n private async compileRefSchema(def: LexiconRef): Promise<string> {\n const { varName, typeName } = await this.refResolver.resolve(def.ref)\n // @NOTE \"as any\" is needed in schemas with circular refs as TypeScript\n // cannot infer the type of a value that depends on its initializer type\n return this.pure(`l.ref<${typeName}>((() => ${varName}) as any)`)\n }\n\n private async compileRefType(def: LexiconRef): Promise<string> {\n const ref = await this.refResolver.resolve(def.ref)\n return ref.typeName\n }\n\n private async compileRefUnionSchema(def: LexiconRefUnion): Promise<string> {\n if (def.refs.length === 0 && def.closed) {\n return this.pure(`l.never()`)\n }\n\n const refs = await Promise.all(\n def.refs.map(async (ref: string) => {\n const { varName, typeName } = await this.refResolver.resolve(ref)\n // @NOTE \"as any\" is needed in schemas with circular refs as TypeScript\n // cannot infer the type of a value that depends on its initializer type\n return this.pure(`l.typedRef<${typeName}>((() => ${varName}) as any)`)\n }),\n )\n\n return this.pure(\n `l.typedUnion([${refs.join(',')}], ${def.closed ?? false})`,\n )\n }\n\n private async compileRefUnionType(def: LexiconRefUnion): Promise<string> {\n const types = await Promise.all(\n def.refs.map(async (ref) => {\n const { typeName } = await this.refResolver.resolve(ref)\n return `l.TypedRef<${typeName}>`\n }),\n )\n if (!def.closed) types.push('l.TypedObject')\n return types.join(' | ') || 'never'\n }\n\n private async compileConstSchema<\n T extends null | number | string | boolean,\n >(def: { const: T; enum?: readonly T[]; default?: T }): Promise<string> {\n if (hasEnum(def) && !def.enum.includes(def.const)) {\n return this.pure(`l.never()`)\n }\n\n const options = stringifyOptions(def, [\n 'default',\n ] satisfies (keyof l.LiteralSchemaOptions<any>)[])\n return this.pure(`l.literal(${JSON.stringify(def.const)}, ${options})`)\n }\n\n private async compileConstType<\n T extends null | number | string | boolean,\n >(def: { const: T; enum?: readonly T[] }): Promise<string> {\n if (hasEnum(def) && !def.enum.includes(def.const)) {\n return 'never'\n }\n return JSON.stringify(def.const)\n }\n\n private async compileEnumSchema<T extends null | number | string>(def: {\n enum: readonly T[]\n default?: T\n }): Promise<string> {\n if (def.enum.length === 0) {\n return this.pure(`l.never()`)\n }\n if (def.enum.length === 1 && def.default === undefined) {\n return this.pure(`l.literal(${JSON.stringify(def.enum[0])})`)\n }\n const options = stringifyOptions(def, [\n 'default',\n ] satisfies (keyof l.EnumSchemaOptions<any>)[])\n return this.pure(`l.enum(${JSON.stringify(def.enum)}, ${options})`)\n }\n\n private async compileEnumType<T extends null | number | string>(def: {\n enum: readonly T[]\n }): Promise<string> {\n return def.enum.map((v) => JSON.stringify(v)).join(' | ') || 'never'\n }\n}\n\ntype ParsedDescription = OptionalKind<JSDocStructure> & {\n description?: string\n tags?: { tagName: string; text?: string }[]\n}\n\nfunction parseDescription(description: string): ParsedDescription {\n if (/deprecated/i.test(description)) {\n const deprecationMatch = description.match(\n /(\\s*deprecated\\s*(?:--?|:)?\\s*([^-]*)(?:-+)?)/i,\n )\n if (deprecationMatch) {\n const { 1: match, 2: deprecationNotice } = deprecationMatch\n return {\n description: description.replace(match, '').trim() || undefined,\n tags: [{ tagName: 'deprecated', text: deprecationNotice?.trim() }],\n }\n } else {\n return {\n description: description.trim() || undefined,\n tags: [{ tagName: 'deprecated' }],\n }\n }\n }\n\n return {\n description: description.trim() || undefined,\n }\n}\n\nfunction compileLeadingTrivia(description?: string) {\n if (!description) return undefined\n const parsed = parseDescription(description)\n if (!parsed.description && !parsed.tags?.length) return undefined\n const tags = parsed.tags\n ?.map(({ tagName, text }) => (text ? `@${tagName} ${text}` : `@${tagName}`))\n ?.join('\\n')\n const text = `\\n${[parsed.description, tags].filter(Boolean).join('\\n\\n')}`\n return `\\n\\n/**${text.replaceAll('\\n', '\\n * ')}\\n */\\n`\n}\n\nfunction compileDocs(description?: string) {\n if (!description) return undefined\n return [parseDescription(description)]\n}\n\nfunction stringifyOptions<O extends Record<string, unknown>>(\n obj: O,\n include?: (keyof O)[],\n exclude?: (keyof O)[],\n) {\n const filtered = Object.entries(obj).filter(\n ([k]) => (!include || include.includes(k)) && !exclude?.includes(k),\n )\n return filtered.length ? JSON.stringify(Object.fromEntries(filtered)) : ''\n}\n\nfunction hasConst<T extends { const?: unknown }>(\n def: T,\n): def is T & { const: NonNullable<T['const']> } {\n return def.const != null\n}\n\nfunction hasEnum<T extends { enum?: readonly unknown[] }>(\n def: T,\n): def is T & { enum: unknown[] } {\n return def.enum != null\n}\n\nfunction markPure<T extends string>(v: T): `/*#__PURE__*/ ${T}` {\n return `/*#__PURE__*/ ${v}`\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"ref-resolver.d.ts","sourceRoot":"","sources":["../src/ref-resolver.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAA;AACrC,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AAUvE,MAAM,MAAM,kBAAkB,GAAG;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB,CAAA;AAED,MAAM,MAAM,WAAW,GAAG;IACxB,OAAO,EAAE,MAAM,CAAA;IACf,QAAQ,EAAE,MAAM,CAAA;CACjB,CAAA;AAED;;;GAGG;AACH,qBAAa,WAAW;;IAEpB,OAAO,CAAC,GAAG;IACX,OAAO,CAAC,IAAI;IACZ,OAAO,CAAC,OAAO;IACf,OAAO,CAAC,OAAO;gBAHP,GAAG,EAAE,eAAe,EACpB,IAAI,EAAE,UAAU,EAChB,OAAO,EAAE,cAAc,EACvB,OAAO,EAAE,kBAAkB;IAGrC,SAAgB,OAAO,QACT,MAAM,KAAG,OAAO,CAAC,WAAW,CAAC,CAW1C;IAGD,OAAO,CAAC,4BAA4B;IASpC;;;OAGG;IACH,SAAgB,YAAY,SACb,MAAM,KAAG,OAAO,CAAC,WAAW,CAAC,CAsD3C;IAED;;;;;OAKG;IACH,OAAO,CAAC,QAAQ,CAAC,eAAe,CA6B/B;IAED,OAAO,CAAC,eAAe;IAiBvB,OAAO,CAAC,iCAAiC;IAazC,OAAO,CAAC,uBAAuB;IAU/B,OAAO,CAAC,qBAAqB;IAI7B,OAAO,CAAC,kBAAkB;IAc1B,OAAO,CAAC,sBAAsB;IAkB9B,OAAO,CAAC,8BAA8B;IActC,OAAO,CAAC,oBAAoB;CAe7B;AAoBD;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,CAU9D"}
1
+ {"version":3,"file":"ref-resolver.d.ts","sourceRoot":"","sources":["../src/ref-resolver.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAA;AACrC,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AAWvE,MAAM,MAAM,kBAAkB,GAAG;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB,CAAA;AAED,MAAM,MAAM,WAAW,GAAG;IACxB,OAAO,EAAE,MAAM,CAAA;IACf,QAAQ,EAAE,MAAM,CAAA;CACjB,CAAA;AAED;;;GAGG;AACH,qBAAa,WAAW;;IAEpB,OAAO,CAAC,GAAG;IACX,OAAO,CAAC,IAAI;IACZ,OAAO,CAAC,OAAO;IACf,OAAO,CAAC,OAAO;gBAHP,GAAG,EAAE,eAAe,EACpB,IAAI,EAAE,UAAU,EAChB,OAAO,EAAE,cAAc,EACvB,OAAO,EAAE,kBAAkB;IAGrC,SAAgB,OAAO,QACT,MAAM,KAAG,OAAO,CAAC,WAAW,CAAC,CAW1C;IAGD,OAAO,CAAC,4BAA4B;IASpC;;;OAGG;IACH,SAAgB,YAAY,SACb,MAAM,KAAG,OAAO,CAAC,WAAW,CAAC,CAsD3C;IAED;;;;;OAKG;IACH,OAAO,CAAC,QAAQ,CAAC,eAAe,CA6B/B;IAED,OAAO,CAAC,eAAe;IAiBvB,OAAO,CAAC,iCAAiC;IAazC,OAAO,CAAC,uBAAuB;IAU/B,OAAO,CAAC,qBAAqB;IAI7B,OAAO,CAAC,kBAAkB;IAc1B,OAAO,CAAC,sBAAsB;IAkB9B,OAAO,CAAC,8BAA8B;IActC,OAAO,CAAC,oBAAoB;CAe7B;AAoBD;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,CAU9D"}
@@ -238,11 +238,15 @@ function getPublicIdentifiers(hash) {
238
238
  return { varName, typeName };
239
239
  }
240
240
  function asSafeDefinitionIdentifier(name) {
241
- if ((0, ts_lang_js_1.isSafeIdentifier)(name) && (0, ts_lang_js_1.isSafeIdentifier)((0, util_js_1.ucFirst)(name)))
241
+ if ((0, util_js_1.startsWithLowerLetter)(name) &&
242
+ (0, ts_lang_js_1.isSafeIdentifier)(name) &&
243
+ (0, ts_lang_js_1.isSafeIdentifier)((0, util_js_1.ucFirst)(name))) {
242
244
  return name;
245
+ }
243
246
  const camel = (0, util_js_1.toCamelCase)(name);
244
- if ((0, ts_lang_js_1.isSafeIdentifier)(camel) && (0, ts_lang_js_1.isSafeIdentifier)((0, util_js_1.ucFirst)(camel)))
247
+ if ((0, ts_lang_js_1.isSafeIdentifier)(camel) && (0, ts_lang_js_1.isSafeIdentifier)((0, util_js_1.ucFirst)(camel))) {
245
248
  return camel;
249
+ }
246
250
  return undefined;
247
251
  }
248
252
  //# sourceMappingURL=ref-resolver.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ref-resolver.js","sourceRoot":"","sources":["../src/ref-resolver.ts"],"names":[],"mappings":"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","sourcesContent":["import assert from 'node:assert'\nimport { join } from 'node:path'\nimport { SourceFile } from 'ts-morph'\nimport { LexiconDocument, LexiconIndexer } from '@atproto/lex-document'\nimport { isReservedWord, isSafeIdentifier } from './ts-lang.js'\nimport {\n asRelativePath,\n memoize,\n toCamelCase,\n toPascalCase,\n ucFirst,\n} from './util.js'\n\nexport type RefResolverOptions = {\n importExt?: string\n}\n\nexport type ResolvedRef = {\n varName: string\n typeName: string\n}\n\n/**\n * Utility class to resolve lexicon references to TypeScript identifiers,\n * generating \"import\" statements as needed.\n */\nexport class RefResolver {\n constructor(\n private doc: LexiconDocument,\n private file: SourceFile,\n private indexer: LexiconIndexer,\n private options: RefResolverOptions,\n ) {}\n\n public readonly resolve = memoize(\n async (ref: string): Promise<ResolvedRef> => {\n const [nsid, hash = 'main'] = ref.split('#')\n\n if (nsid === '' || nsid === this.doc.id) {\n return this.resolveLocal(hash)\n } else {\n // @NOTE: Normalize (#main fragment) to ensure proper memoization\n const fullRef = `${nsid}#${hash}`\n return this.resolveExternal(fullRef)\n }\n },\n )\n\n #defCounters = new Map<string, number>()\n private nextSafeDefinitionIdentifier(safeIdentifier: string) {\n const count = this.#defCounters.get(safeIdentifier) ?? 0\n this.#defCounters.set(safeIdentifier, count + 1)\n // @NOTE We don't need to check against local declarations in the file here\n // since we are using a naming system that should guarantee no other\n // identifier has a <safeIdentifier>$<number> format.\n return `${safeIdentifier}$${count}`\n }\n\n /**\n * @note The returned `typeName` and `varName` are *both* guaranteed to be\n * valid TypeScript identifiers.\n */\n public readonly resolveLocal = memoize(\n async (hash: string): Promise<ResolvedRef> => {\n const hashes = Object.keys(this.doc.defs)\n\n if (!hashes.includes(hash)) {\n throw new Error(`Definition ${hash} not found in ${this.doc.id}`)\n }\n\n // Because we are using predictable \"public\" identifiers for type names,\n // we need to ensure there are no conflicts between different definitions\n // in the same lexicon document.\n //\n // @NOTE It should be possible to implement a way to generate\n // non-conflicting type names for all public (type) identifiers in a\n // project. However, this would add a lot of complexity to the code\n // generation process, and the likelihood of such conflicts happening in\n // practice is very low, so we opt for a simpler approach of just throwing\n // an error if a conflict is detected.\n const pub = getPublicIdentifiers(hash)\n for (const otherHash of hashes) {\n if (otherHash === hash) continue\n const otherPub = getPublicIdentifiers(otherHash)\n if (otherPub.typeName === pub.typeName) {\n throw new Error(\n `Conflicting type names for definitions #${hash} and #${otherHash} in ${this.doc.id}`,\n )\n }\n }\n\n // Try to keep and identifier that resembles the original hash as identifier\n const safeIdentifier = asSafeDefinitionIdentifier(hash)\n\n // If the safe identifier is not conflicting with other definition names,\n // or reserved words, we can use it as-is. Otherwise, we need to generate\n // a unique safe identifier.\n const varName = safeIdentifier\n ? !hashes.some((otherHash) => {\n if (otherHash === hash) return false\n const otherIdentifier = asSafeDefinitionIdentifier(otherHash)\n return otherIdentifier === safeIdentifier\n })\n ? // Safe identifier can be used as-is as it does not conflict with\n // other definition names\n safeIdentifier\n : // In order to keep identifiers stable, we use the safe identifier\n // as base, and append a counter to avoid conflicts\n this.nextSafeDefinitionIdentifier(safeIdentifier)\n : // hash only contained unsafe characters, generate a safe one\n this.nextSafeDefinitionIdentifier('def')\n\n const typeName = ucFirst(varName)\n assert(varName !== typeName, 'Variable and type name should be different')\n\n return { varName, typeName }\n },\n )\n\n /**\n * @note Since this is a memoized function, and is used to generate the name\n * of local variables, we should avoid returning different results for\n * similar, but non strictly equal, inputs (eg. normalized / non-normalized).\n * @see {@link resolve}\n */\n private readonly resolveExternal = memoize(\n async (fullRef: string): Promise<ResolvedRef> => {\n const [nsid, hash] = fullRef.split('#')\n const moduleSpecifier = `${asRelativePath(\n this.file.getDirectoryPath(),\n join('/', ...nsid.split('.')),\n )}.defs${this.options.importExt ?? '.js'}`\n\n // Lets first make sure the referenced lexicon exists\n const srcDoc = await this.indexer.get(nsid)\n const srcDef = Object.hasOwn(srcDoc.defs, hash) ? srcDoc.defs[hash] : null\n if (!srcDef) {\n throw new Error(\n `Missing def \"${hash}\" in \"${nsid}\" (referenced from ${this.doc.id})`,\n )\n }\n\n // import * as <nsIdentifier> from './<moduleSpecifier>'\n const nsIdentifier = this.getNsIdentifier(nsid, moduleSpecifier)\n\n const publicIds = getPublicIdentifiers(hash)\n\n return {\n varName: isSafeIdentifier(publicIds.varName)\n ? `${nsIdentifier}.${publicIds.varName}`\n : `${nsIdentifier}[${JSON.stringify(publicIds.varName)}]`,\n typeName: `${nsIdentifier}.${publicIds.typeName}`,\n }\n },\n )\n\n private getNsIdentifier(nsid: string, moduleSpecifier: string) {\n const namespaceImportDeclaration =\n this.file.getImportDeclaration(\n (imp) =>\n !imp.isTypeOnly() &&\n imp.getModuleSpecifierValue() === moduleSpecifier &&\n imp.getNamespaceImport() != null,\n ) ||\n this.file.addImportDeclaration({\n moduleSpecifier,\n namespaceImport: this.computeSafeNamespaceIdentifierFor(nsid),\n })\n\n return namespaceImportDeclaration.getNamespaceImport()!.getText()\n }\n\n #nsIdentifiersCounters = new Map<string, number>()\n private computeSafeNamespaceIdentifierFor(nsid: string) {\n const baseName = nsidToIdentifier(nsid) || 'NS'\n\n let name = baseName\n while (this.isConflictingIdentifier(name)) {\n const count = this.#nsIdentifiersCounters.get(baseName) ?? 0\n this.#nsIdentifiersCounters.set(baseName, count + 1)\n name = `${baseName}$$${count}`\n }\n\n return name\n }\n\n private isConflictingIdentifier(name: string) {\n return (\n this.conflictsWithKeywords(name) ||\n this.conflictsWithUtils(name) ||\n this.conflictsWithLocalDefs(name) ||\n this.conflictsWithLocalDeclarations(name) ||\n this.conflictsWithImports(name)\n )\n }\n\n private conflictsWithKeywords(name: string) {\n return isReservedWord(name)\n }\n\n private conflictsWithUtils(name: string) {\n // Do not allow \"Main\" as imported ns identifier since it has a special\n // meaning in the context of lexicon definitions.\n if (name === 'Main') return true\n\n // When \"useRecordExport\" returns true, an export named \"Record\" will be\n // used in addition to the hash named export. So we need to make sure both\n // names are not conflicting with local variables.\n if (name === 'Record') return true\n\n // Utility functions generated for lexicon schemas are prefixed with \"$\"\n return name.startsWith('$')\n }\n\n private conflictsWithLocalDefs(name: string) {\n return Object.keys(this.doc.defs).some((hash) => {\n const identifier = toCamelCase(hash)\n\n // A safe identifier will be generated, no risk of conflict.\n if (!identifier) return false\n\n // The imported name conflicts with a local definition name\n if (identifier === name || `_${identifier}` === name) return true\n\n // The imported name conflicts with the type name of a local definition\n const typeName = ucFirst(identifier)\n if (typeName === name || `_${typeName}` === name) return true\n\n return false\n })\n }\n\n private conflictsWithLocalDeclarations(name: string) {\n return (\n this.file.getVariableDeclarations().some((v) => v.getName() === name) ||\n this.file\n .getVariableStatements()\n .some((vs) => vs.getDeclarations().some((d) => d.getName() === name)) ||\n this.file.getTypeAliases().some((t) => t.getName() === name) ||\n this.file.getInterfaces().some((i) => i.getName() === name) ||\n this.file.getClasses().some((c) => c.getName() === name) ||\n this.file.getFunctions().some((f) => f.getName() === name) ||\n this.file.getEnums().some((e) => e.getName() === name)\n )\n }\n\n private conflictsWithImports(name: string) {\n return this.file.getImportDeclarations().some(\n (imp) =>\n // import name from '...'\n imp.getDefaultImport()?.getText() === name ||\n // import * as name from '...'\n imp.getNamespaceImport()?.getText() === name ||\n imp.getNamedImports().some(\n (named) =>\n // import { name } from '...'\n // import { foo as name } from '...'\n (named.getAliasNode()?.getText() ?? named.getName()) === name,\n ),\n )\n }\n}\n\n/**\n * @see {@link https://atproto.com/specs/nsid NSID syntax spec}\n */\nfunction nsidToIdentifier(nsid: string) {\n const parts = nsid.split('.')\n\n // By default, try to keep only to the last two segments of the NSID as\n // contextual information. If those do not form a safe identifier (typically\n // because they start with a digit), try with more segments until we reach the\n // full NSID.\n for (let i = 2; i < parts.length; i++) {\n const identifier = toPascalCase(parts.slice(-i).join('.'))\n if (isSafeIdentifier(identifier)) return identifier\n }\n\n return undefined\n}\n\n/**\n * Generates predictable public identifiers for a given definition hash.\n *\n * @note The returned `typeName` is guaranteed to be a valid TypeScript\n * identifier. `varName` may not be a valid identifier (eg. if the hash contains\n * unsafe characters), and may need to be accessed using string indexing.\n */\nexport function getPublicIdentifiers(hash: string): ResolvedRef {\n const varName = hash\n // @NOTE Type names *must* be valid TypeScript identifiers (this is because,\n // unlike variable names, we cannot use string indexing to access exported\n // types).\n const typeName = toPascalCase(hash)\n if (!typeName || varName === typeName || !isSafeIdentifier(typeName)) {\n return { varName, typeName: `Def${typeName}` }\n }\n return { varName, typeName }\n}\n\nfunction asSafeDefinitionIdentifier(name: string) {\n if (isSafeIdentifier(name) && isSafeIdentifier(ucFirst(name))) return name\n const camel = toCamelCase(name)\n if (isSafeIdentifier(camel) && isSafeIdentifier(ucFirst(camel))) return camel\n return undefined\n}\n"]}
1
+ {"version":3,"file":"ref-resolver.js","sourceRoot":"","sources":["../src/ref-resolver.ts"],"names":[],"mappings":"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","sourcesContent":["import assert from 'node:assert'\nimport { join } from 'node:path'\nimport { SourceFile } from 'ts-morph'\nimport { LexiconDocument, LexiconIndexer } from '@atproto/lex-document'\nimport { isReservedWord, isSafeIdentifier } from './ts-lang.js'\nimport {\n asRelativePath,\n memoize,\n startsWithLowerLetter,\n toCamelCase,\n toPascalCase,\n ucFirst,\n} from './util.js'\n\nexport type RefResolverOptions = {\n importExt?: string\n}\n\nexport type ResolvedRef = {\n varName: string\n typeName: string\n}\n\n/**\n * Utility class to resolve lexicon references to TypeScript identifiers,\n * generating \"import\" statements as needed.\n */\nexport class RefResolver {\n constructor(\n private doc: LexiconDocument,\n private file: SourceFile,\n private indexer: LexiconIndexer,\n private options: RefResolverOptions,\n ) {}\n\n public readonly resolve = memoize(\n async (ref: string): Promise<ResolvedRef> => {\n const [nsid, hash = 'main'] = ref.split('#')\n\n if (nsid === '' || nsid === this.doc.id) {\n return this.resolveLocal(hash)\n } else {\n // @NOTE: Normalize (#main fragment) to ensure proper memoization\n const fullRef = `${nsid}#${hash}`\n return this.resolveExternal(fullRef)\n }\n },\n )\n\n #defCounters = new Map<string, number>()\n private nextSafeDefinitionIdentifier(safeIdentifier: string) {\n const count = this.#defCounters.get(safeIdentifier) ?? 0\n this.#defCounters.set(safeIdentifier, count + 1)\n // @NOTE We don't need to check against local declarations in the file here\n // since we are using a naming system that should guarantee no other\n // identifier has a <safeIdentifier>$<number> format.\n return `${safeIdentifier}$${count}`\n }\n\n /**\n * @note The returned `typeName` and `varName` are *both* guaranteed to be\n * valid TypeScript identifiers.\n */\n public readonly resolveLocal = memoize(\n async (hash: string): Promise<ResolvedRef> => {\n const hashes = Object.keys(this.doc.defs)\n\n if (!hashes.includes(hash)) {\n throw new Error(`Definition ${hash} not found in ${this.doc.id}`)\n }\n\n // Because we are using predictable \"public\" identifiers for type names,\n // we need to ensure there are no conflicts between different definitions\n // in the same lexicon document.\n //\n // @NOTE It should be possible to implement a way to generate\n // non-conflicting type names for all public (type) identifiers in a\n // project. However, this would add a lot of complexity to the code\n // generation process, and the likelihood of such conflicts happening in\n // practice is very low, so we opt for a simpler approach of just throwing\n // an error if a conflict is detected.\n const pub = getPublicIdentifiers(hash)\n for (const otherHash of hashes) {\n if (otherHash === hash) continue\n const otherPub = getPublicIdentifiers(otherHash)\n if (otherPub.typeName === pub.typeName) {\n throw new Error(\n `Conflicting type names for definitions #${hash} and #${otherHash} in ${this.doc.id}`,\n )\n }\n }\n\n // Try to keep and identifier that resembles the original hash as identifier\n const safeIdentifier = asSafeDefinitionIdentifier(hash)\n\n // If the safe identifier is not conflicting with other definition names,\n // or reserved words, we can use it as-is. Otherwise, we need to generate\n // a unique safe identifier.\n const varName = safeIdentifier\n ? !hashes.some((otherHash) => {\n if (otherHash === hash) return false\n const otherIdentifier = asSafeDefinitionIdentifier(otherHash)\n return otherIdentifier === safeIdentifier\n })\n ? // Safe identifier can be used as-is as it does not conflict with\n // other definition names\n safeIdentifier\n : // In order to keep identifiers stable, we use the safe identifier\n // as base, and append a counter to avoid conflicts\n this.nextSafeDefinitionIdentifier(safeIdentifier)\n : // hash only contained unsafe characters, generate a safe one\n this.nextSafeDefinitionIdentifier('def')\n\n const typeName = ucFirst(varName)\n assert(varName !== typeName, 'Variable and type name should be different')\n\n return { varName, typeName }\n },\n )\n\n /**\n * @note Since this is a memoized function, and is used to generate the name\n * of local variables, we should avoid returning different results for\n * similar, but non strictly equal, inputs (eg. normalized / non-normalized).\n * @see {@link resolve}\n */\n private readonly resolveExternal = memoize(\n async (fullRef: string): Promise<ResolvedRef> => {\n const [nsid, hash] = fullRef.split('#')\n const moduleSpecifier = `${asRelativePath(\n this.file.getDirectoryPath(),\n join('/', ...nsid.split('.')),\n )}.defs${this.options.importExt ?? '.js'}`\n\n // Lets first make sure the referenced lexicon exists\n const srcDoc = await this.indexer.get(nsid)\n const srcDef = Object.hasOwn(srcDoc.defs, hash) ? srcDoc.defs[hash] : null\n if (!srcDef) {\n throw new Error(\n `Missing def \"${hash}\" in \"${nsid}\" (referenced from ${this.doc.id})`,\n )\n }\n\n // import * as <nsIdentifier> from './<moduleSpecifier>'\n const nsIdentifier = this.getNsIdentifier(nsid, moduleSpecifier)\n\n const publicIds = getPublicIdentifiers(hash)\n\n return {\n varName: isSafeIdentifier(publicIds.varName)\n ? `${nsIdentifier}.${publicIds.varName}`\n : `${nsIdentifier}[${JSON.stringify(publicIds.varName)}]`,\n typeName: `${nsIdentifier}.${publicIds.typeName}`,\n }\n },\n )\n\n private getNsIdentifier(nsid: string, moduleSpecifier: string) {\n const namespaceImportDeclaration =\n this.file.getImportDeclaration(\n (imp) =>\n !imp.isTypeOnly() &&\n imp.getModuleSpecifierValue() === moduleSpecifier &&\n imp.getNamespaceImport() != null,\n ) ||\n this.file.addImportDeclaration({\n moduleSpecifier,\n namespaceImport: this.computeSafeNamespaceIdentifierFor(nsid),\n })\n\n return namespaceImportDeclaration.getNamespaceImport()!.getText()\n }\n\n #nsIdentifiersCounters = new Map<string, number>()\n private computeSafeNamespaceIdentifierFor(nsid: string) {\n const baseName = nsidToIdentifier(nsid) || 'NS'\n\n let name = baseName\n while (this.isConflictingIdentifier(name)) {\n const count = this.#nsIdentifiersCounters.get(baseName) ?? 0\n this.#nsIdentifiersCounters.set(baseName, count + 1)\n name = `${baseName}$$${count}`\n }\n\n return name\n }\n\n private isConflictingIdentifier(name: string) {\n return (\n this.conflictsWithKeywords(name) ||\n this.conflictsWithUtils(name) ||\n this.conflictsWithLocalDefs(name) ||\n this.conflictsWithLocalDeclarations(name) ||\n this.conflictsWithImports(name)\n )\n }\n\n private conflictsWithKeywords(name: string) {\n return isReservedWord(name)\n }\n\n private conflictsWithUtils(name: string) {\n // Do not allow \"Main\" as imported ns identifier since it has a special\n // meaning in the context of lexicon definitions.\n if (name === 'Main') return true\n\n // When \"useRecordExport\" returns true, an export named \"Record\" will be\n // used in addition to the hash named export. So we need to make sure both\n // names are not conflicting with local variables.\n if (name === 'Record') return true\n\n // Utility functions generated for lexicon schemas are prefixed with \"$\"\n return name.startsWith('$')\n }\n\n private conflictsWithLocalDefs(name: string) {\n return Object.keys(this.doc.defs).some((hash) => {\n const identifier = toCamelCase(hash)\n\n // A safe identifier will be generated, no risk of conflict.\n if (!identifier) return false\n\n // The imported name conflicts with a local definition name\n if (identifier === name || `_${identifier}` === name) return true\n\n // The imported name conflicts with the type name of a local definition\n const typeName = ucFirst(identifier)\n if (typeName === name || `_${typeName}` === name) return true\n\n return false\n })\n }\n\n private conflictsWithLocalDeclarations(name: string) {\n return (\n this.file.getVariableDeclarations().some((v) => v.getName() === name) ||\n this.file\n .getVariableStatements()\n .some((vs) => vs.getDeclarations().some((d) => d.getName() === name)) ||\n this.file.getTypeAliases().some((t) => t.getName() === name) ||\n this.file.getInterfaces().some((i) => i.getName() === name) ||\n this.file.getClasses().some((c) => c.getName() === name) ||\n this.file.getFunctions().some((f) => f.getName() === name) ||\n this.file.getEnums().some((e) => e.getName() === name)\n )\n }\n\n private conflictsWithImports(name: string) {\n return this.file.getImportDeclarations().some(\n (imp) =>\n // import name from '...'\n imp.getDefaultImport()?.getText() === name ||\n // import * as name from '...'\n imp.getNamespaceImport()?.getText() === name ||\n imp.getNamedImports().some(\n (named) =>\n // import { name } from '...'\n // import { foo as name } from '...'\n (named.getAliasNode()?.getText() ?? named.getName()) === name,\n ),\n )\n }\n}\n\n/**\n * @see {@link https://atproto.com/specs/nsid NSID syntax spec}\n */\nfunction nsidToIdentifier(nsid: string) {\n const parts = nsid.split('.')\n\n // By default, try to keep only to the last two segments of the NSID as\n // contextual information. If those do not form a safe identifier (typically\n // because they start with a digit), try with more segments until we reach the\n // full NSID.\n for (let i = 2; i < parts.length; i++) {\n const identifier = toPascalCase(parts.slice(-i).join('.'))\n if (isSafeIdentifier(identifier)) return identifier\n }\n\n return undefined\n}\n\n/**\n * Generates predictable public identifiers for a given definition hash.\n *\n * @note The returned `typeName` is guaranteed to be a valid TypeScript\n * identifier. `varName` may not be a valid identifier (eg. if the hash contains\n * unsafe characters), and may need to be accessed using string indexing.\n */\nexport function getPublicIdentifiers(hash: string): ResolvedRef {\n const varName = hash\n // @NOTE Type names *must* be valid TypeScript identifiers (this is because,\n // unlike variable names, we cannot use string indexing to access exported\n // types).\n const typeName = toPascalCase(hash)\n if (!typeName || varName === typeName || !isSafeIdentifier(typeName)) {\n return { varName, typeName: `Def${typeName}` }\n }\n return { varName, typeName }\n}\n\nfunction asSafeDefinitionIdentifier(name: string) {\n if (\n startsWithLowerLetter(name) &&\n isSafeIdentifier(name) &&\n isSafeIdentifier(ucFirst(name))\n ) {\n return name\n }\n const camel = toCamelCase(name)\n if (isSafeIdentifier(camel) && isSafeIdentifier(ucFirst(camel))) {\n return camel\n }\n return undefined\n}\n"]}
package/dist/ts-lang.d.ts CHANGED
@@ -1,3 +1,11 @@
1
+ export declare function isJsKeyword(word: string): boolean;
2
+ export declare function isGlobalIdentifier(word: string): boolean;
1
3
  export declare function isReservedWord(word: string): boolean;
2
- export declare function isSafeIdentifier(name: string): boolean;
4
+ type SafeIdentifierOptions = {
5
+ /** Defaults to `false` */
6
+ allowGlobal?: boolean;
7
+ };
8
+ export declare function isSafeIdentifier(name: string, options?: SafeIdentifierOptions): boolean;
9
+ export declare function asNamespaceExport(name: string): string;
10
+ export {};
3
11
  //# sourceMappingURL=ts-lang.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ts-lang.d.ts","sourceRoot":"","sources":["../src/ts-lang.ts"],"names":[],"mappings":"AA+HA,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,WAE1C;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,WAE5C"}
1
+ {"version":3,"file":"ts-lang.d.ts","sourceRoot":"","sources":["../src/ts-lang.ts"],"names":[],"mappings":"AA+EA,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,WAEvC;AAwDD,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,WAO9C;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,WAE1C;AAED,KAAK,qBAAqB,GAAG;IAC3B,0BAA0B;IAC1B,WAAW,CAAC,EAAE,OAAO,CAAA;CACtB,CAAA;AAED,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE,qBAAqB,WAOhC;AAMD,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,UAI7C"}
package/dist/ts-lang.js CHANGED
@@ -1,10 +1,15 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isJsKeyword = isJsKeyword;
4
+ exports.isGlobalIdentifier = isGlobalIdentifier;
3
5
  exports.isReservedWord = isReservedWord;
4
6
  exports.isSafeIdentifier = isSafeIdentifier;
5
- const RESERVED_WORDS = new Set([
6
- // JavaScript keywords
7
- // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Lexical_grammar
7
+ exports.asNamespaceExport = asNamespaceExport;
8
+ /**
9
+ * JavaScript keywords
10
+ * @see {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Lexical_grammar}
11
+ */
12
+ const JS_KEYWORDS = new Set([
8
13
  'abstract',
9
14
  'arguments',
10
15
  'as',
@@ -77,29 +82,20 @@ const RESERVED_WORDS = new Set([
77
82
  'while',
78
83
  'with',
79
84
  'yield',
80
- // Constructors and globals
81
- 'Array',
82
- 'Boolean',
83
- 'Buffer',
84
- 'Date',
85
- 'Error',
86
- 'Function',
87
- 'Infinity',
88
- 'JSON',
89
- 'Map',
90
- 'Math',
91
- 'NaN',
92
- 'Number',
93
- 'Object',
94
- 'Set',
95
- 'String',
96
- 'Symbol',
97
- 'console',
98
- 'document',
99
- 'global',
100
- 'globalThis',
101
- 'window',
102
- // Test globals
85
+ ]);
86
+ function isJsKeyword(word) {
87
+ return JS_KEYWORDS.has(word);
88
+ }
89
+ const WELL_KNOWN_GLOBALS = new Set([
90
+ // ESM
91
+ 'import',
92
+ // CommonJS
93
+ '__dirname',
94
+ '__filename',
95
+ 'require',
96
+ 'module',
97
+ 'exports',
98
+ // Jest
103
99
  'afterAll',
104
100
  'afterEach',
105
101
  'assert',
@@ -109,30 +105,61 @@ const RESERVED_WORDS = new Set([
109
105
  'expect',
110
106
  'it',
111
107
  'test',
112
- // CommonJS globals
113
- '__dirname',
114
- '__filename',
115
- 'require',
116
- 'module',
117
- 'exports',
118
- // TypeScript
119
- 'Record',
108
+ ]);
109
+ const TYPE_SCRIPT_GLOBALS = new Set([
110
+ // Primitives
120
111
  'any',
112
+ 'bigint',
113
+ 'boolean',
121
114
  'declare',
122
115
  'never',
116
+ 'null',
123
117
  'number',
124
118
  'object',
125
119
  'string',
126
120
  'symbol',
121
+ 'undefined',
127
122
  'unknown',
128
- // Future reserved words
129
- 'constructor',
130
- 'meta',
123
+ 'void',
124
+ // Utility types
125
+ 'Record',
126
+ 'Partial',
127
+ 'Readonly',
128
+ 'Pick',
129
+ 'Omit',
130
+ 'Exclude',
131
+ 'Extract',
132
+ 'InstanceType',
133
+ 'ReturnType',
134
+ 'Required',
135
+ 'ThisType',
136
+ 'Uppercase',
137
+ 'Lowercase',
138
+ 'Capitalize',
139
+ 'Uncapitalize',
131
140
  ]);
141
+ function isGlobalIdentifier(word) {
142
+ return (
143
+ // Should cover most common globals
144
+ word in globalThis ||
145
+ WELL_KNOWN_GLOBALS.has(word) ||
146
+ TYPE_SCRIPT_GLOBALS.has(word));
147
+ }
132
148
  function isReservedWord(word) {
133
- return RESERVED_WORDS.has(word);
149
+ return isJsKeyword(word) || isGlobalIdentifier(word);
150
+ }
151
+ function isSafeIdentifier(name, options) {
152
+ if (!options?.allowGlobal && isGlobalIdentifier(name)) {
153
+ return false;
154
+ }
155
+ return isValidJsIdentifier(name);
156
+ }
157
+ function isValidJsIdentifier(name) {
158
+ return !isJsKeyword(name) && /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(name);
134
159
  }
135
- function isSafeIdentifier(name) {
136
- return !isReservedWord(name) && /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(name);
160
+ function asNamespaceExport(name) {
161
+ return isSafeIdentifier(name, { allowGlobal: true })
162
+ ? name
163
+ : JSON.stringify(name);
137
164
  }
138
165
  //# sourceMappingURL=ts-lang.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ts-lang.js","sourceRoot":"","sources":["../src/ts-lang.ts"],"names":[],"mappings":";;AA+HA,wCAEC;AAED,4CAEC;AArID,MAAM,cAAc,GAAG,IAAI,GAAG,CAAC;IAC7B,sBAAsB;IACtB,oFAAoF;IACpF,UAAU;IACV,WAAW;IACX,IAAI;IACJ,OAAO;IACP,OAAO;IACP,SAAS;IACT,OAAO;IACP,MAAM;IACN,MAAM;IACN,OAAO;IACP,MAAM;IACN,OAAO;IACP,OAAO;IACP,UAAU;IACV,UAAU;IACV,SAAS;IACT,QAAQ;IACR,IAAI;IACJ,QAAQ;IACR,MAAM;IACN,MAAM;IACN,MAAM;IACN,QAAQ;IACR,SAAS;IACT,OAAO;IACP,OAAO;IACP,SAAS;IACT,OAAO;IACP,KAAK;IACL,MAAM;IACN,UAAU;IACV,KAAK;IACL,MAAM;IACN,IAAI;IACJ,YAAY;IACZ,QAAQ;IACR,IAAI;IACJ,YAAY;IACZ,KAAK;IACL,WAAW;IACX,KAAK;IACL,MAAM;IACN,QAAQ;IACR,KAAK;IACL,MAAM;IACN,IAAI;IACJ,SAAS;IACT,SAAS;IACT,WAAW;IACX,QAAQ;IACR,QAAQ;IACR,KAAK;IACL,OAAO;IACP,QAAQ;IACR,OAAO;IACP,QAAQ;IACR,cAAc;IACd,MAAM;IACN,OAAO;IACP,QAAQ;IACR,WAAW;IACX,MAAM;IACN,KAAK;IACL,QAAQ;IACR,WAAW;IACX,OAAO;IACP,KAAK;IACL,MAAM;IACN,UAAU;IACV,OAAO;IACP,MAAM;IACN,OAAO;IACP,2BAA2B;IAC3B,OAAO;IACP,SAAS;IACT,QAAQ;IACR,MAAM;IACN,OAAO;IACP,UAAU;IACV,UAAU;IACV,MAAM;IACN,KAAK;IACL,MAAM;IACN,KAAK;IACL,QAAQ;IACR,QAAQ;IACR,KAAK;IACL,QAAQ;IACR,QAAQ;IACR,SAAS;IACT,UAAU;IACV,QAAQ;IACR,YAAY;IACZ,QAAQ;IACR,eAAe;IACf,UAAU;IACV,WAAW;IACX,QAAQ;IACR,WAAW;IACX,YAAY;IACZ,UAAU;IACV,QAAQ;IACR,IAAI;IACJ,MAAM;IACN,mBAAmB;IACnB,WAAW;IACX,YAAY;IACZ,SAAS;IACT,QAAQ;IACR,SAAS;IACT,aAAa;IACb,QAAQ;IACR,KAAK;IACL,SAAS;IACT,OAAO;IACP,QAAQ;IACR,QAAQ;IACR,QAAQ;IACR,QAAQ;IACR,SAAS;IACT,wBAAwB;IACxB,aAAa;IACb,MAAM;CACP,CAAC,CAAA;AACF,SAAgB,cAAc,CAAC,IAAY;IACzC,OAAO,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;AACjC,CAAC;AAED,SAAgB,gBAAgB,CAAC,IAAY;IAC3C,OAAO,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,4BAA4B,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AACzE,CAAC","sourcesContent":["const RESERVED_WORDS = new Set([\n // JavaScript keywords\n // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Lexical_grammar\n 'abstract',\n 'arguments',\n 'as',\n 'async',\n 'await',\n 'boolean',\n 'break',\n 'byte',\n 'case',\n 'catch',\n 'char',\n 'class',\n 'const',\n 'continue',\n 'debugger',\n 'default',\n 'delete',\n 'do',\n 'double',\n 'else',\n 'enum',\n 'eval',\n 'export',\n 'extends',\n 'false',\n 'final',\n 'finally',\n 'float',\n 'for',\n 'from',\n 'function',\n 'get',\n 'goto',\n 'if',\n 'implements',\n 'import',\n 'in',\n 'instanceof',\n 'int',\n 'interface',\n 'let',\n 'long',\n 'native',\n 'new',\n 'null',\n 'of',\n 'package',\n 'private',\n 'protected',\n 'public',\n 'return',\n 'set',\n 'short',\n 'static',\n 'super',\n 'switch',\n 'synchronized',\n 'this',\n 'throw',\n 'throws',\n 'transient',\n 'true',\n 'try',\n 'typeof',\n 'undefined',\n 'using',\n 'var',\n 'void',\n 'volatile',\n 'while',\n 'with',\n 'yield',\n // Constructors and globals\n 'Array',\n 'Boolean',\n 'Buffer',\n 'Date',\n 'Error',\n 'Function',\n 'Infinity',\n 'JSON',\n 'Map',\n 'Math',\n 'NaN',\n 'Number',\n 'Object',\n 'Set',\n 'String',\n 'Symbol',\n 'console',\n 'document',\n 'global',\n 'globalThis',\n 'window',\n // Test globals\n 'afterAll',\n 'afterEach',\n 'assert',\n 'beforeAll',\n 'beforeEach',\n 'describe',\n 'expect',\n 'it',\n 'test',\n // CommonJS globals\n '__dirname',\n '__filename',\n 'require',\n 'module',\n 'exports',\n // TypeScript\n 'Record',\n 'any',\n 'declare',\n 'never',\n 'number',\n 'object',\n 'string',\n 'symbol',\n 'unknown',\n // Future reserved words\n 'constructor',\n 'meta',\n])\nexport function isReservedWord(word: string) {\n return RESERVED_WORDS.has(word)\n}\n\nexport function isSafeIdentifier(name: string) {\n return !isReservedWord(name) && /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(name)\n}\n"]}
1
+ {"version":3,"file":"ts-lang.js","sourceRoot":"","sources":["../src/ts-lang.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * JavaScript keywords\n * @see {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Lexical_grammar}\n */\nconst JS_KEYWORDS = new Set([\n 'abstract',\n 'arguments',\n 'as',\n 'async',\n 'await',\n 'boolean',\n 'break',\n 'byte',\n 'case',\n 'catch',\n 'char',\n 'class',\n 'const',\n 'continue',\n 'debugger',\n 'default',\n 'delete',\n 'do',\n 'double',\n 'else',\n 'enum',\n 'eval',\n 'export',\n 'extends',\n 'false',\n 'final',\n 'finally',\n 'float',\n 'for',\n 'from',\n 'function',\n 'get',\n 'goto',\n 'if',\n 'implements',\n 'import',\n 'in',\n 'instanceof',\n 'int',\n 'interface',\n 'let',\n 'long',\n 'native',\n 'new',\n 'null',\n 'of',\n 'package',\n 'private',\n 'protected',\n 'public',\n 'return',\n 'set',\n 'short',\n 'static',\n 'super',\n 'switch',\n 'synchronized',\n 'this',\n 'throw',\n 'throws',\n 'transient',\n 'true',\n 'try',\n 'typeof',\n 'undefined',\n 'using',\n 'var',\n 'void',\n 'volatile',\n 'while',\n 'with',\n 'yield',\n])\n\nexport function isJsKeyword(word: string) {\n return JS_KEYWORDS.has(word)\n}\n\nconst WELL_KNOWN_GLOBALS = new Set([\n // ESM\n 'import',\n // CommonJS\n '__dirname',\n '__filename',\n 'require',\n 'module',\n 'exports',\n // Jest\n 'afterAll',\n 'afterEach',\n 'assert',\n 'beforeAll',\n 'beforeEach',\n 'describe',\n 'expect',\n 'it',\n 'test',\n])\n\nconst TYPE_SCRIPT_GLOBALS = new Set([\n // Primitives\n 'any',\n 'bigint',\n 'boolean',\n 'declare',\n 'never',\n 'null',\n 'number',\n 'object',\n 'string',\n 'symbol',\n 'undefined',\n 'unknown',\n 'void',\n // Utility types\n 'Record',\n 'Partial',\n 'Readonly',\n 'Pick',\n 'Omit',\n 'Exclude',\n 'Extract',\n 'InstanceType',\n 'ReturnType',\n 'Required',\n 'ThisType',\n 'Uppercase',\n 'Lowercase',\n 'Capitalize',\n 'Uncapitalize',\n])\n\nexport function isGlobalIdentifier(word: string) {\n return (\n // Should cover most common globals\n word in globalThis ||\n WELL_KNOWN_GLOBALS.has(word) ||\n TYPE_SCRIPT_GLOBALS.has(word)\n )\n}\n\nexport function isReservedWord(word: string) {\n return isJsKeyword(word) || isGlobalIdentifier(word)\n}\n\ntype SafeIdentifierOptions = {\n /** Defaults to `false` */\n allowGlobal?: boolean\n}\n\nexport function isSafeIdentifier(\n name: string,\n options?: SafeIdentifierOptions,\n) {\n if (!options?.allowGlobal && isGlobalIdentifier(name)) {\n return false\n }\n\n return isValidJsIdentifier(name)\n}\n\nfunction isValidJsIdentifier(name: string) {\n return !isJsKeyword(name) && /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(name)\n}\n\nexport function asNamespaceExport(name: string) {\n return isSafeIdentifier(name, { allowGlobal: true })\n ? name\n : JSON.stringify(name)\n}\n"]}
package/dist/util.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  export declare function memoize<T extends (arg: string) => NonNullable<unknown> | null>(fn: T): T;
2
+ export declare function startsWithLowerLetter(str: string): boolean;
2
3
  export declare function ucFirst(str: string): string;
3
4
  export declare function lcFirst(str: string): string;
4
5
  export declare function toPascalCase(str: string): string;
@@ -1 +1 @@
1
- {"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":"AAEA,wBAAgB,OAAO,CAAC,CAAC,SAAS,CAAC,GAAG,EAAE,MAAM,KAAK,WAAW,CAAC,OAAO,CAAC,GAAG,IAAI,EAC5E,EAAE,EAAE,CAAC,GACJ,CAAC,CASH;AAED,wBAAgB,OAAO,CAAC,GAAG,EAAE,MAAM,UAElC;AAED,wBAAgB,OAAO,CAAC,GAAG,EAAE,MAAM,UAElC;AAED,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAEhD;AAED,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAE/C;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAElD;AAED,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAE/C;AAED,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAE/C;AAeD,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,UAKtD;AAED,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,WAG1C"}
1
+ {"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":"AAEA,wBAAgB,OAAO,CAAC,CAAC,SAAS,CAAC,GAAG,EAAE,MAAM,KAAK,WAAW,CAAC,OAAO,CAAC,GAAG,IAAI,EAC5E,EAAE,EAAE,CAAC,GACJ,CAAC,CASH;AAED,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,MAAM,WAGhD;AAED,wBAAgB,OAAO,CAAC,GAAG,EAAE,MAAM,UAElC;AAED,wBAAgB,OAAO,CAAC,GAAG,EAAE,MAAM,UAElC;AAED,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAEhD;AAED,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAE/C;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAElD;AAED,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAE/C;AAED,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAE/C;AAeD,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,UAKtD;AAED,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,WAG1C"}
package/dist/util.js CHANGED
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.memoize = memoize;
4
+ exports.startsWithLowerLetter = startsWithLowerLetter;
4
5
  exports.ucFirst = ucFirst;
5
6
  exports.lcFirst = lcFirst;
6
7
  exports.toPascalCase = toPascalCase;
@@ -22,6 +23,10 @@ function memoize(fn) {
22
23
  return result;
23
24
  });
24
25
  }
26
+ function startsWithLowerLetter(str) {
27
+ const code = str.charCodeAt(0);
28
+ return code >= 97 && code <= 122; // 'a' to 'z'
29
+ }
25
30
  function ucFirst(str) {
26
31
  return str.charAt(0).toUpperCase() + str.slice(1);
27
32
  }
package/dist/util.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"util.js","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":"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","sourcesContent":["import { relative } from 'node:path'\n\nexport function memoize<T extends (arg: string) => NonNullable<unknown> | null>(\n fn: T,\n): T {\n const cache = new Map<string, NonNullable<unknown> | null>()\n return ((arg: string) => {\n const cached = cache.get(arg)\n if (cached !== undefined) return cached\n const result = fn(arg)\n cache.set(arg, result)\n return result\n }) as T\n}\n\nexport function ucFirst(str: string) {\n return str.charAt(0).toUpperCase() + str.slice(1)\n}\n\nexport function lcFirst(str: string) {\n return str.charAt(0).toLowerCase() + str.slice(1)\n}\n\nexport function toPascalCase(str: string): string {\n return extractWords(str).map(toLowerCase).map(ucFirst).join('')\n}\n\nexport function toCamelCase(str: string): string {\n return lcFirst(toPascalCase(str))\n}\n\nexport function toConstantCase(str: string): string {\n return extractWords(str).map(toUpperCase).join('_')\n}\n\nexport function toLowerCase(str: string): string {\n return str.toLowerCase()\n}\n\nexport function toUpperCase(str: string): string {\n return str.toUpperCase()\n}\n\nfunction extractWords(str: string): string[] {\n const processedStr = str\n .replace(/([a-z0-9])([A-Z])/g, '$1 $2') // split camelCase\n .replace(/([A-Z])([A-Z][a-z])/g, '$1 $2') // split ALLCAPSWords\n .replace(/([0-9])([A-Za-z])/g, '$1 $2') // split number followed by letter\n .replace(/[^a-zA-Z0-9]+/g, ' ') // replace non-alphanumeric with space\n .trim() // trim leading/trailing spaces\n\n return processedStr\n ? processedStr.split(/\\s+/) // split by spaces\n : [] // Avoid returning [''] for empty strings\n}\n\nexport function asRelativePath(from: string, to: string) {\n const relPath = relative(from, to)\n return relPath.startsWith('./') || relPath.startsWith('../')\n ? relPath\n : `./${relPath}`\n}\n\nexport function startsWithDigit(str: string) {\n const code = str.charCodeAt(0)\n return code >= 48 && code <= 57 // '0' to '9'\n}\n"]}
1
+ {"version":3,"file":"util.js","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":"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","sourcesContent":["import { relative } from 'node:path'\n\nexport function memoize<T extends (arg: string) => NonNullable<unknown> | null>(\n fn: T,\n): T {\n const cache = new Map<string, NonNullable<unknown> | null>()\n return ((arg: string) => {\n const cached = cache.get(arg)\n if (cached !== undefined) return cached\n const result = fn(arg)\n cache.set(arg, result)\n return result\n }) as T\n}\n\nexport function startsWithLowerLetter(str: string) {\n const code = str.charCodeAt(0)\n return code >= 97 && code <= 122 // 'a' to 'z'\n}\n\nexport function ucFirst(str: string) {\n return str.charAt(0).toUpperCase() + str.slice(1)\n}\n\nexport function lcFirst(str: string) {\n return str.charAt(0).toLowerCase() + str.slice(1)\n}\n\nexport function toPascalCase(str: string): string {\n return extractWords(str).map(toLowerCase).map(ucFirst).join('')\n}\n\nexport function toCamelCase(str: string): string {\n return lcFirst(toPascalCase(str))\n}\n\nexport function toConstantCase(str: string): string {\n return extractWords(str).map(toUpperCase).join('_')\n}\n\nexport function toLowerCase(str: string): string {\n return str.toLowerCase()\n}\n\nexport function toUpperCase(str: string): string {\n return str.toUpperCase()\n}\n\nfunction extractWords(str: string): string[] {\n const processedStr = str\n .replace(/([a-z0-9])([A-Z])/g, '$1 $2') // split camelCase\n .replace(/([A-Z])([A-Z][a-z])/g, '$1 $2') // split ALLCAPSWords\n .replace(/([0-9])([A-Za-z])/g, '$1 $2') // split number followed by letter\n .replace(/[^a-zA-Z0-9]+/g, ' ') // replace non-alphanumeric with space\n .trim() // trim leading/trailing spaces\n\n return processedStr\n ? processedStr.split(/\\s+/) // split by spaces\n : [] // Avoid returning [''] for empty strings\n}\n\nexport function asRelativePath(from: string, to: string) {\n const relPath = relative(from, to)\n return relPath.startsWith('./') || relPath.startsWith('../')\n ? relPath\n : `./${relPath}`\n}\n\nexport function startsWithDigit(str: string) {\n const code = str.charCodeAt(0)\n return code >= 48 && code <= 57 // '0' to '9'\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atproto/lex-builder",
3
- "version": "0.0.7",
3
+ "version": "0.0.9",
4
4
  "license": "MIT",
5
5
  "description": "TypeScript schema builder for AT Lexicons",
6
6
  "keywords": [
@@ -29,25 +29,25 @@
29
29
  "types": "./dist/index.d.ts",
30
30
  "exports": {
31
31
  ".": {
32
+ "types": "./dist/index.d.ts",
32
33
  "browser": "./dist/index.js",
33
34
  "require": "./dist/index.js",
34
- "import": "./dist/index.js",
35
- "types": "./dist/index.d.ts"
35
+ "import": "./dist/index.js"
36
36
  }
37
37
  },
38
38
  "dependencies": {
39
39
  "prettier": "^3.2.5",
40
40
  "ts-morph": "^27.0.0",
41
41
  "tslib": "^2.8.1",
42
- "@atproto/lex-document": "0.0.6",
43
- "@atproto/lex-schema": "0.0.5"
42
+ "@atproto/lex-document": "0.0.8",
43
+ "@atproto/lex-schema": "0.0.7"
44
44
  },
45
45
  "devDependencies": {
46
46
  "@ts-morph/common": "^0.28.0",
47
- "jest": "^28.1.2"
47
+ "vitest": "^4.0.16"
48
48
  },
49
49
  "scripts": {
50
50
  "build": "tsc --build tsconfig.build.json",
51
- "test": "jest"
51
+ "test": "vitest run"
52
52
  }
53
53
  }
@@ -1,3 +1,4 @@
1
+ import { describe, expect, it } from 'vitest'
1
2
  import { LexiconDocument, LexiconIndexer } from '@atproto/lex-document'
2
3
  import { FilteredIndexer } from './filtered-indexer.js'
3
4
 
@@ -1,3 +1,4 @@
1
+ import assert from 'node:assert'
1
2
  import { mkdir, rm, stat, writeFile } from 'node:fs/promises'
2
3
  import { join, resolve } from 'node:path'
3
4
  import { IndentationText, Project } from 'ts-morph'
@@ -10,9 +11,17 @@ import {
10
11
  LexiconDirectoryIndexer,
11
12
  LexiconDirectoryIndexerOptions,
12
13
  } from './lexicon-directory-indexer.js'
13
- import { isSafeIdentifier } from './ts-lang.js'
14
+ import { asNamespaceExport } from './ts-lang.js'
14
15
 
15
16
  export type LexBuilderOptions = LexDefBuilderOptions & {
17
+ /**
18
+ * Whether to generate an index file at the root exporting all top-level
19
+ * namespaces.
20
+ *
21
+ * @note This could theoretically cause name conflicts if a
22
+ * @default false
23
+ */
24
+ indexFile?: boolean
16
25
  importExt?: string
17
26
  fileExt?: string
18
27
  }
@@ -100,6 +109,23 @@ export class LexBuilder {
100
109
  private async createExportTree(doc: LexiconDocument) {
101
110
  const namespaces = doc.id.split('.')
102
111
 
112
+ if (this.options.indexFile) {
113
+ const indexFile = this.getFile(`/index${this.fileExt}`)
114
+
115
+ const tldNs = namespaces[0]!
116
+ assert(
117
+ tldNs !== 'index',
118
+ 'The "indexFile" options cannot be used with namespaces using a ".index" tld.',
119
+ )
120
+ const tldNsSpecifier = `./${tldNs}${this.importExt}`
121
+ if (!indexFile.getExportDeclaration(tldNsSpecifier)) {
122
+ indexFile.addExportDeclaration({
123
+ moduleSpecifier: tldNsSpecifier,
124
+ namespaceExport: asNamespaceExport(tldNs),
125
+ })
126
+ }
127
+ }
128
+
103
129
  // First create the parent namespaces
104
130
  for (let i = 0; i < namespaces.length - 1; i++) {
105
131
  const currentNs = namespaces[i]
@@ -113,9 +139,7 @@ export class LexBuilder {
113
139
  if (!dec) {
114
140
  file.addExportDeclaration({
115
141
  moduleSpecifier: childModuleSpecifier,
116
- namespaceExport: isSafeIdentifier(childNs)
117
- ? childNs
118
- : JSON.stringify(childNs),
142
+ namespaceExport: asNamespaceExport(childNs),
119
143
  })
120
144
  }
121
145
  }
@@ -452,6 +452,12 @@ export class LexDefBuilder {
452
452
  private async compilePayload(def: LexiconPayload | undefined) {
453
453
  if (!def) return this.pure(`l.payload()`)
454
454
 
455
+ // Special case for JSON object payloads
456
+ if (def.encoding === 'application/json' && def.schema?.type === 'object') {
457
+ const properties = await this.compilePropertiesSchemas(def.schema)
458
+ return this.pure(`l.jsonPayload({${properties.join(',')}})`)
459
+ }
460
+
455
461
  const encodedEncoding = JSON.stringify(def.encoding)
456
462
  if (def.schema) {
457
463
  const bodySchema = await this.compileBodySchema(def.schema)
@@ -470,7 +476,7 @@ export class LexDefBuilder {
470
476
  }
471
477
 
472
478
  private async compileParamsSchema(def: undefined | LexiconParameters) {
473
- if (!def) return this.pure(`l.params({})`)
479
+ if (!def) return this.pure(`l.params()`)
474
480
 
475
481
  const properties = await this.compilePropertiesSchemas(def)
476
482
  return this.pure(`l.params({${properties.join(',')}})`)
@@ -6,6 +6,7 @@ import { isReservedWord, isSafeIdentifier } from './ts-lang.js'
6
6
  import {
7
7
  asRelativePath,
8
8
  memoize,
9
+ startsWithLowerLetter,
9
10
  toCamelCase,
10
11
  toPascalCase,
11
12
  ucFirst,
@@ -299,8 +300,16 @@ export function getPublicIdentifiers(hash: string): ResolvedRef {
299
300
  }
300
301
 
301
302
  function asSafeDefinitionIdentifier(name: string) {
302
- if (isSafeIdentifier(name) && isSafeIdentifier(ucFirst(name))) return name
303
+ if (
304
+ startsWithLowerLetter(name) &&
305
+ isSafeIdentifier(name) &&
306
+ isSafeIdentifier(ucFirst(name))
307
+ ) {
308
+ return name
309
+ }
303
310
  const camel = toCamelCase(name)
304
- if (isSafeIdentifier(camel) && isSafeIdentifier(ucFirst(camel))) return camel
311
+ if (isSafeIdentifier(camel) && isSafeIdentifier(ucFirst(camel))) {
312
+ return camel
313
+ }
305
314
  return undefined
306
315
  }
package/src/ts-lang.ts CHANGED
@@ -1,6 +1,8 @@
1
- const RESERVED_WORDS = new Set([
2
- // JavaScript keywords
3
- // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Lexical_grammar
1
+ /**
2
+ * JavaScript keywords
3
+ * @see {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Lexical_grammar}
4
+ */
5
+ const JS_KEYWORDS = new Set([
4
6
  'abstract',
5
7
  'arguments',
6
8
  'as',
@@ -73,29 +75,22 @@ const RESERVED_WORDS = new Set([
73
75
  'while',
74
76
  'with',
75
77
  'yield',
76
- // Constructors and globals
77
- 'Array',
78
- 'Boolean',
79
- 'Buffer',
80
- 'Date',
81
- 'Error',
82
- 'Function',
83
- 'Infinity',
84
- 'JSON',
85
- 'Map',
86
- 'Math',
87
- 'NaN',
88
- 'Number',
89
- 'Object',
90
- 'Set',
91
- 'String',
92
- 'Symbol',
93
- 'console',
94
- 'document',
95
- 'global',
96
- 'globalThis',
97
- 'window',
98
- // Test globals
78
+ ])
79
+
80
+ export function isJsKeyword(word: string) {
81
+ return JS_KEYWORDS.has(word)
82
+ }
83
+
84
+ const WELL_KNOWN_GLOBALS = new Set([
85
+ // ESM
86
+ 'import',
87
+ // CommonJS
88
+ '__dirname',
89
+ '__filename',
90
+ 'require',
91
+ 'module',
92
+ 'exports',
93
+ // Jest
99
94
  'afterAll',
100
95
  'afterEach',
101
96
  'assert',
@@ -105,30 +100,76 @@ const RESERVED_WORDS = new Set([
105
100
  'expect',
106
101
  'it',
107
102
  'test',
108
- // CommonJS globals
109
- '__dirname',
110
- '__filename',
111
- 'require',
112
- 'module',
113
- 'exports',
114
- // TypeScript
115
- 'Record',
103
+ ])
104
+
105
+ const TYPE_SCRIPT_GLOBALS = new Set([
106
+ // Primitives
116
107
  'any',
108
+ 'bigint',
109
+ 'boolean',
117
110
  'declare',
118
111
  'never',
112
+ 'null',
119
113
  'number',
120
114
  'object',
121
115
  'string',
122
116
  'symbol',
117
+ 'undefined',
123
118
  'unknown',
124
- // Future reserved words
125
- 'constructor',
126
- 'meta',
119
+ 'void',
120
+ // Utility types
121
+ 'Record',
122
+ 'Partial',
123
+ 'Readonly',
124
+ 'Pick',
125
+ 'Omit',
126
+ 'Exclude',
127
+ 'Extract',
128
+ 'InstanceType',
129
+ 'ReturnType',
130
+ 'Required',
131
+ 'ThisType',
132
+ 'Uppercase',
133
+ 'Lowercase',
134
+ 'Capitalize',
135
+ 'Uncapitalize',
127
136
  ])
137
+
138
+ export function isGlobalIdentifier(word: string) {
139
+ return (
140
+ // Should cover most common globals
141
+ word in globalThis ||
142
+ WELL_KNOWN_GLOBALS.has(word) ||
143
+ TYPE_SCRIPT_GLOBALS.has(word)
144
+ )
145
+ }
146
+
128
147
  export function isReservedWord(word: string) {
129
- return RESERVED_WORDS.has(word)
148
+ return isJsKeyword(word) || isGlobalIdentifier(word)
149
+ }
150
+
151
+ type SafeIdentifierOptions = {
152
+ /** Defaults to `false` */
153
+ allowGlobal?: boolean
154
+ }
155
+
156
+ export function isSafeIdentifier(
157
+ name: string,
158
+ options?: SafeIdentifierOptions,
159
+ ) {
160
+ if (!options?.allowGlobal && isGlobalIdentifier(name)) {
161
+ return false
162
+ }
163
+
164
+ return isValidJsIdentifier(name)
165
+ }
166
+
167
+ function isValidJsIdentifier(name: string) {
168
+ return !isJsKeyword(name) && /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(name)
130
169
  }
131
170
 
132
- export function isSafeIdentifier(name: string) {
133
- return !isReservedWord(name) && /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(name)
171
+ export function asNamespaceExport(name: string) {
172
+ return isSafeIdentifier(name, { allowGlobal: true })
173
+ ? name
174
+ : JSON.stringify(name)
134
175
  }
package/src/util.ts CHANGED
@@ -13,6 +13,11 @@ export function memoize<T extends (arg: string) => NonNullable<unknown> | null>(
13
13
  }) as T
14
14
  }
15
15
 
16
+ export function startsWithLowerLetter(str: string) {
17
+ const code = str.charCodeAt(0)
18
+ return code >= 97 && code <= 122 // 'a' to 'z'
19
+ }
20
+
16
21
  export function ucFirst(str: string) {
17
22
  return str.charAt(0).toUpperCase() + str.slice(1)
18
23
  }
@@ -1,5 +1,5 @@
1
1
  {
2
- "extends": "../../../tsconfig/tests.json",
2
+ "extends": "../../../tsconfig/vitest.json",
3
3
  "include": ["./tests", "./src/**/*.test.ts"],
4
4
  "compilerOptions": {
5
5
  "noImplicitAny": true,