@hey-api/codegen-core 0.1.0 → 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
@@ -6,7 +6,7 @@
6
6
  * @template Key Type of the map keys
7
7
  * @template Value Type of the map values
8
8
  */
9
- interface ICodegenBiMap<Key, Value> {
9
+ interface IBiMap<Key, Value> {
10
10
  /**
11
11
  * Deletes a key and its associated value from the map.
12
12
  *
@@ -73,642 +73,512 @@ interface ICodegenBiMap<Key, Value> {
73
73
  [Symbol.iterator](): IterableIterator<[Key, Value]>;
74
74
  }
75
75
 
76
- declare class BiMap<Key, Value> implements ICodegenBiMap<Key, Value> {
77
- private map;
78
- private reverse;
79
- delete(key: Key): boolean;
80
- deleteValue(value: Value): boolean;
81
- entries(): IterableIterator<[Key, Value]>;
82
- get(key: Key): Value | undefined;
83
- getKey(value: Value): Key | undefined;
84
- hasKey(key: Key): boolean;
85
- hasValue(value: Value): boolean;
86
- keys(): IterableIterator<Key>;
87
- set(key: Key, value: Value): this;
88
- get size(): number;
89
- values(): IterableIterator<Value>;
90
- [Symbol.iterator](): IterableIterator<[Key, Value]>;
91
- }
92
-
93
- /**
94
- * Arbitrary metadata passed to render functions.
95
- *
96
- * Implementors should extend this interface for their own needs.
97
- */
98
- interface ICodegenMeta {
99
- [key: string]: unknown;
100
- }
101
-
102
- interface ICodegenOutput {
76
+ interface IBinding {
103
77
  /**
104
- * The main content of the file to output.
78
+ * Optional aliasing map for named symbols.
105
79
  *
106
- * A raw string representing source code.
80
+ * Keys must be a subset of `names`, values are aliases.
107
81
  *
108
- * @example "function foo(): void {\n // implementation\n}\n"
82
+ * @example { User: "ImportedUser" }
109
83
  */
110
- content: string;
84
+ aliases?: Record<string, string>;
111
85
  /**
112
- * Optional metadata or hints for the emitter, such as formatting options,
113
- * source maps, or language-specific flags.
86
+ * Name of the default binding, if any.
114
87
  *
115
- * @example { format: "prettier", sourceMap: true }
88
+ * @example "React"
116
89
  */
117
- meta: Record<string, unknown>;
90
+ defaultBinding?: string;
118
91
  /**
119
- * Logical output path (used for writing the file).
92
+ * Source file or external module from which symbols are imported.
120
93
  *
121
- * @example "models/user.ts"
94
+ * @example "./models/user"
95
+ * @example "node:path"
122
96
  */
123
- path: string;
124
- }
125
-
126
- interface ICodegenRenderer {
97
+ from: string;
127
98
  /**
128
- * Optional: hook for renderer-level setup logic (e.g., formatting, config)
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"]
129
105
  */
130
- configure?(options: Record<string, unknown>): void;
106
+ names?: ReadonlyArray<string>;
131
107
  /**
132
- * Unique identifier for this renderer.
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.
133
110
  *
134
- * @example "typescript"
111
+ * @example "utils"
112
+ * @example true
135
113
  */
136
- id: string;
114
+ namespaceBinding?: boolean | string;
137
115
  /**
138
- * Returns printable data containing header and imports.
116
+ * Whether the default binding is type-only.
139
117
  *
140
- * @param file The file to render.
141
- * @param meta Arbitrary metadata.
142
- * @returns Printable string containing header and imports.
118
+ * @example true
143
119
  */
144
- renderHeader(file: ICodegenFile, meta?: ICodegenMeta): string;
120
+ typeDefaultBinding?: boolean;
145
121
  /**
146
- * Returns printable data containing symbols and exports.
122
+ * Subset of `names` that are imported using the `type` modifier.
123
+ * These symbols will be emitted as type-only imports in TypeScript.
147
124
  *
148
- * @param file The file to render.
149
- * @param meta Arbitrary metadata.
150
- * @returns Printable string containing symbols and exports.
125
+ * @example ["UserDTO"]
151
126
  */
152
- renderSymbols(file: ICodegenFile, meta?: ICodegenMeta): string;
127
+ typeNames?: ReadonlyArray<string>;
153
128
  /**
154
- * Function replacing symbols with resolved names.
129
+ * Whether the namespace binding is type-only.
155
130
  *
156
- * @returns String with replaced symbols.
131
+ * @example true
157
132
  */
158
- replacerFn(args: {
159
- file: ICodegenFile;
160
- headless?: boolean;
161
- scope?: 'file' | 'project';
162
- symbolId: number;
163
- }): string | undefined;
133
+ typeNamespaceBinding?: boolean;
164
134
  }
165
135
 
166
136
  /**
167
- * Selector array used to select symbols. It doesn't have to be
168
- * unique, but in practice it might be desirable.
137
+ * Selector array used to reference resources. We don't enforce
138
+ * uniqueness, but in practice it's desirable.
169
139
  *
170
140
  * @example ["zod", "#/components/schemas/Foo"]
171
141
  */
172
- type ICodegenSymbolSelector = ReadonlyArray<string>;
142
+ type ISelector = ReadonlyArray<string>;
173
143
 
174
- interface ICodegenSymbolIn {
144
+ interface IFileIn {
175
145
  /**
176
- * Symbols can be **headed** or **headless**.
177
- *
178
- * Headless symbols never render their `value`. Headed symbols render their
179
- * `value` if defined.
180
- *
181
- * Symbols are rendered in the order they were registered as headed.
182
- *
183
- * Example 1: We register headless symbol `foo`, headed `bar`, and headed
184
- * `foo`. The render order is [`bar`, `foo`].
185
- *
186
- * Example 2: We register headed symbol `foo` and headed `bar`. The render
187
- * order is [`foo`, `bar`].
188
- *
189
- * Headless symbols can be used to claim a symbol or to represent imports
190
- * or exports.
146
+ * File extension, if any.
147
+ */
148
+ readonly extension?: string;
149
+ /**
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).
191
153
  *
192
- * @default false
154
+ * @example true
193
155
  */
194
- headless?: boolean;
156
+ readonly external?: boolean;
195
157
  /**
196
- * The desired name for the symbol within its file. If there are multiple symbols
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
197
163
  * with the same desired name, this might not end up being the actual name.
198
164
  *
199
165
  * @example "UserModel"
200
166
  */
201
- readonly name: string;
167
+ readonly name?: string;
202
168
  /**
203
- * Selector array used to select this symbol. It doesn't have to be
204
- * unique, but in practice it might be desirable.
169
+ * Absolute logical output path for the file.
205
170
  *
206
- * @example ["zod", "#/components/schemas/Foo"]
171
+ * @example "/src/models/user.ts"
207
172
  */
208
- readonly selector?: ICodegenSymbolSelector;
173
+ readonly path?: string;
209
174
  /**
210
- * Internal representation of the symbol (e.g. AST node, IR object, raw code).
211
- * Used to generate output. If left undefined, this symbol becomes `headless`.
175
+ * Selector array used to select this file. It doesn't have to be
176
+ * unique, but in practice it might be desirable.
177
+ *
178
+ * @example ["zod", "#/components/schemas/Foo"]
212
179
  */
213
- readonly value?: unknown;
180
+ readonly selector?: ISelector;
214
181
  }
215
182
 
216
- interface ICodegenSymbolOut extends ICodegenSymbolIn {
183
+ interface IFileOut extends IFileIn {
217
184
  /**
218
- * The file this symbol is located in.
219
- */
220
- readonly file: ICodegenFile;
221
- /**
222
- * Unique symbol ID.
185
+ * Unique file ID.
223
186
  */
224
187
  readonly id: number;
225
188
  /**
226
- * Placeholder name for the symbol to be replaced later with the final value.
227
- *
228
- * @example "_heyapi_31_"
189
+ * Map holding resolved names for symbols in this file.
229
190
  */
230
- readonly placeholder: string;
191
+ readonly resolvedNames: IBiMap<number, string>;
231
192
  /**
232
- * Updates this symbol.
233
- *
234
- * @param symbol The values to update.
235
- * @returns The updated symbol.
193
+ * Symbols in this file, categorized by their role.
236
194
  */
237
- readonly update: (symbol: Partial<ICodegenSymbolOut>) => ICodegenSymbolOut;
195
+ readonly symbols: {
196
+ /**
197
+ * Symbols declared in the body of this file.
198
+ */
199
+ body: Array<number>;
200
+ /**
201
+ * Symbols re-exported from other files.
202
+ */
203
+ exports: Array<number>;
204
+ /**
205
+ * Symbols imported from other files.
206
+ */
207
+ imports: Array<number>;
208
+ };
238
209
  }
239
210
 
240
- interface SelectorMethods {
211
+ interface IFileRegistry {
241
212
  /**
242
- * Retrieves symbols matching the selector.
213
+ * Get a file by its ID.
243
214
  *
244
- * @param selector The symbol selector to find.
245
- * @param file Find symbols only in this file.
246
- * @returns The array of all symbols matching the selector.
247
- * @example
248
- * const symbols = project.selectSymbolAll(["zod", "#/components/schemas/Foo"]);
215
+ * @param fileIdOrSelector File ID or selector to reference.
216
+ * @returns The file, or undefined if not found.
249
217
  */
250
- selectSymbolAll(
251
- selector: ICodegenSymbolSelector,
252
- file?: ICodegenFile,
253
- ): ReadonlyArray<ICodegenSymbolOut>;
218
+ get(fileIdOrSelector: number | ISelector): IFileOut | undefined;
254
219
  /**
255
- * Retrieves the first symbol from all symbols matching the selector.
220
+ * Returns the current file ID and increments it.
256
221
  *
257
- * @param selector The symbol selector to find.
258
- * @param file Find symbols only in this file.
259
- * @returns The symbol if found, or undefined otherwise.
260
- * @example
261
- * const symbol = project.selectSymbolFirst(["zod", "#/components/schemas/Foo"]);
222
+ * @returns File ID before being incremented
262
223
  */
263
- selectSymbolFirst(
264
- selector: ICodegenSymbolSelector,
265
- file?: ICodegenFile,
266
- ): ICodegenSymbolOut | undefined;
224
+ readonly id: number;
267
225
  /**
268
- * Retrieves the first symbol from all symbols matching the selector.
226
+ * Returns a file by ID or selector, registering it if it doesn't exist.
269
227
  *
270
- * @param selector The symbol selector to find.
271
- * @param file Find symbols only in this file.
272
- * @returns The symbol if found, or throw otherwise.
273
- * @example
274
- * const symbol = project.selectSymbolFirstOrThrow(["zod", "#/components/schemas/Foo"]);
228
+ * @param fileIdOrSelector File ID or selector to reference.
229
+ * @returns The referenced or newly registered file.
275
230
  */
276
- selectSymbolFirstOrThrow(
277
- selector: ICodegenSymbolSelector,
278
- file?: ICodegenFile,
279
- ): ICodegenSymbolOut;
231
+ reference(fileIdOrSelector: number | ISelector): IFileOut;
280
232
  /**
281
- * Retrieves the last symbol from all symbols matching the selector.
233
+ * Get all unregistered files in the order they were referenced.
282
234
  *
283
- * @param selector The symbol selector to find.
284
- * @param file Find symbols only in this file.
285
- * @returns The symbol if found, or undefined otherwise.
286
- * @example
287
- * const symbol = project.selectSymbolLast(["zod", "#/components/schemas/Foo"]);
235
+ * @returns Array of all unregistered files, in reference order.
288
236
  */
289
- selectSymbolLast(
290
- selector: ICodegenSymbolSelector,
291
- file?: ICodegenFile,
292
- ): ICodegenSymbolOut | undefined;
293
- }
294
-
295
- /**
296
- * Represents a code generation project consisting of multiple codegen files.
297
- * Manages imports, symbols, and output generation across the project.
298
- */
299
- interface ICodegenProject extends SelectorMethods {
237
+ referenced(): IterableIterator<IFileOut>;
300
238
  /**
301
- * Adds an export declaration to a specific file, creating the file if it doesn't exist.
239
+ * Register a file globally.
302
240
  *
303
- * @param fileOrPath - File instance or file path where to add the export.
304
- * @param imp - The export declaration to add.
305
- * @example
306
- * project.addExport("models/user.ts", { from: "lib", names: ["User"] });
241
+ * Deduplicates identical files by ID.
242
+ *
243
+ * @param file File to register.
244
+ * @returns true if added, false if duplicate.
307
245
  */
308
- addExport(fileOrPath: ICodegenFile | string, imp: ICodegenImport): void;
246
+ register(file: IFileIn): IFileOut;
309
247
  /**
310
- * Adds an import declaration to a specific file, creating the file if it doesn't exist.
248
+ * Get all files in the order they were registered.
311
249
  *
312
- * @param fileOrPath - File instance or file path where to add the import.
313
- * @param imp - The import declaration to add.
314
- * @example
315
- * project.addImport("models/user.ts", { from: "lib", names: ["User"] });
250
+ * @returns Array of all registered files, in insert order.
316
251
  */
317
- addImport(fileOrPath: ICodegenFile | string, imp: ICodegenImport): void;
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 {
318
274
  /**
319
- * Adds a symbol to a specific file, creating the file if it doesn't exist.
275
+ * Array of file names (without extensions) from which this symbol is re-exported.
320
276
  *
321
- * @param fileOrPath - File instance or file path where to add the symbol.
322
- * @param symbol - The symbol to add.
323
- * @returns The inserted symbol.
324
- * @example
325
- * project.addSymbol("models/user.ts", { name: "User", value: tsNode });
277
+ * @default undefined
326
278
  */
327
- addSymbol(
328
- fileOrPath: ICodegenFile | string,
329
- symbol: ICodegenSymbolIn,
330
- ): ICodegenSymbolOut;
279
+ readonly exportFrom?: ReadonlyArray<string>;
331
280
  /**
332
- * Creates a new codegen file with optional metadata and adds it to the project.
333
- *
334
- * If a file with the same path already exists, it is returned instead.
281
+ * Whether this symbol is exported from its own file.
335
282
  *
336
- * @param path - The logical output path for the file (e.g. "models/user.ts").
337
- * @param meta - Optional renderer and metadata to attach to the file (e.g. { isInternal: true }).
338
- * @returns The newly created file instance.
339
- * @example
340
- * const file = project.createFile("models/user.ts", { isInternal: true });
283
+ * @default false
341
284
  */
342
- createFile(
343
- path: string,
344
- meta?: ICodegenFile['meta'] & { renderer?: ICodegenRenderer },
345
- ): ICodegenFile;
285
+ readonly exported?: boolean;
346
286
  /**
347
- * Ensures a codegen file exists and returns it.
287
+ * External module name if this symbol is imported from a module not managed
288
+ * by the project (e.g. "zod", "lodash").
348
289
  *
349
- * If a file does not exist yet, it is created with minimal information.
350
- * Later, it is expected `createFile()` will be called which will fill in
351
- * the missing information such as optional metadata.
352
- *
353
- * @param fileOrPath - The logical output path for the file or the file itself.
354
- * @returns The file instance.
355
- * @example
356
- * const file = project.ensureFile("models/user.ts");
290
+ * @default undefined
357
291
  */
358
- ensureFile(fileOrPath: ICodegenFile | string): ICodegenFile;
292
+ readonly external?: string;
359
293
  /**
360
- * Returns all files in the project in insertion order.
294
+ * Optional output strategy to override default behavior.
361
295
  *
362
- * @example
363
- * project.files.forEach(file => console.log(file.path));
296
+ * @returns The file path to output the symbol to, or undefined to fallback to default behavior.
364
297
  */
365
- readonly files: ReadonlyArray<ICodegenFile>;
298
+ readonly getFilePath?: (symbol: ISymbolOut) => string | undefined;
366
299
  /**
367
- * Returns all symbols declared or imported across all files.
368
- *
369
- * @returns Flattened list of all codegen symbols.
370
- * @example
371
- * project.getAllSymbols().filter(s => s.name === "User");
300
+ * Unique symbol ID. If one is not provided, it will be auto-generated.
372
301
  */
373
- getAllSymbols(): ReadonlyArray<Pick<ICodegenSymbolOut, 'name'>>;
302
+ readonly id?: number;
374
303
  /**
375
- * Retrieves a file by its logical output path.
304
+ * Arbitrary metadata about the symbol.
376
305
  *
377
- * @param path - The file path to find.
378
- * @returns The file if found, or undefined otherwise.
379
- * @example
380
- * const file = project.getFileByPath("models/user.ts");
306
+ * @default undefined
381
307
  */
382
- getFileByPath(path: string): ICodegenFile | undefined;
308
+ readonly meta?: ISymbolMeta & {
309
+ /**
310
+ * Kind of import if this symbol represents an import.
311
+ */
312
+ importKind?: 'namespace' | 'default' | 'named';
313
+ /**
314
+ * Kind of symbol.
315
+ */
316
+ kind?: 'type';
317
+ };
383
318
  /**
384
- * Retrieves a file from symbol ID included in 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.
385
321
  *
386
- * @param id The symbol ID to find.
387
- * @returns The file if found, undefined otherwise.
388
- * @example
389
- * const file = project.getFileBySymbolId(31);
322
+ * @example "UserModel"
390
323
  */
391
- getFileBySymbolId(id: number): ICodegenFile | undefined;
324
+ readonly name?: string;
392
325
  /**
393
- * Retrieves a symbol from ID included in the project.
326
+ * Placeholder name for the symbol to be replaced later with the final value.
394
327
  *
395
- * @param id The symbol ID to find.
396
- * @returns The symbol if found, undefined otherwise.
397
- * @example
398
- * const symbol = project.getSymbolById(31);
328
+ * @example "_heyapi_31_"
399
329
  */
400
- getSymbolById(id: number): ICodegenSymbolOut | undefined;
330
+ readonly placeholder?: string;
401
331
  /**
402
- * Returns the current file ID and increments it.
332
+ * Selector array used to select this symbol. It doesn't have to be
333
+ * unique, but in practice it might be desirable.
403
334
  *
404
- * @returns File ID before being incremented
335
+ * @example ["zod", "#/components/schemas/Foo"]
405
336
  */
406
- incrementFileId(): number;
337
+ readonly selector?: ISelector;
338
+ }
339
+
340
+ interface ISymbolOut extends ISymbolIn {
407
341
  /**
408
- * Returns the current symbol ID and increments it.
409
- *
410
- * @returns Symbol ID before being incremented
342
+ * Array of file names (without extensions) from which this symbol is re-exported.
411
343
  */
412
- incrementSymbolId(): number;
344
+ readonly exportFrom: ReadonlyArray<string>;
413
345
  /**
414
- * Tracks added symbol across the project.
415
- *
416
- * @param symbol The symbol added to file.
417
- * @param file The file containing the added symbol.
346
+ * Unique symbol ID.
418
347
  */
419
- registerSymbol(symbol: ICodegenSymbolOut, file: ICodegenFile): void;
348
+ readonly id: number;
420
349
  /**
421
- * Produces output representations for all files in the project.
350
+ * Placeholder name for the symbol to be replaced later with the final value.
422
351
  *
423
- * @param meta Arbitrary metadata.
424
- * @returns Array of outputs ready for writing or further processing.
425
- * @example
426
- * project.render().forEach(output => writeFile(output));
352
+ * @example "_heyapi_31_"
427
353
  */
428
- render(meta?: ICodegenMeta): ReadonlyArray<ICodegenOutput>;
354
+ readonly placeholder: string;
429
355
  }
430
356
 
431
- interface ICodegenFile extends SelectorMethods {
357
+ interface ISymbolRegistry {
432
358
  /**
433
- * Adds an export to this file.
434
- *
435
- * This is also known as a re-export.
359
+ * Get a symbol by its ID.
436
360
  *
437
- * @param exp The export to add
361
+ * @param symbolIdOrSelector Symbol ID or selector to reference.
362
+ * @returns The symbol, or undefined if not found.
438
363
  */
439
- addExport(exp: ICodegenImport): void;
364
+ get(symbolIdOrSelector: number | ISelector): ISymbolOut | undefined;
440
365
  /**
441
- * Adds an import to this file.
366
+ * Returns the value associated with a symbol ID.
442
367
  *
443
- * @param imp The import to add
368
+ * @param symbolId Symbol ID.
369
+ * @return The value associated with the symbol ID, or undefined if not found.
444
370
  */
445
- addImport(imp: ICodegenImport): void;
371
+ getValue(symbolId: number): unknown;
446
372
  /**
447
- * Adds a symbol defined by this file.
373
+ * Checks if the registry has a value associated with a symbol ID.
448
374
  *
449
- * @param symbol The symbol to add
375
+ * @param symbolId Symbol ID.
376
+ * @returns True if the registry has a value for symbol ID, false otherwise.
450
377
  */
451
- addSymbol(symbol: ICodegenSymbolIn): ICodegenSymbolOut;
378
+ hasValue(symbolId: number): boolean;
452
379
  /**
453
- * Ensures a symbol for the given selector exists, so it can be
454
- * safely used.
380
+ * Returns the current symbol ID and increments it.
455
381
  *
456
- * @param symbol The symbol to find. The required selector is used
457
- * to match a symbol. If there's no match, we create a headless
458
- * instance with the provided fields.
459
- * @returns The symbol if it exists, headless instance otherwise.
382
+ * @returns Symbol ID before being incremented.
460
383
  */
461
- ensureSymbol(
462
- symbol: Partial<ICodegenSymbolIn> &
463
- Pick<Required<ICodegenSymbolIn>, 'selector'>,
464
- ): ICodegenSymbolOut;
465
- /**
466
- * Symbols exported from other files.
467
- **/
468
- exports: ReadonlyArray<ICodegenImport>;
384
+ readonly id: number;
469
385
  /**
470
- * Returns all symbols used in this file (declared + imported).
386
+ * Returns a symbol by ID or selector, registering it if it doesn't exist.
471
387
  *
472
- * @returns List of all symbols used in this file
388
+ * @param symbolIdOrSelector Symbol ID or selector to reference.
389
+ * @returns The referenced or newly registered symbol.
473
390
  */
474
- getAllSymbols(): ReadonlyArray<Pick<ICodegenSymbolOut, 'name'>>;
391
+ reference(symbolIdOrSelector: number | ISelector): ISymbolOut;
475
392
  /**
476
- * Finds a symbol by symbol ID.
393
+ * Register a symbol globally.
394
+ *
395
+ * Deduplicates identical symbols by ID.
477
396
  *
478
- * @param id Symbol ID
479
- * @returns The symbol if it exists, undefined otherwise.
397
+ * @param symbol Symbol to register.
398
+ * @returns The registered symbol.
480
399
  */
481
- getSymbolById(id: number): ICodegenSymbolOut | undefined;
400
+ register(symbol: ISymbolIn): ISymbolOut;
482
401
  /**
483
- * Checks if this file contains any content.
402
+ * Get all symbols in the order they were registered.
484
403
  *
485
- * This is used to determine whether we want to process the file further.
486
- * By default, we consider only symbols and exports as content.
487
- *
488
- * @returns True if the file contains content
404
+ * @returns Array of all registered symbols, in insert order.
489
405
  */
490
- hasContent(): boolean;
406
+ registered(): IterableIterator<ISymbolOut>;
491
407
  /**
492
- * Checks if this file defines a symbol with the given name.
408
+ * Sets a value for a symbol by its ID.
493
409
  *
494
- * @param id Symbol ID to check
495
- * @returns True if the symbol is defined by this file
410
+ * @param symbolId Symbol ID.
411
+ * @param value The value to set.
412
+ * @returns void
496
413
  */
497
- hasSymbol(id: number): 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 {
498
426
  /**
499
- * File ID within the project.
427
+ * The main content of the file to output.
428
+ *
429
+ * A raw string representing source code.
430
+ *
431
+ * @example "function foo(): void {\n // implementation\n}\n"
500
432
  */
501
- id: number;
502
- /**
503
- * Symbols imported from other files.
504
- **/
505
- imports: ReadonlyArray<ICodegenImport>;
506
- /**
507
- * Optional metadata about the file.
508
- **/
509
- meta: {
510
- /**
511
- * Optional file extension.
512
- *
513
- * @example ".ts"
514
- */
515
- extension?: '.ts' | (string & {});
516
- /**
517
- * Optional logical module or package name.
518
- *
519
- * @example "models.user"
520
- */
521
- moduleName?: string;
522
- /**
523
- * Optional path transformer.
524
- *
525
- * @param path Original file path passed to the constructor.
526
- */
527
- path?: ((path: string) => string) | string;
528
- /**
529
- * Renderer ID.
530
- *
531
- * @example "typescript"
532
- */
533
- renderer?: ICodegenRenderer['id'];
534
- };
433
+ content: string;
535
434
  /**
536
435
  * Logical output path (used for writing the file).
537
436
  *
538
437
  * @example "models/user.ts"
539
438
  */
540
439
  path: string;
440
+ }
441
+
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>;
455
+ }
456
+
457
+ /**
458
+ * Represents a code generation project consisting of multiple codegen files.
459
+ * Manages imports, symbols, and output generation across the project.
460
+ */
461
+ interface IProject {
541
462
  /**
542
- * Parent project this file belongs to.
543
- */
544
- project: ICodegenProject;
545
- /**
546
- * Returns a relative path to this file from another file.
547
- *
548
- * @param file The file from which we want the relative path to this file.
549
- * @example "./this-file.ts"
550
- */
551
- relativePathFromFile(file: Pick<ICodegenFile, 'path'>): string;
552
- /**
553
- * Returns a relative path to file from this file.
463
+ * The default file to assign symbols without a specific file selector.
554
464
  *
555
- * @param file The file to which we want the relative path.
556
- * @example "./another-file.ts"
557
- */
558
- relativePathToFile(file: Pick<ICodegenFile, 'path'>): string;
559
- /**
560
- * Map holding resolved names for symbols in this file.
465
+ * @default 'main'
561
466
  */
562
- resolvedNames: ICodegenBiMap<number, string>;
467
+ readonly defaultFileName?: string;
563
468
  /**
564
- * Top-level symbols declared in this file.
565
- **/
566
- symbols: ReadonlyArray<ICodegenSymbolOut>;
567
- /**
568
- * Updates a symbol defined by this file.
469
+ * Optional function to transform file names before they are used.
569
470
  *
570
- * @param id ID of symbol to update.
571
- * @param symbol The values to update.
572
- * @returns The updated symbol.
471
+ * @param name The original file name.
472
+ * @returns The transformed file name.
573
473
  */
574
- updateSymbol(
575
- id: number,
576
- symbol: Partial<ICodegenSymbolOut>,
577
- ): ICodegenSymbolOut;
578
- }
579
-
580
- interface ICodegenImport {
474
+ readonly fileName?: (name: string) => string;
581
475
  /**
582
- * Optional aliasing map for imported symbols.
583
- *
584
- * Keys must be a subset of `names`, values are aliases.
585
- *
586
- * @example { User: "ImportedUser" }
476
+ * Centralized file registry for the project.
587
477
  */
588
- aliases?: Record<string, string>;
478
+ readonly files: IFileRegistry;
589
479
  /**
590
- * Name of the default import, if any.
480
+ * Produces output representations for all files in the project.
591
481
  *
592
- * @example "React"
482
+ * @param meta Arbitrary metadata.
483
+ * @returns Array of outputs ready for writing or further processing.
484
+ * @example
485
+ * project.render().forEach(output => writeFile(output));
593
486
  */
594
- defaultImport?: string;
487
+ render(meta?: IProjectRenderMeta): ReadonlyArray<IOutput>;
595
488
  /**
596
- * Source file or external module from which symbols are imported.
489
+ * Map of available renderers by file extension.
597
490
  *
598
- * For internal files, this should be a ICodegenFile instance to enable
599
- * dynamic path computation. For external or system modules, use a string.
600
- *
601
- * @example "./models/user"
602
- * @example "node:path"
491
+ * @example
492
+ * {
493
+ * ".ts": tsRenderer,
494
+ * ".js": jsRenderer,
495
+ * }
603
496
  */
604
- from: ICodegenFile | string;
497
+ readonly renderers: Record<string, IRenderer>;
605
498
  /**
606
- * Names of the symbols imported from the source.
607
- *
608
- * Must be non-empty unless `isNamespaceImport` is true.
609
- * All imported names, regardless of whether they are used as types or values.
610
- *
611
- * @example ["User", "UserDTO"]
499
+ * The absolute path to the root folder of the project.
612
500
  */
613
- names?: ReadonlyArray<string>;
501
+ readonly root: string;
614
502
  /**
615
- * If this import is a namespace import (e.g. `import * as ns from "..."`),
616
- * this should be the namespace alias. Set to `true` if no alias is needed.
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.
617
505
  *
618
- * @example "utils"
619
- * @example true
506
+ * @param symbolId The symbol ID to find.
507
+ * @returns An array of files containing the symbol.
508
+ * @example
509
+ * const files = project.symbolIdToFiles(31);
510
+ * for (const file of files) {
511
+ * console.log(file.path);
512
+ * }
620
513
  */
621
- namespaceImport?: boolean | string;
514
+ symbolIdToFiles(symbolId: number): ReadonlyArray<IFileOut>;
622
515
  /**
623
- * Whether the default import is type-only.
624
- *
625
- * @example true
516
+ * Centralized symbol registry for the project.
626
517
  */
627
- typeDefaultImport?: boolean;
518
+ readonly symbols: ISymbolRegistry;
519
+ }
520
+
521
+ interface IRenderer {
628
522
  /**
629
- * Subset of `names` that are imported using the `type` modifier.
630
- * These symbols will be emitted as type-only imports in TypeScript.
523
+ * Renders content with replaced symbols.
631
524
  *
632
- * @example ["UserDTO"]
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.
633
529
  */
634
- typeNames?: ReadonlyArray<string>;
530
+ renderFile(
531
+ content: string,
532
+ file: IFile,
533
+ project: IProject,
534
+ meta?: IProjectRenderMeta,
535
+ ): string;
635
536
  /**
636
- * Whether the namespace import is type-only.
537
+ * Returns printable data containing symbols and exports.
637
538
  *
638
- * @example true
539
+ * @param file The file to render.
540
+ * @param project The parent project the file belongs to.
541
+ * @param meta Arbitrary metadata.
542
+ * @returns Printable string containing symbols and exports.
639
543
  */
640
- typeNamespaceImport?: boolean;
544
+ renderSymbols(
545
+ file: IFileOut,
546
+ project: IProject,
547
+ meta?: IProjectRenderMeta,
548
+ ): string;
641
549
  }
642
550
 
643
- declare class CodegenFile implements ICodegenFile {
644
- path: string;
645
- project: ICodegenProject;
646
- meta: ICodegenFile['meta'];
647
- private cache;
648
- private renderSymbols;
649
- private state;
650
- id: number;
651
- resolvedNames: ICodegenBiMap<number, string>;
652
- constructor(path: string, project: ICodegenProject, meta?: ICodegenFile['meta']);
653
- addExport(exp: ICodegenImport): void;
654
- addImport(imp: ICodegenImport): void;
655
- private addImportExport;
656
- private addRenderSymbol;
657
- addSymbol(symbol: ICodegenSymbolIn): ICodegenSymbolOut;
658
- ensureSymbol(symbol: Partial<ICodegenSymbolIn> & Pick<Required<ICodegenSymbolIn>, 'selector'>): ICodegenSymbolOut;
659
- get exports(): ReadonlyArray<ICodegenImport>;
660
- getAllSymbols(): ReadonlyArray<Pick<ICodegenSymbolOut, 'name'>>;
661
- private getImportExportKey;
662
- getSymbolById(id: number): ICodegenSymbolOut | undefined;
663
- hasContent(): boolean;
664
- hasSymbol(id: number): boolean;
665
- get imports(): ReadonlyArray<ICodegenImport>;
666
- private mergeImportExportValues;
667
- static pathToFilePath(source: string): string;
668
- relativePathFromFile(file: Pick<ICodegenFile, 'path'>): string;
669
- relativePathToFile(file: Pick<ICodegenFile, 'path'>): string;
670
- selectSymbolAll(selector: ICodegenSymbolSelector): ReadonlyArray<ICodegenSymbolOut>;
671
- selectSymbolFirst(selector: ICodegenSymbolSelector): ICodegenSymbolOut | undefined;
672
- selectSymbolFirstOrThrow(selector: ICodegenSymbolSelector): ICodegenSymbolOut;
673
- selectSymbolLast(selector: ICodegenSymbolSelector): ICodegenSymbolOut | undefined;
674
- get symbols(): ReadonlyArray<ICodegenSymbolOut>;
675
- updateSymbol(id: number, symbol: Partial<ICodegenSymbolOut>): ICodegenSymbolOut;
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>;
676
566
  }
677
567
 
678
- declare class CodegenProject implements ICodegenProject {
679
- private fileId;
680
- private fileIdToFile;
681
- private fileOrder;
682
- private filePathToFileId;
683
- private renderers;
684
- private selectorToSymbolIds;
685
- private symbolId;
686
- private symbolIdToFileId;
687
- addExport(fileOrPath: ICodegenFile | string, imp: ICodegenImport): void;
688
- addImport(fileOrPath: ICodegenFile | string, imp: ICodegenImport): void;
689
- addSymbol(fileOrPath: ICodegenFile | string, symbol: ICodegenSymbolIn): ICodegenSymbolOut;
690
- createFile(path: string, meta?: Omit<ICodegenFile['meta'], 'renderer'> & {
691
- /**
692
- * Renderer to use to render this file.
693
- */
694
- renderer?: ICodegenRenderer;
695
- }): ICodegenFile;
696
- ensureFile(fileOrPath: ICodegenFile | string): ICodegenFile;
697
- private ensureRenderer;
698
- get files(): ReadonlyArray<ICodegenFile>;
699
- getAllSymbols(): ReadonlyArray<Pick<ICodegenSymbolOut, 'name'>>;
700
- getFileByPath(path: string): ICodegenFile | undefined;
701
- getFileBySymbolId(id: number): ICodegenFile | undefined;
702
- private getFileRenderer;
703
- getSymbolById(id: number): ICodegenSymbolOut | undefined;
704
- incrementFileId(): number;
705
- incrementSymbolId(): number;
706
- registerSymbol(symbol: ICodegenSymbolOut, file: ICodegenFile): void;
707
- render(meta?: ICodegenMeta): ReadonlyArray<ICodegenOutput>;
708
- selectSymbolAll(selector: ICodegenSymbolSelector, file?: ICodegenFile): ReadonlyArray<ICodegenSymbolOut>;
709
- selectSymbolFirst(selector: ICodegenSymbolSelector, file?: ICodegenFile): ICodegenSymbolOut | undefined;
710
- selectSymbolFirstOrThrow(selector: ICodegenSymbolSelector, file?: ICodegenFile): ICodegenSymbolOut;
711
- selectSymbolLast(selector: ICodegenSymbolSelector, file?: ICodegenFile): ICodegenSymbolOut | undefined;
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;
712
582
  }
713
583
 
714
584
  /**
@@ -717,6 +587,6 @@ declare class CodegenProject implements ICodegenProject {
717
587
  * @param replacerFn Accepts a symbol ID, returns resolved symbol name.
718
588
  * @returns The replaced source string.
719
589
  */
720
- declare const replaceWrappedIds: (source: string, replacerFn: (symbolId: number) => string | undefined) => string;
590
+ declare const renderIds: (source: string, replacerFn: (symbolId: number) => string | undefined) => string;
721
591
 
722
- export { BiMap, CodegenFile, CodegenProject, type ICodegenBiMap, type ICodegenFile, type ICodegenImport, type ICodegenMeta, type ICodegenOutput, type ICodegenProject, type ICodegenRenderer, type ICodegenSymbolIn, type ICodegenSymbolOut, type ICodegenSymbolSelector, replaceWrappedIds };
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 };