@hey-api/codegen-core 0.0.1 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -1,391 +1,592 @@
1
1
  /**
2
- * Arbitrary metadata passed to render functions.
2
+ * Bi-directional map interface.
3
3
  *
4
- * Implementors should extend this interface for their own needs.
4
+ * Keys map to values and values map back to keys.
5
+ *
6
+ * @template Key Type of the map keys
7
+ * @template Value Type of the map values
5
8
  */
6
- interface ICodegenMeta {
7
- [key: string]: unknown;
8
- }
9
-
10
- interface ICodegenOutput {
9
+ interface IBiMap<Key, Value> {
11
10
  /**
12
- * The main content of the file to output.
11
+ * Deletes a key and its associated value from the map.
13
12
  *
14
- * A raw string representing source code.
13
+ * @param key The key to delete.
14
+ */
15
+ delete(key: Key): boolean;
16
+ /**
17
+ * Deletes a value and its associated key from the map.
15
18
  *
16
- * @example "function foo(): void {\n // implementation\n}\n"
19
+ * @param value The value to delete.
17
20
  */
18
- content: string;
21
+ deleteValue(value: Value): boolean;
19
22
  /**
20
- * Optional metadata or hints for the emitter, such as formatting options,
21
- * source maps, or language-specific flags.
23
+ * Returns an iterator of [key, value] pairs.
24
+ */
25
+ entries(): IterableIterator<[Key, Value]>;
26
+ /**
27
+ * Gets the value associated with a key.
22
28
  *
23
- * @example { format: "prettier", sourceMap: true }
29
+ * @param key The key to look up.
24
30
  */
25
- meta: Record<string, unknown>;
31
+ get(key: Key): Value | undefined;
26
32
  /**
27
- * Logical output path (used for writing the file).
33
+ * Gets the key associated with a value.
28
34
  *
29
- * @example "models/user.ts"
35
+ * @param value The value to look up.
30
36
  */
31
- path: string;
32
- }
33
-
34
- interface ICodegenRenderer {
37
+ getKey(value: Value): Key | undefined;
35
38
  /**
36
- * Optional: hook for renderer-level setup logic (e.g., formatting, config)
39
+ * Checks if a key exists in the map.
40
+ *
41
+ * @param key The key to check.
37
42
  */
38
- configure?(options: Record<string, unknown>): void;
43
+ hasKey(key: Key): boolean;
39
44
  /**
40
- * Unique identifier for this renderer.
45
+ * Checks if a value exists in the map.
41
46
  *
42
- * @example "typescript"
47
+ * @param value The value to check.
48
+ */
49
+ hasValue(value: Value): boolean;
50
+ /**
51
+ * Returns an iterator of keys.
43
52
  */
44
- id: string;
53
+ keys(): IterableIterator<Key>;
45
54
  /**
46
- * Returns printable data.
55
+ * Sets a key-value pair in the map.
47
56
  *
48
- * @param file The file to render.
49
- * @param meta Arbitrary metadata.
50
- * @returns Output for file emit step
57
+ * @param key The key.
58
+ * @param value The value.
59
+ * @returns This instance for chaining.
60
+ */
61
+ set(key: Key, value: Value): this;
62
+ /**
63
+ * Number of key-value pairs in the map.
64
+ */
65
+ readonly size: number;
66
+ /**
67
+ * Returns an iterator of values.
51
68
  */
52
- render(file: CodegenFile, meta?: ICodegenMeta): ICodegenOutput;
69
+ values(): IterableIterator<Value>;
70
+ /**
71
+ * Enables iteration with `for...of`.
72
+ */
73
+ [Symbol.iterator](): IterableIterator<[Key, Value]>;
53
74
  }
54
75
 
55
- interface ICodegenSymbol {
76
+ interface IBinding {
56
77
  /**
57
- * Optional description or doc comment.
78
+ * Optional aliasing map for named symbols.
79
+ *
80
+ * Keys must be a subset of `names`, values are aliases.
58
81
  *
59
- * @example "Represents a user in the system"
82
+ * @example { User: "ImportedUser" }
60
83
  */
61
- description?: string;
84
+ aliases?: Record<string, string>;
62
85
  /**
63
- * Optional kind of symbol (e.g. "class", "function", "type", etc.).
86
+ * Name of the default binding, if any.
64
87
  *
65
- * @example "class"
88
+ * @example "React"
66
89
  */
67
- kind?: string;
90
+ defaultBinding?: string;
68
91
  /**
69
- * Unique identifier for the symbol within its file.
92
+ * Source file or external module from which symbols are imported.
70
93
  *
71
- * @example "UserModel"
94
+ * @example "./models/user"
95
+ * @example "node:path"
72
96
  */
73
- name: string;
97
+ from: string;
74
98
  /**
75
- * Internal representation of the symbol (e.g. AST node, IR object, raw
76
- * code). Used to generate output.
99
+ * Names of the symbols imported from the source.
100
+ *
101
+ * Must be non-empty unless `namespaceBinding` is true.
102
+ * All imported names, regardless of whether they are used as types or values.
103
+ *
104
+ * @example ["User", "UserDTO"]
77
105
  */
78
- value?: unknown;
79
- }
80
-
81
- interface ICodegenFile {
106
+ names?: ReadonlyArray<string>;
82
107
  /**
83
- * Adds an export to this file.
108
+ * If this import is a namespace import (e.g. `import * as ns from "..."`),
109
+ * this should be the namespace alias. Set to `true` if no alias is needed.
84
110
  *
85
- * This is also known as a re-export.
111
+ * @example "utils"
112
+ * @example true
113
+ */
114
+ namespaceBinding?: boolean | string;
115
+ /**
116
+ * Whether the default binding is type-only.
86
117
  *
87
- * @param exp The export to add
118
+ * @example true
88
119
  */
89
- addExport(exp: ICodegenImport): void;
120
+ typeDefaultBinding?: boolean;
90
121
  /**
91
- * Adds an import to this file.
122
+ * Subset of `names` that are imported using the `type` modifier.
123
+ * These symbols will be emitted as type-only imports in TypeScript.
92
124
  *
93
- * @param imp The import to add
125
+ * @example ["UserDTO"]
94
126
  */
95
- addImport(imp: ICodegenImport): void;
127
+ typeNames?: ReadonlyArray<string>;
96
128
  /**
97
- * Adds a symbol defined by this file.
129
+ * Whether the namespace binding is type-only.
98
130
  *
99
- * @param symbol The symbol to add
131
+ * @example true
100
132
  */
101
- addSymbol(symbol: ICodegenSymbol): void;
133
+ typeNamespaceBinding?: boolean;
134
+ }
135
+
136
+ /**
137
+ * Selector array used to reference resources. We don't enforce
138
+ * uniqueness, but in practice it's desirable.
139
+ *
140
+ * @example ["zod", "#/components/schemas/Foo"]
141
+ */
142
+ type ISelector = ReadonlyArray<string>;
143
+
144
+ interface IFileIn {
102
145
  /**
103
- * Symbols exported from other files.
104
- **/
105
- exports: ReadonlyArray<ICodegenImport>;
146
+ * File extension, if any.
147
+ */
148
+ readonly extension?: string;
106
149
  /**
107
- * Returns all symbols used in this file (declared + imported).
150
+ * Indicates whether the file is external, meaning it is not generated
151
+ * as part of the project but is referenced (e.g., a module from
152
+ * node_modules).
108
153
  *
109
- * @returns List of all symbols used in this file
154
+ * @example true
110
155
  */
111
- getAllSymbols(): ReadonlyArray<ICodegenSymbol>;
156
+ readonly external?: boolean;
112
157
  /**
113
- * Checks if this file contains any content.
158
+ * Unique file ID. If one is not provided, it will be auto-generated.
159
+ */
160
+ readonly id?: number;
161
+ /**
162
+ * The desired name for the file within the project. If there are multiple files
163
+ * with the same desired name, this might not end up being the actual name.
114
164
  *
115
- * This is used to determine whether we want to process the file further.
116
- * By default, we consider only symbols and exports as content.
165
+ * @example "UserModel"
166
+ */
167
+ readonly name?: string;
168
+ /**
169
+ * Absolute logical output path for the file.
117
170
  *
118
- * @returns True if the file contains content
171
+ * @example "/src/models/user.ts"
119
172
  */
120
- hasContent(): boolean;
173
+ readonly path?: string;
121
174
  /**
122
- * Checks if this file defines a symbol with the given name.
175
+ * Selector array used to select this file. It doesn't have to be
176
+ * unique, but in practice it might be desirable.
123
177
  *
124
- * @param name Symbol name to check
125
- * @returns True if the symbol is defined by this file
178
+ * @example ["zod", "#/components/schemas/Foo"]
126
179
  */
127
- hasSymbol(name: string): boolean;
180
+ readonly selector?: ISelector;
181
+ }
182
+
183
+ interface IFileOut extends IFileIn {
128
184
  /**
129
- * Symbols imported from other files.
130
- **/
131
- imports: ReadonlyArray<ICodegenImport>;
185
+ * Unique file ID.
186
+ */
187
+ readonly id: number;
188
+ /**
189
+ * Map holding resolved names for symbols in this file.
190
+ */
191
+ readonly resolvedNames: IBiMap<number, string>;
132
192
  /**
133
- * Optional metadata about the file.
134
- **/
135
- meta: {
193
+ * Symbols in this file, categorized by their role.
194
+ */
195
+ readonly symbols: {
196
+ /**
197
+ * Symbols declared in the body of this file.
198
+ */
199
+ body: Array<number>;
136
200
  /**
137
- * Optional file extension.
138
- *
139
- * @example ".ts"
201
+ * Symbols re-exported from other files.
140
202
  */
141
- extension?: '.ts' | (string & {});
203
+ exports: Array<number>;
142
204
  /**
143
- * Optional logical module or package name.
144
- *
145
- * @example "models.user"
205
+ * Symbols imported from other files.
146
206
  */
147
- moduleName?: string;
207
+ imports: Array<number>;
208
+ };
209
+ }
210
+
211
+ interface IFileRegistry {
212
+ /**
213
+ * Get a file by its ID.
214
+ *
215
+ * @param fileIdOrSelector File ID or selector to reference.
216
+ * @returns The file, or undefined if not found.
217
+ */
218
+ get(fileIdOrSelector: number | ISelector): IFileOut | undefined;
219
+ /**
220
+ * Returns the current file ID and increments it.
221
+ *
222
+ * @returns File ID before being incremented
223
+ */
224
+ readonly id: number;
225
+ /**
226
+ * Returns a file by ID or selector, registering it if it doesn't exist.
227
+ *
228
+ * @param fileIdOrSelector File ID or selector to reference.
229
+ * @returns The referenced or newly registered file.
230
+ */
231
+ reference(fileIdOrSelector: number | ISelector): IFileOut;
232
+ /**
233
+ * Get all unregistered files in the order they were referenced.
234
+ *
235
+ * @returns Array of all unregistered files, in reference order.
236
+ */
237
+ referenced(): IterableIterator<IFileOut>;
238
+ /**
239
+ * Register a file globally.
240
+ *
241
+ * Deduplicates identical files by ID.
242
+ *
243
+ * @param file File to register.
244
+ * @returns true if added, false if duplicate.
245
+ */
246
+ register(file: IFileIn): IFileOut;
247
+ /**
248
+ * Get all files in the order they were registered.
249
+ *
250
+ * @returns Array of all registered files, in insert order.
251
+ */
252
+ registered(): IterableIterator<IFileOut>;
253
+ }
254
+
255
+ /**
256
+ * Arbitrary metadata passed to the project's render function.
257
+ *
258
+ * Implementers should extend this interface for their own needs.
259
+ */
260
+ interface IProjectRenderMeta {
261
+ [key: string]: unknown;
262
+ }
263
+
264
+ /**
265
+ * Additional metadata about the symbol.
266
+ *
267
+ * Implementers should extend this interface for their own needs.
268
+ */
269
+ interface ISymbolMeta {
270
+ [key: string]: unknown;
271
+ }
272
+
273
+ interface ISymbolIn {
274
+ /**
275
+ * Array of file names (without extensions) from which this symbol is re-exported.
276
+ *
277
+ * @default undefined
278
+ */
279
+ readonly exportFrom?: ReadonlyArray<string>;
280
+ /**
281
+ * Whether this symbol is exported from its own file.
282
+ *
283
+ * @default false
284
+ */
285
+ readonly exported?: boolean;
286
+ /**
287
+ * External module name if this symbol is imported from a module not managed
288
+ * by the project (e.g. "zod", "lodash").
289
+ *
290
+ * @default undefined
291
+ */
292
+ readonly external?: string;
293
+ /**
294
+ * Optional output strategy to override default behavior.
295
+ *
296
+ * @returns The file path to output the symbol to, or undefined to fallback to default behavior.
297
+ */
298
+ readonly getFilePath?: (symbol: ISymbolOut) => string | undefined;
299
+ /**
300
+ * Unique symbol ID. If one is not provided, it will be auto-generated.
301
+ */
302
+ readonly id?: number;
303
+ /**
304
+ * Arbitrary metadata about the symbol.
305
+ *
306
+ * @default undefined
307
+ */
308
+ readonly meta?: ISymbolMeta & {
148
309
  /**
149
- * Optional path transformer.
150
- *
151
- * @param path Original file path passed to the constructor.
310
+ * Kind of import if this symbol represents an import.
152
311
  */
153
- path?: ((path: string) => string) | string;
312
+ importKind?: 'namespace' | 'default' | 'named';
154
313
  /**
155
- * Renderer ID.
156
- *
157
- * @example "typescript"
314
+ * Kind of symbol.
158
315
  */
159
- renderer?: ICodegenRenderer['id'];
316
+ kind?: 'type';
160
317
  };
161
318
  /**
162
- * Logical output path (used for writing the file).
319
+ * The desired name for the symbol within its file. If there are multiple symbols
320
+ * with the same desired name, this might not end up being the actual name.
163
321
  *
164
- * @example "models/user.ts"
322
+ * @example "UserModel"
165
323
  */
166
- path: string;
324
+ readonly name?: string;
167
325
  /**
168
- * Returns a relative path to this file from another file.
326
+ * Placeholder name for the symbol to be replaced later with the final value.
169
327
  *
170
- * @param file The file from which we want the relative path to this file.
171
- * @example "./this-file.ts"
328
+ * @example "_heyapi_31_"
172
329
  */
173
- relativePathFromFile(file: Pick<ICodegenFile, 'path'>): string;
330
+ readonly placeholder?: string;
174
331
  /**
175
- * Returns a relative path to file from this file.
332
+ * Selector array used to select this symbol. It doesn't have to be
333
+ * unique, but in practice it might be desirable.
176
334
  *
177
- * @param file The file to which we want the relative path.
178
- * @example "./another-file.ts"
335
+ * @example ["zod", "#/components/schemas/Foo"]
179
336
  */
180
- relativePathToFile(file: Pick<ICodegenFile, 'path'>): string;
337
+ readonly selector?: ISelector;
338
+ }
339
+
340
+ interface ISymbolOut extends ISymbolIn {
181
341
  /**
182
- * Top-level symbols declared in this file.
183
- **/
184
- symbols: ReadonlyArray<ICodegenSymbol>;
342
+ * Array of file names (without extensions) from which this symbol is re-exported.
343
+ */
344
+ readonly exportFrom: ReadonlyArray<string>;
345
+ /**
346
+ * Unique symbol ID.
347
+ */
348
+ readonly id: number;
349
+ /**
350
+ * Placeholder name for the symbol to be replaced later with the final value.
351
+ *
352
+ * @example "_heyapi_31_"
353
+ */
354
+ readonly placeholder: string;
185
355
  }
186
356
 
187
- interface ICodegenImport {
357
+ interface ISymbolRegistry {
188
358
  /**
189
- * Optional aliasing map for imported symbols.
359
+ * Get a symbol by its ID.
190
360
  *
191
- * Keys must be a subset of `names`, values are aliases.
361
+ * @param symbolIdOrSelector Symbol ID or selector to reference.
362
+ * @returns The symbol, or undefined if not found.
363
+ */
364
+ get(symbolIdOrSelector: number | ISelector): ISymbolOut | undefined;
365
+ /**
366
+ * Returns the value associated with a symbol ID.
192
367
  *
193
- * @example { User: "ImportedUser" }
368
+ * @param symbolId Symbol ID.
369
+ * @return The value associated with the symbol ID, or undefined if not found.
194
370
  */
195
- aliases?: Record<string, string>;
371
+ getValue(symbolId: number): unknown;
196
372
  /**
197
- * Name of the default import, if any.
373
+ * Checks if the registry has a value associated with a symbol ID.
198
374
  *
199
- * @example "React"
375
+ * @param symbolId Symbol ID.
376
+ * @returns True if the registry has a value for symbol ID, false otherwise.
200
377
  */
201
- defaultImport?: string;
378
+ hasValue(symbolId: number): boolean;
202
379
  /**
203
- * Source file or external module from which symbols are imported.
380
+ * Returns the current symbol ID and increments it.
204
381
  *
205
- * For internal files, this should be a ICodegenFile instance to enable
206
- * dynamic path computation. For external or system modules, use a string.
382
+ * @returns Symbol ID before being incremented.
383
+ */
384
+ readonly id: number;
385
+ /**
386
+ * Returns a symbol by ID or selector, registering it if it doesn't exist.
207
387
  *
208
- * @example "./models/user"
209
- * @example "node:path"
388
+ * @param symbolIdOrSelector Symbol ID or selector to reference.
389
+ * @returns The referenced or newly registered symbol.
210
390
  */
211
- from: ICodegenFile | string;
391
+ reference(symbolIdOrSelector: number | ISelector): ISymbolOut;
212
392
  /**
213
- * Names of the symbols imported from the source.
393
+ * Register a symbol globally.
214
394
  *
215
- * Must be non-empty unless `isNamespaceImport` is true.
216
- * All imported names, regardless of whether they are used as types or values.
395
+ * Deduplicates identical symbols by ID.
217
396
  *
218
- * @example ["User", "UserDTO"]
397
+ * @param symbol Symbol to register.
398
+ * @returns The registered symbol.
219
399
  */
220
- names?: ReadonlyArray<string>;
400
+ register(symbol: ISymbolIn): ISymbolOut;
221
401
  /**
222
- * If this import is a namespace import (e.g. `import * as ns from "..."`),
223
- * this should be the namespace alias. Set to `true` if no alias is needed.
402
+ * Get all symbols in the order they were registered.
224
403
  *
225
- * @example "utils"
226
- * @example true
404
+ * @returns Array of all registered symbols, in insert order.
227
405
  */
228
- namespaceImport?: boolean | string;
406
+ registered(): IterableIterator<ISymbolOut>;
229
407
  /**
230
- * Whether the default import is type-only.
408
+ * Sets a value for a symbol by its ID.
231
409
  *
232
- * @example true
410
+ * @param symbolId Symbol ID.
411
+ * @param value The value to set.
412
+ * @returns void
233
413
  */
234
- typeDefaultImport?: boolean;
414
+ setValue(symbolId: number, value: unknown): Map<number, unknown>;
415
+ }
416
+
417
+ declare const createBinding: ({ file, modulePath, symbol, symbolFile, }: {
418
+ file: IFileOut;
419
+ modulePath: string;
420
+ symbol: ISymbolOut;
421
+ symbolFile: IFileOut;
422
+ }) => IBinding;
423
+ declare const mergeBindings: (target: IBinding, source: IBinding) => void;
424
+
425
+ interface IOutput {
235
426
  /**
236
- * Subset of `names` that are imported using the `type` modifier.
237
- * These symbols will be emitted as type-only imports in TypeScript.
427
+ * The main content of the file to output.
238
428
  *
239
- * @example ["UserDTO"]
429
+ * A raw string representing source code.
430
+ *
431
+ * @example "function foo(): void {\n // implementation\n}\n"
240
432
  */
241
- typeNames?: ReadonlyArray<string>;
433
+ content: string;
242
434
  /**
243
- * Whether the namespace import is type-only.
435
+ * Logical output path (used for writing the file).
244
436
  *
245
- * @example true
437
+ * @example "models/user.ts"
246
438
  */
247
- typeNamespaceImport?: boolean;
439
+ path: string;
248
440
  }
249
441
 
250
- declare class CodegenFile implements ICodegenFile {
251
- path: string;
252
- meta: ICodegenFile['meta'];
253
- private cache;
254
- private state;
255
- constructor(path: string, meta?: ICodegenFile['meta']);
256
- addExport(exp: ICodegenImport): void;
257
- addImport(imp: ICodegenImport): void;
258
- private addImportExport;
259
- addSymbol(symbol: ICodegenSymbol): void;
260
- get exports(): ReadonlyArray<ICodegenImport>;
261
- getAllSymbols(): ReadonlyArray<ICodegenSymbol>;
262
- hasContent(): boolean;
263
- hasSymbol(name: string): boolean;
264
- get imports(): ReadonlyArray<ICodegenImport>;
265
- private mergeImportExportValues;
266
- static pathToFilePath(source: string): string;
267
- relativePathFromFile(file: Pick<ICodegenFile, 'path'>): string;
268
- relativePathToFile(file: Pick<ICodegenFile, 'path'>): string;
269
- get symbols(): ReadonlyArray<ICodegenSymbol>;
442
+ declare class FileRegistry implements IFileRegistry {
443
+ private _id;
444
+ private referenceOrder;
445
+ private registerOrder;
446
+ private selectorToId;
447
+ private values;
448
+ get(fileIdOrSelector: number | ISelector): IFileOut | undefined;
449
+ get id(): number;
450
+ private idOrSelector;
451
+ reference(fileIdOrSelector: number | ISelector): IFileOut;
452
+ referenced(): IterableIterator<IFileOut>;
453
+ register(file: IFileIn): IFileOut;
454
+ registered(): IterableIterator<IFileOut>;
270
455
  }
271
456
 
272
457
  /**
273
458
  * Represents a code generation project consisting of multiple codegen files.
274
459
  * Manages imports, symbols, and output generation across the project.
275
460
  */
276
- interface ICodegenProject {
461
+ interface IProject {
277
462
  /**
278
- * Adds an export declaration to a specific file, creating the file if it doesn't exist.
463
+ * The default file to assign symbols without a specific file selector.
279
464
  *
280
- * @param fileOrPath - File instance or file path where to add the export.
281
- * @param imp - The export declaration to add.
282
- * @example
283
- * project.addExportToFile("models/user.ts", { from: "lib", names: ["User"] });
465
+ * @default 'main'
284
466
  */
285
- addExportToFile(fileOrPath: ICodegenFile | string, imp: ICodegenImport): void;
467
+ readonly defaultFileName?: string;
286
468
  /**
287
- * Adds an import declaration to a specific file, creating the file if it doesn't exist.
469
+ * Optional function to transform file names before they are used.
288
470
  *
289
- * @param fileOrPath - File instance or file path where to add the import.
290
- * @param imp - The import declaration to add.
291
- * @example
292
- * project.addImportToFile("models/user.ts", { from: "lib", names: ["User"] });
471
+ * @param name The original file name.
472
+ * @returns The transformed file name.
293
473
  */
294
- addImportToFile(fileOrPath: ICodegenFile | string, imp: ICodegenImport): void;
474
+ readonly fileName?: (name: string) => string;
295
475
  /**
296
- * Adds a symbol to a specific file, creating the file if it doesn't exist.
297
- *
298
- * @param fileOrPath - File instance or file path where to add the symbol.
299
- * @param symbol - The symbol to add.
300
- * @example
301
- * project.addSymbolToFile("models/user.ts", { name: "User", value: tsNode });
476
+ * Centralized file registry for the project.
302
477
  */
303
- addSymbolToFile(
304
- fileOrPath: ICodegenFile | string,
305
- symbol: ICodegenSymbol,
306
- ): void;
478
+ readonly files: IFileRegistry;
307
479
  /**
308
- * Creates a new codegen file with optional metadata and adds it to the project.
309
- *
310
- * If a file with the same path already exists, it is returned instead.
480
+ * Produces output representations for all files in the project.
311
481
  *
312
- * @param path - The logical output path for the file (e.g. "models/user.ts").
313
- * @param meta - Optional renderer and metadata to attach to the file (e.g. { isInternal: true }).
314
- * @returns The newly created file instance.
482
+ * @param meta Arbitrary metadata.
483
+ * @returns Array of outputs ready for writing or further processing.
315
484
  * @example
316
- * const file = project.createFile("models/user.ts", { isInternal: true });
485
+ * project.render().forEach(output => writeFile(output));
317
486
  */
318
- createFile(
319
- path: string,
320
- meta?: ICodegenFile['meta'] & { renderer?: ICodegenRenderer },
321
- ): ICodegenFile;
487
+ render(meta?: IProjectRenderMeta): ReadonlyArray<IOutput>;
322
488
  /**
323
- * Ensures a codegen file exists and returns it.
324
- *
325
- * If a file does not exist yet, it is created with minimal information.
326
- * Later, it is expected `createFile()` will be called which will fill in
327
- * the missing information such as optional metadata.
489
+ * Map of available renderers by file extension.
328
490
  *
329
- * @param fileOrPath - The logical output path for the file or the file itself.
330
- * @returns The file instance.
331
491
  * @example
332
- * const file = project.ensureFile("models/user.ts");
492
+ * {
493
+ * ".ts": tsRenderer,
494
+ * ".js": jsRenderer,
495
+ * }
333
496
  */
334
- ensureFile(fileOrPath: ICodegenFile | string): ICodegenFile;
497
+ readonly renderers: Record<string, IRenderer>;
335
498
  /**
336
- * Returns all files in the project in insertion order.
337
- *
338
- * @example
339
- * project.files.forEach(file => console.log(file.path));
499
+ * The absolute path to the root folder of the project.
340
500
  */
341
- readonly files: ReadonlyArray<ICodegenFile>;
501
+ readonly root: string;
342
502
  /**
343
- * Returns all symbols declared or imported across all files.
503
+ * Retrieves files that include symbol ID. The first file is the one
504
+ * where the symbol is declared, the rest are files that re-export it.
344
505
  *
345
- * @returns Flattened list of all codegen symbols.
506
+ * @param symbolId The symbol ID to find.
507
+ * @returns An array of files containing the symbol.
346
508
  * @example
347
- * project.getAllSymbols().filter(s => s.name === "User");
509
+ * const files = project.symbolIdToFiles(31);
510
+ * for (const file of files) {
511
+ * console.log(file.path);
512
+ * }
513
+ */
514
+ symbolIdToFiles(symbolId: number): ReadonlyArray<IFileOut>;
515
+ /**
516
+ * Centralized symbol registry for the project.
348
517
  */
349
- getAllSymbols(): ReadonlyArray<ICodegenSymbol>;
518
+ readonly symbols: ISymbolRegistry;
519
+ }
520
+
521
+ interface IRenderer {
350
522
  /**
351
- * Retrieves a file by its logical output path.
523
+ * Renders content with replaced symbols.
352
524
  *
353
- * @param path - The file path to find.
354
- * @returns The file if found, or undefined otherwise.
355
- * @example
356
- * const file = project.getFileByPath("models/user.ts");
525
+ * @param content Content to render.
526
+ * @param file The file to render.
527
+ * @param project The parent project the file belongs to.
528
+ * @returns Rendered content.
357
529
  */
358
- getFileByPath(path: string): ICodegenFile | undefined;
530
+ renderFile(
531
+ content: string,
532
+ file: IFile,
533
+ project: IProject,
534
+ meta?: IProjectRenderMeta,
535
+ ): string;
359
536
  /**
360
- * Produces output representations for all files in the project.
537
+ * Returns printable data containing symbols and exports.
361
538
  *
539
+ * @param file The file to render.
540
+ * @param project The parent project the file belongs to.
362
541
  * @param meta Arbitrary metadata.
363
- * @returns Array of outputs ready for writing or further processing.
364
- * @example
365
- * project.render().forEach(output => writeFile(output));
542
+ * @returns Printable string containing symbols and exports.
366
543
  */
367
- render(meta?: ICodegenMeta): ReadonlyArray<ICodegenOutput>;
544
+ renderSymbols(
545
+ file: IFileOut,
546
+ project: IProject,
547
+ meta?: IProjectRenderMeta,
548
+ ): string;
368
549
  }
369
550
 
370
- declare class CodegenProject implements ICodegenProject {
371
- private filesMap;
372
- private filesOrder;
373
- private renderers;
374
- addExportToFile(fileOrPath: CodegenFile | string, imp: ICodegenImport): void;
375
- addImportToFile(fileOrPath: CodegenFile | string, imp: ICodegenImport): void;
376
- addSymbolToFile(fileOrPath: CodegenFile | string, symbol: ICodegenSymbol): void;
377
- createFile(path: string, meta?: Omit<CodegenFile['meta'], 'renderer'> & {
378
- /**
379
- * Renderer to use to render this file.
380
- */
381
- renderer?: ICodegenRenderer;
382
- }): CodegenFile;
383
- ensureFile(fileOrPath: CodegenFile | string): CodegenFile;
384
- private ensureRenderer;
385
- get files(): ReadonlyArray<CodegenFile>;
386
- getAllSymbols(): ReadonlyArray<ICodegenSymbol>;
387
- getFileByPath(path: string): CodegenFile | undefined;
388
- render(meta?: ICodegenMeta): ReadonlyArray<ICodegenOutput>;
551
+ declare class SymbolRegistry implements ISymbolRegistry {
552
+ private _id;
553
+ private nodes;
554
+ private registerOrder;
555
+ private selectorToId;
556
+ private values;
557
+ get(symbolIdOrSelector: number | ISelector): ISymbolOut | undefined;
558
+ getValue(symbolId: number): unknown;
559
+ hasValue(symbolId: number): boolean;
560
+ get id(): number;
561
+ private idOrSelector;
562
+ reference(symbolIdOrSelector: number | ISelector): ISymbolOut;
563
+ register(symbol: ISymbolIn): ISymbolOut;
564
+ registered(): IterableIterator<ISymbolOut>;
565
+ setValue(symbolId: number, value: unknown): Map<number, unknown>;
389
566
  }
390
567
 
391
- export { CodegenFile, CodegenProject, type ICodegenFile, type ICodegenImport, type ICodegenMeta, type ICodegenOutput, type ICodegenProject, type ICodegenRenderer, type ICodegenSymbol };
568
+ declare class Project implements IProject {
569
+ private symbolIdToFileIds;
570
+ readonly defaultFileName: string;
571
+ readonly files: FileRegistry;
572
+ readonly fileName?: (name: string) => string;
573
+ readonly renderers: Record<string, IRenderer>;
574
+ readonly root: string;
575
+ readonly symbols: SymbolRegistry;
576
+ constructor({ defaultFileName, fileName, renderers, root, }: Pick<IProject, 'defaultFileName' | 'fileName' | 'renderers' | 'root'>);
577
+ private getRenderer;
578
+ private prepareFiles;
579
+ render(meta?: IProjectRenderMeta): ReadonlyArray<IOutput>;
580
+ symbolIdToFiles(symbolId: number): ReadonlyArray<IFileOut>;
581
+ private symbolToFileSelector;
582
+ }
583
+
584
+ /**
585
+ *
586
+ * @param source The source string to replace.
587
+ * @param replacerFn Accepts a symbol ID, returns resolved symbol name.
588
+ * @returns The replaced source string.
589
+ */
590
+ declare const renderIds: (source: string, replacerFn: (symbolId: number) => string | undefined) => string;
591
+
592
+ export { type IBiMap as BiMap, type IBinding as Binding, type IFileOut as File, type IFileIn as FileIn, type IProject, type IOutput as Output, Project, type IProjectRenderMeta as ProjectRenderMeta, type IRenderer as Renderer, type ISelector as Selector, type ISymbolOut as Symbol, type ISymbolIn as SymbolIn, type ISymbolMeta as SymbolMeta, createBinding, mergeBindings, renderIds };