@formspec/build 0.1.0-alpha.28 → 0.1.0-alpha.29
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/analyzer/class-analyzer.d.ts +11 -5
- package/dist/analyzer/class-analyzer.d.ts.map +1 -1
- package/dist/analyzer/program.d.ts +3 -2
- package/dist/analyzer/program.d.ts.map +1 -1
- package/dist/browser.cjs +485 -76
- package/dist/browser.cjs.map +1 -1
- package/dist/browser.js +486 -77
- package/dist/browser.js.map +1 -1
- package/dist/build-alpha.d.ts +18 -2
- package/dist/build-beta.d.ts +18 -2
- package/dist/build-internal.d.ts +18 -2
- package/dist/build.d.ts +18 -2
- package/dist/canonicalize/chain-dsl-canonicalizer.d.ts +5 -2
- package/dist/canonicalize/chain-dsl-canonicalizer.d.ts.map +1 -1
- package/dist/canonicalize/tsdoc-canonicalizer.d.ts +5 -1
- package/dist/canonicalize/tsdoc-canonicalizer.d.ts.map +1 -1
- package/dist/cli.cjs +1031 -170
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +1032 -171
- package/dist/cli.js.map +1 -1
- package/dist/generators/class-schema.d.ts +6 -1
- package/dist/generators/class-schema.d.ts.map +1 -1
- package/dist/generators/method-schema.d.ts.map +1 -1
- package/dist/generators/mixed-authoring.d.ts.map +1 -1
- package/dist/index.cjs +998 -170
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +4 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +999 -171
- package/dist/index.js.map +1 -1
- package/dist/internals.cjs +921 -155
- package/dist/internals.cjs.map +1 -1
- package/dist/internals.js +922 -156
- package/dist/internals.js.map +1 -1
- package/dist/json-schema/generator.d.ts +3 -1
- package/dist/json-schema/generator.d.ts.map +1 -1
- package/dist/json-schema/ir-generator.d.ts.map +1 -1
- package/dist/metadata/collision-guards.d.ts +3 -0
- package/dist/metadata/collision-guards.d.ts.map +1 -0
- package/dist/metadata/index.d.ts +7 -0
- package/dist/metadata/index.d.ts.map +1 -0
- package/dist/metadata/policy.d.ts +11 -0
- package/dist/metadata/policy.d.ts.map +1 -0
- package/dist/metadata/resolve.d.ts +20 -0
- package/dist/metadata/resolve.d.ts.map +1 -0
- package/dist/ui-schema/generator.d.ts +11 -2
- package/dist/ui-schema/generator.d.ts.map +1 -1
- package/dist/ui-schema/ir-generator.d.ts +2 -1
- package/dist/ui-schema/ir-generator.d.ts.map +1 -1
- package/package.json +4 -4
package/dist/cli.cjs
CHANGED
|
@@ -30,6 +30,334 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
30
30
|
mod
|
|
31
31
|
));
|
|
32
32
|
|
|
33
|
+
// src/metadata/policy.ts
|
|
34
|
+
function normalizePluralization(input) {
|
|
35
|
+
if (input?.mode === "infer-if-missing") {
|
|
36
|
+
return {
|
|
37
|
+
mode: "infer-if-missing",
|
|
38
|
+
infer: () => "",
|
|
39
|
+
inflect: input.inflect
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
if (input?.mode === "require-explicit") {
|
|
43
|
+
return {
|
|
44
|
+
mode: "require-explicit",
|
|
45
|
+
infer: () => "",
|
|
46
|
+
inflect: NOOP_INFLECT
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
return {
|
|
50
|
+
mode: "disabled",
|
|
51
|
+
infer: () => "",
|
|
52
|
+
inflect: NOOP_INFLECT
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
function normalizeScalarPolicy(input) {
|
|
56
|
+
if (input?.mode === "infer-if-missing") {
|
|
57
|
+
return {
|
|
58
|
+
mode: "infer-if-missing",
|
|
59
|
+
infer: input.infer,
|
|
60
|
+
pluralization: normalizePluralization(input.pluralization)
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
if (input?.mode === "require-explicit") {
|
|
64
|
+
return {
|
|
65
|
+
mode: "require-explicit",
|
|
66
|
+
infer: () => "",
|
|
67
|
+
pluralization: normalizePluralization(input.pluralization)
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
return {
|
|
71
|
+
mode: "disabled",
|
|
72
|
+
infer: () => "",
|
|
73
|
+
pluralization: normalizePluralization(input?.pluralization)
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
function normalizeDeclarationPolicy(input) {
|
|
77
|
+
return {
|
|
78
|
+
apiName: normalizeScalarPolicy(input?.apiName),
|
|
79
|
+
displayName: normalizeScalarPolicy(input?.displayName)
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
function normalizeMetadataPolicy(input) {
|
|
83
|
+
return {
|
|
84
|
+
type: normalizeDeclarationPolicy(input?.type),
|
|
85
|
+
field: normalizeDeclarationPolicy(input?.field),
|
|
86
|
+
method: normalizeDeclarationPolicy(input?.method)
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
function getDeclarationMetadataPolicy(policy, declarationKind) {
|
|
90
|
+
return policy[declarationKind];
|
|
91
|
+
}
|
|
92
|
+
function makeMetadataContext(surface, declarationKind, logicalName, buildContext) {
|
|
93
|
+
return {
|
|
94
|
+
surface,
|
|
95
|
+
declarationKind,
|
|
96
|
+
logicalName,
|
|
97
|
+
...buildContext !== void 0 && { buildContext }
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
var NOOP_INFLECT;
|
|
101
|
+
var init_policy = __esm({
|
|
102
|
+
"src/metadata/policy.ts"() {
|
|
103
|
+
"use strict";
|
|
104
|
+
NOOP_INFLECT = () => "";
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
// src/metadata/resolve.ts
|
|
109
|
+
function toExplicitScalar(value) {
|
|
110
|
+
return value !== void 0 && value.trim() !== "" ? { value, source: "explicit" } : void 0;
|
|
111
|
+
}
|
|
112
|
+
function toExplicitResolvedMetadata(explicit) {
|
|
113
|
+
if (explicit === void 0) {
|
|
114
|
+
return void 0;
|
|
115
|
+
}
|
|
116
|
+
const apiName = toExplicitScalar(explicit.apiName);
|
|
117
|
+
const displayName = toExplicitScalar(explicit.displayName);
|
|
118
|
+
const apiNamePlural = toExplicitScalar(explicit.apiNamePlural);
|
|
119
|
+
const displayNamePlural = toExplicitScalar(explicit.displayNamePlural);
|
|
120
|
+
const metadata = {
|
|
121
|
+
...apiName !== void 0 && { apiName },
|
|
122
|
+
...displayName !== void 0 && { displayName },
|
|
123
|
+
...apiNamePlural !== void 0 && { apiNamePlural },
|
|
124
|
+
...displayNamePlural !== void 0 && { displayNamePlural }
|
|
125
|
+
};
|
|
126
|
+
return Object.keys(metadata).length > 0 ? metadata : void 0;
|
|
127
|
+
}
|
|
128
|
+
function resolveScalar(current, policy, context, metadataLabel) {
|
|
129
|
+
if (current !== void 0) {
|
|
130
|
+
return current;
|
|
131
|
+
}
|
|
132
|
+
if (policy.mode === "require-explicit") {
|
|
133
|
+
throw new Error(
|
|
134
|
+
`Metadata policy requires explicit ${metadataLabel} for ${context.declarationKind} "${context.logicalName}" on the ${context.surface} surface.`
|
|
135
|
+
);
|
|
136
|
+
}
|
|
137
|
+
if (policy.mode !== "infer-if-missing") {
|
|
138
|
+
return void 0;
|
|
139
|
+
}
|
|
140
|
+
const inferredValue = policy.infer(context);
|
|
141
|
+
return inferredValue.trim() !== "" ? { value: inferredValue, source: "inferred" } : void 0;
|
|
142
|
+
}
|
|
143
|
+
function resolvePlural(current, singular, policy, context, metadataLabel) {
|
|
144
|
+
if (current !== void 0) {
|
|
145
|
+
return current;
|
|
146
|
+
}
|
|
147
|
+
if (policy.mode === "require-explicit") {
|
|
148
|
+
throw new Error(
|
|
149
|
+
`Metadata policy requires explicit ${metadataLabel} for ${context.declarationKind} "${context.logicalName}" on the ${context.surface} surface.`
|
|
150
|
+
);
|
|
151
|
+
}
|
|
152
|
+
if (singular === void 0 || policy.mode !== "infer-if-missing") {
|
|
153
|
+
return void 0;
|
|
154
|
+
}
|
|
155
|
+
const pluralValue = policy.inflect({ ...context, singular: singular.value });
|
|
156
|
+
return pluralValue.trim() !== "" ? { value: pluralValue, source: "inferred" } : void 0;
|
|
157
|
+
}
|
|
158
|
+
function resolveResolvedMetadata(current, policy, context) {
|
|
159
|
+
const apiName = resolveScalar(current?.apiName, policy.apiName, context, "apiName");
|
|
160
|
+
const displayName = resolveScalar(
|
|
161
|
+
current?.displayName,
|
|
162
|
+
policy.displayName,
|
|
163
|
+
context,
|
|
164
|
+
"displayName"
|
|
165
|
+
);
|
|
166
|
+
const apiNamePlural = resolvePlural(
|
|
167
|
+
current?.apiNamePlural,
|
|
168
|
+
apiName,
|
|
169
|
+
policy.apiName.pluralization,
|
|
170
|
+
context,
|
|
171
|
+
"apiNamePlural"
|
|
172
|
+
);
|
|
173
|
+
const displayNamePlural = resolvePlural(
|
|
174
|
+
current?.displayNamePlural,
|
|
175
|
+
displayName,
|
|
176
|
+
policy.displayName.pluralization,
|
|
177
|
+
context,
|
|
178
|
+
"displayNamePlural"
|
|
179
|
+
);
|
|
180
|
+
if (apiName === void 0 && displayName === void 0 && apiNamePlural === void 0 && displayNamePlural === void 0) {
|
|
181
|
+
return void 0;
|
|
182
|
+
}
|
|
183
|
+
return {
|
|
184
|
+
...apiName !== void 0 && { apiName },
|
|
185
|
+
...displayName !== void 0 && { displayName },
|
|
186
|
+
...apiNamePlural !== void 0 && { apiNamePlural },
|
|
187
|
+
...displayNamePlural !== void 0 && { displayNamePlural }
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
function pickResolvedMetadataValue(baseValue, overlayValue) {
|
|
191
|
+
if (overlayValue?.source === "explicit") {
|
|
192
|
+
return overlayValue;
|
|
193
|
+
}
|
|
194
|
+
if (baseValue?.source === "explicit") {
|
|
195
|
+
return baseValue;
|
|
196
|
+
}
|
|
197
|
+
return baseValue ?? overlayValue;
|
|
198
|
+
}
|
|
199
|
+
function resolveTypeNodeMetadata(type, options) {
|
|
200
|
+
switch (type.kind) {
|
|
201
|
+
case "array":
|
|
202
|
+
return {
|
|
203
|
+
...type,
|
|
204
|
+
items: resolveTypeNodeMetadata(type.items, options)
|
|
205
|
+
};
|
|
206
|
+
case "object":
|
|
207
|
+
return {
|
|
208
|
+
...type,
|
|
209
|
+
properties: type.properties.map((property) => resolveObjectPropertyMetadata(property, options))
|
|
210
|
+
};
|
|
211
|
+
case "record":
|
|
212
|
+
return {
|
|
213
|
+
...type,
|
|
214
|
+
valueType: resolveTypeNodeMetadata(type.valueType, options)
|
|
215
|
+
};
|
|
216
|
+
case "union":
|
|
217
|
+
return {
|
|
218
|
+
...type,
|
|
219
|
+
members: type.members.map((member) => resolveTypeNodeMetadata(member, options))
|
|
220
|
+
};
|
|
221
|
+
case "reference":
|
|
222
|
+
case "primitive":
|
|
223
|
+
case "enum":
|
|
224
|
+
case "dynamic":
|
|
225
|
+
case "custom":
|
|
226
|
+
return type;
|
|
227
|
+
default: {
|
|
228
|
+
const _exhaustive = type;
|
|
229
|
+
return _exhaustive;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
function resolveObjectPropertyMetadata(property, options) {
|
|
234
|
+
const metadata = resolveResolvedMetadata(property.metadata, options.policy.field, {
|
|
235
|
+
surface: options.surface,
|
|
236
|
+
declarationKind: "field",
|
|
237
|
+
logicalName: property.name,
|
|
238
|
+
...options.buildContext !== void 0 && { buildContext: options.buildContext }
|
|
239
|
+
});
|
|
240
|
+
return {
|
|
241
|
+
...property,
|
|
242
|
+
...metadata !== void 0 && { metadata },
|
|
243
|
+
type: resolveTypeNodeMetadata(property.type, options)
|
|
244
|
+
};
|
|
245
|
+
}
|
|
246
|
+
function resolveFieldMetadataNode(field, options) {
|
|
247
|
+
const metadata = resolveResolvedMetadata(field.metadata, options.policy.field, {
|
|
248
|
+
surface: options.surface,
|
|
249
|
+
declarationKind: "field",
|
|
250
|
+
logicalName: field.name,
|
|
251
|
+
...options.buildContext !== void 0 && { buildContext: options.buildContext }
|
|
252
|
+
});
|
|
253
|
+
return {
|
|
254
|
+
...field,
|
|
255
|
+
...metadata !== void 0 && { metadata },
|
|
256
|
+
type: resolveTypeNodeMetadata(field.type, options)
|
|
257
|
+
};
|
|
258
|
+
}
|
|
259
|
+
function resolveFormElementMetadata(element, options) {
|
|
260
|
+
switch (element.kind) {
|
|
261
|
+
case "field":
|
|
262
|
+
return resolveFieldMetadataNode(element, options);
|
|
263
|
+
case "group":
|
|
264
|
+
return {
|
|
265
|
+
...element,
|
|
266
|
+
elements: element.elements.map((child) => resolveFormElementMetadata(child, options))
|
|
267
|
+
};
|
|
268
|
+
case "conditional":
|
|
269
|
+
return {
|
|
270
|
+
...element,
|
|
271
|
+
elements: element.elements.map((child) => resolveFormElementMetadata(child, options))
|
|
272
|
+
};
|
|
273
|
+
default: {
|
|
274
|
+
const _exhaustive = element;
|
|
275
|
+
return _exhaustive;
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
function resolveTypeDefinitionMetadata(typeDefinition, options) {
|
|
280
|
+
const metadata = resolveResolvedMetadata(typeDefinition.metadata, options.policy.type, {
|
|
281
|
+
surface: options.surface,
|
|
282
|
+
declarationKind: "type",
|
|
283
|
+
logicalName: typeDefinition.name,
|
|
284
|
+
...options.buildContext !== void 0 && { buildContext: options.buildContext }
|
|
285
|
+
});
|
|
286
|
+
return {
|
|
287
|
+
...typeDefinition,
|
|
288
|
+
...metadata !== void 0 && { metadata },
|
|
289
|
+
type: resolveTypeNodeMetadata(typeDefinition.type, options)
|
|
290
|
+
};
|
|
291
|
+
}
|
|
292
|
+
function resolveMetadata(explicit, policy, context) {
|
|
293
|
+
return resolveResolvedMetadata(toExplicitResolvedMetadata(explicit), policy, context);
|
|
294
|
+
}
|
|
295
|
+
function mergeResolvedMetadata(baseMetadata, overlayMetadata) {
|
|
296
|
+
const apiName = pickResolvedMetadataValue(baseMetadata?.apiName, overlayMetadata?.apiName);
|
|
297
|
+
const displayName = pickResolvedMetadataValue(
|
|
298
|
+
baseMetadata?.displayName,
|
|
299
|
+
overlayMetadata?.displayName
|
|
300
|
+
);
|
|
301
|
+
const apiNamePlural = pickResolvedMetadataValue(
|
|
302
|
+
baseMetadata?.apiNamePlural,
|
|
303
|
+
overlayMetadata?.apiNamePlural
|
|
304
|
+
);
|
|
305
|
+
const displayNamePlural = pickResolvedMetadataValue(
|
|
306
|
+
baseMetadata?.displayNamePlural,
|
|
307
|
+
overlayMetadata?.displayNamePlural
|
|
308
|
+
);
|
|
309
|
+
if (apiName === void 0 && displayName === void 0 && apiNamePlural === void 0 && displayNamePlural === void 0) {
|
|
310
|
+
return void 0;
|
|
311
|
+
}
|
|
312
|
+
return {
|
|
313
|
+
...apiName !== void 0 && { apiName },
|
|
314
|
+
...displayName !== void 0 && { displayName },
|
|
315
|
+
...apiNamePlural !== void 0 && { apiNamePlural },
|
|
316
|
+
...displayNamePlural !== void 0 && { displayNamePlural }
|
|
317
|
+
};
|
|
318
|
+
}
|
|
319
|
+
function getSerializedName(logicalName, metadata) {
|
|
320
|
+
return metadata?.apiName?.value ?? logicalName;
|
|
321
|
+
}
|
|
322
|
+
function getDisplayName(metadata) {
|
|
323
|
+
return metadata?.displayName?.value;
|
|
324
|
+
}
|
|
325
|
+
function resolveFormIRMetadata(ir, options) {
|
|
326
|
+
const rootLogicalName = options.rootLogicalName ?? ir.name ?? "FormSpec";
|
|
327
|
+
const metadata = resolveResolvedMetadata(ir.metadata, options.policy.type, {
|
|
328
|
+
surface: options.surface,
|
|
329
|
+
declarationKind: "type",
|
|
330
|
+
logicalName: rootLogicalName,
|
|
331
|
+
...options.buildContext !== void 0 && { buildContext: options.buildContext }
|
|
332
|
+
});
|
|
333
|
+
return {
|
|
334
|
+
...ir,
|
|
335
|
+
...metadata !== void 0 && { metadata },
|
|
336
|
+
elements: ir.elements.map((element) => resolveFormElementMetadata(element, options)),
|
|
337
|
+
typeRegistry: Object.fromEntries(
|
|
338
|
+
Object.entries(ir.typeRegistry).map(([name, definition]) => [
|
|
339
|
+
name,
|
|
340
|
+
resolveTypeDefinitionMetadata(definition, options)
|
|
341
|
+
])
|
|
342
|
+
)
|
|
343
|
+
};
|
|
344
|
+
}
|
|
345
|
+
var init_resolve = __esm({
|
|
346
|
+
"src/metadata/resolve.ts"() {
|
|
347
|
+
"use strict";
|
|
348
|
+
}
|
|
349
|
+
});
|
|
350
|
+
|
|
351
|
+
// src/metadata/index.ts
|
|
352
|
+
var init_metadata = __esm({
|
|
353
|
+
"src/metadata/index.ts"() {
|
|
354
|
+
"use strict";
|
|
355
|
+
init_policy();
|
|
356
|
+
init_resolve();
|
|
357
|
+
init_resolve();
|
|
358
|
+
}
|
|
359
|
+
});
|
|
360
|
+
|
|
33
361
|
// src/canonicalize/chain-dsl-canonicalizer.ts
|
|
34
362
|
function isGroup(el) {
|
|
35
363
|
return el._type === "group";
|
|
@@ -40,57 +368,60 @@ function isConditional(el) {
|
|
|
40
368
|
function isField(el) {
|
|
41
369
|
return el._type === "field";
|
|
42
370
|
}
|
|
43
|
-
function canonicalizeChainDSL(form) {
|
|
371
|
+
function canonicalizeChainDSL(form, options) {
|
|
372
|
+
const metadataPolicy = normalizeMetadataPolicy(
|
|
373
|
+
options?.metadata ?? (0, import_internals._getFormSpecMetadataPolicy)(form)
|
|
374
|
+
);
|
|
44
375
|
return {
|
|
45
376
|
kind: "form-ir",
|
|
46
377
|
irVersion: import_internals.IR_VERSION,
|
|
47
|
-
elements: canonicalizeElements(form.elements),
|
|
378
|
+
elements: canonicalizeElements(form.elements, metadataPolicy),
|
|
48
379
|
rootAnnotations: [],
|
|
49
380
|
typeRegistry: {},
|
|
50
381
|
provenance: CHAIN_DSL_PROVENANCE
|
|
51
382
|
};
|
|
52
383
|
}
|
|
53
|
-
function canonicalizeElements(elements) {
|
|
54
|
-
return elements.map(canonicalizeElement);
|
|
384
|
+
function canonicalizeElements(elements, metadataPolicy) {
|
|
385
|
+
return elements.map((element) => canonicalizeElement(element, metadataPolicy));
|
|
55
386
|
}
|
|
56
|
-
function canonicalizeElement(element) {
|
|
387
|
+
function canonicalizeElement(element, metadataPolicy) {
|
|
57
388
|
if (isField(element)) {
|
|
58
|
-
return canonicalizeField(element);
|
|
389
|
+
return canonicalizeField(element, metadataPolicy);
|
|
59
390
|
}
|
|
60
391
|
if (isGroup(element)) {
|
|
61
|
-
return canonicalizeGroup(element);
|
|
392
|
+
return canonicalizeGroup(element, metadataPolicy);
|
|
62
393
|
}
|
|
63
394
|
if (isConditional(element)) {
|
|
64
|
-
return canonicalizeConditional(element);
|
|
395
|
+
return canonicalizeConditional(element, metadataPolicy);
|
|
65
396
|
}
|
|
66
397
|
const _exhaustive = element;
|
|
67
398
|
throw new Error(`Unknown element type: ${JSON.stringify(_exhaustive)}`);
|
|
68
399
|
}
|
|
69
|
-
function canonicalizeField(field) {
|
|
400
|
+
function canonicalizeField(field, metadataPolicy) {
|
|
70
401
|
switch (field._field) {
|
|
71
402
|
case "text":
|
|
72
|
-
return canonicalizeTextField(field);
|
|
403
|
+
return canonicalizeTextField(field, metadataPolicy);
|
|
73
404
|
case "number":
|
|
74
|
-
return canonicalizeNumberField(field);
|
|
405
|
+
return canonicalizeNumberField(field, metadataPolicy);
|
|
75
406
|
case "boolean":
|
|
76
|
-
return canonicalizeBooleanField(field);
|
|
407
|
+
return canonicalizeBooleanField(field, metadataPolicy);
|
|
77
408
|
case "enum":
|
|
78
|
-
return canonicalizeStaticEnumField(field);
|
|
409
|
+
return canonicalizeStaticEnumField(field, metadataPolicy);
|
|
79
410
|
case "dynamic_enum":
|
|
80
|
-
return canonicalizeDynamicEnumField(field);
|
|
411
|
+
return canonicalizeDynamicEnumField(field, metadataPolicy);
|
|
81
412
|
case "dynamic_schema":
|
|
82
|
-
return canonicalizeDynamicSchemaField(field);
|
|
413
|
+
return canonicalizeDynamicSchemaField(field, metadataPolicy);
|
|
83
414
|
case "array":
|
|
84
|
-
return canonicalizeArrayField(field);
|
|
415
|
+
return canonicalizeArrayField(field, metadataPolicy);
|
|
85
416
|
case "object":
|
|
86
|
-
return canonicalizeObjectField(field);
|
|
417
|
+
return canonicalizeObjectField(field, metadataPolicy);
|
|
87
418
|
default: {
|
|
88
419
|
const _exhaustive = field;
|
|
89
420
|
throw new Error(`Unknown field type: ${JSON.stringify(_exhaustive)}`);
|
|
90
421
|
}
|
|
91
422
|
}
|
|
92
423
|
}
|
|
93
|
-
function canonicalizeTextField(field) {
|
|
424
|
+
function canonicalizeTextField(field, metadataPolicy) {
|
|
94
425
|
const type = { kind: "primitive", primitiveKind: "string" };
|
|
95
426
|
const constraints = [];
|
|
96
427
|
if (field.minLength !== void 0) {
|
|
@@ -122,13 +453,14 @@ function canonicalizeTextField(field) {
|
|
|
122
453
|
}
|
|
123
454
|
return buildFieldNode(
|
|
124
455
|
field.name,
|
|
456
|
+
resolveFieldMetadata(field.name, field, metadataPolicy),
|
|
125
457
|
type,
|
|
126
458
|
field.required,
|
|
127
|
-
buildAnnotations(field
|
|
459
|
+
buildAnnotations(getExplicitDisplayName(field), field.placeholder),
|
|
128
460
|
constraints
|
|
129
461
|
);
|
|
130
462
|
}
|
|
131
|
-
function canonicalizeNumberField(field) {
|
|
463
|
+
function canonicalizeNumberField(field, metadataPolicy) {
|
|
132
464
|
const type = { kind: "primitive", primitiveKind: "number" };
|
|
133
465
|
const constraints = [];
|
|
134
466
|
if (field.min !== void 0) {
|
|
@@ -160,17 +492,24 @@ function canonicalizeNumberField(field) {
|
|
|
160
492
|
}
|
|
161
493
|
return buildFieldNode(
|
|
162
494
|
field.name,
|
|
495
|
+
resolveFieldMetadata(field.name, field, metadataPolicy),
|
|
163
496
|
type,
|
|
164
497
|
field.required,
|
|
165
|
-
buildAnnotations(field
|
|
498
|
+
buildAnnotations(getExplicitDisplayName(field)),
|
|
166
499
|
constraints
|
|
167
500
|
);
|
|
168
501
|
}
|
|
169
|
-
function canonicalizeBooleanField(field) {
|
|
502
|
+
function canonicalizeBooleanField(field, metadataPolicy) {
|
|
170
503
|
const type = { kind: "primitive", primitiveKind: "boolean" };
|
|
171
|
-
return buildFieldNode(
|
|
504
|
+
return buildFieldNode(
|
|
505
|
+
field.name,
|
|
506
|
+
resolveFieldMetadata(field.name, field, metadataPolicy),
|
|
507
|
+
type,
|
|
508
|
+
field.required,
|
|
509
|
+
buildAnnotations(getExplicitDisplayName(field))
|
|
510
|
+
);
|
|
172
511
|
}
|
|
173
|
-
function canonicalizeStaticEnumField(field) {
|
|
512
|
+
function canonicalizeStaticEnumField(field, metadataPolicy) {
|
|
174
513
|
const members = field.options.map((opt) => {
|
|
175
514
|
if (typeof opt === "string") {
|
|
176
515
|
return { value: opt };
|
|
@@ -178,28 +517,46 @@ function canonicalizeStaticEnumField(field) {
|
|
|
178
517
|
return { value: opt.id, displayName: opt.label };
|
|
179
518
|
});
|
|
180
519
|
const type = { kind: "enum", members };
|
|
181
|
-
return buildFieldNode(
|
|
520
|
+
return buildFieldNode(
|
|
521
|
+
field.name,
|
|
522
|
+
resolveFieldMetadata(field.name, field, metadataPolicy),
|
|
523
|
+
type,
|
|
524
|
+
field.required,
|
|
525
|
+
buildAnnotations(getExplicitDisplayName(field))
|
|
526
|
+
);
|
|
182
527
|
}
|
|
183
|
-
function canonicalizeDynamicEnumField(field) {
|
|
528
|
+
function canonicalizeDynamicEnumField(field, metadataPolicy) {
|
|
184
529
|
const type = {
|
|
185
530
|
kind: "dynamic",
|
|
186
531
|
dynamicKind: "enum",
|
|
187
532
|
sourceKey: field.source,
|
|
188
533
|
parameterFields: field.params ? [...field.params] : []
|
|
189
534
|
};
|
|
190
|
-
return buildFieldNode(
|
|
535
|
+
return buildFieldNode(
|
|
536
|
+
field.name,
|
|
537
|
+
resolveFieldMetadata(field.name, field, metadataPolicy),
|
|
538
|
+
type,
|
|
539
|
+
field.required,
|
|
540
|
+
buildAnnotations(getExplicitDisplayName(field))
|
|
541
|
+
);
|
|
191
542
|
}
|
|
192
|
-
function canonicalizeDynamicSchemaField(field) {
|
|
543
|
+
function canonicalizeDynamicSchemaField(field, metadataPolicy) {
|
|
193
544
|
const type = {
|
|
194
545
|
kind: "dynamic",
|
|
195
546
|
dynamicKind: "schema",
|
|
196
547
|
sourceKey: field.schemaSource,
|
|
197
548
|
parameterFields: []
|
|
198
549
|
};
|
|
199
|
-
return buildFieldNode(
|
|
550
|
+
return buildFieldNode(
|
|
551
|
+
field.name,
|
|
552
|
+
resolveFieldMetadata(field.name, field, metadataPolicy),
|
|
553
|
+
type,
|
|
554
|
+
field.required,
|
|
555
|
+
buildAnnotations(getExplicitDisplayName(field))
|
|
556
|
+
);
|
|
200
557
|
}
|
|
201
|
-
function canonicalizeArrayField(field) {
|
|
202
|
-
const itemProperties = buildObjectProperties(field.items);
|
|
558
|
+
function canonicalizeArrayField(field, metadataPolicy) {
|
|
559
|
+
const itemProperties = buildObjectProperties(field.items, metadataPolicy);
|
|
203
560
|
const itemsType = {
|
|
204
561
|
kind: "object",
|
|
205
562
|
properties: itemProperties,
|
|
@@ -227,37 +584,44 @@ function canonicalizeArrayField(field) {
|
|
|
227
584
|
}
|
|
228
585
|
return buildFieldNode(
|
|
229
586
|
field.name,
|
|
587
|
+
resolveFieldMetadata(field.name, field, metadataPolicy),
|
|
230
588
|
type,
|
|
231
589
|
field.required,
|
|
232
|
-
buildAnnotations(field
|
|
590
|
+
buildAnnotations(getExplicitDisplayName(field)),
|
|
233
591
|
constraints
|
|
234
592
|
);
|
|
235
593
|
}
|
|
236
|
-
function canonicalizeObjectField(field) {
|
|
237
|
-
const properties = buildObjectProperties(field.properties);
|
|
594
|
+
function canonicalizeObjectField(field, metadataPolicy) {
|
|
595
|
+
const properties = buildObjectProperties(field.properties, metadataPolicy);
|
|
238
596
|
const type = {
|
|
239
597
|
kind: "object",
|
|
240
598
|
properties,
|
|
241
599
|
additionalProperties: true
|
|
242
600
|
};
|
|
243
|
-
return buildFieldNode(
|
|
601
|
+
return buildFieldNode(
|
|
602
|
+
field.name,
|
|
603
|
+
resolveFieldMetadata(field.name, field, metadataPolicy),
|
|
604
|
+
type,
|
|
605
|
+
field.required,
|
|
606
|
+
buildAnnotations(getExplicitDisplayName(field))
|
|
607
|
+
);
|
|
244
608
|
}
|
|
245
|
-
function canonicalizeGroup(g) {
|
|
609
|
+
function canonicalizeGroup(g, metadataPolicy) {
|
|
246
610
|
return {
|
|
247
611
|
kind: "group",
|
|
248
612
|
label: g.label,
|
|
249
|
-
elements: canonicalizeElements(g.elements),
|
|
613
|
+
elements: canonicalizeElements(g.elements, metadataPolicy),
|
|
250
614
|
provenance: CHAIN_DSL_PROVENANCE
|
|
251
615
|
};
|
|
252
616
|
}
|
|
253
|
-
function canonicalizeConditional(c) {
|
|
617
|
+
function canonicalizeConditional(c, metadataPolicy) {
|
|
254
618
|
return {
|
|
255
619
|
kind: "conditional",
|
|
256
620
|
fieldName: c.field,
|
|
257
621
|
// Conditional values from the chain DSL are JSON-serializable primitives
|
|
258
622
|
// (strings, numbers, booleans) produced by the `is()` predicate helper.
|
|
259
623
|
value: assertJsonValue(c.value),
|
|
260
|
-
elements: canonicalizeElements(c.elements),
|
|
624
|
+
elements: canonicalizeElements(c.elements, metadataPolicy),
|
|
261
625
|
provenance: CHAIN_DSL_PROVENANCE
|
|
262
626
|
};
|
|
263
627
|
}
|
|
@@ -277,10 +641,11 @@ function assertJsonValue(v) {
|
|
|
277
641
|
}
|
|
278
642
|
throw new TypeError(`Conditional value is not a valid JsonValue: ${typeof v}`);
|
|
279
643
|
}
|
|
280
|
-
function buildFieldNode(name, type, required, annotations, constraints = []) {
|
|
644
|
+
function buildFieldNode(name, metadata, type, required, annotations, constraints = []) {
|
|
281
645
|
return {
|
|
282
646
|
kind: "field",
|
|
283
647
|
name,
|
|
648
|
+
...metadata !== void 0 && { metadata },
|
|
284
649
|
type,
|
|
285
650
|
required: required === true,
|
|
286
651
|
constraints,
|
|
@@ -310,13 +675,14 @@ function buildAnnotations(label, placeholder) {
|
|
|
310
675
|
}
|
|
311
676
|
return annotations;
|
|
312
677
|
}
|
|
313
|
-
function buildObjectProperties(elements, insideConditional = false) {
|
|
678
|
+
function buildObjectProperties(elements, metadataPolicy, insideConditional = false) {
|
|
314
679
|
const properties = [];
|
|
315
680
|
for (const el of elements) {
|
|
316
681
|
if (isField(el)) {
|
|
317
|
-
const fieldNode = canonicalizeField(el);
|
|
682
|
+
const fieldNode = canonicalizeField(el, metadataPolicy);
|
|
318
683
|
properties.push({
|
|
319
684
|
name: fieldNode.name,
|
|
685
|
+
...fieldNode.metadata !== void 0 && { metadata: fieldNode.metadata },
|
|
320
686
|
type: fieldNode.type,
|
|
321
687
|
// Fields inside a conditional branch are always optional in the
|
|
322
688
|
// data schema, regardless of their `required` flag — the condition
|
|
@@ -327,18 +693,36 @@ function buildObjectProperties(elements, insideConditional = false) {
|
|
|
327
693
|
provenance: CHAIN_DSL_PROVENANCE
|
|
328
694
|
});
|
|
329
695
|
} else if (isGroup(el)) {
|
|
330
|
-
properties.push(...buildObjectProperties(el.elements, insideConditional));
|
|
696
|
+
properties.push(...buildObjectProperties(el.elements, metadataPolicy, insideConditional));
|
|
331
697
|
} else if (isConditional(el)) {
|
|
332
|
-
properties.push(...buildObjectProperties(el.elements, true));
|
|
698
|
+
properties.push(...buildObjectProperties(el.elements, metadataPolicy, true));
|
|
333
699
|
}
|
|
334
700
|
}
|
|
335
701
|
return properties;
|
|
336
702
|
}
|
|
703
|
+
function getExplicitDisplayName(field) {
|
|
704
|
+
if (field.label !== void 0 && field.displayName !== void 0) {
|
|
705
|
+
throw new Error('Chain DSL fields cannot specify both "label" and "displayName".');
|
|
706
|
+
}
|
|
707
|
+
return field.displayName ?? field.label;
|
|
708
|
+
}
|
|
709
|
+
function resolveFieldMetadata(logicalName, field, metadataPolicy) {
|
|
710
|
+
const displayName = getExplicitDisplayName(field);
|
|
711
|
+
return resolveMetadata(
|
|
712
|
+
{
|
|
713
|
+
...field.apiName !== void 0 && { apiName: field.apiName },
|
|
714
|
+
...displayName !== void 0 && { displayName }
|
|
715
|
+
},
|
|
716
|
+
getDeclarationMetadataPolicy(metadataPolicy, "field"),
|
|
717
|
+
makeMetadataContext("chain-dsl", "field", logicalName)
|
|
718
|
+
);
|
|
719
|
+
}
|
|
337
720
|
var import_internals, CHAIN_DSL_PROVENANCE;
|
|
338
721
|
var init_chain_dsl_canonicalizer = __esm({
|
|
339
722
|
"src/canonicalize/chain-dsl-canonicalizer.ts"() {
|
|
340
723
|
"use strict";
|
|
341
724
|
import_internals = require("@formspec/core/internals");
|
|
725
|
+
init_metadata();
|
|
342
726
|
CHAIN_DSL_PROVENANCE = {
|
|
343
727
|
surface: "chain-dsl",
|
|
344
728
|
file: "",
|
|
@@ -349,7 +733,7 @@ var init_chain_dsl_canonicalizer = __esm({
|
|
|
349
733
|
});
|
|
350
734
|
|
|
351
735
|
// src/canonicalize/tsdoc-canonicalizer.ts
|
|
352
|
-
function canonicalizeTSDoc(analysis, source) {
|
|
736
|
+
function canonicalizeTSDoc(analysis, source, options) {
|
|
353
737
|
const file = source?.file ?? "";
|
|
354
738
|
const provenance = {
|
|
355
739
|
surface: "tsdoc",
|
|
@@ -358,15 +742,21 @@ function canonicalizeTSDoc(analysis, source) {
|
|
|
358
742
|
column: 0
|
|
359
743
|
};
|
|
360
744
|
const elements = assembleElements(analysis.fields, analysis.fieldLayouts, provenance);
|
|
361
|
-
|
|
745
|
+
const ir = {
|
|
362
746
|
kind: "form-ir",
|
|
747
|
+
name: analysis.name,
|
|
363
748
|
irVersion: import_internals2.IR_VERSION,
|
|
364
749
|
elements,
|
|
750
|
+
...analysis.metadata !== void 0 && { metadata: analysis.metadata },
|
|
365
751
|
typeRegistry: analysis.typeRegistry,
|
|
366
752
|
...analysis.annotations !== void 0 && analysis.annotations.length > 0 && { rootAnnotations: analysis.annotations },
|
|
367
753
|
...analysis.annotations !== void 0 && analysis.annotations.length > 0 && { annotations: analysis.annotations },
|
|
368
754
|
provenance
|
|
369
755
|
};
|
|
756
|
+
return resolveFormIRMetadata(ir, {
|
|
757
|
+
policy: normalizeMetadataPolicy(options?.metadata),
|
|
758
|
+
surface: "tsdoc"
|
|
759
|
+
});
|
|
370
760
|
}
|
|
371
761
|
function assembleElements(fields, layouts, provenance) {
|
|
372
762
|
const elements = [];
|
|
@@ -427,6 +817,7 @@ var init_tsdoc_canonicalizer = __esm({
|
|
|
427
817
|
"src/canonicalize/tsdoc-canonicalizer.ts"() {
|
|
428
818
|
"use strict";
|
|
429
819
|
import_internals2 = require("@formspec/core/internals");
|
|
820
|
+
init_metadata();
|
|
430
821
|
}
|
|
431
822
|
});
|
|
432
823
|
|
|
@@ -439,6 +830,126 @@ var init_canonicalize = __esm({
|
|
|
439
830
|
}
|
|
440
831
|
});
|
|
441
832
|
|
|
833
|
+
// src/metadata/collision-guards.ts
|
|
834
|
+
function assertUniqueSerializedNames(entries, scope) {
|
|
835
|
+
const seen = /* @__PURE__ */ new Map();
|
|
836
|
+
for (const entry of entries) {
|
|
837
|
+
const previous = seen.get(entry.serializedName);
|
|
838
|
+
if (previous !== void 0) {
|
|
839
|
+
if (previous.logicalName === entry.logicalName && previous.category === entry.category) {
|
|
840
|
+
continue;
|
|
841
|
+
}
|
|
842
|
+
throw new Error(
|
|
843
|
+
`Serialized name collision in ${scope}: ${previous.category} "${previous.logicalName}" and ${entry.category} "${entry.logicalName}" both resolve to "${entry.serializedName}".`
|
|
844
|
+
);
|
|
845
|
+
}
|
|
846
|
+
seen.set(entry.serializedName, entry);
|
|
847
|
+
}
|
|
848
|
+
}
|
|
849
|
+
function collectFlattenedFields(elements) {
|
|
850
|
+
const fields = [];
|
|
851
|
+
for (const element of elements) {
|
|
852
|
+
switch (element.kind) {
|
|
853
|
+
case "field":
|
|
854
|
+
fields.push(element);
|
|
855
|
+
break;
|
|
856
|
+
case "group":
|
|
857
|
+
case "conditional":
|
|
858
|
+
fields.push(...collectFlattenedFields(element.elements));
|
|
859
|
+
break;
|
|
860
|
+
default: {
|
|
861
|
+
const exhaustive = element;
|
|
862
|
+
void exhaustive;
|
|
863
|
+
}
|
|
864
|
+
}
|
|
865
|
+
}
|
|
866
|
+
return fields;
|
|
867
|
+
}
|
|
868
|
+
function validateObjectProperties(properties, scope) {
|
|
869
|
+
assertUniqueSerializedNames(
|
|
870
|
+
properties.map((property) => ({
|
|
871
|
+
logicalName: property.name,
|
|
872
|
+
serializedName: getSerializedName(property.name, property.metadata),
|
|
873
|
+
category: "object property"
|
|
874
|
+
})),
|
|
875
|
+
scope
|
|
876
|
+
);
|
|
877
|
+
for (const property of properties) {
|
|
878
|
+
validateTypeNode(
|
|
879
|
+
property.type,
|
|
880
|
+
`${scope}.${getSerializedName(property.name, property.metadata)}`
|
|
881
|
+
);
|
|
882
|
+
}
|
|
883
|
+
}
|
|
884
|
+
function validateTypeNode(type, scope) {
|
|
885
|
+
switch (type.kind) {
|
|
886
|
+
case "array":
|
|
887
|
+
validateTypeNode(type.items, `${scope}[]`);
|
|
888
|
+
break;
|
|
889
|
+
case "object":
|
|
890
|
+
validateObjectProperties(type.properties, scope);
|
|
891
|
+
break;
|
|
892
|
+
case "record":
|
|
893
|
+
validateTypeNode(type.valueType, `${scope}.*`);
|
|
894
|
+
break;
|
|
895
|
+
case "union":
|
|
896
|
+
type.members.forEach((member, index) => {
|
|
897
|
+
validateTypeNode(member, `${scope}|${String(index)}`);
|
|
898
|
+
});
|
|
899
|
+
break;
|
|
900
|
+
case "reference":
|
|
901
|
+
case "primitive":
|
|
902
|
+
case "enum":
|
|
903
|
+
case "dynamic":
|
|
904
|
+
case "custom":
|
|
905
|
+
break;
|
|
906
|
+
default: {
|
|
907
|
+
const exhaustive = type;
|
|
908
|
+
void exhaustive;
|
|
909
|
+
}
|
|
910
|
+
}
|
|
911
|
+
}
|
|
912
|
+
function validateTypeDefinitions(typeRegistry) {
|
|
913
|
+
const definitions = Object.values(typeRegistry);
|
|
914
|
+
assertUniqueSerializedNames(
|
|
915
|
+
definitions.map((definition) => ({
|
|
916
|
+
logicalName: definition.name,
|
|
917
|
+
serializedName: getSerializedName(definition.name, definition.metadata),
|
|
918
|
+
category: "type definition"
|
|
919
|
+
})),
|
|
920
|
+
"$defs"
|
|
921
|
+
);
|
|
922
|
+
for (const definition of definitions) {
|
|
923
|
+
validateTypeDefinition(definition);
|
|
924
|
+
}
|
|
925
|
+
}
|
|
926
|
+
function validateTypeDefinition(definition) {
|
|
927
|
+
validateTypeNode(
|
|
928
|
+
definition.type,
|
|
929
|
+
`type "${getSerializedName(definition.name, definition.metadata)}"`
|
|
930
|
+
);
|
|
931
|
+
}
|
|
932
|
+
function assertNoSerializedNameCollisions(ir) {
|
|
933
|
+
assertUniqueSerializedNames(
|
|
934
|
+
collectFlattenedFields(ir.elements).map((field) => ({
|
|
935
|
+
logicalName: field.name,
|
|
936
|
+
serializedName: getSerializedName(field.name, field.metadata),
|
|
937
|
+
category: "field"
|
|
938
|
+
})),
|
|
939
|
+
"form root"
|
|
940
|
+
);
|
|
941
|
+
for (const field of collectFlattenedFields(ir.elements)) {
|
|
942
|
+
validateTypeNode(field.type, `field "${getSerializedName(field.name, field.metadata)}"`);
|
|
943
|
+
}
|
|
944
|
+
validateTypeDefinitions(ir.typeRegistry);
|
|
945
|
+
}
|
|
946
|
+
var init_collision_guards = __esm({
|
|
947
|
+
"src/metadata/collision-guards.ts"() {
|
|
948
|
+
"use strict";
|
|
949
|
+
init_resolve();
|
|
950
|
+
}
|
|
951
|
+
});
|
|
952
|
+
|
|
442
953
|
// src/json-schema/ir-generator.ts
|
|
443
954
|
function makeContext(options) {
|
|
444
955
|
const vendorPrefix = options?.vendorPrefix ?? "x-formspec";
|
|
@@ -449,19 +960,33 @@ function makeContext(options) {
|
|
|
449
960
|
}
|
|
450
961
|
return {
|
|
451
962
|
defs: {},
|
|
963
|
+
typeNameMap: {},
|
|
964
|
+
typeRegistry: {},
|
|
452
965
|
extensionRegistry: options?.extensionRegistry,
|
|
453
966
|
vendorPrefix
|
|
454
967
|
};
|
|
455
968
|
}
|
|
456
969
|
function generateJsonSchemaFromIR(ir, options) {
|
|
457
|
-
|
|
970
|
+
assertNoSerializedNameCollisions(ir);
|
|
971
|
+
const ctx = {
|
|
972
|
+
...makeContext(options),
|
|
973
|
+
typeRegistry: ir.typeRegistry,
|
|
974
|
+
typeNameMap: Object.fromEntries(
|
|
975
|
+
Object.entries(ir.typeRegistry).map(([name, typeDef]) => [
|
|
976
|
+
name,
|
|
977
|
+
getSerializedName(name, typeDef.metadata)
|
|
978
|
+
])
|
|
979
|
+
)
|
|
980
|
+
};
|
|
458
981
|
for (const [name, typeDef] of Object.entries(ir.typeRegistry)) {
|
|
459
|
-
ctx.
|
|
982
|
+
const schemaName = ctx.typeNameMap[name] ?? name;
|
|
983
|
+
ctx.defs[schemaName] = generateTypeNode(typeDef.type, ctx);
|
|
984
|
+
applyResolvedMetadata(ctx.defs[schemaName], typeDef.metadata);
|
|
460
985
|
if (typeDef.constraints && typeDef.constraints.length > 0) {
|
|
461
|
-
applyConstraints(ctx.defs[
|
|
986
|
+
applyConstraints(ctx.defs[schemaName], typeDef.constraints, ctx);
|
|
462
987
|
}
|
|
463
988
|
if (typeDef.annotations && typeDef.annotations.length > 0) {
|
|
464
|
-
applyAnnotations(ctx.defs[
|
|
989
|
+
applyAnnotations(ctx.defs[schemaName], typeDef.annotations, ctx);
|
|
465
990
|
}
|
|
466
991
|
}
|
|
467
992
|
const properties = {};
|
|
@@ -474,6 +999,7 @@ function generateJsonSchemaFromIR(ir, options) {
|
|
|
474
999
|
properties,
|
|
475
1000
|
...uniqueRequired.length > 0 && { required: uniqueRequired }
|
|
476
1001
|
};
|
|
1002
|
+
applyResolvedMetadata(result, ir.metadata);
|
|
477
1003
|
if (ir.annotations && ir.annotations.length > 0) {
|
|
478
1004
|
applyAnnotations(result, ir.annotations, ctx);
|
|
479
1005
|
}
|
|
@@ -486,9 +1012,9 @@ function collectFields(elements, properties, required, ctx) {
|
|
|
486
1012
|
for (const element of elements) {
|
|
487
1013
|
switch (element.kind) {
|
|
488
1014
|
case "field":
|
|
489
|
-
properties[element.name] = generateFieldSchema(element, ctx);
|
|
1015
|
+
properties[getSerializedName(element.name, element.metadata)] = generateFieldSchema(element, ctx);
|
|
490
1016
|
if (element.required) {
|
|
491
|
-
required.push(element.name);
|
|
1017
|
+
required.push(getSerializedName(element.name, element.metadata));
|
|
492
1018
|
}
|
|
493
1019
|
break;
|
|
494
1020
|
case "group":
|
|
@@ -532,6 +1058,7 @@ function generateFieldSchema(field, ctx) {
|
|
|
532
1058
|
rootAnnotations.push(annotation);
|
|
533
1059
|
}
|
|
534
1060
|
}
|
|
1061
|
+
applyResolvedMetadata(schema, field.metadata);
|
|
535
1062
|
applyAnnotations(schema, rootAnnotations, ctx);
|
|
536
1063
|
if (itemStringSchema !== void 0) {
|
|
537
1064
|
applyAnnotations(itemStringSchema, itemAnnotations, ctx);
|
|
@@ -539,7 +1066,7 @@ function generateFieldSchema(field, ctx) {
|
|
|
539
1066
|
if (pathConstraints.length === 0) {
|
|
540
1067
|
return schema;
|
|
541
1068
|
}
|
|
542
|
-
return applyPathTargetedConstraints(schema, pathConstraints, ctx);
|
|
1069
|
+
return applyPathTargetedConstraints(schema, pathConstraints, ctx, field.type);
|
|
543
1070
|
}
|
|
544
1071
|
function isStringItemConstraint(constraint) {
|
|
545
1072
|
switch (constraint.constraintKind) {
|
|
@@ -551,9 +1078,11 @@ function isStringItemConstraint(constraint) {
|
|
|
551
1078
|
return false;
|
|
552
1079
|
}
|
|
553
1080
|
}
|
|
554
|
-
function applyPathTargetedConstraints(schema, pathConstraints, ctx) {
|
|
1081
|
+
function applyPathTargetedConstraints(schema, pathConstraints, ctx, typeNode) {
|
|
555
1082
|
if (schema.type === "array" && schema.items) {
|
|
556
|
-
|
|
1083
|
+
const referencedType = typeNode?.kind === "reference" ? resolveReferencedType(typeNode, ctx) : void 0;
|
|
1084
|
+
const nestedType = typeNode?.kind === "array" ? typeNode.items : referencedType?.kind === "array" ? referencedType.items : void 0;
|
|
1085
|
+
schema.items = applyPathTargetedConstraints(schema.items, pathConstraints, ctx, nestedType);
|
|
557
1086
|
return schema;
|
|
558
1087
|
}
|
|
559
1088
|
const byTarget = /* @__PURE__ */ new Map();
|
|
@@ -568,7 +1097,7 @@ function applyPathTargetedConstraints(schema, pathConstraints, ctx) {
|
|
|
568
1097
|
for (const [target, constraints] of byTarget) {
|
|
569
1098
|
const subSchema = {};
|
|
570
1099
|
applyConstraints(subSchema, constraints, ctx);
|
|
571
|
-
propertyOverrides[target] = subSchema;
|
|
1100
|
+
propertyOverrides[resolveSerializedPropertyName(target, typeNode, ctx)] = subSchema;
|
|
572
1101
|
}
|
|
573
1102
|
if (schema.$ref) {
|
|
574
1103
|
const { $ref, ...rest } = schema;
|
|
@@ -616,7 +1145,7 @@ function generateTypeNode(type, ctx) {
|
|
|
616
1145
|
case "union":
|
|
617
1146
|
return generateUnionType(type, ctx);
|
|
618
1147
|
case "reference":
|
|
619
|
-
return generateReferenceType(type);
|
|
1148
|
+
return generateReferenceType(type, ctx);
|
|
620
1149
|
case "dynamic":
|
|
621
1150
|
return generateDynamicType(type);
|
|
622
1151
|
case "custom":
|
|
@@ -657,9 +1186,10 @@ function generateObjectType(type, ctx) {
|
|
|
657
1186
|
const properties = {};
|
|
658
1187
|
const required = [];
|
|
659
1188
|
for (const prop of type.properties) {
|
|
660
|
-
|
|
1189
|
+
const propertyName = getSerializedName(prop.name, prop.metadata);
|
|
1190
|
+
properties[propertyName] = generatePropertySchema(prop, ctx);
|
|
661
1191
|
if (!prop.optional) {
|
|
662
|
-
required.push(
|
|
1192
|
+
required.push(propertyName);
|
|
663
1193
|
}
|
|
664
1194
|
}
|
|
665
1195
|
const schema = { type: "object", properties };
|
|
@@ -680,6 +1210,7 @@ function generateRecordType(type, ctx) {
|
|
|
680
1210
|
function generatePropertySchema(prop, ctx) {
|
|
681
1211
|
const schema = generateTypeNode(prop.type, ctx);
|
|
682
1212
|
applyConstraints(schema, prop.constraints, ctx);
|
|
1213
|
+
applyResolvedMetadata(schema, prop.metadata);
|
|
683
1214
|
applyAnnotations(schema, prop.annotations, ctx);
|
|
684
1215
|
return schema;
|
|
685
1216
|
}
|
|
@@ -708,8 +1239,28 @@ function isNullableUnion(type) {
|
|
|
708
1239
|
).length;
|
|
709
1240
|
return nullCount === 1;
|
|
710
1241
|
}
|
|
711
|
-
function generateReferenceType(type) {
|
|
712
|
-
return { $ref: `#/$defs/${type.name}` };
|
|
1242
|
+
function generateReferenceType(type, ctx) {
|
|
1243
|
+
return { $ref: `#/$defs/${ctx.typeNameMap[type.name] ?? type.name}` };
|
|
1244
|
+
}
|
|
1245
|
+
function applyResolvedMetadata(schema, metadata) {
|
|
1246
|
+
const displayName = getDisplayName(metadata);
|
|
1247
|
+
if (displayName !== void 0) {
|
|
1248
|
+
schema.title = displayName;
|
|
1249
|
+
}
|
|
1250
|
+
}
|
|
1251
|
+
function resolveReferencedType(type, ctx) {
|
|
1252
|
+
return ctx.typeRegistry[type.name]?.type;
|
|
1253
|
+
}
|
|
1254
|
+
function resolveSerializedPropertyName(logicalName, typeNode, ctx) {
|
|
1255
|
+
if (typeNode?.kind === "object") {
|
|
1256
|
+
const property = typeNode.properties.find((candidate) => candidate.name === logicalName);
|
|
1257
|
+
return property === void 0 ? logicalName : getSerializedName(property.name, property.metadata);
|
|
1258
|
+
}
|
|
1259
|
+
if (typeNode?.kind === "reference") {
|
|
1260
|
+
const referencedType = resolveReferencedType(typeNode, ctx);
|
|
1261
|
+
return referencedType === void 0 ? logicalName : resolveSerializedPropertyName(logicalName, referencedType, ctx);
|
|
1262
|
+
}
|
|
1263
|
+
return logicalName;
|
|
713
1264
|
}
|
|
714
1265
|
function generateDynamicType(type) {
|
|
715
1266
|
if (type.dynamicKind === "enum") {
|
|
@@ -789,7 +1340,7 @@ function applyAnnotations(schema, annotations, ctx) {
|
|
|
789
1340
|
for (const annotation of annotations) {
|
|
790
1341
|
switch (annotation.annotationKind) {
|
|
791
1342
|
case "displayName":
|
|
792
|
-
schema.title
|
|
1343
|
+
schema.title ??= annotation.value;
|
|
793
1344
|
break;
|
|
794
1345
|
case "description":
|
|
795
1346
|
schema.description = annotation.value;
|
|
@@ -876,12 +1427,17 @@ function assignVendorPrefixedExtensionKeywords(schema, extensionSchema, vendorPr
|
|
|
876
1427
|
var init_ir_generator = __esm({
|
|
877
1428
|
"src/json-schema/ir-generator.ts"() {
|
|
878
1429
|
"use strict";
|
|
1430
|
+
init_metadata();
|
|
1431
|
+
init_collision_guards();
|
|
879
1432
|
}
|
|
880
1433
|
});
|
|
881
1434
|
|
|
882
1435
|
// src/json-schema/generator.ts
|
|
883
1436
|
function generateJsonSchema(form, options) {
|
|
884
|
-
const ir = canonicalizeChainDSL(
|
|
1437
|
+
const ir = canonicalizeChainDSL(
|
|
1438
|
+
form,
|
|
1439
|
+
options?.metadata !== void 0 ? { metadata: options.metadata } : void 0
|
|
1440
|
+
);
|
|
885
1441
|
const internalOptions = options?.vendorPrefix === void 0 ? void 0 : { vendorPrefix: options.vendorPrefix };
|
|
886
1442
|
return generateJsonSchemaFromIR(ir, internalOptions);
|
|
887
1443
|
}
|
|
@@ -1063,13 +1619,21 @@ function combineRules(parentRule, childRule) {
|
|
|
1063
1619
|
}
|
|
1064
1620
|
};
|
|
1065
1621
|
}
|
|
1066
|
-
function
|
|
1067
|
-
const
|
|
1622
|
+
function getFieldDisplayName(field) {
|
|
1623
|
+
const resolvedDisplayName = getDisplayName(field.metadata);
|
|
1624
|
+
if (resolvedDisplayName !== void 0) {
|
|
1625
|
+
return resolvedDisplayName;
|
|
1626
|
+
}
|
|
1627
|
+
return field.annotations.find((annotation) => annotation.annotationKind === "displayName")?.value;
|
|
1628
|
+
}
|
|
1629
|
+
function fieldNodeToControl(field, fieldNameMap, parentRule) {
|
|
1068
1630
|
const placeholderAnnotation = field.annotations.find((a) => a.annotationKind === "placeholder");
|
|
1631
|
+
const serializedName = fieldNameMap.get(field.name) ?? getSerializedName(field.name, field.metadata);
|
|
1632
|
+
const displayName = getFieldDisplayName(field);
|
|
1069
1633
|
const control = {
|
|
1070
1634
|
type: "Control",
|
|
1071
|
-
scope: fieldToScope(
|
|
1072
|
-
...
|
|
1635
|
+
scope: fieldToScope(serializedName),
|
|
1636
|
+
...displayName !== void 0 && { label: displayName },
|
|
1073
1637
|
...placeholderAnnotation !== void 0 && {
|
|
1074
1638
|
options: { placeholder: placeholderAnnotation.value }
|
|
1075
1639
|
},
|
|
@@ -1077,30 +1641,30 @@ function fieldNodeToControl(field, parentRule) {
|
|
|
1077
1641
|
};
|
|
1078
1642
|
return control;
|
|
1079
1643
|
}
|
|
1080
|
-
function groupNodeToLayout(group, parentRule) {
|
|
1644
|
+
function groupNodeToLayout(group, fieldNameMap, parentRule) {
|
|
1081
1645
|
return {
|
|
1082
1646
|
type: "Group",
|
|
1083
1647
|
label: group.label,
|
|
1084
|
-
elements: irElementsToUiSchema(group.elements, parentRule),
|
|
1648
|
+
elements: irElementsToUiSchema(group.elements, fieldNameMap, parentRule),
|
|
1085
1649
|
...parentRule !== void 0 && { rule: parentRule }
|
|
1086
1650
|
};
|
|
1087
1651
|
}
|
|
1088
|
-
function irElementsToUiSchema(elements, parentRule) {
|
|
1652
|
+
function irElementsToUiSchema(elements, fieldNameMap, parentRule) {
|
|
1089
1653
|
const result = [];
|
|
1090
1654
|
for (const element of elements) {
|
|
1091
1655
|
switch (element.kind) {
|
|
1092
1656
|
case "field": {
|
|
1093
|
-
result.push(fieldNodeToControl(element, parentRule));
|
|
1657
|
+
result.push(fieldNodeToControl(element, fieldNameMap, parentRule));
|
|
1094
1658
|
break;
|
|
1095
1659
|
}
|
|
1096
1660
|
case "group": {
|
|
1097
|
-
result.push(groupNodeToLayout(element, parentRule));
|
|
1661
|
+
result.push(groupNodeToLayout(element, fieldNameMap, parentRule));
|
|
1098
1662
|
break;
|
|
1099
1663
|
}
|
|
1100
1664
|
case "conditional": {
|
|
1101
|
-
const newRule = createShowRule(element.fieldName, element.value);
|
|
1665
|
+
const newRule = createShowRule(fieldNameMap.get(element.fieldName) ?? element.fieldName, element.value);
|
|
1102
1666
|
const combinedRule = parentRule !== void 0 ? combineRules(parentRule, newRule) : newRule;
|
|
1103
|
-
const childElements = irElementsToUiSchema(element.elements, combinedRule);
|
|
1667
|
+
const childElements = irElementsToUiSchema(element.elements, fieldNameMap, combinedRule);
|
|
1104
1668
|
result.push(...childElements);
|
|
1105
1669
|
break;
|
|
1106
1670
|
}
|
|
@@ -1114,24 +1678,52 @@ function irElementsToUiSchema(elements, parentRule) {
|
|
|
1114
1678
|
return result;
|
|
1115
1679
|
}
|
|
1116
1680
|
function generateUiSchemaFromIR(ir) {
|
|
1681
|
+
assertNoSerializedNameCollisions(ir);
|
|
1682
|
+
const fieldNameMap = collectFieldNameMap(ir.elements);
|
|
1117
1683
|
const result = {
|
|
1118
1684
|
type: "VerticalLayout",
|
|
1119
|
-
elements: irElementsToUiSchema(ir.elements)
|
|
1685
|
+
elements: irElementsToUiSchema(ir.elements, fieldNameMap)
|
|
1120
1686
|
};
|
|
1121
1687
|
return parseOrThrow(uiSchema, result, "UI Schema");
|
|
1122
1688
|
}
|
|
1689
|
+
function collectFieldNameMap(elements) {
|
|
1690
|
+
const map = /* @__PURE__ */ new Map();
|
|
1691
|
+
for (const element of elements) {
|
|
1692
|
+
switch (element.kind) {
|
|
1693
|
+
case "field":
|
|
1694
|
+
map.set(element.name, getSerializedName(element.name, element.metadata));
|
|
1695
|
+
break;
|
|
1696
|
+
case "group":
|
|
1697
|
+
case "conditional":
|
|
1698
|
+
for (const [key, value] of collectFieldNameMap(element.elements)) {
|
|
1699
|
+
map.set(key, value);
|
|
1700
|
+
}
|
|
1701
|
+
break;
|
|
1702
|
+
default: {
|
|
1703
|
+
const _exhaustive = element;
|
|
1704
|
+
void _exhaustive;
|
|
1705
|
+
}
|
|
1706
|
+
}
|
|
1707
|
+
}
|
|
1708
|
+
return map;
|
|
1709
|
+
}
|
|
1123
1710
|
var import_zod2;
|
|
1124
1711
|
var init_ir_generator2 = __esm({
|
|
1125
1712
|
"src/ui-schema/ir-generator.ts"() {
|
|
1126
1713
|
"use strict";
|
|
1714
|
+
init_metadata();
|
|
1715
|
+
init_collision_guards();
|
|
1127
1716
|
init_schema();
|
|
1128
1717
|
import_zod2 = require("zod");
|
|
1129
1718
|
}
|
|
1130
1719
|
});
|
|
1131
1720
|
|
|
1132
1721
|
// src/ui-schema/generator.ts
|
|
1133
|
-
function generateUiSchema(form) {
|
|
1134
|
-
const ir = canonicalizeChainDSL(
|
|
1722
|
+
function generateUiSchema(form, options) {
|
|
1723
|
+
const ir = canonicalizeChainDSL(
|
|
1724
|
+
form,
|
|
1725
|
+
options?.metadata !== void 0 ? { metadata: options.metadata } : void 0
|
|
1726
|
+
);
|
|
1135
1727
|
return generateUiSchemaFromIR(ir);
|
|
1136
1728
|
}
|
|
1137
1729
|
var init_generator2 = __esm({
|
|
@@ -2185,7 +2777,76 @@ function makeParseOptions(extensionRegistry, fieldType, checker, subjectType, ho
|
|
|
2185
2777
|
...hostType !== void 0 && { hostType }
|
|
2186
2778
|
};
|
|
2187
2779
|
}
|
|
2188
|
-
function
|
|
2780
|
+
function makeExplicitScalarMetadata(value) {
|
|
2781
|
+
return value === void 0 || value === "" ? void 0 : { value, source: "explicit" };
|
|
2782
|
+
}
|
|
2783
|
+
function extractExplicitMetadata(node) {
|
|
2784
|
+
let apiName;
|
|
2785
|
+
let displayName;
|
|
2786
|
+
let apiNamePlural;
|
|
2787
|
+
let displayNamePlural;
|
|
2788
|
+
for (const tag of getLeadingParsedTags(node)) {
|
|
2789
|
+
const value = tag.argumentText.trim();
|
|
2790
|
+
if (value === "") {
|
|
2791
|
+
continue;
|
|
2792
|
+
}
|
|
2793
|
+
if (tag.normalizedTagName === "apiName") {
|
|
2794
|
+
if (tag.target === null) {
|
|
2795
|
+
apiName ??= value;
|
|
2796
|
+
} else if (tag.target.kind === "variant") {
|
|
2797
|
+
if (tag.target.rawText === "singular") {
|
|
2798
|
+
apiName ??= value;
|
|
2799
|
+
} else if (tag.target.rawText === "plural") {
|
|
2800
|
+
apiNamePlural ??= value;
|
|
2801
|
+
}
|
|
2802
|
+
}
|
|
2803
|
+
continue;
|
|
2804
|
+
}
|
|
2805
|
+
if (tag.normalizedTagName === "displayName") {
|
|
2806
|
+
if (tag.target === null) {
|
|
2807
|
+
displayName ??= value;
|
|
2808
|
+
} else if (tag.target.kind === "variant") {
|
|
2809
|
+
if (tag.target.rawText === "singular") {
|
|
2810
|
+
displayName ??= value;
|
|
2811
|
+
} else if (tag.target.rawText === "plural") {
|
|
2812
|
+
displayNamePlural ??= value;
|
|
2813
|
+
}
|
|
2814
|
+
}
|
|
2815
|
+
}
|
|
2816
|
+
}
|
|
2817
|
+
const resolvedApiName = makeExplicitScalarMetadata(apiName);
|
|
2818
|
+
const resolvedDisplayName = makeExplicitScalarMetadata(displayName);
|
|
2819
|
+
const resolvedApiNamePlural = makeExplicitScalarMetadata(apiNamePlural);
|
|
2820
|
+
const resolvedDisplayNamePlural = makeExplicitScalarMetadata(displayNamePlural);
|
|
2821
|
+
const metadata = {
|
|
2822
|
+
...resolvedApiName !== void 0 && { apiName: resolvedApiName },
|
|
2823
|
+
...resolvedDisplayName !== void 0 && { displayName: resolvedDisplayName },
|
|
2824
|
+
...resolvedApiNamePlural !== void 0 && { apiNamePlural: resolvedApiNamePlural },
|
|
2825
|
+
...resolvedDisplayNamePlural !== void 0 && {
|
|
2826
|
+
displayNamePlural: resolvedDisplayNamePlural
|
|
2827
|
+
}
|
|
2828
|
+
};
|
|
2829
|
+
return Object.keys(metadata).length === 0 ? void 0 : metadata;
|
|
2830
|
+
}
|
|
2831
|
+
function resolveNodeMetadata(metadataPolicy, declarationKind, logicalName, node, buildContext) {
|
|
2832
|
+
const explicit = extractExplicitMetadata(node);
|
|
2833
|
+
return resolveMetadata(
|
|
2834
|
+
{
|
|
2835
|
+
...explicit?.apiName !== void 0 && { apiName: explicit.apiName.value },
|
|
2836
|
+
...explicit?.displayName !== void 0 && { displayName: explicit.displayName.value },
|
|
2837
|
+
...explicit?.apiNamePlural !== void 0 && {
|
|
2838
|
+
apiNamePlural: explicit.apiNamePlural.value
|
|
2839
|
+
},
|
|
2840
|
+
...explicit?.displayNamePlural !== void 0 && {
|
|
2841
|
+
displayNamePlural: explicit.displayNamePlural.value
|
|
2842
|
+
}
|
|
2843
|
+
},
|
|
2844
|
+
getDeclarationMetadataPolicy(metadataPolicy, declarationKind),
|
|
2845
|
+
makeMetadataContext("tsdoc", declarationKind, logicalName, buildContext)
|
|
2846
|
+
);
|
|
2847
|
+
}
|
|
2848
|
+
function analyzeClassToIR(classDecl, checker, file = "", extensionRegistry, metadataPolicy) {
|
|
2849
|
+
const normalizedMetadataPolicy = normalizeMetadataPolicy(metadataPolicy);
|
|
2189
2850
|
const name = classDecl.name?.text ?? "AnonymousClass";
|
|
2190
2851
|
const fields = [];
|
|
2191
2852
|
const fieldLayouts = [];
|
|
@@ -2212,6 +2873,7 @@ function analyzeClassToIR(classDecl, checker, file = "", extensionRegistry) {
|
|
|
2212
2873
|
visiting,
|
|
2213
2874
|
diagnostics,
|
|
2214
2875
|
classType,
|
|
2876
|
+
normalizedMetadataPolicy,
|
|
2215
2877
|
extensionRegistry
|
|
2216
2878
|
);
|
|
2217
2879
|
if (fieldNode) {
|
|
@@ -2236,10 +2898,18 @@ function analyzeClassToIR(classDecl, checker, file = "", extensionRegistry) {
|
|
|
2236
2898
|
classType,
|
|
2237
2899
|
checker,
|
|
2238
2900
|
file,
|
|
2239
|
-
diagnostics
|
|
2901
|
+
diagnostics,
|
|
2902
|
+
normalizedMetadataPolicy
|
|
2240
2903
|
);
|
|
2904
|
+
const metadata = resolveNodeMetadata(normalizedMetadataPolicy, "type", name, classDecl, {
|
|
2905
|
+
checker,
|
|
2906
|
+
declaration: classDecl,
|
|
2907
|
+
subjectType: classType,
|
|
2908
|
+
hostType: classType
|
|
2909
|
+
});
|
|
2241
2910
|
return {
|
|
2242
2911
|
name,
|
|
2912
|
+
...metadata !== void 0 && { metadata },
|
|
2243
2913
|
fields: specializedFields,
|
|
2244
2914
|
fieldLayouts,
|
|
2245
2915
|
typeRegistry,
|
|
@@ -2249,7 +2919,8 @@ function analyzeClassToIR(classDecl, checker, file = "", extensionRegistry) {
|
|
|
2249
2919
|
staticMethods
|
|
2250
2920
|
};
|
|
2251
2921
|
}
|
|
2252
|
-
function analyzeInterfaceToIR(interfaceDecl, checker, file = "", extensionRegistry) {
|
|
2922
|
+
function analyzeInterfaceToIR(interfaceDecl, checker, file = "", extensionRegistry, metadataPolicy) {
|
|
2923
|
+
const normalizedMetadataPolicy = normalizeMetadataPolicy(metadataPolicy);
|
|
2253
2924
|
const name = interfaceDecl.name.text;
|
|
2254
2925
|
const fields = [];
|
|
2255
2926
|
const typeRegistry = {};
|
|
@@ -2273,6 +2944,7 @@ function analyzeInterfaceToIR(interfaceDecl, checker, file = "", extensionRegist
|
|
|
2273
2944
|
visiting,
|
|
2274
2945
|
diagnostics,
|
|
2275
2946
|
interfaceType,
|
|
2947
|
+
normalizedMetadataPolicy,
|
|
2276
2948
|
extensionRegistry
|
|
2277
2949
|
);
|
|
2278
2950
|
if (fieldNode) {
|
|
@@ -2286,11 +2958,19 @@ function analyzeInterfaceToIR(interfaceDecl, checker, file = "", extensionRegist
|
|
|
2286
2958
|
interfaceType,
|
|
2287
2959
|
checker,
|
|
2288
2960
|
file,
|
|
2289
|
-
diagnostics
|
|
2961
|
+
diagnostics,
|
|
2962
|
+
normalizedMetadataPolicy
|
|
2290
2963
|
);
|
|
2291
2964
|
const fieldLayouts = specializedFields.map(() => ({}));
|
|
2965
|
+
const metadata = resolveNodeMetadata(normalizedMetadataPolicy, "type", name, interfaceDecl, {
|
|
2966
|
+
checker,
|
|
2967
|
+
declaration: interfaceDecl,
|
|
2968
|
+
subjectType: interfaceType,
|
|
2969
|
+
hostType: interfaceType
|
|
2970
|
+
});
|
|
2292
2971
|
return {
|
|
2293
2972
|
name,
|
|
2973
|
+
...metadata !== void 0 && { metadata },
|
|
2294
2974
|
fields: specializedFields,
|
|
2295
2975
|
fieldLayouts,
|
|
2296
2976
|
typeRegistry,
|
|
@@ -2300,7 +2980,7 @@ function analyzeInterfaceToIR(interfaceDecl, checker, file = "", extensionRegist
|
|
|
2300
2980
|
staticMethods: []
|
|
2301
2981
|
};
|
|
2302
2982
|
}
|
|
2303
|
-
function analyzeTypeAliasToIR(typeAlias, checker, file = "", extensionRegistry) {
|
|
2983
|
+
function analyzeTypeAliasToIR(typeAlias, checker, file = "", extensionRegistry, metadataPolicy) {
|
|
2304
2984
|
if (!ts3.isTypeLiteralNode(typeAlias.type)) {
|
|
2305
2985
|
const sourceFile = typeAlias.getSourceFile();
|
|
2306
2986
|
const { line } = sourceFile.getLineAndCharacterOfPosition(typeAlias.getStart());
|
|
@@ -2310,6 +2990,8 @@ function analyzeTypeAliasToIR(typeAlias, checker, file = "", extensionRegistry)
|
|
|
2310
2990
|
error: `Type alias "${typeAlias.name.text}" at line ${String(line + 1)} is not an object type literal (found ${kindDesc})`
|
|
2311
2991
|
};
|
|
2312
2992
|
}
|
|
2993
|
+
const typeLiteral = typeAlias.type;
|
|
2994
|
+
const normalizedMetadataPolicy = normalizeMetadataPolicy(metadataPolicy);
|
|
2313
2995
|
const name = typeAlias.name.text;
|
|
2314
2996
|
const fields = [];
|
|
2315
2997
|
const typeRegistry = {};
|
|
@@ -2323,7 +3005,7 @@ function analyzeTypeAliasToIR(typeAlias, checker, file = "", extensionRegistry)
|
|
|
2323
3005
|
const annotations = [...typeAliasDoc.annotations];
|
|
2324
3006
|
diagnostics.push(...typeAliasDoc.diagnostics);
|
|
2325
3007
|
const visiting = /* @__PURE__ */ new Set();
|
|
2326
|
-
for (const member of
|
|
3008
|
+
for (const member of typeLiteral.members) {
|
|
2327
3009
|
if (ts3.isPropertySignature(member)) {
|
|
2328
3010
|
const fieldNode = analyzeInterfacePropertyToIR(
|
|
2329
3011
|
member,
|
|
@@ -2333,6 +3015,7 @@ function analyzeTypeAliasToIR(typeAlias, checker, file = "", extensionRegistry)
|
|
|
2333
3015
|
visiting,
|
|
2334
3016
|
diagnostics,
|
|
2335
3017
|
aliasType,
|
|
3018
|
+
normalizedMetadataPolicy,
|
|
2336
3019
|
extensionRegistry
|
|
2337
3020
|
);
|
|
2338
3021
|
if (fieldNode) {
|
|
@@ -2346,12 +3029,20 @@ function analyzeTypeAliasToIR(typeAlias, checker, file = "", extensionRegistry)
|
|
|
2346
3029
|
aliasType,
|
|
2347
3030
|
checker,
|
|
2348
3031
|
file,
|
|
2349
|
-
diagnostics
|
|
3032
|
+
diagnostics,
|
|
3033
|
+
normalizedMetadataPolicy
|
|
2350
3034
|
);
|
|
3035
|
+
const metadata = resolveNodeMetadata(normalizedMetadataPolicy, "type", name, typeAlias, {
|
|
3036
|
+
checker,
|
|
3037
|
+
declaration: typeAlias,
|
|
3038
|
+
subjectType: aliasType,
|
|
3039
|
+
hostType: aliasType
|
|
3040
|
+
});
|
|
2351
3041
|
return {
|
|
2352
3042
|
ok: true,
|
|
2353
3043
|
analysis: {
|
|
2354
3044
|
name,
|
|
3045
|
+
...metadata !== void 0 && { metadata },
|
|
2355
3046
|
fields: specializedFields,
|
|
2356
3047
|
fieldLayouts: specializedFields.map(() => ({})),
|
|
2357
3048
|
typeRegistry,
|
|
@@ -2391,31 +3082,20 @@ function getLeadingParsedTags(node) {
|
|
|
2391
3082
|
}
|
|
2392
3083
|
return parsedTags;
|
|
2393
3084
|
}
|
|
2394
|
-
function
|
|
2395
|
-
|
|
2396
|
-
|
|
2397
|
-
|
|
2398
|
-
return member;
|
|
2399
|
-
}
|
|
2400
|
-
}
|
|
2401
|
-
return null;
|
|
2402
|
-
}
|
|
2403
|
-
if (ts3.isInterfaceDeclaration(node)) {
|
|
2404
|
-
for (const member of node.members) {
|
|
2405
|
-
if (ts3.isPropertySignature(member) && ts3.isIdentifier(member.name) && member.name.text === fieldName) {
|
|
2406
|
-
return member;
|
|
2407
|
-
}
|
|
2408
|
-
}
|
|
3085
|
+
function resolveDiscriminatorProperty(node, checker, fieldName) {
|
|
3086
|
+
const subjectType = checker.getTypeAtLocation(node);
|
|
3087
|
+
const propertySymbol = subjectType.getProperty(fieldName);
|
|
3088
|
+
if (propertySymbol === void 0) {
|
|
2409
3089
|
return null;
|
|
2410
3090
|
}
|
|
2411
|
-
|
|
2412
|
-
|
|
2413
|
-
|
|
2414
|
-
|
|
2415
|
-
|
|
2416
|
-
|
|
2417
|
-
|
|
2418
|
-
|
|
3091
|
+
const declaration = propertySymbol.valueDeclaration ?? propertySymbol.declarations?.find(
|
|
3092
|
+
(candidate) => ts3.isPropertyDeclaration(candidate) || ts3.isPropertySignature(candidate)
|
|
3093
|
+
) ?? propertySymbol.declarations?.[0];
|
|
3094
|
+
return {
|
|
3095
|
+
declaration,
|
|
3096
|
+
type: checker.getTypeOfSymbolAtLocation(propertySymbol, declaration ?? node),
|
|
3097
|
+
optional: !!(propertySymbol.flags & ts3.SymbolFlags.Optional) || declaration !== void 0 && "questionToken" in declaration && declaration.questionToken !== void 0
|
|
3098
|
+
};
|
|
2419
3099
|
}
|
|
2420
3100
|
function isLocalTypeParameterName(node, typeParameterName) {
|
|
2421
3101
|
return node.typeParameters?.some((typeParameter) => typeParameter.name.text === typeParameterName) ?? false;
|
|
@@ -2508,8 +3188,8 @@ function validateDiscriminatorDirective(node, checker, file, diagnostics) {
|
|
|
2508
3188
|
);
|
|
2509
3189
|
return null;
|
|
2510
3190
|
}
|
|
2511
|
-
const
|
|
2512
|
-
if (
|
|
3191
|
+
const property = resolveDiscriminatorProperty(node, checker, directive.fieldName);
|
|
3192
|
+
if (property === null) {
|
|
2513
3193
|
diagnostics.push(
|
|
2514
3194
|
makeAnalysisDiagnostic(
|
|
2515
3195
|
"UNKNOWN_PATH_TARGET",
|
|
@@ -2519,36 +3199,35 @@ function validateDiscriminatorDirective(node, checker, file, diagnostics) {
|
|
|
2519
3199
|
);
|
|
2520
3200
|
return null;
|
|
2521
3201
|
}
|
|
2522
|
-
if (
|
|
3202
|
+
if (property.optional) {
|
|
2523
3203
|
diagnostics.push(
|
|
2524
3204
|
makeAnalysisDiagnostic(
|
|
2525
3205
|
"TYPE_MISMATCH",
|
|
2526
3206
|
`Discriminator field "${directive.fieldName}" must be required; optional discriminator fields are not supported.`,
|
|
2527
3207
|
directive.provenance,
|
|
2528
|
-
[provenanceForNode(
|
|
3208
|
+
property.declaration !== void 0 ? [provenanceForNode(property.declaration, file)] : []
|
|
2529
3209
|
)
|
|
2530
3210
|
);
|
|
2531
3211
|
return null;
|
|
2532
3212
|
}
|
|
2533
|
-
|
|
2534
|
-
if (isNullishSemanticType(propertyType)) {
|
|
3213
|
+
if (isNullishSemanticType(property.type)) {
|
|
2535
3214
|
diagnostics.push(
|
|
2536
3215
|
makeAnalysisDiagnostic(
|
|
2537
3216
|
"TYPE_MISMATCH",
|
|
2538
3217
|
`Discriminator field "${directive.fieldName}" must not be nullable.`,
|
|
2539
3218
|
directive.provenance,
|
|
2540
|
-
[provenanceForNode(
|
|
3219
|
+
property.declaration !== void 0 ? [provenanceForNode(property.declaration, file)] : []
|
|
2541
3220
|
)
|
|
2542
3221
|
);
|
|
2543
3222
|
return null;
|
|
2544
3223
|
}
|
|
2545
|
-
if (!isStringLikeSemanticType(
|
|
3224
|
+
if (!isStringLikeSemanticType(property.type)) {
|
|
2546
3225
|
diagnostics.push(
|
|
2547
3226
|
makeAnalysisDiagnostic(
|
|
2548
3227
|
"TYPE_MISMATCH",
|
|
2549
3228
|
`Discriminator field "${directive.fieldName}" must be string-like.`,
|
|
2550
3229
|
directive.provenance,
|
|
2551
|
-
[provenanceForNode(
|
|
3230
|
+
property.declaration !== void 0 ? [provenanceForNode(property.declaration, file)] : []
|
|
2552
3231
|
)
|
|
2553
3232
|
);
|
|
2554
3233
|
return null;
|
|
@@ -2569,25 +3248,58 @@ function getConcreteTypeArgumentForDiscriminator(node, subjectType, checker, typ
|
|
|
2569
3248
|
const localTypeParameter = node.typeParameters?.[typeParameterIndex];
|
|
2570
3249
|
return localTypeParameter === void 0 ? null : checker.getTypeAtLocation(localTypeParameter);
|
|
2571
3250
|
}
|
|
2572
|
-
function
|
|
2573
|
-
|
|
2574
|
-
|
|
2575
|
-
|
|
2576
|
-
|
|
2577
|
-
|
|
2578
|
-
|
|
2579
|
-
|
|
2580
|
-
|
|
2581
|
-
|
|
2582
|
-
|
|
2583
|
-
|
|
2584
|
-
|
|
3251
|
+
function resolveLiteralDiscriminatorPropertyValue(boundType, fieldName, checker, provenance, diagnostics) {
|
|
3252
|
+
const propertySymbol = boundType.getProperty(fieldName);
|
|
3253
|
+
if (propertySymbol === void 0) {
|
|
3254
|
+
return void 0;
|
|
3255
|
+
}
|
|
3256
|
+
const declaration = propertySymbol.valueDeclaration ?? propertySymbol.declarations?.[0];
|
|
3257
|
+
const anchorNode = declaration ?? boundType.symbol.declarations?.[0] ?? null;
|
|
3258
|
+
const resolvedAnchorNode = anchorNode ?? resolveNamedDiscriminatorDeclaration(boundType, checker);
|
|
3259
|
+
if (resolvedAnchorNode === null) {
|
|
3260
|
+
return void 0;
|
|
3261
|
+
}
|
|
3262
|
+
const propertyType = checker.getTypeOfSymbolAtLocation(
|
|
3263
|
+
propertySymbol,
|
|
3264
|
+
resolvedAnchorNode
|
|
3265
|
+
);
|
|
3266
|
+
if (propertyType.isStringLiteral()) {
|
|
3267
|
+
return propertyType.value;
|
|
3268
|
+
}
|
|
3269
|
+
if (propertyType.isUnion()) {
|
|
3270
|
+
const nonNullMembers = propertyType.types.filter(
|
|
3271
|
+
(member) => !(member.flags & (ts3.TypeFlags.Null | ts3.TypeFlags.Undefined))
|
|
3272
|
+
);
|
|
3273
|
+
if (nonNullMembers.length > 0 && nonNullMembers.every((member) => member.isStringLiteral())) {
|
|
3274
|
+
diagnostics.push(
|
|
3275
|
+
makeAnalysisDiagnostic(
|
|
3276
|
+
"INVALID_TAG_ARGUMENT",
|
|
3277
|
+
"Discriminator resolution for union-valued identity properties is out of scope for v1.",
|
|
3278
|
+
provenance
|
|
3279
|
+
)
|
|
3280
|
+
);
|
|
3281
|
+
return null;
|
|
2585
3282
|
}
|
|
2586
3283
|
}
|
|
2587
|
-
return
|
|
3284
|
+
return void 0;
|
|
2588
3285
|
}
|
|
2589
|
-
function
|
|
2590
|
-
|
|
3286
|
+
function resolveDiscriminatorApiName(boundType, checker, metadataPolicy) {
|
|
3287
|
+
const declaration = resolveNamedDiscriminatorDeclaration(boundType, checker);
|
|
3288
|
+
if (declaration === null) {
|
|
3289
|
+
return void 0;
|
|
3290
|
+
}
|
|
3291
|
+
const metadata = resolveNodeMetadata(
|
|
3292
|
+
metadataPolicy,
|
|
3293
|
+
"type",
|
|
3294
|
+
getDiscriminatorLogicalName(boundType, declaration, checker),
|
|
3295
|
+
declaration,
|
|
3296
|
+
{
|
|
3297
|
+
checker,
|
|
3298
|
+
declaration,
|
|
3299
|
+
subjectType: boundType
|
|
3300
|
+
}
|
|
3301
|
+
);
|
|
3302
|
+
return metadata?.apiName;
|
|
2591
3303
|
}
|
|
2592
3304
|
function resolveNamedDiscriminatorDeclaration(type, checker, seen = /* @__PURE__ */ new Set()) {
|
|
2593
3305
|
if (seen.has(type)) {
|
|
@@ -2614,7 +3326,7 @@ function resolveNamedDiscriminatorDeclaration(type, checker, seen = /* @__PURE__
|
|
|
2614
3326
|
}
|
|
2615
3327
|
return null;
|
|
2616
3328
|
}
|
|
2617
|
-
function resolveDiscriminatorValue(boundType, checker, provenance, diagnostics) {
|
|
3329
|
+
function resolveDiscriminatorValue(boundType, fieldName, checker, provenance, diagnostics, metadataPolicy) {
|
|
2618
3330
|
if (boundType === null) {
|
|
2619
3331
|
diagnostics.push(
|
|
2620
3332
|
makeAnalysisDiagnostic(
|
|
@@ -2643,9 +3355,22 @@ function resolveDiscriminatorValue(boundType, checker, provenance, diagnostics)
|
|
|
2643
3355
|
return null;
|
|
2644
3356
|
}
|
|
2645
3357
|
}
|
|
2646
|
-
const
|
|
2647
|
-
|
|
2648
|
-
|
|
3358
|
+
const literalIdentityValue = resolveLiteralDiscriminatorPropertyValue(
|
|
3359
|
+
boundType,
|
|
3360
|
+
fieldName,
|
|
3361
|
+
checker,
|
|
3362
|
+
provenance,
|
|
3363
|
+
diagnostics
|
|
3364
|
+
);
|
|
3365
|
+
if (literalIdentityValue !== void 0) {
|
|
3366
|
+
return literalIdentityValue;
|
|
3367
|
+
}
|
|
3368
|
+
const apiName = resolveDiscriminatorApiName(boundType, checker, metadataPolicy);
|
|
3369
|
+
if (apiName?.source === "explicit") {
|
|
3370
|
+
return apiName.value;
|
|
3371
|
+
}
|
|
3372
|
+
if (apiName?.source === "inferred") {
|
|
3373
|
+
return apiName.value;
|
|
2649
3374
|
}
|
|
2650
3375
|
diagnostics.push(
|
|
2651
3376
|
makeAnalysisDiagnostic(
|
|
@@ -2662,7 +3387,15 @@ function getDeclarationName(node) {
|
|
|
2662
3387
|
}
|
|
2663
3388
|
return "anonymous";
|
|
2664
3389
|
}
|
|
2665
|
-
function
|
|
3390
|
+
function getResolvedTypeArguments(type) {
|
|
3391
|
+
return (isTypeReference(type) ? type.typeArguments : void 0) ?? type.aliasTypeArguments ?? [];
|
|
3392
|
+
}
|
|
3393
|
+
function getDiscriminatorLogicalName(type, declaration, checker) {
|
|
3394
|
+
const baseName = getDeclarationName(declaration);
|
|
3395
|
+
const typeArguments = getResolvedTypeArguments(type);
|
|
3396
|
+
return typeArguments.length === 0 ? baseName : buildInstantiatedReferenceName(baseName, typeArguments, checker);
|
|
3397
|
+
}
|
|
3398
|
+
function applyDeclarationDiscriminatorToFields(fields, node, subjectType, checker, file, diagnostics, metadataPolicy) {
|
|
2666
3399
|
const directive = validateDiscriminatorDirective(node, checker, file, diagnostics);
|
|
2667
3400
|
if (directive === null) {
|
|
2668
3401
|
return [...fields];
|
|
@@ -2674,9 +3407,11 @@ function applyDeclarationDiscriminatorToFields(fields, node, subjectType, checke
|
|
|
2674
3407
|
checker,
|
|
2675
3408
|
directive.typeParameterName
|
|
2676
3409
|
),
|
|
3410
|
+
directive.fieldName,
|
|
2677
3411
|
checker,
|
|
2678
3412
|
directive.provenance,
|
|
2679
|
-
diagnostics
|
|
3413
|
+
diagnostics,
|
|
3414
|
+
metadataPolicy
|
|
2680
3415
|
);
|
|
2681
3416
|
if (discriminatorValue === null) {
|
|
2682
3417
|
return [...fields];
|
|
@@ -2697,7 +3432,7 @@ function buildInstantiatedReferenceName(baseName, typeArguments, checker) {
|
|
|
2697
3432
|
).filter((value) => value !== "");
|
|
2698
3433
|
return renderedArguments.length === 0 ? baseName : `${baseName}__${renderedArguments.join("__")}`;
|
|
2699
3434
|
}
|
|
2700
|
-
function extractReferenceTypeArguments(type, checker, file, typeRegistry, visiting, sourceNode, extensionRegistry, diagnostics) {
|
|
3435
|
+
function extractReferenceTypeArguments(type, checker, file, typeRegistry, visiting, sourceNode, metadataPolicy, extensionRegistry, diagnostics) {
|
|
2701
3436
|
const typeNode = sourceNode === void 0 ? void 0 : extractTypeNodeFromSource(sourceNode);
|
|
2702
3437
|
if (typeNode === void 0) {
|
|
2703
3438
|
return [];
|
|
@@ -2717,13 +3452,14 @@ function extractReferenceTypeArguments(type, checker, file, typeRegistry, visiti
|
|
|
2717
3452
|
typeRegistry,
|
|
2718
3453
|
visiting,
|
|
2719
3454
|
argumentNode,
|
|
3455
|
+
metadataPolicy,
|
|
2720
3456
|
extensionRegistry,
|
|
2721
3457
|
diagnostics
|
|
2722
3458
|
)
|
|
2723
3459
|
};
|
|
2724
3460
|
});
|
|
2725
3461
|
}
|
|
2726
|
-
function applyDiscriminatorToObjectProperties(properties, node, subjectType, checker, file, diagnostics) {
|
|
3462
|
+
function applyDiscriminatorToObjectProperties(properties, node, subjectType, checker, file, diagnostics, metadataPolicy) {
|
|
2727
3463
|
const directive = validateDiscriminatorDirective(node, checker, file, diagnostics);
|
|
2728
3464
|
if (directive === null) {
|
|
2729
3465
|
return properties;
|
|
@@ -2735,9 +3471,11 @@ function applyDiscriminatorToObjectProperties(properties, node, subjectType, che
|
|
|
2735
3471
|
checker,
|
|
2736
3472
|
directive.typeParameterName
|
|
2737
3473
|
),
|
|
3474
|
+
directive.fieldName,
|
|
2738
3475
|
checker,
|
|
2739
3476
|
directive.provenance,
|
|
2740
|
-
diagnostics
|
|
3477
|
+
diagnostics,
|
|
3478
|
+
metadataPolicy
|
|
2741
3479
|
);
|
|
2742
3480
|
if (discriminatorValue === null) {
|
|
2743
3481
|
return properties;
|
|
@@ -2752,7 +3490,7 @@ function applyDiscriminatorToObjectProperties(properties, node, subjectType, che
|
|
|
2752
3490
|
} : property
|
|
2753
3491
|
);
|
|
2754
3492
|
}
|
|
2755
|
-
function analyzeFieldToIR(prop, checker, file, typeRegistry, visiting, diagnostics, hostType, extensionRegistry) {
|
|
3493
|
+
function analyzeFieldToIR(prop, checker, file, typeRegistry, visiting, diagnostics, hostType, metadataPolicy, extensionRegistry) {
|
|
2756
3494
|
if (!ts3.isIdentifier(prop.name)) {
|
|
2757
3495
|
return null;
|
|
2758
3496
|
}
|
|
@@ -2767,6 +3505,7 @@ function analyzeFieldToIR(prop, checker, file, typeRegistry, visiting, diagnosti
|
|
|
2767
3505
|
typeRegistry,
|
|
2768
3506
|
visiting,
|
|
2769
3507
|
prop,
|
|
3508
|
+
metadataPolicy,
|
|
2770
3509
|
extensionRegistry,
|
|
2771
3510
|
diagnostics
|
|
2772
3511
|
);
|
|
@@ -2790,9 +3529,16 @@ function analyzeFieldToIR(prop, checker, file, typeRegistry, visiting, diagnosti
|
|
|
2790
3529
|
annotations.push(defaultAnnotation);
|
|
2791
3530
|
}
|
|
2792
3531
|
({ type, annotations } = applyEnumMemberDisplayNames(type, annotations));
|
|
3532
|
+
const metadata = resolveNodeMetadata(metadataPolicy, "field", name, prop, {
|
|
3533
|
+
checker,
|
|
3534
|
+
declaration: prop,
|
|
3535
|
+
subjectType: tsType,
|
|
3536
|
+
hostType
|
|
3537
|
+
});
|
|
2793
3538
|
return {
|
|
2794
3539
|
kind: "field",
|
|
2795
3540
|
name,
|
|
3541
|
+
...metadata !== void 0 && { metadata },
|
|
2796
3542
|
type,
|
|
2797
3543
|
required: !optional,
|
|
2798
3544
|
constraints,
|
|
@@ -2800,7 +3546,7 @@ function analyzeFieldToIR(prop, checker, file, typeRegistry, visiting, diagnosti
|
|
|
2800
3546
|
provenance
|
|
2801
3547
|
};
|
|
2802
3548
|
}
|
|
2803
|
-
function analyzeInterfacePropertyToIR(prop, checker, file, typeRegistry, visiting, diagnostics, hostType, extensionRegistry) {
|
|
3549
|
+
function analyzeInterfacePropertyToIR(prop, checker, file, typeRegistry, visiting, diagnostics, hostType, metadataPolicy, extensionRegistry) {
|
|
2804
3550
|
if (!ts3.isIdentifier(prop.name)) {
|
|
2805
3551
|
return null;
|
|
2806
3552
|
}
|
|
@@ -2815,6 +3561,7 @@ function analyzeInterfacePropertyToIR(prop, checker, file, typeRegistry, visitin
|
|
|
2815
3561
|
typeRegistry,
|
|
2816
3562
|
visiting,
|
|
2817
3563
|
prop,
|
|
3564
|
+
metadataPolicy,
|
|
2818
3565
|
extensionRegistry,
|
|
2819
3566
|
diagnostics
|
|
2820
3567
|
);
|
|
@@ -2834,9 +3581,16 @@ function analyzeInterfacePropertyToIR(prop, checker, file, typeRegistry, visitin
|
|
|
2834
3581
|
let annotations = [];
|
|
2835
3582
|
annotations.push(...docResult.annotations);
|
|
2836
3583
|
({ type, annotations } = applyEnumMemberDisplayNames(type, annotations));
|
|
3584
|
+
const metadata = resolveNodeMetadata(metadataPolicy, "field", name, prop, {
|
|
3585
|
+
checker,
|
|
3586
|
+
declaration: prop,
|
|
3587
|
+
subjectType: tsType,
|
|
3588
|
+
hostType
|
|
3589
|
+
});
|
|
2837
3590
|
return {
|
|
2838
3591
|
kind: "field",
|
|
2839
3592
|
name,
|
|
3593
|
+
...metadata !== void 0 && { metadata },
|
|
2840
3594
|
type,
|
|
2841
3595
|
required: !optional,
|
|
2842
3596
|
constraints,
|
|
@@ -2961,7 +3715,7 @@ function getTypeNodeRegistrationName(typeNode) {
|
|
|
2961
3715
|
}
|
|
2962
3716
|
return null;
|
|
2963
3717
|
}
|
|
2964
|
-
function resolveTypeNode(type, checker, file, typeRegistry, visiting, sourceNode, extensionRegistry, diagnostics) {
|
|
3718
|
+
function resolveTypeNode(type, checker, file, typeRegistry, visiting, sourceNode, metadataPolicy = normalizeMetadataPolicy(void 0), extensionRegistry, diagnostics) {
|
|
2965
3719
|
const customType = resolveRegisteredCustomType(sourceNode, extensionRegistry, checker);
|
|
2966
3720
|
if (customType) {
|
|
2967
3721
|
return customType;
|
|
@@ -2973,6 +3727,7 @@ function resolveTypeNode(type, checker, file, typeRegistry, visiting, sourceNode
|
|
|
2973
3727
|
typeRegistry,
|
|
2974
3728
|
visiting,
|
|
2975
3729
|
sourceNode,
|
|
3730
|
+
metadataPolicy,
|
|
2976
3731
|
extensionRegistry,
|
|
2977
3732
|
diagnostics
|
|
2978
3733
|
);
|
|
@@ -3017,6 +3772,7 @@ function resolveTypeNode(type, checker, file, typeRegistry, visiting, sourceNode
|
|
|
3017
3772
|
typeRegistry,
|
|
3018
3773
|
visiting,
|
|
3019
3774
|
sourceNode,
|
|
3775
|
+
metadataPolicy,
|
|
3020
3776
|
extensionRegistry,
|
|
3021
3777
|
diagnostics
|
|
3022
3778
|
);
|
|
@@ -3029,6 +3785,7 @@ function resolveTypeNode(type, checker, file, typeRegistry, visiting, sourceNode
|
|
|
3029
3785
|
typeRegistry,
|
|
3030
3786
|
visiting,
|
|
3031
3787
|
sourceNode,
|
|
3788
|
+
metadataPolicy,
|
|
3032
3789
|
extensionRegistry,
|
|
3033
3790
|
diagnostics
|
|
3034
3791
|
);
|
|
@@ -3041,13 +3798,14 @@ function resolveTypeNode(type, checker, file, typeRegistry, visiting, sourceNode
|
|
|
3041
3798
|
typeRegistry,
|
|
3042
3799
|
visiting,
|
|
3043
3800
|
sourceNode,
|
|
3801
|
+
metadataPolicy,
|
|
3044
3802
|
extensionRegistry,
|
|
3045
3803
|
diagnostics
|
|
3046
3804
|
);
|
|
3047
3805
|
}
|
|
3048
3806
|
return { kind: "primitive", primitiveKind: "string" };
|
|
3049
3807
|
}
|
|
3050
|
-
function tryResolveNamedPrimitiveAlias(type, checker, file, typeRegistry, visiting, sourceNode, extensionRegistry, diagnostics) {
|
|
3808
|
+
function tryResolveNamedPrimitiveAlias(type, checker, file, typeRegistry, visiting, sourceNode, metadataPolicy = normalizeMetadataPolicy(void 0), extensionRegistry, diagnostics) {
|
|
3051
3809
|
if (!(type.flags & (ts3.TypeFlags.String | ts3.TypeFlags.Number | ts3.TypeFlags.BigInt | ts3.TypeFlags.BigIntLiteral | ts3.TypeFlags.Boolean | ts3.TypeFlags.Null))) {
|
|
3052
3810
|
return null;
|
|
3053
3811
|
}
|
|
@@ -3067,14 +3825,21 @@ function tryResolveNamedPrimitiveAlias(type, checker, file, typeRegistry, visiti
|
|
|
3067
3825
|
file,
|
|
3068
3826
|
makeParseOptions(extensionRegistry)
|
|
3069
3827
|
);
|
|
3828
|
+
const metadata = resolveNodeMetadata(metadataPolicy, "type", aliasName, aliasDecl, {
|
|
3829
|
+
checker,
|
|
3830
|
+
declaration: aliasDecl,
|
|
3831
|
+
subjectType: aliasType
|
|
3832
|
+
});
|
|
3070
3833
|
typeRegistry[aliasName] = {
|
|
3071
3834
|
name: aliasName,
|
|
3835
|
+
...metadata !== void 0 && { metadata },
|
|
3072
3836
|
type: resolveAliasedPrimitiveTarget(
|
|
3073
3837
|
aliasType,
|
|
3074
3838
|
checker,
|
|
3075
3839
|
file,
|
|
3076
3840
|
typeRegistry,
|
|
3077
3841
|
visiting,
|
|
3842
|
+
metadataPolicy,
|
|
3078
3843
|
extensionRegistry,
|
|
3079
3844
|
diagnostics
|
|
3080
3845
|
),
|
|
@@ -3103,7 +3868,7 @@ function shouldEmitPrimitiveAliasDefinition(typeNode, checker) {
|
|
|
3103
3868
|
const resolved = checker.getTypeFromTypeNode(aliasDecl.type);
|
|
3104
3869
|
return !!(resolved.flags & (ts3.TypeFlags.String | ts3.TypeFlags.Number | ts3.TypeFlags.BigInt | ts3.TypeFlags.BigIntLiteral | ts3.TypeFlags.Boolean | ts3.TypeFlags.Null));
|
|
3105
3870
|
}
|
|
3106
|
-
function resolveAliasedPrimitiveTarget(type, checker, file, typeRegistry, visiting, extensionRegistry, diagnostics) {
|
|
3871
|
+
function resolveAliasedPrimitiveTarget(type, checker, file, typeRegistry, visiting, metadataPolicy = normalizeMetadataPolicy(void 0), extensionRegistry, diagnostics) {
|
|
3107
3872
|
const nestedAliasDecl = type.aliasSymbol?.declarations?.find(ts3.isTypeAliasDeclaration);
|
|
3108
3873
|
if (nestedAliasDecl !== void 0) {
|
|
3109
3874
|
return resolveAliasedPrimitiveTarget(
|
|
@@ -3112,6 +3877,7 @@ function resolveAliasedPrimitiveTarget(type, checker, file, typeRegistry, visiti
|
|
|
3112
3877
|
file,
|
|
3113
3878
|
typeRegistry,
|
|
3114
3879
|
visiting,
|
|
3880
|
+
metadataPolicy,
|
|
3115
3881
|
extensionRegistry,
|
|
3116
3882
|
diagnostics
|
|
3117
3883
|
);
|
|
@@ -3123,11 +3889,12 @@ function resolveAliasedPrimitiveTarget(type, checker, file, typeRegistry, visiti
|
|
|
3123
3889
|
typeRegistry,
|
|
3124
3890
|
visiting,
|
|
3125
3891
|
void 0,
|
|
3892
|
+
metadataPolicy,
|
|
3126
3893
|
extensionRegistry,
|
|
3127
3894
|
diagnostics
|
|
3128
3895
|
);
|
|
3129
3896
|
}
|
|
3130
|
-
function resolveUnionType(type, checker, file, typeRegistry, visiting, sourceNode, extensionRegistry, diagnostics) {
|
|
3897
|
+
function resolveUnionType(type, checker, file, typeRegistry, visiting, sourceNode, metadataPolicy = normalizeMetadataPolicy(void 0), extensionRegistry, diagnostics) {
|
|
3131
3898
|
const typeName = getNamedTypeName(type);
|
|
3132
3899
|
const namedDecl = getNamedTypeDeclaration(type);
|
|
3133
3900
|
if (typeName && typeName in typeRegistry) {
|
|
@@ -3162,8 +3929,14 @@ function resolveUnionType(type, checker, file, typeRegistry, visiting, sourceNod
|
|
|
3162
3929
|
return result;
|
|
3163
3930
|
}
|
|
3164
3931
|
const annotations = namedDecl ? extractJSDocAnnotationNodes(namedDecl, file, makeParseOptions(extensionRegistry)) : void 0;
|
|
3932
|
+
const metadata = namedDecl !== void 0 ? resolveNodeMetadata(metadataPolicy, "type", typeName, namedDecl, {
|
|
3933
|
+
checker,
|
|
3934
|
+
declaration: namedDecl,
|
|
3935
|
+
subjectType: type
|
|
3936
|
+
}) : void 0;
|
|
3165
3937
|
typeRegistry[typeName] = {
|
|
3166
3938
|
name: typeName,
|
|
3939
|
+
...metadata !== void 0 && { metadata },
|
|
3167
3940
|
type: result,
|
|
3168
3941
|
...annotations !== void 0 && annotations.length > 0 && { annotations },
|
|
3169
3942
|
provenance: provenanceForDeclaration(namedDecl ?? sourceNode, file)
|
|
@@ -3217,6 +3990,7 @@ function resolveUnionType(type, checker, file, typeRegistry, visiting, sourceNod
|
|
|
3217
3990
|
typeRegistry,
|
|
3218
3991
|
visiting,
|
|
3219
3992
|
nonNullMembers[0].sourceNode ?? sourceNode,
|
|
3993
|
+
metadataPolicy,
|
|
3220
3994
|
extensionRegistry,
|
|
3221
3995
|
diagnostics
|
|
3222
3996
|
);
|
|
@@ -3234,6 +4008,7 @@ function resolveUnionType(type, checker, file, typeRegistry, visiting, sourceNod
|
|
|
3234
4008
|
typeRegistry,
|
|
3235
4009
|
visiting,
|
|
3236
4010
|
memberSourceNode ?? sourceNode,
|
|
4011
|
+
metadataPolicy,
|
|
3237
4012
|
extensionRegistry,
|
|
3238
4013
|
diagnostics
|
|
3239
4014
|
)
|
|
@@ -3243,7 +4018,7 @@ function resolveUnionType(type, checker, file, typeRegistry, visiting, sourceNod
|
|
|
3243
4018
|
}
|
|
3244
4019
|
return registerNamed({ kind: "union", members });
|
|
3245
4020
|
}
|
|
3246
|
-
function resolveArrayType(type, checker, file, typeRegistry, visiting, sourceNode, extensionRegistry, diagnostics) {
|
|
4021
|
+
function resolveArrayType(type, checker, file, typeRegistry, visiting, sourceNode, metadataPolicy = normalizeMetadataPolicy(void 0), extensionRegistry, diagnostics) {
|
|
3247
4022
|
const typeArgs = isTypeReference(type) ? type.typeArguments : void 0;
|
|
3248
4023
|
const elementType = typeArgs?.[0];
|
|
3249
4024
|
const elementSourceNode = extractArrayElementTypeNode(sourceNode, checker);
|
|
@@ -3254,12 +4029,13 @@ function resolveArrayType(type, checker, file, typeRegistry, visiting, sourceNod
|
|
|
3254
4029
|
typeRegistry,
|
|
3255
4030
|
visiting,
|
|
3256
4031
|
elementSourceNode,
|
|
4032
|
+
metadataPolicy,
|
|
3257
4033
|
extensionRegistry,
|
|
3258
4034
|
diagnostics
|
|
3259
4035
|
) : { kind: "primitive", primitiveKind: "string" };
|
|
3260
4036
|
return { kind: "array", items };
|
|
3261
4037
|
}
|
|
3262
|
-
function tryResolveRecordType(type, checker, file, typeRegistry, visiting, extensionRegistry, diagnostics) {
|
|
4038
|
+
function tryResolveRecordType(type, checker, file, typeRegistry, visiting, metadataPolicy = normalizeMetadataPolicy(void 0), extensionRegistry, diagnostics) {
|
|
3263
4039
|
if (type.getProperties().length > 0) {
|
|
3264
4040
|
return null;
|
|
3265
4041
|
}
|
|
@@ -3274,6 +4050,7 @@ function tryResolveRecordType(type, checker, file, typeRegistry, visiting, exten
|
|
|
3274
4050
|
typeRegistry,
|
|
3275
4051
|
visiting,
|
|
3276
4052
|
void 0,
|
|
4053
|
+
metadataPolicy,
|
|
3277
4054
|
extensionRegistry,
|
|
3278
4055
|
diagnostics
|
|
3279
4056
|
);
|
|
@@ -3304,7 +4081,22 @@ function typeNodeContainsReference(type, targetName) {
|
|
|
3304
4081
|
}
|
|
3305
4082
|
}
|
|
3306
4083
|
}
|
|
3307
|
-
function
|
|
4084
|
+
function shouldEmitResolvedObjectProperty(property, declaration) {
|
|
4085
|
+
if (property.name.startsWith("__@")) {
|
|
4086
|
+
return false;
|
|
4087
|
+
}
|
|
4088
|
+
if (declaration !== void 0 && "name" in declaration && declaration.name !== void 0) {
|
|
4089
|
+
const name = declaration.name;
|
|
4090
|
+
if (ts3.isComputedPropertyName(name) || ts3.isPrivateIdentifier(name)) {
|
|
4091
|
+
return false;
|
|
4092
|
+
}
|
|
4093
|
+
if (!ts3.isIdentifier(name) && !ts3.isStringLiteral(name) && !ts3.isNumericLiteral(name)) {
|
|
4094
|
+
return false;
|
|
4095
|
+
}
|
|
4096
|
+
}
|
|
4097
|
+
return true;
|
|
4098
|
+
}
|
|
4099
|
+
function resolveObjectType(type, checker, file, typeRegistry, visiting, sourceNode, metadataPolicy = normalizeMetadataPolicy(void 0), extensionRegistry, diagnostics) {
|
|
3308
4100
|
const collectedDiagnostics = diagnostics ?? [];
|
|
3309
4101
|
const typeName = getNamedTypeName(type);
|
|
3310
4102
|
const namedTypeName = typeName ?? void 0;
|
|
@@ -3316,6 +4108,7 @@ function resolveObjectType(type, checker, file, typeRegistry, visiting, sourceNo
|
|
|
3316
4108
|
typeRegistry,
|
|
3317
4109
|
visiting,
|
|
3318
4110
|
sourceNode,
|
|
4111
|
+
metadataPolicy,
|
|
3319
4112
|
extensionRegistry,
|
|
3320
4113
|
collectedDiagnostics
|
|
3321
4114
|
);
|
|
@@ -3366,6 +4159,7 @@ function resolveObjectType(type, checker, file, typeRegistry, visiting, sourceNo
|
|
|
3366
4159
|
file,
|
|
3367
4160
|
typeRegistry,
|
|
3368
4161
|
visiting,
|
|
4162
|
+
metadataPolicy,
|
|
3369
4163
|
extensionRegistry,
|
|
3370
4164
|
collectedDiagnostics
|
|
3371
4165
|
);
|
|
@@ -3378,8 +4172,14 @@ function resolveObjectType(type, checker, file, typeRegistry, visiting, sourceNo
|
|
|
3378
4172
|
return recordNode;
|
|
3379
4173
|
}
|
|
3380
4174
|
const annotations = namedDecl ? extractJSDocAnnotationNodes(namedDecl, file, makeParseOptions(extensionRegistry)) : void 0;
|
|
4175
|
+
const metadata = namedDecl !== void 0 ? resolveNodeMetadata(metadataPolicy, "type", registryTypeName, namedDecl, {
|
|
4176
|
+
checker,
|
|
4177
|
+
declaration: namedDecl,
|
|
4178
|
+
subjectType: type
|
|
4179
|
+
}) : void 0;
|
|
3381
4180
|
typeRegistry[registryTypeName] = {
|
|
3382
4181
|
name: registryTypeName,
|
|
4182
|
+
...metadata !== void 0 && { metadata },
|
|
3383
4183
|
type: recordNode,
|
|
3384
4184
|
...annotations !== void 0 && annotations.length > 0 && { annotations },
|
|
3385
4185
|
provenance: provenanceForDeclaration(namedDecl, file)
|
|
@@ -3399,12 +4199,14 @@ function resolveObjectType(type, checker, file, typeRegistry, visiting, sourceNo
|
|
|
3399
4199
|
file,
|
|
3400
4200
|
typeRegistry,
|
|
3401
4201
|
visiting,
|
|
4202
|
+
metadataPolicy,
|
|
3402
4203
|
collectedDiagnostics,
|
|
3403
4204
|
extensionRegistry
|
|
3404
4205
|
);
|
|
3405
4206
|
for (const prop of type.getProperties()) {
|
|
3406
4207
|
const declaration = prop.valueDeclaration ?? prop.declarations?.[0];
|
|
3407
4208
|
if (!declaration) continue;
|
|
4209
|
+
if (!shouldEmitResolvedObjectProperty(prop, declaration)) continue;
|
|
3408
4210
|
const propType = checker.getTypeOfSymbolAtLocation(prop, declaration);
|
|
3409
4211
|
const optional = !!(prop.flags & ts3.SymbolFlags.Optional);
|
|
3410
4212
|
const propTypeNode = resolveTypeNode(
|
|
@@ -3414,12 +4216,14 @@ function resolveObjectType(type, checker, file, typeRegistry, visiting, sourceNo
|
|
|
3414
4216
|
typeRegistry,
|
|
3415
4217
|
visiting,
|
|
3416
4218
|
declaration,
|
|
4219
|
+
metadataPolicy,
|
|
3417
4220
|
extensionRegistry,
|
|
3418
4221
|
collectedDiagnostics
|
|
3419
4222
|
);
|
|
3420
4223
|
const fieldNodeInfo = fieldInfoMap?.get(prop.name);
|
|
3421
4224
|
properties.push({
|
|
3422
4225
|
name: prop.name,
|
|
4226
|
+
...fieldNodeInfo?.metadata !== void 0 && { metadata: fieldNodeInfo.metadata },
|
|
3423
4227
|
type: propTypeNode,
|
|
3424
4228
|
optional,
|
|
3425
4229
|
constraints: fieldNodeInfo?.constraints ?? [],
|
|
@@ -3436,14 +4240,21 @@ function resolveObjectType(type, checker, file, typeRegistry, visiting, sourceNo
|
|
|
3436
4240
|
type,
|
|
3437
4241
|
checker,
|
|
3438
4242
|
file,
|
|
3439
|
-
collectedDiagnostics
|
|
4243
|
+
collectedDiagnostics,
|
|
4244
|
+
metadataPolicy
|
|
3440
4245
|
) : properties,
|
|
3441
4246
|
additionalProperties: true
|
|
3442
4247
|
};
|
|
3443
4248
|
if (registryTypeName !== void 0 && shouldRegisterNamedType) {
|
|
3444
4249
|
const annotations = namedDecl ? extractJSDocAnnotationNodes(namedDecl, file, makeParseOptions(extensionRegistry)) : void 0;
|
|
4250
|
+
const metadata = namedDecl !== void 0 ? resolveNodeMetadata(metadataPolicy, "type", registryTypeName, namedDecl, {
|
|
4251
|
+
checker,
|
|
4252
|
+
declaration: namedDecl,
|
|
4253
|
+
subjectType: type
|
|
4254
|
+
}) : void 0;
|
|
3445
4255
|
typeRegistry[registryTypeName] = {
|
|
3446
4256
|
name: registryTypeName,
|
|
4257
|
+
...metadata !== void 0 && { metadata },
|
|
3447
4258
|
type: objectNode,
|
|
3448
4259
|
...annotations !== void 0 && annotations.length > 0 && { annotations },
|
|
3449
4260
|
provenance: provenanceForDeclaration(namedDecl, file)
|
|
@@ -3456,7 +4267,7 @@ function resolveObjectType(type, checker, file, typeRegistry, visiting, sourceNo
|
|
|
3456
4267
|
}
|
|
3457
4268
|
return objectNode;
|
|
3458
4269
|
}
|
|
3459
|
-
function getNamedTypeFieldNodeInfoMap(type, checker, file, typeRegistry, visiting, diagnostics, extensionRegistry) {
|
|
4270
|
+
function getNamedTypeFieldNodeInfoMap(type, checker, file, typeRegistry, visiting, metadataPolicy, diagnostics, extensionRegistry) {
|
|
3460
4271
|
const symbols = [type.getSymbol(), type.aliasSymbol].filter(
|
|
3461
4272
|
(s) => s?.declarations != null && s.declarations.length > 0
|
|
3462
4273
|
);
|
|
@@ -3477,10 +4288,12 @@ function getNamedTypeFieldNodeInfoMap(type, checker, file, typeRegistry, visitin
|
|
|
3477
4288
|
visiting,
|
|
3478
4289
|
diagnostics,
|
|
3479
4290
|
hostType,
|
|
4291
|
+
metadataPolicy,
|
|
3480
4292
|
extensionRegistry
|
|
3481
4293
|
);
|
|
3482
4294
|
if (fieldNode) {
|
|
3483
4295
|
map.set(fieldNode.name, {
|
|
4296
|
+
...fieldNode.metadata !== void 0 && { metadata: fieldNode.metadata },
|
|
3484
4297
|
constraints: [...fieldNode.constraints],
|
|
3485
4298
|
annotations: [...fieldNode.annotations],
|
|
3486
4299
|
provenance: fieldNode.provenance
|
|
@@ -3498,6 +4311,7 @@ function getNamedTypeFieldNodeInfoMap(type, checker, file, typeRegistry, visitin
|
|
|
3498
4311
|
file,
|
|
3499
4312
|
typeRegistry,
|
|
3500
4313
|
visiting,
|
|
4314
|
+
metadataPolicy,
|
|
3501
4315
|
checker.getTypeAtLocation(interfaceDecl),
|
|
3502
4316
|
diagnostics,
|
|
3503
4317
|
extensionRegistry
|
|
@@ -3511,6 +4325,7 @@ function getNamedTypeFieldNodeInfoMap(type, checker, file, typeRegistry, visitin
|
|
|
3511
4325
|
file,
|
|
3512
4326
|
typeRegistry,
|
|
3513
4327
|
visiting,
|
|
4328
|
+
metadataPolicy,
|
|
3514
4329
|
checker.getTypeAtLocation(typeAliasDecl),
|
|
3515
4330
|
diagnostics,
|
|
3516
4331
|
extensionRegistry
|
|
@@ -3562,7 +4377,7 @@ function isNullishTypeNode(typeNode) {
|
|
|
3562
4377
|
}
|
|
3563
4378
|
return ts3.isLiteralTypeNode(typeNode) && (typeNode.literal.kind === ts3.SyntaxKind.NullKeyword || typeNode.literal.kind === ts3.SyntaxKind.UndefinedKeyword);
|
|
3564
4379
|
}
|
|
3565
|
-
function buildFieldNodeInfoMap(members, checker, file, typeRegistry, visiting, hostType, diagnostics, extensionRegistry) {
|
|
4380
|
+
function buildFieldNodeInfoMap(members, checker, file, typeRegistry, visiting, metadataPolicy, hostType, diagnostics, extensionRegistry) {
|
|
3566
4381
|
const map = /* @__PURE__ */ new Map();
|
|
3567
4382
|
for (const member of members) {
|
|
3568
4383
|
if (ts3.isPropertySignature(member)) {
|
|
@@ -3574,10 +4389,12 @@ function buildFieldNodeInfoMap(members, checker, file, typeRegistry, visiting, h
|
|
|
3574
4389
|
visiting,
|
|
3575
4390
|
diagnostics,
|
|
3576
4391
|
hostType,
|
|
4392
|
+
metadataPolicy,
|
|
3577
4393
|
extensionRegistry
|
|
3578
4394
|
);
|
|
3579
4395
|
if (fieldNode) {
|
|
3580
4396
|
map.set(fieldNode.name, {
|
|
4397
|
+
...fieldNode.metadata !== void 0 && { metadata: fieldNode.metadata },
|
|
3581
4398
|
constraints: [...fieldNode.constraints],
|
|
3582
4399
|
annotations: [...fieldNode.annotations],
|
|
3583
4400
|
provenance: fieldNode.provenance
|
|
@@ -3607,6 +4424,7 @@ function extractTypeAliasConstraintNodes(typeNode, checker, file, extensionRegis
|
|
|
3607
4424
|
{},
|
|
3608
4425
|
/* @__PURE__ */ new Set(),
|
|
3609
4426
|
aliasDecl.type,
|
|
4427
|
+
void 0,
|
|
3610
4428
|
extensionRegistry
|
|
3611
4429
|
);
|
|
3612
4430
|
const constraints = extractJSDocConstraintNodes(
|
|
@@ -3718,6 +4536,7 @@ var init_class_analyzer = __esm({
|
|
|
3718
4536
|
import_internal2 = require("@formspec/analysis/internal");
|
|
3719
4537
|
init_jsdoc_constraints();
|
|
3720
4538
|
init_tsdoc_parser();
|
|
4539
|
+
init_metadata();
|
|
3721
4540
|
RESOLVING_TYPE_PLACEHOLDER = {
|
|
3722
4541
|
kind: "object",
|
|
3723
4542
|
properties: [],
|
|
@@ -3808,19 +4627,37 @@ function findInterfaceByName(sourceFile, interfaceName) {
|
|
|
3808
4627
|
function findTypeAliasByName(sourceFile, aliasName) {
|
|
3809
4628
|
return findNodeByName(sourceFile, aliasName, ts4.isTypeAliasDeclaration, (n) => n.name.text);
|
|
3810
4629
|
}
|
|
3811
|
-
function analyzeNamedTypeToIR(filePath, typeName, extensionRegistry) {
|
|
4630
|
+
function analyzeNamedTypeToIR(filePath, typeName, extensionRegistry, metadataPolicy) {
|
|
3812
4631
|
const ctx = createProgramContext(filePath);
|
|
3813
|
-
return analyzeNamedTypeToIRFromProgramContext(
|
|
4632
|
+
return analyzeNamedTypeToIRFromProgramContext(
|
|
4633
|
+
ctx,
|
|
4634
|
+
filePath,
|
|
4635
|
+
typeName,
|
|
4636
|
+
extensionRegistry,
|
|
4637
|
+
metadataPolicy
|
|
4638
|
+
);
|
|
3814
4639
|
}
|
|
3815
|
-
function analyzeNamedTypeToIRFromProgramContext(ctx, filePath, typeName, extensionRegistry) {
|
|
4640
|
+
function analyzeNamedTypeToIRFromProgramContext(ctx, filePath, typeName, extensionRegistry, metadataPolicy) {
|
|
3816
4641
|
const analysisFilePath = path.resolve(filePath);
|
|
3817
4642
|
const classDecl = findClassByName(ctx.sourceFile, typeName);
|
|
3818
4643
|
if (classDecl !== null) {
|
|
3819
|
-
return analyzeClassToIR(
|
|
4644
|
+
return analyzeClassToIR(
|
|
4645
|
+
classDecl,
|
|
4646
|
+
ctx.checker,
|
|
4647
|
+
analysisFilePath,
|
|
4648
|
+
extensionRegistry,
|
|
4649
|
+
metadataPolicy
|
|
4650
|
+
);
|
|
3820
4651
|
}
|
|
3821
4652
|
const interfaceDecl = findInterfaceByName(ctx.sourceFile, typeName);
|
|
3822
4653
|
if (interfaceDecl !== null) {
|
|
3823
|
-
return analyzeInterfaceToIR(
|
|
4654
|
+
return analyzeInterfaceToIR(
|
|
4655
|
+
interfaceDecl,
|
|
4656
|
+
ctx.checker,
|
|
4657
|
+
analysisFilePath,
|
|
4658
|
+
extensionRegistry,
|
|
4659
|
+
metadataPolicy
|
|
4660
|
+
);
|
|
3824
4661
|
}
|
|
3825
4662
|
const typeAlias = findTypeAliasByName(ctx.sourceFile, typeName);
|
|
3826
4663
|
if (typeAlias !== null) {
|
|
@@ -3828,7 +4665,8 @@ function analyzeNamedTypeToIRFromProgramContext(ctx, filePath, typeName, extensi
|
|
|
3828
4665
|
typeAlias,
|
|
3829
4666
|
ctx.checker,
|
|
3830
4667
|
analysisFilePath,
|
|
3831
|
-
extensionRegistry
|
|
4668
|
+
extensionRegistry,
|
|
4669
|
+
metadataPolicy
|
|
3832
4670
|
);
|
|
3833
4671
|
if (result.ok) {
|
|
3834
4672
|
return result.analysis;
|
|
@@ -3944,7 +4782,11 @@ function generateClassSchemas(analysis, source, options) {
|
|
|
3944
4782
|
if (errorDiagnostics !== void 0 && errorDiagnostics.length > 0) {
|
|
3945
4783
|
throw new Error(formatValidationError(errorDiagnostics));
|
|
3946
4784
|
}
|
|
3947
|
-
const ir = canonicalizeTSDoc(
|
|
4785
|
+
const ir = canonicalizeTSDoc(
|
|
4786
|
+
analysis,
|
|
4787
|
+
source,
|
|
4788
|
+
options?.metadata !== void 0 ? { metadata: options.metadata } : void 0
|
|
4789
|
+
);
|
|
3948
4790
|
const validationResult = validateIR(ir, {
|
|
3949
4791
|
...options?.extensionRegistry !== void 0 && {
|
|
3950
4792
|
extensionRegistry: options.extensionRegistry
|
|
@@ -3981,13 +4823,15 @@ function generateSchemasFromClass(options) {
|
|
|
3981
4823
|
classDecl,
|
|
3982
4824
|
ctx.checker,
|
|
3983
4825
|
options.filePath,
|
|
3984
|
-
options.extensionRegistry
|
|
4826
|
+
options.extensionRegistry,
|
|
4827
|
+
options.metadata
|
|
3985
4828
|
);
|
|
3986
4829
|
return generateClassSchemas(
|
|
3987
4830
|
analysis,
|
|
3988
4831
|
{ file: options.filePath },
|
|
3989
4832
|
{
|
|
3990
4833
|
extensionRegistry: options.extensionRegistry,
|
|
4834
|
+
metadata: options.metadata,
|
|
3991
4835
|
vendorPrefix: options.vendorPrefix
|
|
3992
4836
|
}
|
|
3993
4837
|
);
|
|
@@ -4005,13 +4849,15 @@ function generateSchemasFromProgram(options) {
|
|
|
4005
4849
|
ctx,
|
|
4006
4850
|
options.filePath,
|
|
4007
4851
|
options.typeName,
|
|
4008
|
-
options.extensionRegistry
|
|
4852
|
+
options.extensionRegistry,
|
|
4853
|
+
options.metadata
|
|
4009
4854
|
);
|
|
4010
4855
|
return generateClassSchemas(
|
|
4011
4856
|
analysis,
|
|
4012
4857
|
{ file: options.filePath },
|
|
4013
4858
|
{
|
|
4014
4859
|
extensionRegistry: options.extensionRegistry,
|
|
4860
|
+
metadata: options.metadata,
|
|
4015
4861
|
vendorPrefix: options.vendorPrefix
|
|
4016
4862
|
}
|
|
4017
4863
|
);
|
|
@@ -4033,16 +4879,28 @@ var init_class_schema = __esm({
|
|
|
4033
4879
|
// src/generators/mixed-authoring.ts
|
|
4034
4880
|
function buildMixedAuthoringSchemas(options) {
|
|
4035
4881
|
const { filePath, typeName, overlays, ...schemaOptions } = options;
|
|
4036
|
-
const analysis = analyzeNamedTypeToIR(
|
|
4037
|
-
|
|
4038
|
-
|
|
4882
|
+
const analysis = analyzeNamedTypeToIR(
|
|
4883
|
+
filePath,
|
|
4884
|
+
typeName,
|
|
4885
|
+
schemaOptions.extensionRegistry,
|
|
4886
|
+
schemaOptions.metadata
|
|
4887
|
+
);
|
|
4888
|
+
const composedAnalysis = composeAnalysisWithOverlays(analysis, overlays, schemaOptions.metadata);
|
|
4889
|
+
const ir = canonicalizeTSDoc(
|
|
4890
|
+
composedAnalysis,
|
|
4891
|
+
{ file: filePath },
|
|
4892
|
+
schemaOptions.metadata !== void 0 ? { metadata: schemaOptions.metadata } : void 0
|
|
4893
|
+
);
|
|
4039
4894
|
return {
|
|
4040
4895
|
jsonSchema: generateJsonSchemaFromIR(ir, schemaOptions),
|
|
4041
4896
|
uiSchema: generateUiSchemaFromIR(ir)
|
|
4042
4897
|
};
|
|
4043
4898
|
}
|
|
4044
|
-
function composeAnalysisWithOverlays(analysis, overlays) {
|
|
4045
|
-
const overlayIR = canonicalizeChainDSL(
|
|
4899
|
+
function composeAnalysisWithOverlays(analysis, overlays, metadata) {
|
|
4900
|
+
const overlayIR = canonicalizeChainDSL(
|
|
4901
|
+
overlays,
|
|
4902
|
+
metadata !== void 0 ? { metadata } : void 0
|
|
4903
|
+
);
|
|
4046
4904
|
const overlayFields = collectOverlayFields(overlayIR.elements);
|
|
4047
4905
|
if (overlayFields.length === 0) {
|
|
4048
4906
|
return analysis;
|
|
@@ -4098,8 +4956,10 @@ function collectOverlayFields(elements) {
|
|
|
4098
4956
|
}
|
|
4099
4957
|
function mergeFieldOverlay(baseField, overlayField, typeRegistry) {
|
|
4100
4958
|
assertSupportedOverlayField(baseField, overlayField);
|
|
4959
|
+
const metadata = mergeResolvedMetadata(baseField.metadata, overlayField.metadata);
|
|
4101
4960
|
return {
|
|
4102
4961
|
...baseField,
|
|
4962
|
+
...metadata !== void 0 && { metadata },
|
|
4103
4963
|
type: mergeFieldType(baseField, overlayField, typeRegistry),
|
|
4104
4964
|
annotations: mergeAnnotations(baseField.annotations, overlayField.annotations)
|
|
4105
4965
|
};
|
|
@@ -4212,6 +5072,7 @@ var init_mixed_authoring = __esm({
|
|
|
4212
5072
|
init_ir_generator2();
|
|
4213
5073
|
init_canonicalize();
|
|
4214
5074
|
init_program();
|
|
5075
|
+
init_metadata();
|
|
4215
5076
|
}
|
|
4216
5077
|
});
|
|
4217
5078
|
|
|
@@ -4233,12 +5094,12 @@ __export(index_exports, {
|
|
|
4233
5094
|
function buildFormSchemas(form, options) {
|
|
4234
5095
|
return {
|
|
4235
5096
|
jsonSchema: generateJsonSchema(form, options),
|
|
4236
|
-
uiSchema: generateUiSchema(form)
|
|
5097
|
+
uiSchema: generateUiSchema(form, options)
|
|
4237
5098
|
};
|
|
4238
5099
|
}
|
|
4239
5100
|
function writeSchemas(form, options) {
|
|
4240
|
-
const { outDir, name = "schema", indent = 2, vendorPrefix } = options;
|
|
4241
|
-
const buildOptions = vendorPrefix === void 0 ? void 0 : { vendorPrefix };
|
|
5101
|
+
const { outDir, name = "schema", indent = 2, vendorPrefix, metadata } = options;
|
|
5102
|
+
const buildOptions = vendorPrefix === void 0 && metadata === void 0 ? void 0 : { vendorPrefix, metadata };
|
|
4242
5103
|
const { jsonSchema, uiSchema: uiSchema2 } = buildFormSchemas(form, buildOptions);
|
|
4243
5104
|
if (!fs.existsSync(outDir)) {
|
|
4244
5105
|
fs.mkdirSync(outDir, { recursive: true });
|