@hey-api/codegen-core 0.3.3 → 0.4.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,431 +1,563 @@
1
- //#region src/bimap/types.d.ts
1
+ import colors from "ansi-colors";
2
+
3
+ //#region src/refs/types.d.ts
4
+
2
5
  /**
3
- * Bi-directional map interface.
6
+ * Ref wrapper which ensures a stable reference for a value.
4
7
  *
5
- * Keys map to values and values map back to keys.
8
+ * @example
9
+ * ```ts
10
+ * type NumRef = Ref<number>; // { '~ref': number }
11
+ * const num: NumRef = { '~ref': 42 };
12
+ * console.log(num['~ref']); // 42
13
+ * ```
14
+ */
15
+ type Ref<T> = {
16
+ '~ref': T;
17
+ };
18
+ /**
19
+ * Maps every property of `T` to a `Ref` of that property.
20
+ *
21
+ * @example
22
+ * ```ts
23
+ * type Foo = { a: number; b: string };
24
+ * type Refs = Refs<Foo>; // { a: Ref<number>; b: Ref<string> }
25
+ * const refs: Refs = { a: { '~ref': 1 }, b: { '~ref': 'x' } };
26
+ * console.log(refs.a['~ref'], refs.b['~ref']); // 1 'x'
27
+ * ```
28
+ */
29
+ type Refs<T> = { [K in keyof T]: Ref<T[K]> };
30
+ /**
31
+ * Unwraps a Ref to its value type.
6
32
  *
7
- * @template Key Type of the map keys
8
- * @template Value Type of the map values
33
+ * @example
34
+ * ```ts
35
+ * type N = FromRef<{ '~ref': number }>; // number
36
+ * ```
37
+ */
38
+ type FromRef<T> = T extends Ref<infer V> ? V : T;
39
+ /**
40
+ * Maps every property of a Ref-wrapped object back to its plain value.
41
+ *
42
+ * @example
43
+ * ```ts
44
+ * type Foo = { a: number; b: string };
45
+ * type Refs = Refs<Foo>; // { a: Ref<number>; b: Ref<string> }
46
+ * type Foo2 = FromRefs<Refs>; // { a: number; b: string }
47
+ * ```
48
+ */
49
+ type FromRefs<T> = { [K in keyof T]: T[K] extends Ref<infer V> ? V : T[K] };
50
+ //#endregion
51
+ //#region src/extensions.d.ts
52
+ /**
53
+ * Arbitrary metadata passed to the project's render function.
54
+ *
55
+ * Implementers should extend this interface for their own needs.
56
+ */
57
+ interface IProjectRenderMeta {
58
+ [key: string]: unknown;
59
+ }
60
+ /**
61
+ * Additional metadata about the symbol.
62
+ *
63
+ * Implementers should extend this interface for their own needs.
9
64
  */
10
- interface IBiMap<Key, Value> {
65
+ interface ISymbolMeta {
66
+ [key: string]: unknown;
67
+ }
68
+ //#endregion
69
+ //#region src/nodes/node.d.ts
70
+ interface INode<T = unknown> {
71
+ /** Perform semantic analysis. */
72
+ analyze(ctx: IAnalysisContext): void;
73
+ /** Whether this node is exported from its file. */
74
+ exported?: boolean;
75
+ /** The file this node belongs to. */
76
+ file?: File;
77
+ /** The programming language associated with this node */
78
+ language: Language;
79
+ /** Parent node in the syntax tree. */
80
+ parent?: INode;
81
+ /** Root node of the syntax tree. */
82
+ root?: INode;
83
+ /** The symbol associated with this node. */
84
+ symbol?: Symbol;
85
+ /** Convert this node into AST representation. */
86
+ toAst(): T;
87
+ /** Brand used for renderer dispatch. */
88
+ readonly '~brand': string;
89
+ }
90
+ //#endregion
91
+ //#region src/symbols/types.d.ts
92
+ type BindingKind = 'default' | 'named' | 'namespace';
93
+ type ISymbolIdentifier = number | ISymbolMeta;
94
+ type SymbolKind = 'class' | 'enum' | 'function' | 'interface' | 'namespace' | 'type' | 'var';
95
+ type SymbolNameSanitizer = (name: string) => string;
96
+ type ISymbolIn = {
11
97
  /**
12
- * Deletes a key and its associated value from the map.
98
+ * Array of file names (without extensions) from which this symbol is re-exported.
13
99
  *
14
- * @param key The key to delete.
100
+ * @default undefined
15
101
  */
16
- delete(key: Key): boolean;
102
+ exportFrom?: ReadonlyArray<string>;
17
103
  /**
18
- * Deletes a value and its associated key from the map.
104
+ * Whether this symbol is exported from its own file.
19
105
  *
20
- * @param value The value to delete.
106
+ * @default false
21
107
  */
22
- deleteValue(value: Value): boolean;
108
+ exported?: boolean;
23
109
  /**
24
- * Returns an iterator of [key, value] pairs.
110
+ * External module name if this symbol is imported from a module not managed
111
+ * by the project (e.g. "zod", "lodash").
112
+ *
113
+ * @default undefined
25
114
  */
26
- entries(): IterableIterator<[Key, Value]>;
115
+ external?: string;
27
116
  /**
28
- * Gets the value associated with a key.
117
+ * Optional output strategy to override default behavior.
29
118
  *
30
- * @param key The key to look up.
119
+ * @returns The file path to output the symbol to, or undefined to fallback to default behavior.
31
120
  */
32
- get(key: Key): Value | undefined;
121
+ getFilePath?: Symbol['getFilePath'];
33
122
  /**
34
- * Gets the key associated with a value.
35
- *
36
- * @param value The value to look up.
123
+ * Kind of import if this symbol represents an import.
124
+ */
125
+ importKind?: BindingKind;
126
+ /**
127
+ * Kind of symbol.
37
128
  */
38
- getKey(value: Value): Key | undefined;
129
+ kind?: SymbolKind;
39
130
  /**
40
- * Checks if a key exists in the map.
131
+ * Arbitrary metadata about the symbol.
41
132
  *
42
- * @param key The key to check.
133
+ * @default undefined
43
134
  */
44
- hasKey(key: Key): boolean;
135
+ meta?: ISymbolMeta;
45
136
  /**
46
- * Checks if a value exists in the map.
137
+ * The intended, user-facing name of the symbol before any conflict resolution.
138
+ * It is **not** guaranteed to be the final emitted name — aliasing may occur if the
139
+ * file contains conflicting local identifiers or other symbols with the same intended name.
47
140
  *
48
- * @param value The value to check.
141
+ * @example "UserModel"
49
142
  */
50
- hasValue(value: Value): boolean;
143
+ name: string;
144
+ };
145
+ interface ISymbolRegistry {
51
146
  /**
52
- * Returns an iterator of keys.
147
+ * Get a symbol.
148
+ *
149
+ * @param identifier Symbol identifier to reference.
150
+ * @returns The symbol, or undefined if not found.
53
151
  */
54
- keys(): IterableIterator<Key>;
152
+ get(identifier: ISymbolIdentifier): Symbol | undefined;
55
153
  /**
56
- * Sets a key-value pair in the map.
154
+ * Returns whether a symbol is registered in the registry.
57
155
  *
58
- * @param key The key.
59
- * @param value The value.
60
- * @returns This instance for chaining.
156
+ * @param identifier Symbol identifier to check.
157
+ * @returns True if the symbol is registered, false otherwise.
61
158
  */
62
- set(key: Key, value: Value): this;
159
+ isRegistered(identifier: ISymbolIdentifier): boolean;
63
160
  /**
64
- * Number of key-value pairs in the map.
161
+ * Returns the current symbol ID and increments it.
162
+ *
163
+ * @returns Symbol ID before being incremented.
65
164
  */
66
- readonly size: number;
165
+ readonly nextId: number;
67
166
  /**
68
- * Returns an iterator of values.
167
+ * Queries symbols by metadata filter.
168
+ *
169
+ * @param filter Metadata filter to query symbols by.
170
+ * @returns Array of symbols matching the filter.
69
171
  */
70
- values(): IterableIterator<Value>;
172
+ query(filter: ISymbolMeta): ReadonlyArray<Symbol>;
71
173
  /**
72
- * Enables iteration with `for...of`.
174
+ * References a symbol.
175
+ *
176
+ * @param meta Metadata filter to reference symbol by.
177
+ * @returns The referenced symbol.
73
178
  */
74
- [Symbol.iterator](): IterableIterator<[Key, Value]>;
75
- }
76
- //#endregion
77
- //#region src/bindings/types.d.ts
78
- interface IBinding {
179
+ reference(meta: ISymbolMeta): Symbol;
79
180
  /**
80
- * Optional aliasing map for named symbols.
181
+ * Register a symbol globally.
81
182
  *
82
- * Keys must be a subset of `names`, values are aliases.
183
+ * Deduplicates identical symbols by ID.
83
184
  *
84
- * @example { User: "ImportedUser" }
185
+ * @param symbol Symbol to register.
186
+ * @returns The registered symbol.
85
187
  */
86
- aliases?: Record<string, string>;
188
+ register(symbol: ISymbolIn): Symbol;
87
189
  /**
88
- * Name of the default binding, if any.
190
+ * Get all symbols in the order they were registered.
89
191
  *
90
- * @example "React"
192
+ * @returns Array of all registered symbols, in insert order.
91
193
  */
92
- defaultBinding?: string;
194
+ registered(): IterableIterator<Symbol>;
195
+ }
196
+ //#endregion
197
+ //#region src/symbols/symbol.d.ts
198
+ declare class Symbol {
93
199
  /**
94
- * Source file or external module from which symbols are imported.
200
+ * Canonical symbol this stub resolves to, if any.
95
201
  *
96
- * @example "./models/user"
97
- * @example "node:path"
202
+ * Stubs created during DSL construction may later be associated
203
+ * with a fully registered symbol. Once set, all property lookups
204
+ * should defer to the canonical symbol.
98
205
  */
99
- from: string;
206
+ private _canonical?;
100
207
  /**
101
- * Names of the symbols imported from the source.
102
- *
103
- * Must be non-empty unless `namespaceBinding` is true.
104
- * All imported names, regardless of whether they are used as types or values.
208
+ * True if this symbol is exported from its defining file.
105
209
  *
106
- * @example ["User", "UserDTO"]
210
+ * @default false
107
211
  */
108
- names?: ReadonlyArray<string>;
212
+ private _exported;
109
213
  /**
110
- * If this import is a namespace import (e.g. `import * as ns from "..."`),
111
- * this should be the namespace alias. Set to `true` if no alias is needed.
214
+ * Names of files (without extension) from which this symbol is re-exported.
112
215
  *
113
- * @example "utils"
114
- * @example true
216
+ * @default []
115
217
  */
116
- namespaceBinding?: boolean | string;
218
+ private _exportFrom;
117
219
  /**
118
- * Whether the default binding is type-only.
220
+ * External module name if this symbol is imported from a module not managed
221
+ * by the project (e.g. "zod", "lodash").
119
222
  *
120
- * @example true
223
+ * @default undefined
121
224
  */
122
- typeDefaultBinding?: boolean;
225
+ private _external?;
123
226
  /**
124
- * Subset of `names` that are imported using the `type` modifier.
125
- * These symbols will be emitted as type-only imports in TypeScript.
227
+ * The file this symbol is ultimately emitted into.
126
228
  *
127
- * @example ["UserDTO"]
229
+ * Only top-level symbols have an assigned file.
230
+ */
231
+ private _file?;
232
+ /**
233
+ * The alias-resolved, conflict-free emitted name.
128
234
  */
129
- typeNames?: ReadonlyArray<string>;
235
+ private _finalName?;
130
236
  /**
131
- * Whether the namespace binding is type-only.
237
+ * Custom strategy to determine file output path.
132
238
  *
133
- * @example true
239
+ * @returns The file path to output the symbol to, or undefined to fallback to default behavior.
134
240
  */
135
- typeNamespaceBinding?: boolean;
136
- }
137
- //#endregion
138
- //#region src/files/types.d.ts
139
- /**
140
- * Selector array used to reference files.
141
- *
142
- * @example ["foo", "bar"]
143
- */
144
- type IFileSelector = ReadonlyArray<string>;
145
- type IFileIdentifier = number | IFileSelector;
146
- type IFileIn = {
241
+ private _getFilePath?;
147
242
  /**
148
- * File extension, if any.
243
+ * How this symbol should be imported (namespace/default/named).
244
+ *
245
+ * @default 'named'
149
246
  */
150
- extension?: string;
247
+ private _importKind;
151
248
  /**
152
- * Indicates whether the file is external, meaning it is not generated
153
- * as part of the project but is referenced (e.g., a module from
154
- * node_modules).
249
+ * Kind of symbol (class, type, alias, etc.).
155
250
  *
156
- * @example true
251
+ * @default 'var'
157
252
  */
158
- external?: boolean;
253
+ private _kind;
159
254
  /**
160
- * Unique file ID. If one is not provided, it will be auto-generated.
255
+ * Arbitrary user metadata.
256
+ *
257
+ * @default undefined
161
258
  */
162
- readonly id?: number;
259
+ private _meta?;
163
260
  /**
164
- * The desired name for the file within the project. If there are multiple files
165
- * with the same desired name, this might not end up being the actual name.
261
+ * Intended user-facing name before conflict resolution.
166
262
  *
167
263
  * @example "UserModel"
168
264
  */
169
- name?: string;
265
+ private _name;
170
266
  /**
171
- * Absolute logical output path for the file.
267
+ * Optional function to sanitize the symbol name.
172
268
  *
173
- * @example "/src/models/user.ts"
269
+ * @default undefined
270
+ */
271
+ private _nameSanitizer?;
272
+ /**
273
+ * Node that defines this symbol.
174
274
  */
175
- path?: string;
275
+ private _node?;
276
+ /** Brand used for identifying symbols. */
277
+ readonly '~brand' = "heyapi.symbol";
278
+ /** Globally unique, stable symbol ID. */
279
+ readonly id: number;
280
+ constructor(input: ISymbolIn, id: number);
176
281
  /**
177
- * Selector array used to select this file.
282
+ * Returns the canonical symbol for this instance.
178
283
  *
179
- * @example ["foo", "bar"]
284
+ * If this symbol was created as a stub, this getter returns
285
+ * the fully registered canonical symbol. Otherwise, it returns
286
+ * the symbol itself.
180
287
  */
181
- readonly selector?: IFileSelector;
182
- };
183
- type IFileOut = IFileIn & {
288
+ get canonical(): Symbol;
184
289
  /**
185
- * Unique file ID.
290
+ * Indicates whether this symbol is exported from its defining file.
186
291
  */
187
- readonly id: number;
292
+ get exported(): boolean;
188
293
  /**
189
- * Map holding resolved names for symbols in this file.
190
- */
191
- readonly resolvedNames: IBiMap<number, string>;
192
- /**
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>;
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
- };
209
- };
210
- interface IFileRegistry {
294
+ * Names of files (without extension) that re-export this symbol.
295
+ */
296
+ get exportFrom(): ReadonlyArray<string>;
211
297
  /**
212
- * Get a file.
213
- *
214
- * @param identifier File identifier to reference.
215
- * @returns The file, or undefined if not found.
298
+ * External module from which this symbol originates, if any.
216
299
  */
217
- get(identifier: IFileIdentifier): IFileOut | undefined;
300
+ get external(): string | undefined;
218
301
  /**
219
- * Returns the current file ID and increments it.
302
+ * Read‑only accessor for the assigned output file.
220
303
  *
221
- * @returns File ID before being incremented
304
+ * Only top-level symbols have an assigned file.
222
305
  */
223
- readonly id: number;
306
+ get file(): File | undefined;
224
307
  /**
225
- * Returns whether a file is registered in the registry.
226
- *
227
- * @param identifier File identifier to check.
228
- * @returns True if the file is registered, false otherwise.
308
+ * Read‑only accessor for the resolved final emitted name.
229
309
  */
230
- isRegistered(identifier: IFileIdentifier): boolean;
310
+ get finalName(): string;
231
311
  /**
232
- * Returns a file by identifier, registering it if it doesn't exist.
233
- *
234
- * @param identifier File identifier to reference.
235
- * @returns The referenced or newly registered file.
312
+ * Custom file path resolver, if provided.
236
313
  */
237
- reference(identifier: IFileIdentifier): IFileOut;
314
+ get getFilePath(): ((symbol: Symbol) => string | undefined) | undefined;
238
315
  /**
239
- * Get all unregistered files in the order they were referenced.
240
- *
241
- * @returns Array of all unregistered files, in reference order.
316
+ * How this symbol should be imported (named/default/namespace).
242
317
  */
243
- referenced(): IterableIterator<IFileOut>;
318
+ get importKind(): BindingKind;
244
319
  /**
245
- * Register a file globally.
320
+ * Indicates whether this is a canonical symbol (not a stub).
321
+ */
322
+ get isCanonical(): boolean;
323
+ /**
324
+ * The symbol's kind (class, type, alias, variable, etc.).
325
+ */
326
+ get kind(): SymbolKind;
327
+ /**
328
+ * Arbitrary user‑provided metadata associated with this symbol.
329
+ */
330
+ get meta(): ISymbolMeta | undefined;
331
+ /**
332
+ * User-intended name before aliasing or conflict resolution.
333
+ */
334
+ get name(): string;
335
+ /**
336
+ * Optional function to sanitize the symbol name.
337
+ */
338
+ get nameSanitizer(): SymbolNameSanitizer | undefined;
339
+ /**
340
+ * Read‑only accessor for the defining node.
341
+ */
342
+ get node(): INode | undefined;
343
+ /**
344
+ * Marks this symbol as a stub and assigns its canonical symbol.
246
345
  *
247
- * Deduplicates identical files by ID.
346
+ * After calling this, all semantic queries (name, kind, file,
347
+ * meta, etc.) should reflect the canonical symbol's values.
248
348
  *
249
- * @param file File to register.
250
- * @returns true if added, false if duplicate.
349
+ * @param symbol The canonical symbol this stub should resolve to.
251
350
  */
252
- register(file: IFileIn): IFileOut;
351
+ setCanonical(symbol: Symbol): void;
253
352
  /**
254
- * Get all files in the order they were registered.
353
+ * Marks the symbol as exported from its file.
255
354
  *
256
- * @returns Array of all registered files, in insert order.
355
+ * @param exported Whether the symbol is exported.
257
356
  */
258
- registered(): IterableIterator<IFileOut>;
259
- }
260
- //#endregion
261
- //#region src/extensions/types.d.ts
262
- /**
263
- * Arbitrary metadata passed to the project's render function.
264
- *
265
- * Implementers should extend this interface for their own needs.
266
- */
267
- interface IProjectRenderMeta {
268
- [key: string]: unknown;
269
- }
270
- /**
271
- * Additional metadata about the symbol.
272
- *
273
- * Implementers should extend this interface for their own needs.
274
- */
275
- interface ISymbolMeta {
276
- [key: string]: unknown;
277
- }
278
- //#endregion
279
- //#region src/symbols/types.d.ts
280
- type ISymbolIdentifier = number | ISymbolMeta;
281
- type ISymbolIn = {
357
+ setExported(exported: boolean): void;
282
358
  /**
283
- * Array of file names (without extensions) from which this symbol is re-exported.
359
+ * Records file names that re‑export this symbol.
284
360
  *
285
- * @default undefined
361
+ * @param list — Source files re‑exporting this symbol.
286
362
  */
287
- exportFrom?: ReadonlyArray<string>;
363
+ setExportFrom(list: ReadonlyArray<string>): void;
288
364
  /**
289
- * Whether this symbol is exported from its own file.
365
+ * Assigns the output file this symbol will be emitted into.
290
366
  *
291
- * @default false
367
+ * This may only be set once.
292
368
  */
293
- exported?: boolean;
369
+ setFile(file: File): void;
294
370
  /**
295
- * External module name if this symbol is imported from a module not managed
296
- * by the project (e.g. "zod", "lodash").
371
+ * Assigns the conflict‑resolved final local name for this symbol.
297
372
  *
298
- * @default undefined
373
+ * This may only be set once.
299
374
  */
300
- external?: string;
375
+ setFinalName(name: string): void;
301
376
  /**
302
- * Optional output strategy to override default behavior.
377
+ * Sets how this symbol should be imported.
303
378
  *
304
- * @returns The file path to output the symbol to, or undefined to fallback to default behavior.
379
+ * @param kind The import strategy (named/default/namespace).
305
380
  */
306
- getFilePath?: (symbol: ISymbolOut) => string | undefined;
381
+ setImportKind(kind: BindingKind): void;
307
382
  /**
308
- * Unique symbol ID. If one is not provided, it will be auto-generated.
383
+ * Sets the symbol's kind (class, type, alias, variable, etc.).
384
+ *
385
+ * @param kind — The new symbol kind.
309
386
  */
310
- readonly id?: number;
387
+ setKind(kind: SymbolKind): void;
311
388
  /**
312
- * Kind of import if this symbol represents an import.
389
+ * Updates the intended user‑facing name for this symbol.
390
+ *
391
+ * @param name — The new name.
313
392
  */
314
- importKind?: 'namespace' | 'default' | 'named';
393
+ setName(name: string): void;
315
394
  /**
316
- * Kind of symbol.
395
+ * Sets a custom function to sanitize the symbol's name.
396
+ *
397
+ * @param fn — The name sanitizer function to apply.
317
398
  */
318
- kind?: 'class' | 'function' | 'type';
399
+ setNameSanitizer(fn: SymbolNameSanitizer): void;
319
400
  /**
320
- * Arbitrary metadata about the symbol.
401
+ * Binds the node that defines this symbol.
321
402
  *
322
- * @default undefined
403
+ * This may only be set once.
323
404
  */
324
- meta?: ISymbolMeta;
405
+ setNode(node: INode): void;
325
406
  /**
326
- * The desired name for the symbol within its file. If there are multiple symbols
327
- * with the same desired name, this might not end up being the actual name.
328
- *
329
- * @example "UserModel"
407
+ * Returns a debug‑friendly string representation identifying the symbol.
330
408
  */
331
- name?: string;
409
+ toString(): string;
332
410
  /**
333
- * Placeholder name for the symbol to be replaced later with the final value.
411
+ * Ensures this symbol is canonical before allowing mutation.
412
+ *
413
+ * A symbol that has been marked as a stub (i.e., its `_canonical` points
414
+ * to a different symbol) may not be mutated. This guard throws an error
415
+ * if any setter attempts to modify a stub, preventing accidental writes
416
+ * to non‑canonical instances.
334
417
  *
335
- * @example "_heyapi_31_"
418
+ * @throws {Error} If the symbol is a stub and is being mutated.
336
419
  */
337
- readonly placeholder?: string;
420
+ private assertCanonical;
421
+ }
422
+ //#endregion
423
+ //#region src/planner/types.d.ts
424
+ type Input = Ref<object> | object | string | number | undefined;
425
+ type NameScopes = Map<string, Set<SymbolKind>>;
426
+ type NameConflictResolver = (args: {
427
+ attempt: number;
428
+ baseName: string;
429
+ }) => string | null;
430
+ type Scope = {
431
+ /** Child scopes. */
432
+ children: Array<Scope>;
433
+ /** Resolved names in this scope. */
434
+ localNames: NameScopes;
435
+ /** Parent scope, if any. */
436
+ parent?: Scope;
437
+ /** Symbols registered in this scope. */
438
+ symbols: Array<Ref<Symbol>>;
338
439
  };
339
- type ISymbolOut = Omit<ISymbolIn, 'id' | 'placeholder'> & Pick<Required<ISymbolIn>, 'id' | 'placeholder'>;
340
- interface ISymbolRegistry {
440
+ interface IAnalysisContext {
441
+ /** Register a dependency on another symbol. */
442
+ addDependency(symbol: Ref<Symbol>): void;
443
+ /** Register a dependency on another symbol or analyze further. */
444
+ analyze(input: Input): void;
445
+ /** Get local names in the current scope. */
446
+ localNames(scope: Scope): NameScopes;
447
+ /** Pop the current local scope. */
448
+ popScope(): void;
449
+ /** Push a new local scope. */
450
+ pushScope(): void;
451
+ /** Current local scope. */
452
+ scope: Scope;
453
+ /** Stack of local name scopes. */
454
+ scopes: Scope;
455
+ /** Top-level symbol for the current analysis pass. */
456
+ symbol?: Symbol;
457
+ /** Walks all symbols in the scope tree in depth-first order. */
458
+ walkScopes(callback: (symbol: Ref<Symbol>, scope: Scope) => void, scope?: Scope): void;
459
+ }
460
+ //#endregion
461
+ //#region src/languages/types.d.ts
462
+ type Extensions = Partial<Record<Language, ReadonlyArray<string>>>;
463
+ type Language = 'c' | 'c#' | 'c++' | 'css' | 'dart' | 'go' | 'haskell' | 'html' | 'java' | 'javascript' | 'json' | 'kotlin' | 'lua' | 'markdown' | 'matlab' | 'perl' | 'php' | 'python' | 'r' | 'ruby' | 'rust' | 'scala' | 'shell' | 'sql' | 'swift' | 'typescript' | 'yaml' | (string & {});
464
+ // other/custom language
465
+
466
+ type NameConflictResolvers = Partial<Record<Language, NameConflictResolver>>;
467
+ //#endregion
468
+ //#region src/files/types.d.ts
469
+ type FileKeyArgs = Pick<Required<File>, 'logicalFilePath'> & Pick<Partial<File>, 'external' | 'language'>;
470
+ type IFileIn = {
341
471
  /**
342
- * Get a symbol.
472
+ * Indicates whether the file is external, meaning it is not generated
473
+ * as part of the project but is referenced (e.g., a module from
474
+ * node_modules).
343
475
  *
344
- * @param identifier Symbol identifier to reference.
345
- * @returns The symbol, or undefined if not found.
476
+ * @example true
346
477
  */
347
- get(identifier: ISymbolIdentifier): ISymbolOut | undefined;
478
+ external?: boolean;
348
479
  /**
349
- * Returns the value associated with a symbol ID.
480
+ * Language of the file.
350
481
  *
351
- * @param symbolId Symbol ID.
352
- * @return The value associated with the symbol ID, or undefined if not found.
482
+ * @example "typescript"
353
483
  */
354
- getValue(symbolId: number): unknown;
484
+ language?: Language;
355
485
  /**
356
- * Checks if the registry has a value associated with a symbol ID.
486
+ * Logical, extension-free path used for planning and routing.
357
487
  *
358
- * @param symbolId Symbol ID.
359
- * @returns True if the registry has a value for symbol ID, false otherwise.
488
+ * @example "src/models/user"
360
489
  */
361
- hasValue(symbolId: number): boolean;
490
+ logicalFilePath: string;
362
491
  /**
363
- * Returns the current symbol ID and increments it.
492
+ * The desired name for the file within the project. If there are multiple files
493
+ * with the same desired name, this might not end up being the actual name.
364
494
  *
365
- * @returns Symbol ID before being incremented.
495
+ * @example "UserModel"
366
496
  */
367
- readonly id: number;
497
+ name?: string;
498
+ };
499
+ interface IFileRegistry {
368
500
  /**
369
- * Returns whether a symbol is registered in the registry.
501
+ * Get a file.
370
502
  *
371
- * @param identifier Symbol identifier to check.
372
- * @returns True if the symbol is registered, false otherwise.
503
+ * @returns The file, or undefined if not found.
373
504
  */
374
- isRegistered(identifier: ISymbolIdentifier): boolean;
505
+ get(args: FileKeyArgs): File | undefined;
375
506
  /**
376
- * Queries symbols by metadata filter.
507
+ * Returns whether a file is registered in the registry.
377
508
  *
378
- * @param filter Metadata filter to query symbols by.
379
- * @returns Array of symbols matching the filter.
509
+ * @returns True if the file is registered, false otherwise.
380
510
  */
381
- query(filter: ISymbolMeta): ReadonlyArray<ISymbolOut>;
511
+ isRegistered(args: FileKeyArgs): boolean;
382
512
  /**
383
- * References a symbol.
513
+ * Returns the current file ID and increments it.
384
514
  *
385
- * @param meta Metadata filter to reference symbol by.
386
- * @returns The referenced symbol.
515
+ * @returns File ID before being incremented
387
516
  */
388
- reference(meta: ISymbolMeta): ISymbolOut;
517
+ readonly nextId: number;
389
518
  /**
390
- * Register a symbol globally.
519
+ * Register a file globally.
391
520
  *
392
- * Deduplicates identical symbols by ID.
521
+ * @param file File to register.
522
+ * @returns Newly registered file if created, merged file otherwise.
523
+ */
524
+ register(file: IFileIn): File;
525
+ /**
526
+ * Get all files in the order they were registered.
393
527
  *
394
- * @param symbol Symbol to register.
395
- * @returns The registered symbol.
528
+ * @returns Array of all registered files, in insert order.
396
529
  */
397
- register(symbol: ISymbolIn): ISymbolOut;
530
+ registered(): IterableIterator<File>;
531
+ }
532
+ //#endregion
533
+ //#region src/nodes/types.d.ts
534
+ interface INodeRegistry {
398
535
  /**
399
- * Get all symbols in the order they were registered.
536
+ * Register a syntax node.
400
537
  *
401
- * @returns Array of all registered symbols, in insert order.
538
+ * @returns The index of the registered node.
539
+ */
540
+ add(node: INode | null): number;
541
+ /**
542
+ * All nodes in insertion order.
543
+ */
544
+ all(): Iterable<INode>;
545
+ /**
546
+ * Remove a node by its index.
547
+ *
548
+ * @param index Index of the node to remove.
402
549
  */
403
- registered(): IterableIterator<ISymbolOut>;
550
+ remove(index: number): void;
404
551
  /**
405
- * Sets a value for a symbol by its ID.
552
+ * Update a node at the given index.
406
553
  *
407
- * @param symbolId Symbol ID.
408
- * @param value The value to set.
409
- * @returns void
554
+ * @param index Index of the node to update.
555
+ * @param node New node to set.
410
556
  */
411
- setValue(symbolId: number, value: unknown): Map<number, unknown>;
557
+ update(index: number, node: INode | null): void;
412
558
  }
413
559
  //#endregion
414
- //#region src/bindings/utils.d.ts
415
- declare const createBinding: ({
416
- file,
417
- modulePath,
418
- symbol,
419
- symbolFile
420
- }: {
421
- file: IFileOut;
422
- modulePath: string;
423
- symbol: ISymbolOut;
424
- symbolFile: IFileOut;
425
- }) => IBinding;
426
- declare const mergeBindings: (target: IBinding, source: IBinding) => void;
427
- //#endregion
428
- //#region src/output/types.d.ts
560
+ //#region src/output.d.ts
429
561
  interface IOutput {
430
562
  /**
431
563
  * The main content of the file to output.
@@ -443,26 +575,32 @@ interface IOutput {
443
575
  path: string;
444
576
  }
445
577
  //#endregion
446
- //#region src/files/registry.d.ts
447
- declare class FileRegistry implements IFileRegistry {
448
- private _id;
449
- private referenceOrder;
450
- private registerOrder;
451
- private selectorToId;
452
- private values;
453
- get(identifier: IFileIdentifier): IFileOut | undefined;
454
- get id(): number;
455
- private identifierToFile;
456
- isRegistered(identifier: IFileIdentifier): boolean;
457
- reference(identifier: IFileIdentifier): IFileOut;
458
- referenced(): IterableIterator<IFileOut>;
459
- register(file: IFileIn): IFileOut;
460
- registered(): IterableIterator<IFileOut>;
578
+ //#region src/renderer.d.ts
579
+ interface RenderContext {
580
+ /**
581
+ * The current file.
582
+ */
583
+ file: File;
584
+ /**
585
+ * Arbitrary metadata.
586
+ */
587
+ meta?: IProjectRenderMeta;
588
+ /**
589
+ * The project the file belongs to.
590
+ */
591
+ project: IProject;
592
+ }
593
+ interface Renderer {
594
+ /** Renders the given file. */
595
+ render(ctx: RenderContext): string;
596
+ /** Returns whether this renderer can render the given file. */
597
+ supports(ctx: RenderContext): boolean;
461
598
  }
462
599
  //#endregion
463
600
  //#region src/project/types.d.ts
464
601
  /**
465
- * Represents a code generation project consisting of multiple codegen files.
602
+ * Represents a code generation project consisting of codegen files.
603
+ *
466
604
  * Manages imports, symbols, and output generation across the project.
467
605
  */
468
606
  interface IProject {
@@ -471,18 +609,24 @@ interface IProject {
471
609
  *
472
610
  * @default 'main'
473
611
  */
474
- readonly defaultFileName?: string;
612
+ readonly defaultFileName: string;
613
+ /** Default name conflict resolver used when a file has no specific resolver. */
614
+ readonly defaultNameConflictResolver: NameConflictResolver;
615
+ /** Maps language to array of extensions. First element is used by default. */
616
+ readonly extensions: Extensions;
475
617
  /**
476
- * Optional function to transform file names before they are used.
618
+ * Function to transform file names before they are used.
477
619
  *
478
620
  * @param name The original file name.
479
621
  * @returns The transformed file name.
480
622
  */
481
623
  readonly fileName?: (name: string) => string;
482
- /**
483
- * Centralized file registry for the project.
484
- */
624
+ /** Centralized file registry for the project. */
485
625
  readonly files: IFileRegistry;
626
+ /** Map of language-specific name conflict resolvers for files in the project. */
627
+ readonly nameConflictResolvers: NameConflictResolvers;
628
+ /** Centralized node registry for the project. */
629
+ readonly nodes: INodeRegistry;
486
630
  /**
487
631
  * Produces output representations for all files in the project.
488
632
  *
@@ -493,82 +637,273 @@ interface IProject {
493
637
  */
494
638
  render(meta?: IProjectRenderMeta): ReadonlyArray<IOutput>;
495
639
  /**
496
- * Map of available renderers by file extension.
640
+ * List of available renderers.
497
641
  *
498
642
  * @example
499
- * {
500
- * ".ts": tsRenderer,
501
- * ".js": jsRenderer,
502
- * }
643
+ * [new TypeScriptRenderer()]
503
644
  */
504
- readonly renderers: Record<string, IRenderer>;
645
+ readonly renderers: ReadonlyArray<Renderer>;
646
+ /** The absolute path to the root folder of the project. */
647
+ readonly root: string;
648
+ /** Centralized symbol registry for the project. */
649
+ readonly symbols: ISymbolRegistry;
650
+ }
651
+ //#endregion
652
+ //#region src/files/file.d.ts
653
+ declare class File {
505
654
  /**
506
- * The absolute path to the root folder of the project.
655
+ * Exports from this file.
507
656
  */
508
- readonly root: string;
657
+ private _exports;
658
+ /**
659
+ * File extension (e.g. `.ts`).
660
+ */
661
+ private _extension?;
662
+ /**
663
+ * Actual emitted file path, including extension and directories.
664
+ */
665
+ private _finalPath?;
666
+ /**
667
+ * Imports to this file.
668
+ */
669
+ private _imports;
670
+ /**
671
+ * Language of the file.
672
+ */
673
+ private _language?;
674
+ /**
675
+ * Logical, extension-free path used for planning and routing.
676
+ */
677
+ private _logicalFilePath;
678
+ /**
679
+ * Base name of the file (without extension).
680
+ */
681
+ private _name?;
682
+ /**
683
+ * Syntax nodes contained in this file.
684
+ */
685
+ private _nodes;
686
+ /**
687
+ * Renderer assigned to this file.
688
+ */
689
+ private _renderer?;
690
+ /** Brand used for identifying files. */
691
+ readonly '~brand' = "heyapi.file";
692
+ /** All names defined in this file, including local scopes. */
693
+ allNames: NameScopes;
694
+ /** Whether this file is external to the project. */
695
+ external: boolean;
696
+ /** Unique identifier for the file. */
697
+ readonly id: number;
698
+ /** The project this file belongs to. */
699
+ readonly project: IProject;
700
+ /** Names declared at the top level of the file. */
701
+ topLevelNames: NameScopes;
702
+ constructor(input: IFileIn, id: number, project: IProject);
703
+ /**
704
+ * Exports from this file.
705
+ */
706
+ get exports(): ReadonlyArray<ExportModule>;
707
+ /**
708
+ * Read-only accessor for the file extension.
709
+ */
710
+ get extension(): string | undefined;
509
711
  /**
510
- * Retrieves files that include symbol ID. The first file is the one
511
- * where the symbol is declared, the rest are files that re-export it.
712
+ * Read-only accessor for the final emitted path.
512
713
  *
513
- * @param symbolId The symbol ID to find.
514
- * @returns An array of files containing the symbol.
515
- * @example
516
- * const files = project.symbolIdToFiles(31);
517
- * for (const file of files) {
518
- * console.log(file.path);
519
- * }
714
+ * If undefined, the file has not yet been assigned a final path
715
+ * or is external to the project and should not be emitted.
520
716
  */
521
- symbolIdToFiles(symbolId: number): ReadonlyArray<IFileOut>;
717
+ get finalPath(): string | undefined;
522
718
  /**
523
- * Centralized symbol registry for the project.
719
+ * Imports to this file.
524
720
  */
525
- readonly symbols: ISymbolRegistry;
721
+ get imports(): ReadonlyArray<ImportModule>;
722
+ /**
723
+ * Language of the file; inferred from nodes or fallback if not set explicitly.
724
+ */
725
+ get language(): Language | undefined;
726
+ /**
727
+ * Logical, extension-free path used for planning and routing.
728
+ */
729
+ get logicalFilePath(): string;
730
+ /**
731
+ * Base name of the file (without extension).
732
+ *
733
+ * If no name was set explicitly, it is inferred from the logical file path.
734
+ */
735
+ get name(): string;
736
+ /**
737
+ * Syntax nodes contained in this file.
738
+ */
739
+ get nodes(): ReadonlyArray<INode>;
740
+ /**
741
+ * Renderer assigned to this file.
742
+ */
743
+ get renderer(): Renderer | undefined;
744
+ /**
745
+ * Add an export group to the file.
746
+ */
747
+ addExport(group: ExportModule): void;
748
+ /**
749
+ * Add an import group to the file.
750
+ */
751
+ addImport(group: ImportModule): void;
752
+ /**
753
+ * Add a syntax node to the file.
754
+ */
755
+ addNode(node: INode): void;
756
+ /**
757
+ * Sets the file extension.
758
+ */
759
+ setExtension(extension: string): void;
760
+ /**
761
+ * Sets the final emitted path of the file.
762
+ */
763
+ setFinalPath(path: string): void;
764
+ /**
765
+ * Sets the language of the file.
766
+ */
767
+ setLanguage(lang: Language): void;
768
+ /**
769
+ * Sets the name of the file.
770
+ */
771
+ setName(name: string): void;
772
+ /**
773
+ * Sets the renderer assigned to this file.
774
+ */
775
+ setRenderer(renderer: Renderer): void;
776
+ /**
777
+ * Returns a debug‑friendly string representation identifying the file.
778
+ */
779
+ toString(): string;
526
780
  }
527
781
  //#endregion
528
- //#region src/renderer/types.d.ts
529
- interface IRenderer {
782
+ //#region src/bindings.d.ts
783
+ interface ExportMember {
530
784
  /**
531
- * Renders content with replaced symbols.
785
+ * Name under which the symbol is exported in this file.
532
786
  *
533
- * @param content Content to render.
534
- * @param file The file to render.
535
- * @param project The parent project the file belongs to.
536
- * @returns Rendered content.
787
+ * export { Foo as Bar } from "./models"
788
+ *
789
+ * exportedName === "Bar"
537
790
  */
538
- renderFile(content: string, file: IFile, project: IProject, meta?: IProjectRenderMeta): string;
791
+ exportedName: string;
792
+ /** Whether this export is type-only. */
793
+ isTypeOnly: boolean;
794
+ /** Export flavor. */
795
+ kind: BindingKind;
796
+ /** The exported name of the symbol in its source file. */
797
+ sourceName: string;
798
+ }
799
+ type ExportModule = Pick<ExportMember, 'isTypeOnly'> & {
800
+ /** Whether this module can export all symbols: `export * from 'module'`. */
801
+ canExportAll: boolean;
802
+ /** Members exported from this module. */
803
+ exports: Array<ExportMember>;
804
+ /** Source file. */
805
+ from: File;
806
+ /** Namespace export: `export * as ns from 'module'`. Mutually exclusive with `exports`. */
807
+ namespaceExport?: string;
808
+ };
809
+ interface ImportMember {
810
+ /** Whether this import is type-only. */
811
+ isTypeOnly: boolean;
812
+ /** Import flavor. */
813
+ kind: BindingKind;
539
814
  /**
540
- * Returns printable data containing symbols and exports.
815
+ * The name this symbol will have locally in this file.
816
+ * This is where aliasing is applied:
541
817
  *
542
- * @param file The file to render.
543
- * @param project The parent project the file belongs to.
544
- * @param meta Arbitrary metadata.
545
- * @returns Printable string containing symbols and exports.
818
+ * import { Foo as Foo$2 } from "./x"
819
+ *
820
+ * localName === "Foo$2"
546
821
  */
547
- renderSymbols(file: IFileOut, project: IProject, meta?: IProjectRenderMeta): string;
822
+ localName: string;
823
+ /** The exported name of the symbol in its source file. */
824
+ sourceName: string;
825
+ }
826
+ type ImportModule = Pick<ImportMember, 'isTypeOnly'> & {
827
+ /** Source file. */
828
+ from: File;
829
+ /** List of symbols imported from this module. */
830
+ imports: Array<ImportMember>;
831
+ /** Namespace import: `import * as name from 'module'`. Mutually exclusive with `imports`. */
832
+ namespaceImport?: string;
833
+ };
834
+ //#endregion
835
+ //#region src/brands.d.ts
836
+ declare const nodeBrand = "heyapi.node";
837
+ declare const symbolBrand = "heyapi.symbol";
838
+ //#endregion
839
+ //#region src/debug.d.ts
840
+ declare const DEBUG_GROUPS: {
841
+ readonly analyzer: colors.StyleFunction;
842
+ readonly dsl: colors.StyleFunction;
843
+ readonly file: colors.StyleFunction;
844
+ readonly registry: colors.StyleFunction;
845
+ readonly symbol: colors.StyleFunction;
846
+ };
847
+ declare function debug(message: string, group: keyof typeof DEBUG_GROUPS): void;
848
+ //#endregion
849
+ //#region src/guards.d.ts
850
+ declare function isNode(value: unknown): value is INode;
851
+ declare function isNodeRef(value: Ref<unknown>): value is Ref<INode>;
852
+ declare function isSymbol(value: unknown): value is Symbol;
853
+ declare function isSymbolRef(value: Ref<unknown>): value is Ref<Symbol>;
854
+ //#endregion
855
+ //#region src/languages/extensions.d.ts
856
+ declare const defaultExtensions: Extensions;
857
+ //#endregion
858
+ //#region src/languages/resolvers.d.ts
859
+ declare const defaultNameConflictResolvers: NameConflictResolvers;
860
+ //#endregion
861
+ //#region src/planner/resolvers.d.ts
862
+ declare const simpleNameConflictResolver: NameConflictResolver;
863
+ declare const underscoreNameConflictResolver: NameConflictResolver;
864
+ //#endregion
865
+ //#region src/files/registry.d.ts
866
+ type FileId = number;
867
+ declare class FileRegistry implements IFileRegistry {
868
+ private _id;
869
+ private _values;
870
+ private readonly project;
871
+ constructor(project: IProject);
872
+ get(args: FileKeyArgs): File | undefined;
873
+ isRegistered(args: FileKeyArgs): boolean;
874
+ get nextId(): FileId;
875
+ register(file: IFileIn): File;
876
+ registered(): IterableIterator<File>;
877
+ private createFileKey;
878
+ }
879
+ //#endregion
880
+ //#region src/nodes/registry.d.ts
881
+ declare class NodeRegistry implements INodeRegistry {
882
+ private list;
883
+ add(node: INode | null): number;
884
+ all(): Iterable<INode>;
885
+ remove(index: number): void;
886
+ update(index: number, node: INode | null): void;
548
887
  }
549
888
  //#endregion
550
889
  //#region src/symbols/registry.d.ts
551
890
  type SymbolId = number;
552
891
  declare class SymbolRegistry implements ISymbolRegistry {
553
892
  private _id;
554
- private indices;
555
- private nodes;
556
- private queryCache;
557
- private queryCacheDependencies;
558
- private registerOrder;
559
- private stubCache;
560
- private stubs;
561
- private values;
562
- get(identifier: ISymbolIdentifier): ISymbolOut | undefined;
563
- getValue(symbolId: SymbolId): unknown;
564
- hasValue(symbolId: SymbolId): boolean;
565
- get id(): SymbolId;
893
+ private _indices;
894
+ private _queryCache;
895
+ private _queryCacheDependencies;
896
+ private _registered;
897
+ private _stubs;
898
+ private _stubCache;
899
+ private _values;
900
+ get(identifier: ISymbolIdentifier): Symbol | undefined;
566
901
  isRegistered(identifier: ISymbolIdentifier): boolean;
567
- query(filter: ISymbolMeta): ReadonlyArray<ISymbolOut>;
568
- reference(meta: ISymbolMeta): ISymbolOut;
569
- register(symbol: ISymbolIn): ISymbolOut;
570
- registered(): IterableIterator<ISymbolOut>;
571
- setValue(symbolId: SymbolId, value: unknown): Map<SymbolId, unknown>;
902
+ get nextId(): SymbolId;
903
+ query(filter: ISymbolMeta): ReadonlyArray<Symbol>;
904
+ reference(meta: ISymbolMeta): Symbol;
905
+ register(symbol: ISymbolIn): Symbol;
906
+ registered(): IterableIterator<Symbol>;
572
907
  private buildCacheKey;
573
908
  private buildIndexKeySpace;
574
909
  private indexSymbol;
@@ -580,34 +915,69 @@ declare class SymbolRegistry implements ISymbolRegistry {
580
915
  //#endregion
581
916
  //#region src/project/project.d.ts
582
917
  declare class Project implements IProject {
583
- private symbolIdToFileIds;
584
- readonly defaultFileName: string;
585
918
  readonly files: FileRegistry;
919
+ readonly nodes: NodeRegistry;
920
+ readonly symbols: SymbolRegistry;
921
+ readonly defaultFileName: string;
922
+ readonly defaultNameConflictResolver: NameConflictResolver;
923
+ readonly extensions: Extensions;
586
924
  readonly fileName?: (name: string) => string;
587
- readonly renderers: Record<string, IRenderer>;
925
+ readonly nameConflictResolvers: NameConflictResolvers;
926
+ readonly renderers: ReadonlyArray<Renderer>;
588
927
  readonly root: string;
589
- readonly symbols: SymbolRegistry;
590
- constructor({
591
- defaultFileName,
592
- fileName,
593
- renderers,
594
- root
595
- }: Pick<IProject, 'defaultFileName' | 'fileName' | 'renderers' | 'root'>);
596
- private getRenderer;
597
- private prepareFiles;
928
+ constructor(args: Pick<Partial<IProject>, 'defaultFileName' | 'defaultNameConflictResolver' | 'extensions' | 'fileName' | 'nameConflictResolvers' | 'renderers'> & Pick<IProject, 'root'>);
598
929
  render(meta?: IProjectRenderMeta): ReadonlyArray<IOutput>;
599
- symbolIdToFiles(symbolId: number): ReadonlyArray<IFileOut>;
600
- private symbolToFileSelector;
601
930
  }
602
931
  //#endregion
603
- //#region src/renderer/utils.d.ts
932
+ //#region src/refs/refs.d.ts
933
+ /**
934
+ * Wraps a single value in a Ref object.
935
+ *
936
+ * @example
937
+ * ```ts
938
+ * const r = ref(123); // { '~ref': 123 }
939
+ * console.log(r['~ref']); // 123
940
+ * ```
941
+ */
942
+ declare const ref: <T>(value: T) => Ref<T>;
943
+ /**
944
+ * Converts a plain object to an object of Refs (deep, per property).
945
+ *
946
+ * @example
947
+ * ```ts
948
+ * const obj = { a: 1, b: "x" };
949
+ * const refs = refs(obj); // { a: { '~ref': 1 }, b: { '~ref': "x" } }
950
+ * ```
951
+ */
952
+ declare const refs: <T extends Record<string, unknown>>(obj: T) => Refs<T>;
953
+ /**
954
+ * Unwraps a single Ref object to its value.
955
+ *
956
+ * @example
957
+ * ```ts
958
+ * const r = { '~ref': 42 };
959
+ * const n = fromRef(r); // 42
960
+ * console.log(n); // 42
961
+ * ```
962
+ */
963
+ declare const fromRef: <T extends Ref<unknown> | undefined>(ref: T) => T extends Ref<infer U> ? U : undefined;
964
+ /**
965
+ * Converts an object of Refs back to a plain object (unwraps all refs).
966
+ *
967
+ * @example
968
+ * ```ts
969
+ * const refs = { a: { '~ref': 1 }, b: { '~ref': "x" } };
970
+ * const plain = fromRefs(refs); // { a: 1, b: "x" }
971
+ * ```
972
+ */
973
+ declare const fromRefs: <T extends Refs<Record<string, unknown>>>(obj: T) => FromRefs<T>;
604
974
  /**
975
+ * Checks whether a value is a Ref object.
605
976
  *
606
- * @param source The source string to replace.
607
- * @param replacerFn Accepts a symbol ID, returns resolved symbol name.
608
- * @returns The replaced source string.
977
+ * @param value Value to check
978
+ * @returns True if the value is a Ref object.
609
979
  */
610
- declare const renderIds: (source: string, replacerFn: (symbolId: number) => string | undefined) => string;
980
+ declare const isRef: <T>(value: unknown) => value is Ref<T>;
611
981
  //#endregion
612
- export { type IBiMap as BiMap, type IBinding as Binding, type IFileOut as File, type IFileIdentifier as FileIdentifier, type IFileIn as FileIn, type IProject, type IOutput as Output, Project, type IProjectRenderMeta as ProjectRenderMeta, type IRenderer as Renderer, type ISymbolOut as Symbol, type ISymbolIdentifier as SymbolIdentifier, type ISymbolIn as SymbolIn, type ISymbolMeta as SymbolMeta, createBinding, mergeBindings, renderIds };
982
+ export { type IAnalysisContext as AnalysisContext, type BindingKind, type ExportMember, type ExportModule, type Extensions, File, type IFileIn as FileIn, type FromRef, type FromRefs, type IProject, type ImportMember, type ImportModule, type Language, type NameConflictResolver, type NameConflictResolvers, type INode as Node, type IOutput as Output, Project, type IProjectRenderMeta as ProjectRenderMeta, type Ref, type Refs, type RenderContext, type Renderer, Symbol, type ISymbolIdentifier as SymbolIdentifier, type ISymbolIn as SymbolIn, type ISymbolMeta as SymbolMeta, debug, defaultExtensions, defaultNameConflictResolvers, fromRef, fromRefs, isNode, isNodeRef, isRef, isSymbol, isSymbolRef, nodeBrand, ref, refs, simpleNameConflictResolver, symbolBrand, underscoreNameConflictResolver };
613
983
  //# sourceMappingURL=index.d.cts.map