@atproto/lex-builder 0.0.13 → 0.0.14

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.
Files changed (42) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/dist/filter.d.ts +55 -0
  3. package/dist/filter.d.ts.map +1 -1
  4. package/dist/filter.js +22 -0
  5. package/dist/filter.js.map +1 -1
  6. package/dist/formatter.d.ts +42 -1
  7. package/dist/formatter.d.ts.map +1 -1
  8. package/dist/formatter.js +25 -0
  9. package/dist/formatter.js.map +1 -1
  10. package/dist/index.d.ts +33 -0
  11. package/dist/index.d.ts.map +1 -1
  12. package/dist/index.js +23 -0
  13. package/dist/index.js.map +1 -1
  14. package/dist/lex-builder.d.ts +69 -0
  15. package/dist/lex-builder.d.ts.map +1 -1
  16. package/dist/lex-builder.js +20 -0
  17. package/dist/lex-builder.js.map +1 -1
  18. package/dist/lex-def-builder.d.ts +37 -1
  19. package/dist/lex-def-builder.d.ts.map +1 -1
  20. package/dist/lex-def-builder.js +11 -1
  21. package/dist/lex-def-builder.js.map +1 -1
  22. package/dist/lexicon-directory-indexer.d.ts +13 -0
  23. package/dist/lexicon-directory-indexer.d.ts.map +1 -1
  24. package/dist/lexicon-directory-indexer.js +8 -0
  25. package/dist/lexicon-directory-indexer.js.map +1 -1
  26. package/dist/ref-resolver.d.ts +71 -2
  27. package/dist/ref-resolver.d.ts.map +1 -1
  28. package/dist/ref-resolver.js +44 -2
  29. package/dist/ref-resolver.js.map +1 -1
  30. package/dist/ts-lang.d.ts +44 -0
  31. package/dist/ts-lang.d.ts.map +1 -1
  32. package/dist/ts-lang.js +48 -1
  33. package/dist/ts-lang.js.map +1 -1
  34. package/package.json +3 -3
  35. package/src/filter.ts +55 -0
  36. package/src/formatter.ts +42 -1
  37. package/src/index.ts +33 -0
  38. package/src/lex-builder.ts +69 -0
  39. package/src/lex-def-builder.ts +37 -1
  40. package/src/lexicon-directory-indexer.ts +13 -0
  41. package/src/ref-resolver.ts +71 -2
  42. package/src/ts-lang.ts +48 -1
@@ -17,18 +17,67 @@ import {
17
17
  ucFirst,
18
18
  } from './util.js'
19
19
 
20
+ /**
21
+ * Configuration options for the {@link RefResolver} class.
22
+ */
20
23
  export type RefResolverOptions = {
24
+ /**
25
+ * The file extension to use for import specifiers when resolving
26
+ * external references.
27
+ *
28
+ * @default '.js'
29
+ */
21
30
  importExt?: string
22
31
  }
23
32
 
33
+ /**
34
+ * Represents a resolved lexicon reference as TypeScript identifiers.
35
+ *
36
+ * Contains the variable name (for runtime schema) and type name (for
37
+ * TypeScript type) that can be used to reference a lexicon definition.
38
+ */
24
39
  export type ResolvedRef = {
40
+ /**
41
+ * The variable name for the runtime schema.
42
+ *
43
+ * For local definitions, this is a simple identifier.
44
+ * For external definitions, this may be a qualified name like `ns.varName`
45
+ * or bracket notation like `ns["varName"]` for unsafe identifiers.
46
+ */
25
47
  varName: string
48
+ /**
49
+ * The type name for the TypeScript type alias.
50
+ *
51
+ * Always a valid TypeScript identifier, either simple or qualified.
52
+ */
26
53
  typeName: string
27
54
  }
28
55
 
29
56
  /**
30
- * Utility class to resolve lexicon references to TypeScript identifiers,
31
- * generating "import" statements as needed.
57
+ * Resolves lexicon references to TypeScript identifiers.
58
+ *
59
+ * This class handles the resolution of `ref` types in lexicon documents,
60
+ * converting lexicon reference strings (like `com.example.foo#bar`) into
61
+ * valid TypeScript identifiers. It automatically manages:
62
+ *
63
+ * - Local references within the same document
64
+ * - External references to other lexicon documents
65
+ * - Import statement generation for external references
66
+ * - Conflict avoidance with keywords, globals, and existing declarations
67
+ *
68
+ * Results are memoized to ensure consistent identifiers for the same
69
+ * reference throughout a file.
70
+ *
71
+ * @example
72
+ * ```ts
73
+ * const resolver = new RefResolver(doc, sourceFile, indexer, options)
74
+ *
75
+ * // Resolve a local reference
76
+ * const local = await resolver.resolve('#myDef')
77
+ *
78
+ * // Resolve an external reference
79
+ * const external = await resolver.resolve('com.example.other#def')
80
+ * ```
32
81
  */
33
82
  export class RefResolver {
34
83
  constructor(
@@ -79,6 +128,19 @@ export class RefResolver {
79
128
  }
80
129
 
81
130
  /**
131
+ * Resolves a local definition hash to TypeScript identifiers.
132
+ *
133
+ * This method generates safe, non-conflicting identifiers for definitions
134
+ * within the current document. It handles edge cases like:
135
+ * - Hash names that are JavaScript keywords
136
+ * - Hash names that conflict with global identifiers
137
+ * - Multiple hashes that would produce the same identifier
138
+ *
139
+ * @param hash - The definition hash (e.g., 'main', 'record', 'myType')
140
+ * @returns A promise resolving to the TypeScript identifiers
141
+ * @throws Error if the hash does not exist in the document
142
+ * @throws Error if conflicting type names are detected
143
+ *
82
144
  * @note The returned `typeName` and `varName` are *both* guaranteed to be
83
145
  * valid TypeScript identifiers.
84
146
  */
@@ -325,6 +387,13 @@ function nsidToIdentifier(nsid: string) {
325
387
  /**
326
388
  * Generates predictable public identifiers for a given definition hash.
327
389
  *
390
+ * This function creates the "public" names that will be exported from
391
+ * generated files. The variable name uses the original hash, while the
392
+ * type name is converted to PascalCase.
393
+ *
394
+ * @param hash - The definition hash (e.g., 'main', 'myType')
395
+ * @returns The public identifiers for the definition
396
+ *
328
397
  * @note The returned `typeName` is guaranteed to be a valid TypeScript
329
398
  * identifier. `varName` may not be a valid identifier (eg. if the hash contains
330
399
  * unsafe characters), and may need to be accessed using string indexing.
package/src/ts-lang.ts CHANGED
@@ -1,5 +1,8 @@
1
1
  /**
2
- * JavaScript keywords
2
+ * Set of JavaScript reserved keywords and future reserved words.
3
+ *
4
+ * These identifiers cannot be used as variable or type names in generated code.
5
+ *
3
6
  * @see {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Lexical_grammar}
4
7
  */
5
8
  const JS_KEYWORDS = new Set([
@@ -77,6 +80,12 @@ const JS_KEYWORDS = new Set([
77
80
  'yield',
78
81
  ])
79
82
 
83
+ /**
84
+ * Checks if a word is a JavaScript reserved keyword.
85
+ *
86
+ * @param word - The identifier to check
87
+ * @returns `true` if the word is a reserved keyword
88
+ */
80
89
  export function isJsKeyword(word: string) {
81
90
  return JS_KEYWORDS.has(word)
82
91
  }
@@ -129,14 +138,42 @@ const GLOBAL_IDENTIFIERS = new Set([
129
138
  'Uncapitalize',
130
139
  ])
131
140
 
141
+ /**
142
+ * Checks if a word is a global identifier that should be avoided.
143
+ *
144
+ * This includes JavaScript globals, TypeScript built-in types, and
145
+ * identifiers commonly used in the generated code.
146
+ *
147
+ * @param word - The identifier to check
148
+ * @returns `true` if the word is a global identifier
149
+ */
132
150
  export function isGlobalIdentifier(word: string) {
133
151
  return GLOBAL_IDENTIFIERS.has(word)
134
152
  }
135
153
 
154
+ /**
155
+ * Checks if a name is safe to use as a local identifier.
156
+ *
157
+ * A safe local identifier is a valid JavaScript identifier that does not
158
+ * conflict with global identifiers.
159
+ *
160
+ * @param name - The identifier to check
161
+ * @returns `true` if the name is safe to use locally
162
+ */
136
163
  export function isSafeLocalIdentifier(name: string) {
137
164
  return !isGlobalIdentifier(name) && isValidJsIdentifier(name)
138
165
  }
139
166
 
167
+ /**
168
+ * Checks if a name is a valid JavaScript identifier.
169
+ *
170
+ * Valid identifiers start with a letter, underscore, or dollar sign,
171
+ * followed by any combination of letters, digits, underscores, or dollar
172
+ * signs. Reserved keywords are not valid identifiers.
173
+ *
174
+ * @param name - The string to check
175
+ * @returns `true` if the name is a valid identifier
176
+ */
140
177
  export function isValidJsIdentifier(name: string) {
141
178
  return (
142
179
  name.length > 0 &&
@@ -145,6 +182,16 @@ export function isValidJsIdentifier(name: string) {
145
182
  )
146
183
  }
147
184
 
185
+ /**
186
+ * Converts a name to a valid namespace export identifier.
187
+ *
188
+ * If the name is a valid JavaScript identifier, it is returned as-is.
189
+ * Otherwise, it is returned as a quoted string for use in export statements
190
+ * like `export { foo as "unsafe-name" }`.
191
+ *
192
+ * @param name - The export name
193
+ * @returns The name as a valid export identifier
194
+ */
148
195
  export function asNamespaceExport(name: string) {
149
196
  return isValidJsIdentifier(name) ? name : JSON.stringify(name)
150
197
  }