@webda/content-mapper 0.0.0-stage → 4.0.0-beta.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (115) hide show
  1. package/LICENSE +166 -0
  2. package/lib/coercions.d.ts +22 -0
  3. package/lib/coercions.d.ts.map +1 -0
  4. package/lib/coercions.js +10 -0
  5. package/lib/coercions.js.map +1 -0
  6. package/lib/context.d.ts +56 -0
  7. package/lib/context.d.ts.map +1 -0
  8. package/lib/context.js +111 -0
  9. package/lib/context.js.map +1 -0
  10. package/lib/defaults.d.ts +31 -0
  11. package/lib/defaults.d.ts.map +1 -0
  12. package/lib/defaults.js +33 -0
  13. package/lib/defaults.js.map +1 -0
  14. package/lib/generators/accessors.d.ts +15 -0
  15. package/lib/generators/accessors.d.ts.map +1 -0
  16. package/lib/generators/accessors.js +567 -0
  17. package/lib/generators/accessors.js.map +1 -0
  18. package/lib/generators/behaviors.d.ts +21 -0
  19. package/lib/generators/behaviors.d.ts.map +1 -0
  20. package/lib/generators/behaviors.js +292 -0
  21. package/lib/generators/behaviors.js.map +1 -0
  22. package/lib/generators/imports.d.ts +86 -0
  23. package/lib/generators/imports.d.ts.map +1 -0
  24. package/lib/generators/imports.js +205 -0
  25. package/lib/generators/imports.js.map +1 -0
  26. package/lib/generators/loadparameters.d.ts +7 -0
  27. package/lib/generators/loadparameters.d.ts.map +1 -0
  28. package/lib/generators/loadparameters.js +175 -0
  29. package/lib/generators/loadparameters.js.map +1 -0
  30. package/lib/generators/qlvalidator.d.ts +53 -0
  31. package/lib/generators/qlvalidator.d.ts.map +1 -0
  32. package/lib/generators/qlvalidator.js +238 -0
  33. package/lib/generators/qlvalidator.js.map +1 -0
  34. package/lib/index.d.ts +53 -0
  35. package/lib/index.d.ts.map +1 -0
  36. package/lib/index.js +36 -0
  37. package/lib/index.js.map +1 -0
  38. package/lib/module-discovery.d.ts +211 -0
  39. package/lib/module-discovery.d.ts.map +1 -0
  40. package/lib/module-discovery.js +662 -0
  41. package/lib/module-discovery.js.map +1 -0
  42. package/lib/module.d.ts +213 -0
  43. package/lib/module.d.ts.map +1 -0
  44. package/lib/module.js +1243 -0
  45. package/lib/module.js.map +1 -0
  46. package/lib/plan.d.ts +101 -0
  47. package/lib/plan.d.ts.map +1 -0
  48. package/lib/plan.js +61 -0
  49. package/lib/plan.js.map +1 -0
  50. package/lib/property-order.d.ts +37 -0
  51. package/lib/property-order.d.ts.map +1 -0
  52. package/lib/property-order.js +141 -0
  53. package/lib/property-order.js.map +1 -0
  54. package/lib/schema/action.d.ts +46 -0
  55. package/lib/schema/action.d.ts.map +1 -0
  56. package/lib/schema/action.js +190 -0
  57. package/lib/schema/action.js.map +1 -0
  58. package/lib/schema/annotations.d.ts +63 -0
  59. package/lib/schema/annotations.d.ts.map +1 -0
  60. package/lib/schema/annotations.js +116 -0
  61. package/lib/schema/annotations.js.map +1 -0
  62. package/lib/schema/converter.d.ts +363 -0
  63. package/lib/schema/converter.d.ts.map +1 -0
  64. package/lib/schema/converter.js +1377 -0
  65. package/lib/schema/converter.js.map +1 -0
  66. package/lib/schema/jsdoc.d.ts +34 -0
  67. package/lib/schema/jsdoc.d.ts.map +1 -0
  68. package/lib/schema/jsdoc.js +206 -0
  69. package/lib/schema/jsdoc.js.map +1 -0
  70. package/lib/schema/model.d.ts +27 -0
  71. package/lib/schema/model.d.ts.map +1 -0
  72. package/lib/schema/model.js +86 -0
  73. package/lib/schema/model.js.map +1 -0
  74. package/lib/schema/project.d.ts +34 -0
  75. package/lib/schema/project.d.ts.map +1 -0
  76. package/lib/schema/project.js +305 -0
  77. package/lib/schema/project.js.map +1 -0
  78. package/lib/schema/service.d.ts +62 -0
  79. package/lib/schema/service.d.ts.map +1 -0
  80. package/lib/schema/service.js +130 -0
  81. package/lib/schema/service.js.map +1 -0
  82. package/lib/schema/types.d.ts +61 -0
  83. package/lib/schema/types.d.ts.map +1 -0
  84. package/lib/schema/types.js +36 -0
  85. package/lib/schema/types.js.map +1 -0
  86. package/lib/schema/worker-cli.d.ts +3 -0
  87. package/lib/schema/worker-cli.d.ts.map +1 -0
  88. package/lib/schema/worker-cli.js +7 -0
  89. package/lib/schema/worker-cli.js.map +1 -0
  90. package/lib/schema/worker.d.ts +81 -0
  91. package/lib/schema/worker.d.ts.map +1 -0
  92. package/lib/schema/worker.js +186 -0
  93. package/lib/schema/worker.js.map +1 -0
  94. package/lib/server.d.ts +2 -0
  95. package/lib/server.d.ts.map +1 -0
  96. package/lib/server.js +133 -0
  97. package/lib/server.js.map +1 -0
  98. package/lib/session.d.ts +84 -0
  99. package/lib/session.d.ts.map +1 -0
  100. package/lib/session.js +141 -0
  101. package/lib/session.js.map +1 -0
  102. package/lib/spans.d.ts +46 -0
  103. package/lib/spans.d.ts.map +1 -0
  104. package/lib/spans.js +64 -0
  105. package/lib/spans.js.map +1 -0
  106. package/lib/twopass.d.ts +45 -0
  107. package/lib/twopass.d.ts.map +1 -0
  108. package/lib/twopass.js +87 -0
  109. package/lib/twopass.js.map +1 -0
  110. package/lib/vite.d.ts +20 -0
  111. package/lib/vite.d.ts.map +1 -0
  112. package/lib/vite.js +41 -0
  113. package/lib/vite.js.map +1 -0
  114. package/package.json +89 -3
  115. package/README.md +0 -3
@@ -0,0 +1,292 @@
1
+ import * as is from "typescript/unstable/ast/is";
2
+ import { classesOf, isStatic, memberName } from "../context.js";
3
+ import { ValueImports } from "./imports.js";
4
+ /**
5
+ * Storage slot backing a Behaviour's `parent` reference.
6
+ *
7
+ * Must match `BEHAVIOR_PARENT_KEY` in `@webda/ts-plugin`: the per-Behaviour
8
+ * `parent` getter reads it and `toJSON` filters it out, so a mismatch silently
9
+ * serialises the parent back into stored data.
10
+ */
11
+ export const BEHAVIOR_PARENT_KEY = "__parent__";
12
+ /**
13
+ * Whether a class carries the `@WebdaBehavior` JSDoc tag.
14
+ *
15
+ * Discovery is by tag rather than decorator, matching the compiler, so the
16
+ * marker leaves no runtime trace.
17
+ * @param ctx - analysis context
18
+ * @param sf - file declaring the class
19
+ * @param cls - the class declaration
20
+ * @returns true when the class is a Behaviour
21
+ */
22
+ function hasBehaviorTag(ctx, sf, cls) {
23
+ return /@WebdaBehavior\b/.test(ctx.triviaOf(sf, cls));
24
+ }
25
+ /**
26
+ * Resolve a property's type to a Behaviour class name.
27
+ *
28
+ * Returns undefined for primitives and for classes without the tag.
29
+ * @param ctx - analysis context
30
+ * @param sf - file holding the property
31
+ * @param typeNode - the property's type node
32
+ * @returns the Behaviour class name, when usable at runtime
33
+ */
34
+ function resolveBehaviorClass(ctx, sf, typeNode) {
35
+ const type = ctx.checker.getTypeFromTypeNode(typeNode);
36
+ if (!type)
37
+ return undefined;
38
+ const symbol = type.getSymbol?.() ?? type.symbol;
39
+ const name = symbol?.name;
40
+ if (!name || !/^[A-Za-z_$][\w$]*$/.test(name))
41
+ return undefined;
42
+ const declaration = symbol.valueDeclaration ?? symbol.declarations?.[0];
43
+ const node = declaration?.resolve(ctx.project);
44
+ if (!node || !is.isClassDeclaration(node))
45
+ return undefined;
46
+ const owner = node.getSourceFile?.() ?? node._sourceFile;
47
+ if (!owner || !/@WebdaBehavior\b/.test(ctx.triviaOf(owner, node)))
48
+ return undefined;
49
+ // The symbol name can differ from what the file imports — `@webda/core`
50
+ // exposes the alias `Binaries` while the class is `BinariesImpl`. Whether it
51
+ // can be made a runtime value here is the caller's decision, through
52
+ // `ValueImports`, which promotes or adds the import or refuses.
53
+ void sf;
54
+ return name;
55
+ }
56
+ /**
57
+ * Whether a name reaches this file only through a type-only import.
58
+ * @param sf - the file that will contain the generated reference
59
+ * @param name - identifier to be used as a value
60
+ * @returns true when the name is imported for types only
61
+ */
62
+ function isTypeOnlyImport(sf, name) {
63
+ for (const statement of sf.statements) {
64
+ if (!is.isImportDeclaration(statement))
65
+ continue;
66
+ const clause = statement.importClause;
67
+ const elements = clause?.namedBindings?.elements;
68
+ if (!elements)
69
+ continue;
70
+ for (const element of elements) {
71
+ if (element.name?.text === name && (clause.isTypeOnly || element.isTypeOnly))
72
+ return true;
73
+ }
74
+ }
75
+ return false;
76
+ }
77
+ /**
78
+ * Whether the class already declares the `[WEBDA_STORAGE]` slot.
79
+ *
80
+ * The name is computed, so `memberName` returns undefined for it and a
81
+ * name-based lookup silently misses it — injecting a second declaration then
82
+ * produces TS2300/TS2687/TS2416 against the inherited one.
83
+ * @param ctx - analysis context
84
+ * @param sf - file declaring the class
85
+ * @param cls - the class declaration
86
+ * @returns true when a storage slot is already declared
87
+ */
88
+ function hasStorageSlot(ctx, sf, cls) {
89
+ for (const member of cls.members ?? []) {
90
+ const name = member.name;
91
+ if (name && /\bWEBDA_STORAGE\b/.test(ctx.textOf(sf, name)))
92
+ return true;
93
+ }
94
+ // The slot may be inherited with a narrower shape — `@webda/core`'s binary
95
+ // service declares `protected [WEBDA_STORAGE]: { service: ... }`. Redeclaring
96
+ // it as a loose record is TS2416, and skipping the redeclaration keeps the
97
+ // base type intact. Unique-symbol keys surface as `__@WEBDA_STORAGE@<id>`.
98
+ const symbol = cls.name ? ctx.checker.getSymbolAtLocation(cls.name) : undefined;
99
+ const declared = symbol ? ctx.checker.getDeclaredTypeOfSymbol(symbol) : undefined;
100
+ for (const property of declared?.getProperties?.() ?? []) {
101
+ if (/WEBDA_STORAGE/.test(property.name ?? ""))
102
+ return true;
103
+ }
104
+ return false;
105
+ }
106
+ /**
107
+ * Names of members the class already declares.
108
+ * @param cls - the class declaration
109
+ * @returns declared member names
110
+ */
111
+ function declaredMembers(cls) {
112
+ const names = new Set();
113
+ for (const member of cls.members ?? []) {
114
+ const name = memberName(member);
115
+ if (name)
116
+ names.add(name);
117
+ }
118
+ return names;
119
+ }
120
+ /**
121
+ * The `toJSON` injected into Behaviour classes.
122
+ *
123
+ * Copies own properties, then merges the storage slot while dropping the parent
124
+ * back-reference — serialising it would create a cycle.
125
+ * @param i - indentation of class members
126
+ * @returns generated source
127
+ */
128
+ function renderToJSON(i) {
129
+ return [
130
+ `${i}toJSON() {`,
131
+ `${i} const result: Record<string, any> = {};`,
132
+ `${i} for (const key of Object.keys(this)) {`,
133
+ `${i} result[key] = (this as any)[key];`,
134
+ `${i} }`,
135
+ `${i} const storage: Record<string, any> | undefined = (this as any)[WEBDA_STORAGE];`,
136
+ `${i} if (storage) {`,
137
+ `${i} for (const key of Object.keys(storage)) {`,
138
+ `${i} if (key !== ${JSON.stringify(BEHAVIOR_PARENT_KEY)}) {`,
139
+ `${i} result[key] = storage[key];`,
140
+ `${i} }`,
141
+ `${i} }`,
142
+ `${i} }`,
143
+ `${i} return result;`,
144
+ `${i}}`
145
+ ].join("\n");
146
+ }
147
+ /**
148
+ * One hydration block, for a single Behaviour-typed property.
149
+ *
150
+ * Takes the current value or the raw stored value, coerces it into a Behaviour
151
+ * instance, and links it back to its owner.
152
+ * @param property - property name
153
+ * @param behaviorClass - Behaviour class to instantiate
154
+ * @param i - indentation of the method body
155
+ * @param arrayLike - fill an Array-derived behaviour item by item
156
+ * @returns generated source
157
+ */
158
+ function renderHydrationBlock(property, behaviorClass, i, arrayLike = false) {
159
+ const key = JSON.stringify(property);
160
+ // An Array-derived behaviour (`BinariesImpl`) is filled item by item, as
161
+ // the TypeScript 6 transformer does. `Object.assign` onto an array copies
162
+ // indices but is not what ships, and the oracle holds it to what ships.
163
+ const fill = arrayLike
164
+ ? [
165
+ `${i} if (Array.isArray(v)) {`,
166
+ `${i} for (const item of v) {`,
167
+ `${i} inst.push(item);`,
168
+ `${i} }`,
169
+ `${i} }`
170
+ ]
171
+ : [`${i} if (v !== undefined && v !== null) {`, `${i} Object.assign(inst, v);`, `${i} }`];
172
+ return [
173
+ `${i}{`,
174
+ `${i} let v: any = this.${property};`,
175
+ `${i} if (rawData !== undefined && rawData !== null && rawData[${key}] !== undefined) {`,
176
+ `${i} v = rawData[${key}];`,
177
+ `${i} }`,
178
+ `${i} if (!(v instanceof ${behaviorClass})) {`,
179
+ `${i} const inst = new ${behaviorClass}();`,
180
+ ...fill,
181
+ `${i} v = inst;`,
182
+ `${i} }`,
183
+ `${i} (v as any)[WEBDA_STORAGE] = (v as any)[WEBDA_STORAGE] || {};`,
184
+ `${i} (v as any)[WEBDA_STORAGE][${JSON.stringify(BEHAVIOR_PARENT_KEY)}] = { instance: this, attribute: ${key} };`,
185
+ `${i} this.${property} = v;`,
186
+ `${i}}`
187
+ ].join("\n");
188
+ }
189
+ /**
190
+ * Create the behaviour generator.
191
+ * @param options - generator options
192
+ * @returns a generator
193
+ */
194
+ export function behaviorsGenerator(options = {}) {
195
+ const storageModule = options.storageModule ?? "@webda/models";
196
+ return {
197
+ name: "behaviors",
198
+ analyze(ctx) {
199
+ const out = [];
200
+ for (const sf of ctx.sourceFiles) {
201
+ const edits = [];
202
+ const imports = new ValueImports(ctx, sf, "behaviors");
203
+ let needsStorage = false;
204
+ for (const cls of classesOf(sf)) {
205
+ const existing = declaredMembers(cls);
206
+ // Members start immediately after the class's `{`; the closing brace
207
+ // is the last character of the declaration.
208
+ const openPos = cls.members?.pos ?? undefined;
209
+ const closePos = cls.end - 1;
210
+ if (openPos === undefined)
211
+ continue;
212
+ const memberIndent = `${ctx.textOf(sf, cls).match(/\n([ \t]+)\S/)?.[1] ?? " "}`;
213
+ if (hasBehaviorTag(ctx, sf, cls)) {
214
+ needsStorage = true;
215
+ if (!hasStorageSlot(ctx, sf, cls)) {
216
+ edits.push({
217
+ start: openPos,
218
+ end: openPos,
219
+ text: `\n${memberIndent}[WEBDA_STORAGE]: Record<string, any> = {};`,
220
+ source: "behaviors"
221
+ });
222
+ }
223
+ if (!existing.has("parent")) {
224
+ edits.push({
225
+ start: closePos,
226
+ end: closePos,
227
+ text: `${memberIndent}get parent() { return this[WEBDA_STORAGE][${JSON.stringify(BEHAVIOR_PARENT_KEY)}]; }\n`,
228
+ source: "behaviors"
229
+ });
230
+ }
231
+ // An author-written toJSON wins; replacing it would drop their shape.
232
+ if (!existing.has("toJSON")) {
233
+ edits.push({
234
+ start: closePos,
235
+ end: closePos,
236
+ text: `${renderToJSON(memberIndent)}\n`,
237
+ source: "behaviors"
238
+ });
239
+ }
240
+ }
241
+ // Behaviour-typed properties anywhere gain hydration.
242
+ if (existing.has("__hydrateBehaviors"))
243
+ continue;
244
+ const blocks = [];
245
+ for (const member of cls.members ?? []) {
246
+ if (!is.isPropertyDeclaration(member) || isStatic(member))
247
+ continue;
248
+ const name = memberName(member);
249
+ if (!name || !member.type)
250
+ continue;
251
+ const typeNode = member.type;
252
+ const behaviorClass = resolveBehaviorClass(ctx, sf, typeNode);
253
+ if (!behaviorClass)
254
+ continue;
255
+ // `new BinariesImpl()` needs a binding. `Binaries<...>` names the
256
+ // alias, so its module is where the class is looked for.
257
+ const via = [...new Set(ctx.textOf(sf, typeNode).match(/[A-Za-z_$][\w$]*/g) ?? [])];
258
+ if (!imports.ensure(behaviorClass, typeNode, via))
259
+ continue;
260
+ const arrayLike = ctx.checker.isArrayLikeType(ctx.checker.getTypeFromTypeNode(typeNode));
261
+ blocks.push(renderHydrationBlock(name, behaviorClass, `${memberIndent} `, arrayLike));
262
+ }
263
+ if (!blocks.length)
264
+ continue;
265
+ needsStorage = true;
266
+ edits.push({
267
+ start: closePos,
268
+ end: closePos,
269
+ text: `${memberIndent}protected __hydrateBehaviors(rawData?: any): void {\n` +
270
+ `${blocks.join("\n")}\n` +
271
+ `${memberIndent}}\n`,
272
+ source: "behaviors"
273
+ });
274
+ }
275
+ if (edits.length) {
276
+ edits.push(...imports.collect());
277
+ if (needsStorage && !/\bWEBDA_STORAGE\b/.test(sf.text)) {
278
+ edits.push({
279
+ start: 0,
280
+ end: 0,
281
+ text: `import { WEBDA_STORAGE } from ${JSON.stringify(storageModule)};\n`,
282
+ source: "behaviors"
283
+ });
284
+ }
285
+ out.push({ fileName: sf.fileName, edits });
286
+ }
287
+ }
288
+ return out;
289
+ }
290
+ };
291
+ }
292
+ //# sourceMappingURL=behaviors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"behaviors.js","sourceRoot":"","sources":["../../src/generators/behaviors.ts"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EAAE,MAAM,4BAA4B,CAAC;AACjD,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAChE,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAG5C;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,YAAY,CAAC;AAQhD;;;;;;;;;GASG;AACH,SAAS,cAAc,CAAC,GAAoB,EAAE,EAAc,EAAE,GAAQ;IACpE,OAAO,kBAAkB,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC;AACxD,CAAC;AAED;;;;;;;;GAQG;AACH,SAAS,oBAAoB,CAAC,GAAoB,EAAE,EAAc,EAAE,QAAa;IAC/E,MAAM,IAAI,GAAG,GAAG,CAAC,OAAO,CAAC,mBAAmB,CAAC,QAAQ,CAAC,CAAC;IACvD,IAAI,CAAC,IAAI;QAAE,OAAO,SAAS,CAAC;IAE5B,MAAM,MAAM,GAAI,IAAY,CAAC,SAAS,EAAE,EAAE,IAAK,IAAY,CAAC,MAAM,CAAC;IACnE,MAAM,IAAI,GAAG,MAAM,EAAE,IAAI,CAAC;IAC1B,IAAI,CAAC,IAAI,IAAI,CAAC,oBAAoB,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,SAAS,CAAC;IAEhE,MAAM,WAAW,GAAG,MAAM,CAAC,gBAAgB,IAAI,MAAM,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,CAAC;IACxE,MAAM,IAAI,GAAG,WAAW,EAAE,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IAC/C,IAAI,CAAC,IAAI,IAAI,CAAC,EAAE,CAAC,kBAAkB,CAAC,IAAI,CAAC;QAAE,OAAO,SAAS,CAAC;IAE5D,MAAM,KAAK,GAAI,IAAY,CAAC,aAAa,EAAE,EAAE,IAAK,IAAY,CAAC,WAAW,CAAC;IAC3E,IAAI,CAAC,KAAK,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QAAE,OAAO,SAAS,CAAC;IAEpF,wEAAwE;IACxE,6EAA6E;IAC7E,qEAAqE;IACrE,gEAAgE;IAChE,KAAK,EAAE,CAAC;IACR,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;GAKG;AACH,SAAS,gBAAgB,CAAC,EAAc,EAAE,IAAY;IACpD,KAAK,MAAM,SAAS,IAAI,EAAE,CAAC,UAAU,EAAE,CAAC;QACtC,IAAI,CAAC,EAAE,CAAC,mBAAmB,CAAC,SAAS,CAAC;YAAE,SAAS;QACjD,MAAM,MAAM,GAAS,SAAiB,CAAC,YAAY,CAAC;QACpD,MAAM,QAAQ,GAAG,MAAM,EAAE,aAAa,EAAE,QAAQ,CAAC;QACjD,IAAI,CAAC,QAAQ;YAAE,SAAS;QACxB,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;YAC/B,IAAI,OAAO,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,IAAI,CAAC,MAAM,CAAC,UAAU,IAAI,OAAO,CAAC,UAAU,CAAC;gBAAE,OAAO,IAAI,CAAC;QAC5F,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;;;;;;;GAUG;AACH,SAAS,cAAc,CAAC,GAAoB,EAAE,EAAc,EAAE,GAAQ;IACpE,KAAK,MAAM,MAAM,IAAI,GAAG,CAAC,OAAO,IAAI,EAAE,EAAE,CAAC;QACvC,MAAM,IAAI,GAAI,MAAc,CAAC,IAAI,CAAC;QAClC,IAAI,IAAI,IAAI,mBAAmB,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;YAAE,OAAO,IAAI,CAAC;IAC1E,CAAC;IAED,2EAA2E;IAC3E,8EAA8E;IAC9E,2EAA2E;IAC3E,2EAA2E;IAC3E,MAAM,MAAM,GAAG,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,mBAAmB,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAChF,MAAM,QAAQ,GAAG,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,uBAAuB,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAClF,KAAK,MAAM,QAAQ,IAAK,QAAgB,EAAE,aAAa,EAAE,EAAE,IAAI,EAAE,EAAE,CAAC;QAClE,IAAI,eAAe,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,IAAI,EAAE,CAAC;YAAE,OAAO,IAAI,CAAC;IAC7D,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;GAIG;AACH,SAAS,eAAe,CAAC,GAAQ;IAC/B,MAAM,KAAK,GAAG,IAAI,GAAG,EAAU,CAAC;IAChC,KAAK,MAAM,MAAM,IAAI,GAAG,CAAC,OAAO,IAAI,EAAE,EAAE,CAAC;QACvC,MAAM,IAAI,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC;QAChC,IAAI,IAAI;YAAE,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC5B,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;;;;GAOG;AACH,SAAS,YAAY,CAAC,CAAS;IAC7B,OAAO;QACL,GAAG,CAAC,YAAY;QAChB,GAAG,CAAC,2CAA2C;QAC/C,GAAG,CAAC,0CAA0C;QAC9C,GAAG,CAAC,uCAAuC;QAC3C,GAAG,CAAC,KAAK;QACT,GAAG,CAAC,kFAAkF;QACtF,GAAG,CAAC,kBAAkB;QACtB,GAAG,CAAC,+CAA+C;QACnD,GAAG,CAAC,qBAAqB,IAAI,CAAC,SAAS,CAAC,mBAAmB,CAAC,KAAK;QACjE,GAAG,CAAC,qCAAqC;QACzC,GAAG,CAAC,SAAS;QACb,GAAG,CAAC,OAAO;QACX,GAAG,CAAC,KAAK;QACT,GAAG,CAAC,kBAAkB;QACtB,GAAG,CAAC,GAAG;KACR,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC;AAED;;;;;;;;;;GAUG;AACH,SAAS,oBAAoB,CAAC,QAAgB,EAAE,aAAqB,EAAE,CAAS,EAAE,SAAS,GAAG,KAAK;IACjG,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;IACrC,yEAAyE;IACzE,0EAA0E;IAC1E,wEAAwE;IACxE,MAAM,IAAI,GAAG,SAAS;QACpB,CAAC,CAAC;YACE,GAAG,CAAC,6BAA6B;YACjC,GAAG,CAAC,+BAA+B;YACnC,GAAG,CAAC,0BAA0B;YAC9B,GAAG,CAAC,SAAS;YACb,GAAG,CAAC,OAAO;SACZ;QACH,CAAC,CAAC,CAAC,GAAG,CAAC,0CAA0C,EAAE,GAAG,CAAC,+BAA+B,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;IACvG,OAAO;QACL,GAAG,CAAC,GAAG;QACP,GAAG,CAAC,uBAAuB,QAAQ,GAAG;QACtC,GAAG,CAAC,8DAA8D,GAAG,oBAAoB;QACzF,GAAG,CAAC,mBAAmB,GAAG,IAAI;QAC9B,GAAG,CAAC,KAAK;QACT,GAAG,CAAC,wBAAwB,aAAa,MAAM;QAC/C,GAAG,CAAC,wBAAwB,aAAa,KAAK;QAC9C,GAAG,IAAI;QACP,GAAG,CAAC,eAAe;QACnB,GAAG,CAAC,KAAK;QACT,GAAG,CAAC,gEAAgE;QACpE,GAAG,CAAC,+BAA+B,IAAI,CAAC,SAAS,CAAC,mBAAmB,CAAC,oCAAoC,GAAG,KAAK;QAClH,GAAG,CAAC,UAAU,QAAQ,OAAO;QAC7B,GAAG,CAAC,GAAG;KACR,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,kBAAkB,CAAC,OAAO,GAAoB,EAAE;IAC9D,MAAM,aAAa,GAAG,OAAO,CAAC,aAAa,IAAI,eAAe,CAAC;IAE/D,OAAO;QACL,IAAI,EAAE,WAAW;QACjB,OAAO,CAAC,GAAoB;YAC1B,MAAM,GAAG,GAAgB,EAAE,CAAC;YAE5B,KAAK,MAAM,EAAE,IAAI,GAAG,CAAC,WAAW,EAAE,CAAC;gBACjC,MAAM,KAAK,GAAW,EAAE,CAAC;gBACzB,MAAM,OAAO,GAAG,IAAI,YAAY,CAAC,GAAG,EAAE,EAAE,EAAE,WAAW,CAAC,CAAC;gBACvD,IAAI,YAAY,GAAG,KAAK,CAAC;gBAEzB,KAAK,MAAM,GAAG,IAAI,SAAS,CAAC,EAAE,CAAC,EAAE,CAAC;oBAChC,MAAM,QAAQ,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC;oBACtC,qEAAqE;oBACrE,4CAA4C;oBAC5C,MAAM,OAAO,GAAI,GAAG,CAAC,OAAe,EAAE,GAAG,IAAI,SAAS,CAAC;oBACvD,MAAM,QAAQ,GAAG,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC;oBAC7B,IAAI,OAAO,KAAK,SAAS;wBAAE,SAAS;oBAEpC,MAAM,YAAY,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,cAAc,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC;oBAEjF,IAAI,cAAc,CAAC,GAAG,EAAE,EAAE,EAAE,GAAG,CAAC,EAAE,CAAC;wBACjC,YAAY,GAAG,IAAI,CAAC;wBACpB,IAAI,CAAC,cAAc,CAAC,GAAG,EAAE,EAAE,EAAE,GAAG,CAAC,EAAE,CAAC;4BAClC,KAAK,CAAC,IAAI,CAAC;gCACT,KAAK,EAAE,OAAO;gCACd,GAAG,EAAE,OAAO;gCACZ,IAAI,EAAE,KAAK,YAAY,4CAA4C;gCACnE,MAAM,EAAE,WAAW;6BACpB,CAAC,CAAC;wBACL,CAAC;wBACD,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;4BAC5B,KAAK,CAAC,IAAI,CAAC;gCACT,KAAK,EAAE,QAAQ;gCACf,GAAG,EAAE,QAAQ;gCACb,IAAI,EAAE,GAAG,YAAY,6CAA6C,IAAI,CAAC,SAAS,CAC9E,mBAAmB,CACpB,QAAQ;gCACT,MAAM,EAAE,WAAW;6BACpB,CAAC,CAAC;wBACL,CAAC;wBACD,sEAAsE;wBACtE,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;4BAC5B,KAAK,CAAC,IAAI,CAAC;gCACT,KAAK,EAAE,QAAQ;gCACf,GAAG,EAAE,QAAQ;gCACb,IAAI,EAAE,GAAG,YAAY,CAAC,YAAY,CAAC,IAAI;gCACvC,MAAM,EAAE,WAAW;6BACpB,CAAC,CAAC;wBACL,CAAC;oBACH,CAAC;oBAED,sDAAsD;oBACtD,IAAI,QAAQ,CAAC,GAAG,CAAC,oBAAoB,CAAC;wBAAE,SAAS;oBACjD,MAAM,MAAM,GAAa,EAAE,CAAC;oBAC5B,KAAK,MAAM,MAAM,IAAI,GAAG,CAAC,OAAO,IAAI,EAAE,EAAE,CAAC;wBACvC,IAAI,CAAC,EAAE,CAAC,qBAAqB,CAAC,MAAM,CAAC,IAAI,QAAQ,CAAC,MAAM,CAAC;4BAAE,SAAS;wBACpE,MAAM,IAAI,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC;wBAChC,IAAI,CAAC,IAAI,IAAI,CAAE,MAAc,CAAC,IAAI;4BAAE,SAAS;wBAC7C,MAAM,QAAQ,GAAI,MAAc,CAAC,IAAI,CAAC;wBACtC,MAAM,aAAa,GAAG,oBAAoB,CAAC,GAAG,EAAE,EAAE,EAAE,QAAQ,CAAC,CAAC;wBAC9D,IAAI,CAAC,aAAa;4BAAE,SAAS;wBAC7B,kEAAkE;wBAClE,yDAAyD;wBACzD,MAAM,GAAG,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,EAAE,QAAQ,CAAC,CAAC,KAAK,CAAC,mBAAmB,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;wBACpF,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,aAAa,EAAE,QAAQ,EAAE,GAAG,CAAC;4BAAE,SAAS;wBAC5D,MAAM,SAAS,GAAG,GAAG,CAAC,OAAO,CAAC,eAAe,CAAC,GAAG,CAAC,OAAO,CAAC,mBAAmB,CAAC,QAAQ,CAAC,CAAC,CAAC;wBACzF,MAAM,CAAC,IAAI,CAAC,oBAAoB,CAAC,IAAI,EAAE,aAAa,EAAE,GAAG,YAAY,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC;oBACzF,CAAC;oBACD,IAAI,CAAC,MAAM,CAAC,MAAM;wBAAE,SAAS;oBAE7B,YAAY,GAAG,IAAI,CAAC;oBACpB,KAAK,CAAC,IAAI,CAAC;wBACT,KAAK,EAAE,QAAQ;wBACf,GAAG,EAAE,QAAQ;wBACb,IAAI,EACF,GAAG,YAAY,uDAAuD;4BACtE,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI;4BACxB,GAAG,YAAY,KAAK;wBACtB,MAAM,EAAE,WAAW;qBACpB,CAAC,CAAC;gBACL,CAAC;gBAED,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;oBACjB,KAAK,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;oBACjC,IAAI,YAAY,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;wBACvD,KAAK,CAAC,IAAI,CAAC;4BACT,KAAK,EAAE,CAAC;4BACR,GAAG,EAAE,CAAC;4BACN,IAAI,EAAE,iCAAiC,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC,KAAK;4BACzE,MAAM,EAAE,WAAW;yBACpB,CAAC,CAAC;oBACL,CAAC;oBACD,GAAG,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,EAAE,CAAC,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC;gBAC7C,CAAC;YACH,CAAC;YAED,OAAO,GAAG,CAAC;QACb,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,86 @@
1
+ import type { SourceFile } from "typescript/unstable/ast";
2
+ import type { AnalysisContext, Edit } from "../plan.ts";
3
+ /** Collects the import edits one file needs. */
4
+ export declare class ValueImports {
5
+ private readonly ctx;
6
+ private readonly sf;
7
+ private readonly source;
8
+ private readonly edits;
9
+ /**
10
+ * @param ctx - analysis context
11
+ * @param sf - the file the generated code goes into
12
+ * @param source - generator name, recorded on the edits
13
+ */
14
+ constructor(ctx: AnalysisContext, sf: SourceFile, source: string);
15
+ /**
16
+ * Ensure `name` is a runtime value in this file.
17
+ * @param name - identifier the generated code will use as a value
18
+ * @param location - node the reference will appear at, for scope lookup
19
+ * @param via - names the file already imports whose module may export
20
+ * `name`, nearest first — e.g. `BelongTo` for `ModelLink`
21
+ * @returns true when the name is, or will be, available as a value
22
+ */
23
+ ensure(name: string, location: unknown, via?: string[]): boolean;
24
+ /**
25
+ * Ensure `name` can be used in a type position in this file.
26
+ *
27
+ * The type-level twin of {@link ensure}: a setter's parameter type is
28
+ * printed from the relation's own `set` signature, so it can name types the
29
+ * file never imports — `PrimaryKeyType<User>`. An `import type` is erased at
30
+ * emit, so adding one cannot change runtime behaviour.
31
+ * @param name - identifier the generated code will use as a type
32
+ * @param location - node the reference will appear at, for scope lookup
33
+ * @param via - names the file already imports whose module may export `name`
34
+ * @returns true when the name is, or will be, available as a type
35
+ */
36
+ ensureType(name: string, location: unknown, via?: string[]): boolean;
37
+ /**
38
+ * The edits accumulated so far.
39
+ * @returns promotions and additions, in a stable order
40
+ */
41
+ collect(): Edit[];
42
+ /**
43
+ * Snapshot the pending edits, so a property rejected by a later check does
44
+ * not leave an import behind for code that was never generated.
45
+ * @returns a function restoring the snapshot
46
+ */
47
+ checkpoint(): () => void;
48
+ /**
49
+ * Find the import binding a name, if any.
50
+ * @param name - the local name
51
+ * @returns the declaration, the element, and whether it is type-only
52
+ */
53
+ private importOf;
54
+ /**
55
+ * Turn a type-only import of a name into a value import.
56
+ *
57
+ * `import { type X }` loses its inline `type`. `import type { X, Y }` loses
58
+ * the declaration-level one, which makes Y a value import too — harmless
59
+ * without `verbatimModuleSyntax`, since an unused or type-only value import
60
+ * is still elided.
61
+ * @param binding - the import to promote
62
+ */
63
+ private promote;
64
+ /**
65
+ * Record a deletion keyed by position, so repeated promotions collapse.
66
+ * @param start - offset of the text to remove
67
+ * @param length - characters to remove
68
+ */
69
+ private addRemoval;
70
+ /**
71
+ * Whether the module an import declaration names exports `name` as a value.
72
+ * @param declaration - an import declaration in this file
73
+ * @param name - the export to look for
74
+ * @returns true when the module exports a value by that name
75
+ */
76
+ private moduleExportsValue;
77
+ /**
78
+ * Whether the module an import declaration names exports `name` with a meaning.
79
+ * @param declaration - an import declaration in this file
80
+ * @param name - the export to look for
81
+ * @param meaning - `Value` or `Type`
82
+ * @returns true when the module exports `name` with that meaning
83
+ */
84
+ private moduleExports;
85
+ }
86
+ //# sourceMappingURL=imports.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"imports.d.ts","sourceRoot":"","sources":["../../src/generators/imports.ts"],"names":[],"mappings":"AA0BA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAE1D,OAAO,KAAK,EAAE,eAAe,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAExD,gDAAgD;AAChD,qBAAa,YAAY;IASrB,OAAO,CAAC,QAAQ,CAAC,GAAG;IACpB,OAAO,CAAC,QAAQ,CAAC,EAAE;IACnB,OAAO,CAAC,QAAQ,CAAC,MAAM;IAVzB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA2B;IAEjD;;;;OAIG;IACH,YACmB,GAAG,EAAE,eAAe,EACpB,EAAE,EAAE,UAAU,EACd,MAAM,EAAE,MAAM,EAC7B;IAEJ;;;;;;;OAOG;IACH,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,GAAE,MAAM,EAAO,GAAG,OAAO,CAmBnE;IAED;;;;;;;;;;;OAWG;IACH,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,GAAE,MAAM,EAAO,GAAG,OAAO,CAYvE;IAED;;;OAGG;IACH,OAAO,IAAI,IAAI,EAAE,CAEhB;IAED;;;;OAIG;IACH,UAAU,IAAI,MAAM,IAAI,CAMvB;IAED;;;;OAIG;IACH,OAAO,CAAC,QAAQ;IAiBhB;;;;;;;;OAQG;IACH,OAAO,CAAC,OAAO;IAcf;;;;OAIG;IACH,OAAO,CAAC,UAAU;IAIlB;;;;;OAKG;IACH,OAAO,CAAC,kBAAkB;IAI1B;;;;;;OAMG;IACH,OAAO,CAAC,aAAa;CAQtB"}
@@ -0,0 +1,205 @@
1
+ /**
2
+ * Make a name usable as a runtime value in a file, or report that it cannot be.
3
+ *
4
+ * Generated code constructs things — `new ModelLink(User)`,
5
+ * `new ModelRelated(Ident, this, "_user")`, `new BinariesImpl()` — so every
6
+ * name it mentions has to survive emit as a value. Authors routinely import
7
+ * those names as types only, or not at all (`BelongTo<User>` names the alias,
8
+ * not the `ModelLink` it resolves to). The TypeScript 6 transformers papered
9
+ * over this by synthesising imports from the declaring file's path, which for
10
+ * workspace packages — symlinks — produced monorepo-relative specifiers like
11
+ * `"../../../models/lib/relations.js"` that break once installed from npm.
12
+ *
13
+ * Only two moves are allowed, and anything else is refused:
14
+ *
15
+ * 1. **Promote** an existing `import type` of the name to a value import. The
16
+ * author already chose the module; only the erasure changes.
17
+ * 2. **Add** `import { Name }` from a module the file already imports another
18
+ * name from, when the checker confirms that module exports `Name` as a
19
+ * value. The specifier is the one the author wrote, never a computed path.
20
+ *
21
+ * Each import is emitted as its own statement and each promotion as a fixed
22
+ * range, so two generators that need the same name produce identical edits,
23
+ * which `mergePlan` collapses — rather than duplicate bindings, which are
24
+ * TS2300.
25
+ */
26
+ import { SymbolFlags } from "typescript/unstable/sync";
27
+ import * as is from "typescript/unstable/ast/is";
28
+ /** Collects the import edits one file needs. */
29
+ export class ValueImports {
30
+ ctx;
31
+ sf;
32
+ source;
33
+ edits = new Map();
34
+ /**
35
+ * @param ctx - analysis context
36
+ * @param sf - the file the generated code goes into
37
+ * @param source - generator name, recorded on the edits
38
+ */
39
+ constructor(ctx, sf, source) {
40
+ this.ctx = ctx;
41
+ this.sf = sf;
42
+ this.source = source;
43
+ }
44
+ /**
45
+ * Ensure `name` is a runtime value in this file.
46
+ * @param name - identifier the generated code will use as a value
47
+ * @param location - node the reference will appear at, for scope lookup
48
+ * @param via - names the file already imports whose module may export
49
+ * `name`, nearest first — e.g. `BelongTo` for `ModelLink`
50
+ * @returns true when the name is, or will be, available as a value
51
+ */
52
+ ensure(name, location, via = []) {
53
+ if (!/^[A-Za-z_$][\w$]*$/.test(name))
54
+ return false;
55
+ const importing = this.importOf(name);
56
+ if (importing) {
57
+ if (importing.typeOnly)
58
+ this.promote(importing);
59
+ return true;
60
+ }
61
+ // Declared in this file, or global.
62
+ if (this.ctx.checker.resolveName(name, SymbolFlags.Value, location))
63
+ return true;
64
+ for (const hint of via) {
65
+ const hinted = this.importOf(hint);
66
+ if (!hinted || !this.moduleExportsValue(hinted.declaration, name))
67
+ continue;
68
+ const text = `import { ${name} } from ${this.ctx.textOf(this.sf, hinted.declaration.moduleSpecifier)};\n`;
69
+ this.edits.set(`add:${name}`, { start: 0, end: 0, text, source: this.source });
70
+ return true;
71
+ }
72
+ return false;
73
+ }
74
+ /**
75
+ * Ensure `name` can be used in a type position in this file.
76
+ *
77
+ * The type-level twin of {@link ensure}: a setter's parameter type is
78
+ * printed from the relation's own `set` signature, so it can name types the
79
+ * file never imports — `PrimaryKeyType<User>`. An `import type` is erased at
80
+ * emit, so adding one cannot change runtime behaviour.
81
+ * @param name - identifier the generated code will use as a type
82
+ * @param location - node the reference will appear at, for scope lookup
83
+ * @param via - names the file already imports whose module may export `name`
84
+ * @returns true when the name is, or will be, available as a type
85
+ */
86
+ ensureType(name, location, via = []) {
87
+ if (!/^[A-Za-z_$][\w$]*$/.test(name))
88
+ return false;
89
+ if (this.importOf(name))
90
+ return true;
91
+ if (this.ctx.checker.resolveName(name, SymbolFlags.Type, location))
92
+ return true;
93
+ for (const hint of via) {
94
+ const hinted = this.importOf(hint);
95
+ if (!hinted || !this.moduleExports(hinted.declaration, name, SymbolFlags.Type))
96
+ continue;
97
+ const text = `import type { ${name} } from ${this.ctx.textOf(this.sf, hinted.declaration.moduleSpecifier)};\n`;
98
+ this.edits.set(`type:${name}`, { start: 0, end: 0, text, source: this.source });
99
+ return true;
100
+ }
101
+ return false;
102
+ }
103
+ /**
104
+ * The edits accumulated so far.
105
+ * @returns promotions and additions, in a stable order
106
+ */
107
+ collect() {
108
+ return [...this.edits.values()];
109
+ }
110
+ /**
111
+ * Snapshot the pending edits, so a property rejected by a later check does
112
+ * not leave an import behind for code that was never generated.
113
+ * @returns a function restoring the snapshot
114
+ */
115
+ checkpoint() {
116
+ const saved = new Map(this.edits);
117
+ return () => {
118
+ this.edits.clear();
119
+ for (const [key, edit] of saved)
120
+ this.edits.set(key, edit);
121
+ };
122
+ }
123
+ /**
124
+ * Find the import binding a name, if any.
125
+ * @param name - the local name
126
+ * @returns the declaration, the element, and whether it is type-only
127
+ */
128
+ importOf(name) {
129
+ for (const statement of this.sf.statements) {
130
+ if (!is.isImportDeclaration(statement))
131
+ continue;
132
+ const declaration = statement;
133
+ const clause = declaration.importClause;
134
+ if (!clause)
135
+ continue;
136
+ if (clause.name?.text === name) {
137
+ return { declaration, clause, element: undefined, typeOnly: !!clause.isTypeOnly };
138
+ }
139
+ for (const element of clause.namedBindings?.elements ?? []) {
140
+ if (element.name?.text !== name)
141
+ continue;
142
+ return { declaration, clause, element, typeOnly: !!(clause.isTypeOnly || element.isTypeOnly) };
143
+ }
144
+ }
145
+ return undefined;
146
+ }
147
+ /**
148
+ * Turn a type-only import of a name into a value import.
149
+ *
150
+ * `import { type X }` loses its inline `type`. `import type { X, Y }` loses
151
+ * the declaration-level one, which makes Y a value import too — harmless
152
+ * without `verbatimModuleSyntax`, since an unused or type-only value import
153
+ * is still elided.
154
+ * @param binding - the import to promote
155
+ */
156
+ promote(binding) {
157
+ if (binding.element?.isTypeOnly) {
158
+ const start = binding.element.getStart();
159
+ const match = /^type\s+/.exec(this.sf.text.slice(start, binding.element.end));
160
+ if (match)
161
+ this.addRemoval(start, match[0].length);
162
+ }
163
+ if (binding.clause.isTypeOnly) {
164
+ const start = binding.declaration.getStart();
165
+ const match = /^import(\s+)type\s+/.exec(this.sf.text.slice(start, binding.declaration.end));
166
+ if (match)
167
+ this.addRemoval(start + "import".length + match[1].length, match[0].length - "import".length - match[1].length);
168
+ }
169
+ }
170
+ /**
171
+ * Record a deletion keyed by position, so repeated promotions collapse.
172
+ * @param start - offset of the text to remove
173
+ * @param length - characters to remove
174
+ */
175
+ addRemoval(start, length) {
176
+ this.edits.set(`promote:${start}`, { start, end: start + length, text: "", source: this.source });
177
+ }
178
+ /**
179
+ * Whether the module an import declaration names exports `name` as a value.
180
+ * @param declaration - an import declaration in this file
181
+ * @param name - the export to look for
182
+ * @returns true when the module exports a value by that name
183
+ */
184
+ moduleExportsValue(declaration, name) {
185
+ return this.moduleExports(declaration, name, SymbolFlags.Value);
186
+ }
187
+ /**
188
+ * Whether the module an import declaration names exports `name` with a meaning.
189
+ * @param declaration - an import declaration in this file
190
+ * @param name - the export to look for
191
+ * @param meaning - `Value` or `Type`
192
+ * @returns true when the module exports `name` with that meaning
193
+ */
194
+ moduleExports(declaration, name, meaning) {
195
+ const moduleSymbol = this.ctx.checker.getSymbolAtLocation(declaration.moduleSpecifier);
196
+ if (!moduleSymbol)
197
+ return false;
198
+ const exported = this.ctx.checker.getExportsOfModule(moduleSymbol).find(symbol => symbol.name === name);
199
+ if (!exported)
200
+ return false;
201
+ const target = exported.flags & SymbolFlags.Alias ? this.ctx.checker.getAliasedSymbol(exported) : exported;
202
+ return (target.flags & meaning) !== 0;
203
+ }
204
+ }
205
+ //# sourceMappingURL=imports.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"imports.js","sourceRoot":"","sources":["../../src/generators/imports.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import type { Generator } from "../plan.ts";
2
+ /**
3
+ * Create the loadParameters generator.
4
+ * @returns a generator
5
+ */
6
+ export declare function loadParametersGenerator(): Generator;
7
+ //# sourceMappingURL=loadparameters.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loadparameters.d.ts","sourceRoot":"","sources":["../../src/generators/loadparameters.ts"],"names":[],"mappings":"AAsBA,OAAO,KAAK,EAAoC,SAAS,EAAE,MAAM,YAAY,CAAC;AA6G9E;;;GAGG;AACH,wBAAgB,uBAAuB,IAAI,SAAS,CAyCnD"}