@gaearon/lex-builder 0.0.13
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 +144 -0
- package/dist/filter.d.ts +7 -0
- package/dist/filter.d.ts.map +1 -0
- package/dist/filter.js +30 -0
- package/dist/filter.js.map +1 -0
- package/dist/filtered-indexer.d.ts +2100 -0
- package/dist/filtered-indexer.d.ts.map +1 -0
- package/dist/filtered-indexer.js +56 -0
- package/dist/filtered-indexer.js.map +1 -0
- package/dist/formatter.d.ts +13 -0
- package/dist/formatter.d.ts.map +1 -0
- package/dist/formatter.js +34 -0
- package/dist/formatter.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +16 -0
- package/dist/index.js.map +1 -0
- package/dist/lex-builder.d.ts +36 -0
- package/dist/lex-builder.d.ts.map +1 -0
- package/dist/lex-builder.js +144 -0
- package/dist/lex-builder.js.map +1 -0
- package/dist/lex-def-builder.d.ts +69 -0
- package/dist/lex-def-builder.d.ts.map +1 -0
- package/dist/lex-def-builder.js +734 -0
- package/dist/lex-def-builder.js.map +1 -0
- package/dist/lexicon-directory-indexer.d.ts +11 -0
- package/dist/lexicon-directory-indexer.d.ts.map +1 -0
- package/dist/lexicon-directory-indexer.js +46 -0
- package/dist/lexicon-directory-indexer.js.map +1 -0
- package/dist/polyfill.d.ts +1 -0
- package/dist/polyfill.d.ts.map +1 -0
- package/dist/polyfill.js +7 -0
- package/dist/polyfill.js.map +1 -0
- package/dist/ref-resolver.d.ts +53 -0
- package/dist/ref-resolver.d.ts.map +1 -0
- package/dist/ref-resolver.js +277 -0
- package/dist/ref-resolver.js.map +1 -0
- package/dist/ts-lang.d.ts +6 -0
- package/dist/ts-lang.d.ts.map +1 -0
- package/dist/ts-lang.js +150 -0
- package/dist/ts-lang.js.map +1 -0
- package/dist/util.d.ts +12 -0
- package/dist/util.d.ts.map +1 -0
- package/dist/util.js +72 -0
- package/dist/util.js.map +1 -0
- package/package.json +53 -0
- package/src/filter.ts +41 -0
- package/src/filtered-indexer.test.ts +84 -0
- package/src/filtered-indexer.ts +60 -0
- package/src/formatter.ts +42 -0
- package/src/index.ts +23 -0
- package/src/lex-builder.ts +186 -0
- package/src/lex-def-builder.ts +980 -0
- package/src/lexicon-directory-indexer.ts +52 -0
- package/src/polyfill.ts +7 -0
- package/src/ref-resolver.test.ts +75 -0
- package/src/ref-resolver.ts +368 -0
- package/src/ts-lang.ts +150 -0
- package/src/util.ts +72 -0
- package/tsconfig.build.json +13 -0
- package/tsconfig.json +7 -0
- package/tsconfig.tests.json +9 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lex-def-builder.js","sourceRoot":"","sources":["../src/lex-def-builder.ts"],"names":[],"mappings":"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","sourcesContent":["import {\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 { asNamespaceExport } 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 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:\n ref.typeName === pub.typeName\n ? undefined\n : asNamespaceExport(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 : asNamespaceExport(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 $check: markPure(`${ref.varName}.check.bind(${ref.varName})`),\n $cast: markPure(`${ref.varName}.cast.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 $validate: markPure(`${ref.varName}.validate.bind(${ref.varName})`),\n $safeValidate: markPure(\n `${ref.varName}.safeValidate.bind(${ref.varName})`,\n ),\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(\n properties.length === 0\n ? `l.params()`\n : `l.params({${properties.join(',')}})`,\n )\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 withDefault(schema: string, defaultValue: unknown) {\n if (defaultValue === undefined) return schema\n\n return this.pure(\n `l.withDefault(${schema}, ${JSON.stringify(defaultValue)})`,\n )\n }\n\n private async compileBooleanSchema(def: LexiconBoolean): Promise<string> {\n const schema = l.boolean()\n\n if (def.default !== undefined) {\n schema.check(def.default)\n }\n\n if (hasConst(def)) return this.compileConstSchema(def)\n\n return this.withDefault(this.pure(`l.boolean()`), def.default)\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 const schema = l.integer(def)\n\n if (hasConst(def)) {\n schema.check(def.const)\n }\n\n if (hasEnum(def)) {\n for (const val of def.enum) schema.check(val)\n }\n\n if (def.default !== undefined) {\n schema.check(def.default)\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 'maximum',\n 'minimum',\n ] satisfies (keyof l.IntegerSchemaOptions)[])\n\n return this.withDefault(this.pure(`l.integer(${options})`), def.default)\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 const schema = l.string(def)\n\n if (hasConst(def)) {\n schema.check(def.const)\n }\n\n if (hasEnum(def)) {\n for (const val of def.enum) schema.check(val)\n }\n\n if (def.default !== undefined) {\n schema.check(def.default)\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 'format',\n 'maxGraphemes',\n 'minGraphemes',\n 'maxLength',\n 'minLength',\n ] satisfies (keyof l.StringSchemaOptions)[])\n\n return this.withDefault(this.pure(`l.string(${options})`), def.default)\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.cid()`)\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.$Typed<${typeName}>`\n }),\n )\n if (!def.closed) types.push('l.Unknown$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 result = this.pure(`l.literal(${JSON.stringify(def.const)})`)\n\n return this.withDefault(result, def.default)\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\n const result =\n def.enum.length === 1\n ? this.pure(`l.literal(${JSON.stringify(def.enum[0])})`)\n : this.pure(`l.enum(${JSON.stringify(def.enum)})`)\n\n return this.withDefault(result, def.default)\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"]}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { LexiconIterableIndexer } from '@atproto/lex-document';
|
|
2
|
+
export type LexiconDirectoryIndexerOptions = ReadLexiconsOptions;
|
|
3
|
+
export declare class LexiconDirectoryIndexer extends LexiconIterableIndexer {
|
|
4
|
+
constructor(options: LexiconDirectoryIndexerOptions);
|
|
5
|
+
}
|
|
6
|
+
type ReadLexiconsOptions = {
|
|
7
|
+
lexicons: string;
|
|
8
|
+
ignoreInvalidLexicons?: boolean;
|
|
9
|
+
};
|
|
10
|
+
export {};
|
|
11
|
+
//# sourceMappingURL=lexicon-directory-indexer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lexicon-directory-indexer.d.ts","sourceRoot":"","sources":["../src/lexicon-directory-indexer.ts"],"names":[],"mappings":"AAEA,OAAO,EAEL,sBAAsB,EAEvB,MAAM,uBAAuB,CAAA;AAE9B,MAAM,MAAM,8BAA8B,GAAG,mBAAmB,CAAA;AAEhE,qBAAa,uBAAwB,SAAQ,sBAAsB;gBACrD,OAAO,EAAE,8BAA8B;CAGpD;AAED,KAAK,mBAAmB,GAAG;IACzB,QAAQ,EAAE,MAAM,CAAA;IAChB,qBAAqB,CAAC,EAAE,OAAO,CAAA;CAChC,CAAA"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.LexiconDirectoryIndexer = void 0;
|
|
4
|
+
const promises_1 = require("node:fs/promises");
|
|
5
|
+
const node_path_1 = require("node:path");
|
|
6
|
+
const lex_document_1 = require("@atproto/lex-document");
|
|
7
|
+
class LexiconDirectoryIndexer extends lex_document_1.LexiconIterableIndexer {
|
|
8
|
+
constructor(options) {
|
|
9
|
+
super(readLexicons(options));
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
exports.LexiconDirectoryIndexer = LexiconDirectoryIndexer;
|
|
13
|
+
async function* readLexicons(options) {
|
|
14
|
+
for await (const filePath of listFiles(options.lexicons)) {
|
|
15
|
+
if (filePath.endsWith('.json')) {
|
|
16
|
+
try {
|
|
17
|
+
const data = await (0, promises_1.readFile)(filePath, 'utf8');
|
|
18
|
+
yield lex_document_1.lexiconDocumentSchema.parse(JSON.parse(data));
|
|
19
|
+
}
|
|
20
|
+
catch (cause) {
|
|
21
|
+
const message = `Error parsing lexicon document ${filePath}`;
|
|
22
|
+
if (options.ignoreInvalidLexicons)
|
|
23
|
+
console.error(`${message}:`, cause);
|
|
24
|
+
else
|
|
25
|
+
throw new Error(message, { cause });
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
async function* listFiles(dir) {
|
|
31
|
+
const dirents = await (0, promises_1.readdir)(dir, { withFileTypes: true }).catch((err) => {
|
|
32
|
+
if (err?.code === 'ENOENT')
|
|
33
|
+
return [];
|
|
34
|
+
throw err;
|
|
35
|
+
});
|
|
36
|
+
for (const dirent of dirents) {
|
|
37
|
+
const res = (0, node_path_1.join)(dir, dirent.name);
|
|
38
|
+
if (dirent.isDirectory()) {
|
|
39
|
+
yield* listFiles(res);
|
|
40
|
+
}
|
|
41
|
+
else if (dirent.isFile() || dirent.isSymbolicLink()) {
|
|
42
|
+
yield res;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=lexicon-directory-indexer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lexicon-directory-indexer.js","sourceRoot":"","sources":["../src/lexicon-directory-indexer.ts"],"names":[],"mappings":";;;AAAA,+CAAoD;AACpD,yCAAgC;AAChC,wDAI8B;AAI9B,MAAa,uBAAwB,SAAQ,qCAAsB;IACjE,YAAY,OAAuC;QACjD,KAAK,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,CAAA;IAC9B,CAAC;CACF;AAJD,0DAIC;AAOD,KAAK,SAAS,CAAC,CAAC,YAAY,CAC1B,OAA4B;IAE5B,IAAI,KAAK,EAAE,MAAM,QAAQ,IAAI,SAAS,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;QACzD,IAAI,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;YAC/B,IAAI,CAAC;gBACH,MAAM,IAAI,GAAG,MAAM,IAAA,mBAAQ,EAAC,QAAQ,EAAE,MAAM,CAAC,CAAA;gBAC7C,MAAM,oCAAqB,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAA;YACrD,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,MAAM,OAAO,GAAG,kCAAkC,QAAQ,EAAE,CAAA;gBAC5D,IAAI,OAAO,CAAC,qBAAqB;oBAAE,OAAO,CAAC,KAAK,CAAC,GAAG,OAAO,GAAG,EAAE,KAAK,CAAC,CAAA;;oBACjE,MAAM,IAAI,KAAK,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,CAAC,CAAA;YAC1C,CAAC;QACH,CAAC;IACH,CAAC;AACH,CAAC;AAED,KAAK,SAAS,CAAC,CAAC,SAAS,CAAC,GAAW;IACnC,MAAM,OAAO,GAAG,MAAM,IAAA,kBAAO,EAAC,GAAG,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;QACxE,IAAK,GAAW,EAAE,IAAI,KAAK,QAAQ;YAAE,OAAO,EAAE,CAAA;QAC9C,MAAM,GAAG,CAAA;IACX,CAAC,CAAC,CAAA;IACF,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,MAAM,GAAG,GAAG,IAAA,gBAAI,EAAC,GAAG,EAAE,MAAM,CAAC,IAAI,CAAC,CAAA;QAClC,IAAI,MAAM,CAAC,WAAW,EAAE,EAAE,CAAC;YACzB,KAAK,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,CAAA;QACvB,CAAC;aAAM,IAAI,MAAM,CAAC,MAAM,EAAE,IAAI,MAAM,CAAC,cAAc,EAAE,EAAE,CAAC;YACtD,MAAM,GAAG,CAAA;QACX,CAAC;IACH,CAAC;AACH,CAAC","sourcesContent":["import { readFile, readdir } from 'node:fs/promises'\nimport { join } from 'node:path'\nimport {\n LexiconDocument,\n LexiconIterableIndexer,\n lexiconDocumentSchema,\n} from '@atproto/lex-document'\n\nexport type LexiconDirectoryIndexerOptions = ReadLexiconsOptions\n\nexport class LexiconDirectoryIndexer extends LexiconIterableIndexer {\n constructor(options: LexiconDirectoryIndexerOptions) {\n super(readLexicons(options))\n }\n}\n\ntype ReadLexiconsOptions = {\n lexicons: string\n ignoreInvalidLexicons?: boolean\n}\n\nasync function* readLexicons(\n options: ReadLexiconsOptions,\n): AsyncGenerator<LexiconDocument, void, unknown> {\n for await (const filePath of listFiles(options.lexicons)) {\n if (filePath.endsWith('.json')) {\n try {\n const data = await readFile(filePath, 'utf8')\n yield lexiconDocumentSchema.parse(JSON.parse(data))\n } catch (cause) {\n const message = `Error parsing lexicon document ${filePath}`\n if (options.ignoreInvalidLexicons) console.error(`${message}:`, cause)\n else throw new Error(message, { cause })\n }\n }\n }\n}\n\nasync function* listFiles(dir: string): AsyncGenerator<string> {\n const dirents = await readdir(dir, { withFileTypes: true }).catch((err) => {\n if ((err as any)?.code === 'ENOENT') return []\n throw err\n })\n for (const dirent of dirents) {\n const res = join(dir, dirent.name)\n if (dirent.isDirectory()) {\n yield* listFiles(res)\n } else if (dirent.isFile() || dirent.isSymbolicLink()) {\n yield res\n }\n }\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
//# sourceMappingURL=polyfill.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"polyfill.d.ts","sourceRoot":"","sources":["../src/polyfill.ts"],"names":[],"mappings":""}
|
package/dist/polyfill.js
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Node <18.18, 19.x, <20.4 and 21.x do not have these symbols defined
|
|
3
|
+
// @ts-expect-error
|
|
4
|
+
Symbol.asyncDispose ??= Symbol.for('nodejs.asyncDispose');
|
|
5
|
+
// @ts-expect-error
|
|
6
|
+
Symbol.dispose ??= Symbol.for('nodejs.dispose');
|
|
7
|
+
//# sourceMappingURL=polyfill.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"polyfill.js","sourceRoot":"","sources":["../src/polyfill.ts"],"names":[],"mappings":";AAAA,sEAAsE;AAEtE,mBAAmB;AACnB,MAAM,CAAC,YAAY,KAAK,MAAM,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAA;AAEzD,mBAAmB;AACnB,MAAM,CAAC,OAAO,KAAK,MAAM,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAA","sourcesContent":["// Node <18.18, 19.x, <20.4 and 21.x do not have these symbols defined\n\n// @ts-expect-error\nSymbol.asyncDispose ??= Symbol.for('nodejs.asyncDispose')\n\n// @ts-expect-error\nSymbol.dispose ??= Symbol.for('nodejs.dispose')\n"]}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { SourceFile } from 'ts-morph';
|
|
2
|
+
import { LexiconDocument, LexiconIndexer } from '@atproto/lex-document';
|
|
3
|
+
export type RefResolverOptions = {
|
|
4
|
+
importExt?: string;
|
|
5
|
+
moduleSpecifier?: (nsid: string) => string;
|
|
6
|
+
};
|
|
7
|
+
export type ResolvedRef = {
|
|
8
|
+
varName: string;
|
|
9
|
+
typeName: string;
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* Utility class to resolve lexicon references to TypeScript identifiers,
|
|
13
|
+
* generating "import" statements as needed.
|
|
14
|
+
*/
|
|
15
|
+
export declare class RefResolver {
|
|
16
|
+
#private;
|
|
17
|
+
private doc;
|
|
18
|
+
private file;
|
|
19
|
+
private indexer;
|
|
20
|
+
private options;
|
|
21
|
+
constructor(doc: LexiconDocument, file: SourceFile, indexer: LexiconIndexer, options: RefResolverOptions);
|
|
22
|
+
readonly resolve: (ref: string) => Promise<ResolvedRef>;
|
|
23
|
+
private nextSafeDefinitionIdentifier;
|
|
24
|
+
/**
|
|
25
|
+
* @note The returned `typeName` and `varName` are *both* guaranteed to be
|
|
26
|
+
* valid TypeScript identifiers.
|
|
27
|
+
*/
|
|
28
|
+
readonly resolveLocal: (hash: string) => Promise<ResolvedRef>;
|
|
29
|
+
/**
|
|
30
|
+
* @note Since this is a memoized function, and is used to generate the name
|
|
31
|
+
* of local variables, we should avoid returning different results for
|
|
32
|
+
* similar, but non strictly equal, inputs (eg. normalized / non-normalized).
|
|
33
|
+
* @see {@link resolve}
|
|
34
|
+
*/
|
|
35
|
+
private readonly resolveExternal;
|
|
36
|
+
private getNsIdentifier;
|
|
37
|
+
private computeSafeNamespaceIdentifierFor;
|
|
38
|
+
private isConflictingIdentifier;
|
|
39
|
+
private conflictsWithKeywords;
|
|
40
|
+
private conflictsWithUtils;
|
|
41
|
+
private conflictsWithLocalDefs;
|
|
42
|
+
private conflictsWithLocalDeclarations;
|
|
43
|
+
private conflictsWithImports;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Generates predictable public identifiers for a given definition hash.
|
|
47
|
+
*
|
|
48
|
+
* @note The returned `typeName` is guaranteed to be a valid TypeScript
|
|
49
|
+
* identifier. `varName` may not be a valid identifier (eg. if the hash contains
|
|
50
|
+
* unsafe characters), and may need to be accessed using string indexing.
|
|
51
|
+
*/
|
|
52
|
+
export declare function getPublicIdentifiers(hash: string): ResolvedRef;
|
|
53
|
+
//# sourceMappingURL=ref-resolver.d.ts.map
|
|
@@ -0,0 +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;AAgBvE,MAAM,MAAM,kBAAkB,GAAG;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,eAAe,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAA;CAC3C,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;IAyBpC;;;OAGG;IACH,SAAgB,YAAY,SACb,MAAM,KAAG,OAAO,CAAC,WAAW,CAAC,CAuD3C;IAED;;;;;OAKG;IACH,OAAO,CAAC,QAAQ,CAAC,eAAe,CAmD/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,CAkB9D"}
|
|
@@ -0,0 +1,277 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.RefResolver = void 0;
|
|
4
|
+
exports.getPublicIdentifiers = getPublicIdentifiers;
|
|
5
|
+
const tslib_1 = require("tslib");
|
|
6
|
+
const node_assert_1 = tslib_1.__importDefault(require("node:assert"));
|
|
7
|
+
const node_path_1 = require("node:path");
|
|
8
|
+
const ts_lang_js_1 = require("./ts-lang.js");
|
|
9
|
+
const util_js_1 = require("./util.js");
|
|
10
|
+
/**
|
|
11
|
+
* Utility class to resolve lexicon references to TypeScript identifiers,
|
|
12
|
+
* generating "import" statements as needed.
|
|
13
|
+
*/
|
|
14
|
+
class RefResolver {
|
|
15
|
+
doc;
|
|
16
|
+
file;
|
|
17
|
+
indexer;
|
|
18
|
+
options;
|
|
19
|
+
constructor(doc, file, indexer, options) {
|
|
20
|
+
this.doc = doc;
|
|
21
|
+
this.file = file;
|
|
22
|
+
this.indexer = indexer;
|
|
23
|
+
this.options = options;
|
|
24
|
+
}
|
|
25
|
+
resolve = (0, util_js_1.memoize)(async (ref) => {
|
|
26
|
+
const [nsid, hash = 'main'] = ref.split('#');
|
|
27
|
+
if (nsid === '' || nsid === this.doc.id) {
|
|
28
|
+
return this.resolveLocal(hash);
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
// @NOTE: Normalize (#main fragment) to ensure proper memoization
|
|
32
|
+
const fullRef = `${nsid}#${hash}`;
|
|
33
|
+
return this.resolveExternal(fullRef);
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
#defCounters = new Map();
|
|
37
|
+
nextSafeDefinitionIdentifier(name) {
|
|
38
|
+
// use camelCase version of the hash as base name
|
|
39
|
+
const nameSafe = (0, util_js_1.startsWithLower)(name) && (0, ts_lang_js_1.isValidJsIdentifier)(name)
|
|
40
|
+
? name
|
|
41
|
+
: (0, util_js_1.toCamelCase)(name).replace(/^[0-9]+/g, '') || 'def';
|
|
42
|
+
const count = this.#defCounters.get(nameSafe) ?? 0;
|
|
43
|
+
this.#defCounters.set(nameSafe, count + 1);
|
|
44
|
+
// @NOTE We don't need to check against local declarations in the file here
|
|
45
|
+
// since we are using a naming system that should guarantee no other
|
|
46
|
+
// identifier has a <nameSafe>$<number> format ("$" cannot appear in
|
|
47
|
+
// hashes so only *we* are generating such identifiers).
|
|
48
|
+
const identifier = `${nameSafe}$${count}`;
|
|
49
|
+
(0, node_assert_1.default)((0, ts_lang_js_1.isValidJsIdentifier)(identifier), `Unable to generate safe identifier for: "${name}"`);
|
|
50
|
+
return identifier;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* @note The returned `typeName` and `varName` are *both* guaranteed to be
|
|
54
|
+
* valid TypeScript identifiers.
|
|
55
|
+
*/
|
|
56
|
+
resolveLocal = (0, util_js_1.memoize)(async (hash) => {
|
|
57
|
+
const hashes = Object.keys(this.doc.defs);
|
|
58
|
+
if (!hashes.includes(hash)) {
|
|
59
|
+
throw new Error(`Definition ${hash} not found in ${this.doc.id}`);
|
|
60
|
+
}
|
|
61
|
+
// Because we are using predictable "public" identifiers for type names,
|
|
62
|
+
// we need to ensure there are no conflicts between different definitions
|
|
63
|
+
// in the same lexicon document.
|
|
64
|
+
//
|
|
65
|
+
// @NOTE It should be possible to implement a way to generate
|
|
66
|
+
// non-conflicting type names for all public (type) identifiers in a
|
|
67
|
+
// project. However, this would add a lot of complexity to the code
|
|
68
|
+
// generation process, and the likelihood of such conflicts happening in
|
|
69
|
+
// practice is very low, so we opt for a simpler approach of just throwing
|
|
70
|
+
// an error if a conflict is detected.
|
|
71
|
+
const pub = getPublicIdentifiers(hash);
|
|
72
|
+
for (const otherHash of hashes) {
|
|
73
|
+
if (otherHash === hash)
|
|
74
|
+
continue;
|
|
75
|
+
const otherPub = getPublicIdentifiers(otherHash);
|
|
76
|
+
if (otherPub.typeName === pub.typeName) {
|
|
77
|
+
throw new Error(`Conflicting type names for definitions #${hash} and #${otherHash} in ${this.doc.id}`);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
// Try to keep and identifier that resembles the original hash as identifier
|
|
81
|
+
const safeIdentifier = asSafeDefinitionIdentifier(hash);
|
|
82
|
+
// If the safe identifier is not conflicting with other definition names,
|
|
83
|
+
// or reserved words, we can use it as-is. Otherwise, we need to generate
|
|
84
|
+
// a unique safe identifier.
|
|
85
|
+
const varName = safeIdentifier
|
|
86
|
+
? !hashes.some((otherHash) => {
|
|
87
|
+
if (otherHash === hash)
|
|
88
|
+
return false;
|
|
89
|
+
const otherIdentifier = asSafeDefinitionIdentifier(otherHash);
|
|
90
|
+
return otherIdentifier === safeIdentifier;
|
|
91
|
+
})
|
|
92
|
+
? // Safe identifier can be used as-is as it does not conflict with
|
|
93
|
+
// other definition names
|
|
94
|
+
safeIdentifier
|
|
95
|
+
: // In order to keep identifiers stable, we use the safe identifier
|
|
96
|
+
// as base, and append a counter to avoid conflicts
|
|
97
|
+
this.nextSafeDefinitionIdentifier(safeIdentifier)
|
|
98
|
+
: // hash only contained unsafe characters, generate a safe one
|
|
99
|
+
this.nextSafeDefinitionIdentifier(hash);
|
|
100
|
+
const typeName = (0, util_js_1.ucFirst)(varName);
|
|
101
|
+
(0, node_assert_1.default)((0, ts_lang_js_1.isSafeLocalIdentifier)(typeName), 'Expected safe type identifier');
|
|
102
|
+
(0, node_assert_1.default)(varName !== typeName, 'Variable and type name should be different');
|
|
103
|
+
return { varName, typeName };
|
|
104
|
+
});
|
|
105
|
+
/**
|
|
106
|
+
* @note Since this is a memoized function, and is used to generate the name
|
|
107
|
+
* of local variables, we should avoid returning different results for
|
|
108
|
+
* similar, but non strictly equal, inputs (eg. normalized / non-normalized).
|
|
109
|
+
* @see {@link resolve}
|
|
110
|
+
*/
|
|
111
|
+
resolveExternal = (0, util_js_1.memoize)(async (fullRef) => {
|
|
112
|
+
const [nsid, hash] = fullRef.split('#');
|
|
113
|
+
const moduleSpecifier = this.options.moduleSpecifier
|
|
114
|
+
? this.options.moduleSpecifier(nsid)
|
|
115
|
+
: `${(0, util_js_1.asRelativePath)(this.file.getDirectoryPath(), (0, node_path_1.join)('/', ...nsid.split('.')))}.defs${this.options.importExt ?? '.js'}`;
|
|
116
|
+
// Lets first make sure the referenced lexicon exists
|
|
117
|
+
const srcDoc = await this.indexer.get(nsid);
|
|
118
|
+
const srcDef = Object.hasOwn(srcDoc.defs, hash) ? srcDoc.defs[hash] : null;
|
|
119
|
+
if (!srcDef) {
|
|
120
|
+
throw new Error(`Missing def "${hash}" in "${nsid}" (referenced from ${this.doc.id})`);
|
|
121
|
+
}
|
|
122
|
+
const publicIds = getPublicIdentifiers(hash);
|
|
123
|
+
if (!(0, ts_lang_js_1.isValidJsIdentifier)(publicIds.typeName)) {
|
|
124
|
+
// If <typeName> is not a valid identifier, we cannot access the type
|
|
125
|
+
// using dot notation (<nsIdentifier>.<typeName>). Note that, unlike js
|
|
126
|
+
// variables, types cannot be accessed using string indexing (like:
|
|
127
|
+
// <nsIdentifier>['<typeName>']) because it generates TypeScript errors:
|
|
128
|
+
//
|
|
129
|
+
// > "Cannot use namespace '<nsIdentifier>' as a type."
|
|
130
|
+
// Instead the generated code should look like:
|
|
131
|
+
// import { "<unsafeTypeName>" as <safeIdentifier> } from './<moduleSpecifier>'
|
|
132
|
+
// Because it requires more complex management of local variables names,
|
|
133
|
+
// and we don't expect this to actually happen with properly designed
|
|
134
|
+
// lexicons documents, we do not support this for now.
|
|
135
|
+
throw new Error('Import of definitions with unsafe type names is not supported');
|
|
136
|
+
}
|
|
137
|
+
// import * as <nsIdentifier> from './<moduleSpecifier>'
|
|
138
|
+
const nsIdentifier = this.getNsIdentifier(nsid, moduleSpecifier);
|
|
139
|
+
return {
|
|
140
|
+
varName: (0, ts_lang_js_1.isValidJsIdentifier)(publicIds.varName)
|
|
141
|
+
? `${nsIdentifier}.${publicIds.varName}`
|
|
142
|
+
: `${nsIdentifier}[${JSON.stringify(publicIds.varName)}]`,
|
|
143
|
+
typeName: `${nsIdentifier}.${publicIds.typeName}`,
|
|
144
|
+
};
|
|
145
|
+
});
|
|
146
|
+
getNsIdentifier(nsid, moduleSpecifier) {
|
|
147
|
+
const namespaceImportDeclaration = this.file.getImportDeclaration((imp) => !imp.isTypeOnly() &&
|
|
148
|
+
imp.getModuleSpecifierValue() === moduleSpecifier &&
|
|
149
|
+
imp.getNamespaceImport() != null) ||
|
|
150
|
+
this.file.addImportDeclaration({
|
|
151
|
+
moduleSpecifier,
|
|
152
|
+
namespaceImport: this.computeSafeNamespaceIdentifierFor(nsid),
|
|
153
|
+
});
|
|
154
|
+
return namespaceImportDeclaration.getNamespaceImport().getText();
|
|
155
|
+
}
|
|
156
|
+
#nsIdentifiersCounters = new Map();
|
|
157
|
+
computeSafeNamespaceIdentifierFor(nsid) {
|
|
158
|
+
const baseName = nsidToIdentifier(nsid) || 'NS';
|
|
159
|
+
let name = baseName;
|
|
160
|
+
while (this.isConflictingIdentifier(name)) {
|
|
161
|
+
const count = this.#nsIdentifiersCounters.get(baseName) ?? 0;
|
|
162
|
+
this.#nsIdentifiersCounters.set(baseName, count + 1);
|
|
163
|
+
name = `${baseName}$$${count}`;
|
|
164
|
+
}
|
|
165
|
+
return name;
|
|
166
|
+
}
|
|
167
|
+
isConflictingIdentifier(name) {
|
|
168
|
+
return (this.conflictsWithKeywords(name) ||
|
|
169
|
+
this.conflictsWithUtils(name) ||
|
|
170
|
+
this.conflictsWithLocalDefs(name) ||
|
|
171
|
+
this.conflictsWithLocalDeclarations(name) ||
|
|
172
|
+
this.conflictsWithImports(name));
|
|
173
|
+
}
|
|
174
|
+
conflictsWithKeywords(name) {
|
|
175
|
+
return (0, ts_lang_js_1.isJsKeyword)(name) || (0, ts_lang_js_1.isGlobalIdentifier)(name);
|
|
176
|
+
}
|
|
177
|
+
conflictsWithUtils(name) {
|
|
178
|
+
// Do not allow "Main" as imported ns identifier since it has a special
|
|
179
|
+
// meaning in the context of lexicon definitions.
|
|
180
|
+
if (name === 'Main')
|
|
181
|
+
return true;
|
|
182
|
+
// When "useRecordExport" returns true, an export named "Record" will be
|
|
183
|
+
// used in addition to the hash named export. So we need to make sure both
|
|
184
|
+
// names are not conflicting with local variables.
|
|
185
|
+
if (name === 'Record')
|
|
186
|
+
return true;
|
|
187
|
+
// Utility functions generated for lexicon schemas are prefixed with "$"
|
|
188
|
+
return name.startsWith('$');
|
|
189
|
+
}
|
|
190
|
+
conflictsWithLocalDefs(name) {
|
|
191
|
+
return Object.keys(this.doc.defs).some((hash) => {
|
|
192
|
+
const identifier = (0, util_js_1.toCamelCase)(hash);
|
|
193
|
+
// A safe identifier will be generated, no risk of conflict.
|
|
194
|
+
if (!identifier)
|
|
195
|
+
return false;
|
|
196
|
+
// The imported name conflicts with a local definition name
|
|
197
|
+
if (identifier === name || `_${identifier}` === name)
|
|
198
|
+
return true;
|
|
199
|
+
// The imported name conflicts with the type name of a local definition
|
|
200
|
+
const typeName = (0, util_js_1.ucFirst)(identifier);
|
|
201
|
+
if (typeName === name || `_${typeName}` === name)
|
|
202
|
+
return true;
|
|
203
|
+
return false;
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
conflictsWithLocalDeclarations(name) {
|
|
207
|
+
return (this.file.getVariableDeclarations().some((v) => v.getName() === name) ||
|
|
208
|
+
this.file
|
|
209
|
+
.getVariableStatements()
|
|
210
|
+
.some((vs) => vs.getDeclarations().some((d) => d.getName() === name)) ||
|
|
211
|
+
this.file.getTypeAliases().some((t) => t.getName() === name) ||
|
|
212
|
+
this.file.getInterfaces().some((i) => i.getName() === name) ||
|
|
213
|
+
this.file.getClasses().some((c) => c.getName() === name) ||
|
|
214
|
+
this.file.getFunctions().some((f) => f.getName() === name) ||
|
|
215
|
+
this.file.getEnums().some((e) => e.getName() === name));
|
|
216
|
+
}
|
|
217
|
+
conflictsWithImports(name) {
|
|
218
|
+
return this.file.getImportDeclarations().some((imp) =>
|
|
219
|
+
// import name from '...'
|
|
220
|
+
imp.getDefaultImport()?.getText() === name ||
|
|
221
|
+
// import * as name from '...'
|
|
222
|
+
imp.getNamespaceImport()?.getText() === name ||
|
|
223
|
+
imp.getNamedImports().some((named) =>
|
|
224
|
+
// import { name } from '...'
|
|
225
|
+
// import { foo as name } from '...'
|
|
226
|
+
(named.getAliasNode()?.getText() ?? named.getName()) === name));
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
exports.RefResolver = RefResolver;
|
|
230
|
+
/**
|
|
231
|
+
* @see {@link https://atproto.com/specs/nsid NSID syntax spec}
|
|
232
|
+
*/
|
|
233
|
+
function nsidToIdentifier(nsid) {
|
|
234
|
+
const parts = nsid.split('.');
|
|
235
|
+
// By default, try to keep only to the last two segments of the NSID as
|
|
236
|
+
// contextual information. If those do not form a safe identifier (typically
|
|
237
|
+
// because they start with a digit), try with more segments until we reach the
|
|
238
|
+
// full NSID.
|
|
239
|
+
for (let i = 2; i < parts.length; i++) {
|
|
240
|
+
const identifier = (0, util_js_1.toPascalCase)(parts.slice(-i).join('.'));
|
|
241
|
+
if ((0, ts_lang_js_1.isSafeLocalIdentifier)(identifier))
|
|
242
|
+
return identifier;
|
|
243
|
+
}
|
|
244
|
+
return undefined;
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* Generates predictable public identifiers for a given definition hash.
|
|
248
|
+
*
|
|
249
|
+
* @note The returned `typeName` is guaranteed to be a valid TypeScript
|
|
250
|
+
* identifier. `varName` may not be a valid identifier (eg. if the hash contains
|
|
251
|
+
* unsafe characters), and may need to be accessed using string indexing.
|
|
252
|
+
*/
|
|
253
|
+
function getPublicIdentifiers(hash) {
|
|
254
|
+
const varName = hash;
|
|
255
|
+
// @NOTE we try to circumvent the issue of unsafe type names described in
|
|
256
|
+
// `RefResolver.resolveExternal` by ensuring that type names are always safe
|
|
257
|
+
// identifiers, even if it means changing them from the original hash.
|
|
258
|
+
let typeName = (0, util_js_1.toPascalCase)(hash);
|
|
259
|
+
if (varName === typeName || !(0, ts_lang_js_1.isValidJsIdentifier)(typeName)) {
|
|
260
|
+
typeName = `TypeOf${typeName}`;
|
|
261
|
+
}
|
|
262
|
+
(0, node_assert_1.default)((0, ts_lang_js_1.isValidJsIdentifier)(typeName), `Unable to generate a predictable safe identifier for "${hash}"`);
|
|
263
|
+
return { varName, typeName };
|
|
264
|
+
}
|
|
265
|
+
function asSafeDefinitionIdentifier(name) {
|
|
266
|
+
if ((0, util_js_1.startsWithLower)(name) &&
|
|
267
|
+
(0, ts_lang_js_1.isSafeLocalIdentifier)(name) &&
|
|
268
|
+
(0, ts_lang_js_1.isSafeLocalIdentifier)((0, util_js_1.ucFirst)(name))) {
|
|
269
|
+
return name;
|
|
270
|
+
}
|
|
271
|
+
const camel = (0, util_js_1.toCamelCase)(name);
|
|
272
|
+
if ((0, ts_lang_js_1.isSafeLocalIdentifier)(camel) && (0, ts_lang_js_1.isSafeLocalIdentifier)((0, util_js_1.ucFirst)(camel))) {
|
|
273
|
+
return camel;
|
|
274
|
+
}
|
|
275
|
+
return undefined;
|
|
276
|
+
}
|
|
277
|
+
//# sourceMappingURL=ref-resolver.js.map
|
|
@@ -0,0 +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 {\n isGlobalIdentifier,\n isJsKeyword,\n isSafeLocalIdentifier,\n isValidJsIdentifier,\n} from './ts-lang.js'\nimport {\n asRelativePath,\n memoize,\n startsWithLower,\n toCamelCase,\n toPascalCase,\n ucFirst,\n} from './util.js'\n\nexport type RefResolverOptions = {\n importExt?: string\n moduleSpecifier?: (nsid: string) => 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(name: string) {\n // use camelCase version of the hash as base name\n const nameSafe =\n startsWithLower(name) && isValidJsIdentifier(name)\n ? name\n : toCamelCase(name).replace(/^[0-9]+/g, '') || 'def'\n\n const count = this.#defCounters.get(nameSafe) ?? 0\n this.#defCounters.set(nameSafe, count + 1)\n\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 <nameSafe>$<number> format (\"$\" cannot appear in\n // hashes so only *we* are generating such identifiers).\n\n const identifier = `${nameSafe}$${count}`\n\n assert(\n isValidJsIdentifier(identifier),\n `Unable to generate safe identifier for: \"${name}\"`,\n )\n\n return identifier\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(hash)\n\n const typeName = ucFirst(varName)\n assert(isSafeLocalIdentifier(typeName), 'Expected safe type identifier')\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 = this.options.moduleSpecifier\n ? this.options.moduleSpecifier(nsid)\n : `${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 const publicIds = getPublicIdentifiers(hash)\n\n if (!isValidJsIdentifier(publicIds.typeName)) {\n // If <typeName> is not a valid identifier, we cannot access the type\n // using dot notation (<nsIdentifier>.<typeName>). Note that, unlike js\n // variables, types cannot be accessed using string indexing (like:\n // <nsIdentifier>['<typeName>']) because it generates TypeScript errors:\n //\n // > \"Cannot use namespace '<nsIdentifier>' as a type.\"\n\n // Instead the generated code should look like:\n // import { \"<unsafeTypeName>\" as <safeIdentifier> } from './<moduleSpecifier>'\n\n // Because it requires more complex management of local variables names,\n // and we don't expect this to actually happen with properly designed\n // lexicons documents, we do not support this for now.\n\n throw new Error(\n 'Import of definitions with unsafe type names is not supported',\n )\n }\n\n // import * as <nsIdentifier> from './<moduleSpecifier>'\n const nsIdentifier = this.getNsIdentifier(nsid, moduleSpecifier)\n\n return {\n varName: isValidJsIdentifier(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 isJsKeyword(name) || isGlobalIdentifier(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 (isSafeLocalIdentifier(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\n // @NOTE we try to circumvent the issue of unsafe type names described in\n // `RefResolver.resolveExternal` by ensuring that type names are always safe\n // identifiers, even if it means changing them from the original hash.\n let typeName = toPascalCase(hash)\n\n if (varName === typeName || !isValidJsIdentifier(typeName)) {\n typeName = `TypeOf${typeName}`\n }\n\n assert(\n isValidJsIdentifier(typeName),\n `Unable to generate a predictable safe identifier for \"${hash}\"`,\n )\n\n return { varName, typeName }\n}\n\nfunction asSafeDefinitionIdentifier(name: string) {\n if (\n startsWithLower(name) &&\n isSafeLocalIdentifier(name) &&\n isSafeLocalIdentifier(ucFirst(name))\n ) {\n return name\n }\n const camel = toCamelCase(name)\n if (isSafeLocalIdentifier(camel) && isSafeLocalIdentifier(ucFirst(camel))) {\n return camel\n }\n return undefined\n}\n"]}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export declare function isJsKeyword(word: string): boolean;
|
|
2
|
+
export declare function isGlobalIdentifier(word: string): boolean;
|
|
3
|
+
export declare function isSafeLocalIdentifier(name: string): boolean;
|
|
4
|
+
export declare function isValidJsIdentifier(name: string): boolean;
|
|
5
|
+
export declare function asNamespaceExport(name: string): string;
|
|
6
|
+
//# sourceMappingURL=ts-lang.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
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;AAkDD,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,WAE9C;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,WAEjD;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,WAM/C;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,UAE7C"}
|