@formspec/build 0.1.0-alpha.28 → 0.1.0-alpha.30
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.js
CHANGED
|
@@ -9,8 +9,336 @@ var __export = (target, all) => {
|
|
|
9
9
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
10
10
|
};
|
|
11
11
|
|
|
12
|
+
// src/metadata/policy.ts
|
|
13
|
+
function normalizePluralization(input) {
|
|
14
|
+
if (input?.mode === "infer-if-missing") {
|
|
15
|
+
return {
|
|
16
|
+
mode: "infer-if-missing",
|
|
17
|
+
infer: () => "",
|
|
18
|
+
inflect: input.inflect
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
if (input?.mode === "require-explicit") {
|
|
22
|
+
return {
|
|
23
|
+
mode: "require-explicit",
|
|
24
|
+
infer: () => "",
|
|
25
|
+
inflect: NOOP_INFLECT
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
return {
|
|
29
|
+
mode: "disabled",
|
|
30
|
+
infer: () => "",
|
|
31
|
+
inflect: NOOP_INFLECT
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
function normalizeScalarPolicy(input) {
|
|
35
|
+
if (input?.mode === "infer-if-missing") {
|
|
36
|
+
return {
|
|
37
|
+
mode: "infer-if-missing",
|
|
38
|
+
infer: input.infer,
|
|
39
|
+
pluralization: normalizePluralization(input.pluralization)
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
if (input?.mode === "require-explicit") {
|
|
43
|
+
return {
|
|
44
|
+
mode: "require-explicit",
|
|
45
|
+
infer: () => "",
|
|
46
|
+
pluralization: normalizePluralization(input.pluralization)
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
return {
|
|
50
|
+
mode: "disabled",
|
|
51
|
+
infer: () => "",
|
|
52
|
+
pluralization: normalizePluralization(input?.pluralization)
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
function normalizeDeclarationPolicy(input) {
|
|
56
|
+
return {
|
|
57
|
+
apiName: normalizeScalarPolicy(input?.apiName),
|
|
58
|
+
displayName: normalizeScalarPolicy(input?.displayName)
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
function normalizeMetadataPolicy(input) {
|
|
62
|
+
return {
|
|
63
|
+
type: normalizeDeclarationPolicy(input?.type),
|
|
64
|
+
field: normalizeDeclarationPolicy(input?.field),
|
|
65
|
+
method: normalizeDeclarationPolicy(input?.method)
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
function getDeclarationMetadataPolicy(policy, declarationKind) {
|
|
69
|
+
return policy[declarationKind];
|
|
70
|
+
}
|
|
71
|
+
function makeMetadataContext(surface, declarationKind, logicalName, buildContext) {
|
|
72
|
+
return {
|
|
73
|
+
surface,
|
|
74
|
+
declarationKind,
|
|
75
|
+
logicalName,
|
|
76
|
+
...buildContext !== void 0 && { buildContext }
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
var NOOP_INFLECT;
|
|
80
|
+
var init_policy = __esm({
|
|
81
|
+
"src/metadata/policy.ts"() {
|
|
82
|
+
"use strict";
|
|
83
|
+
NOOP_INFLECT = () => "";
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
// src/metadata/resolve.ts
|
|
88
|
+
function toExplicitScalar(value) {
|
|
89
|
+
return value !== void 0 && value.trim() !== "" ? { value, source: "explicit" } : void 0;
|
|
90
|
+
}
|
|
91
|
+
function toExplicitResolvedMetadata(explicit) {
|
|
92
|
+
if (explicit === void 0) {
|
|
93
|
+
return void 0;
|
|
94
|
+
}
|
|
95
|
+
const apiName = toExplicitScalar(explicit.apiName);
|
|
96
|
+
const displayName = toExplicitScalar(explicit.displayName);
|
|
97
|
+
const apiNamePlural = toExplicitScalar(explicit.apiNamePlural);
|
|
98
|
+
const displayNamePlural = toExplicitScalar(explicit.displayNamePlural);
|
|
99
|
+
const metadata = {
|
|
100
|
+
...apiName !== void 0 && { apiName },
|
|
101
|
+
...displayName !== void 0 && { displayName },
|
|
102
|
+
...apiNamePlural !== void 0 && { apiNamePlural },
|
|
103
|
+
...displayNamePlural !== void 0 && { displayNamePlural }
|
|
104
|
+
};
|
|
105
|
+
return Object.keys(metadata).length > 0 ? metadata : void 0;
|
|
106
|
+
}
|
|
107
|
+
function resolveScalar(current, policy, context, metadataLabel) {
|
|
108
|
+
if (current !== void 0) {
|
|
109
|
+
return current;
|
|
110
|
+
}
|
|
111
|
+
if (policy.mode === "require-explicit") {
|
|
112
|
+
throw new Error(
|
|
113
|
+
`Metadata policy requires explicit ${metadataLabel} for ${context.declarationKind} "${context.logicalName}" on the ${context.surface} surface.`
|
|
114
|
+
);
|
|
115
|
+
}
|
|
116
|
+
if (policy.mode !== "infer-if-missing") {
|
|
117
|
+
return void 0;
|
|
118
|
+
}
|
|
119
|
+
const inferredValue = policy.infer(context);
|
|
120
|
+
return inferredValue.trim() !== "" ? { value: inferredValue, source: "inferred" } : void 0;
|
|
121
|
+
}
|
|
122
|
+
function resolvePlural(current, singular, policy, context, metadataLabel) {
|
|
123
|
+
if (current !== void 0) {
|
|
124
|
+
return current;
|
|
125
|
+
}
|
|
126
|
+
if (policy.mode === "require-explicit") {
|
|
127
|
+
throw new Error(
|
|
128
|
+
`Metadata policy requires explicit ${metadataLabel} for ${context.declarationKind} "${context.logicalName}" on the ${context.surface} surface.`
|
|
129
|
+
);
|
|
130
|
+
}
|
|
131
|
+
if (singular === void 0 || policy.mode !== "infer-if-missing") {
|
|
132
|
+
return void 0;
|
|
133
|
+
}
|
|
134
|
+
const pluralValue = policy.inflect({ ...context, singular: singular.value });
|
|
135
|
+
return pluralValue.trim() !== "" ? { value: pluralValue, source: "inferred" } : void 0;
|
|
136
|
+
}
|
|
137
|
+
function resolveResolvedMetadata(current, policy, context) {
|
|
138
|
+
const apiName = resolveScalar(current?.apiName, policy.apiName, context, "apiName");
|
|
139
|
+
const displayName = resolveScalar(
|
|
140
|
+
current?.displayName,
|
|
141
|
+
policy.displayName,
|
|
142
|
+
context,
|
|
143
|
+
"displayName"
|
|
144
|
+
);
|
|
145
|
+
const apiNamePlural = resolvePlural(
|
|
146
|
+
current?.apiNamePlural,
|
|
147
|
+
apiName,
|
|
148
|
+
policy.apiName.pluralization,
|
|
149
|
+
context,
|
|
150
|
+
"apiNamePlural"
|
|
151
|
+
);
|
|
152
|
+
const displayNamePlural = resolvePlural(
|
|
153
|
+
current?.displayNamePlural,
|
|
154
|
+
displayName,
|
|
155
|
+
policy.displayName.pluralization,
|
|
156
|
+
context,
|
|
157
|
+
"displayNamePlural"
|
|
158
|
+
);
|
|
159
|
+
if (apiName === void 0 && displayName === void 0 && apiNamePlural === void 0 && displayNamePlural === void 0) {
|
|
160
|
+
return void 0;
|
|
161
|
+
}
|
|
162
|
+
return {
|
|
163
|
+
...apiName !== void 0 && { apiName },
|
|
164
|
+
...displayName !== void 0 && { displayName },
|
|
165
|
+
...apiNamePlural !== void 0 && { apiNamePlural },
|
|
166
|
+
...displayNamePlural !== void 0 && { displayNamePlural }
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
function pickResolvedMetadataValue(baseValue, overlayValue) {
|
|
170
|
+
if (overlayValue?.source === "explicit") {
|
|
171
|
+
return overlayValue;
|
|
172
|
+
}
|
|
173
|
+
if (baseValue?.source === "explicit") {
|
|
174
|
+
return baseValue;
|
|
175
|
+
}
|
|
176
|
+
return baseValue ?? overlayValue;
|
|
177
|
+
}
|
|
178
|
+
function resolveTypeNodeMetadata(type, options) {
|
|
179
|
+
switch (type.kind) {
|
|
180
|
+
case "array":
|
|
181
|
+
return {
|
|
182
|
+
...type,
|
|
183
|
+
items: resolveTypeNodeMetadata(type.items, options)
|
|
184
|
+
};
|
|
185
|
+
case "object":
|
|
186
|
+
return {
|
|
187
|
+
...type,
|
|
188
|
+
properties: type.properties.map((property) => resolveObjectPropertyMetadata(property, options))
|
|
189
|
+
};
|
|
190
|
+
case "record":
|
|
191
|
+
return {
|
|
192
|
+
...type,
|
|
193
|
+
valueType: resolveTypeNodeMetadata(type.valueType, options)
|
|
194
|
+
};
|
|
195
|
+
case "union":
|
|
196
|
+
return {
|
|
197
|
+
...type,
|
|
198
|
+
members: type.members.map((member) => resolveTypeNodeMetadata(member, options))
|
|
199
|
+
};
|
|
200
|
+
case "reference":
|
|
201
|
+
case "primitive":
|
|
202
|
+
case "enum":
|
|
203
|
+
case "dynamic":
|
|
204
|
+
case "custom":
|
|
205
|
+
return type;
|
|
206
|
+
default: {
|
|
207
|
+
const _exhaustive = type;
|
|
208
|
+
return _exhaustive;
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
function resolveObjectPropertyMetadata(property, options) {
|
|
213
|
+
const metadata = resolveResolvedMetadata(property.metadata, options.policy.field, {
|
|
214
|
+
surface: options.surface,
|
|
215
|
+
declarationKind: "field",
|
|
216
|
+
logicalName: property.name,
|
|
217
|
+
...options.buildContext !== void 0 && { buildContext: options.buildContext }
|
|
218
|
+
});
|
|
219
|
+
return {
|
|
220
|
+
...property,
|
|
221
|
+
...metadata !== void 0 && { metadata },
|
|
222
|
+
type: resolveTypeNodeMetadata(property.type, options)
|
|
223
|
+
};
|
|
224
|
+
}
|
|
225
|
+
function resolveFieldMetadataNode(field, options) {
|
|
226
|
+
const metadata = resolveResolvedMetadata(field.metadata, options.policy.field, {
|
|
227
|
+
surface: options.surface,
|
|
228
|
+
declarationKind: "field",
|
|
229
|
+
logicalName: field.name,
|
|
230
|
+
...options.buildContext !== void 0 && { buildContext: options.buildContext }
|
|
231
|
+
});
|
|
232
|
+
return {
|
|
233
|
+
...field,
|
|
234
|
+
...metadata !== void 0 && { metadata },
|
|
235
|
+
type: resolveTypeNodeMetadata(field.type, options)
|
|
236
|
+
};
|
|
237
|
+
}
|
|
238
|
+
function resolveFormElementMetadata(element, options) {
|
|
239
|
+
switch (element.kind) {
|
|
240
|
+
case "field":
|
|
241
|
+
return resolveFieldMetadataNode(element, options);
|
|
242
|
+
case "group":
|
|
243
|
+
return {
|
|
244
|
+
...element,
|
|
245
|
+
elements: element.elements.map((child) => resolveFormElementMetadata(child, options))
|
|
246
|
+
};
|
|
247
|
+
case "conditional":
|
|
248
|
+
return {
|
|
249
|
+
...element,
|
|
250
|
+
elements: element.elements.map((child) => resolveFormElementMetadata(child, options))
|
|
251
|
+
};
|
|
252
|
+
default: {
|
|
253
|
+
const _exhaustive = element;
|
|
254
|
+
return _exhaustive;
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
function resolveTypeDefinitionMetadata(typeDefinition, options) {
|
|
259
|
+
const metadata = resolveResolvedMetadata(typeDefinition.metadata, options.policy.type, {
|
|
260
|
+
surface: options.surface,
|
|
261
|
+
declarationKind: "type",
|
|
262
|
+
logicalName: typeDefinition.name,
|
|
263
|
+
...options.buildContext !== void 0 && { buildContext: options.buildContext }
|
|
264
|
+
});
|
|
265
|
+
return {
|
|
266
|
+
...typeDefinition,
|
|
267
|
+
...metadata !== void 0 && { metadata },
|
|
268
|
+
type: resolveTypeNodeMetadata(typeDefinition.type, options)
|
|
269
|
+
};
|
|
270
|
+
}
|
|
271
|
+
function resolveMetadata(explicit, policy, context) {
|
|
272
|
+
return resolveResolvedMetadata(toExplicitResolvedMetadata(explicit), policy, context);
|
|
273
|
+
}
|
|
274
|
+
function mergeResolvedMetadata(baseMetadata, overlayMetadata) {
|
|
275
|
+
const apiName = pickResolvedMetadataValue(baseMetadata?.apiName, overlayMetadata?.apiName);
|
|
276
|
+
const displayName = pickResolvedMetadataValue(
|
|
277
|
+
baseMetadata?.displayName,
|
|
278
|
+
overlayMetadata?.displayName
|
|
279
|
+
);
|
|
280
|
+
const apiNamePlural = pickResolvedMetadataValue(
|
|
281
|
+
baseMetadata?.apiNamePlural,
|
|
282
|
+
overlayMetadata?.apiNamePlural
|
|
283
|
+
);
|
|
284
|
+
const displayNamePlural = pickResolvedMetadataValue(
|
|
285
|
+
baseMetadata?.displayNamePlural,
|
|
286
|
+
overlayMetadata?.displayNamePlural
|
|
287
|
+
);
|
|
288
|
+
if (apiName === void 0 && displayName === void 0 && apiNamePlural === void 0 && displayNamePlural === void 0) {
|
|
289
|
+
return void 0;
|
|
290
|
+
}
|
|
291
|
+
return {
|
|
292
|
+
...apiName !== void 0 && { apiName },
|
|
293
|
+
...displayName !== void 0 && { displayName },
|
|
294
|
+
...apiNamePlural !== void 0 && { apiNamePlural },
|
|
295
|
+
...displayNamePlural !== void 0 && { displayNamePlural }
|
|
296
|
+
};
|
|
297
|
+
}
|
|
298
|
+
function getSerializedName(logicalName, metadata) {
|
|
299
|
+
return metadata?.apiName?.value ?? logicalName;
|
|
300
|
+
}
|
|
301
|
+
function getDisplayName(metadata) {
|
|
302
|
+
return metadata?.displayName?.value;
|
|
303
|
+
}
|
|
304
|
+
function resolveFormIRMetadata(ir, options) {
|
|
305
|
+
const rootLogicalName = options.rootLogicalName ?? ir.name ?? "FormSpec";
|
|
306
|
+
const metadata = resolveResolvedMetadata(ir.metadata, options.policy.type, {
|
|
307
|
+
surface: options.surface,
|
|
308
|
+
declarationKind: "type",
|
|
309
|
+
logicalName: rootLogicalName,
|
|
310
|
+
...options.buildContext !== void 0 && { buildContext: options.buildContext }
|
|
311
|
+
});
|
|
312
|
+
return {
|
|
313
|
+
...ir,
|
|
314
|
+
...metadata !== void 0 && { metadata },
|
|
315
|
+
elements: ir.elements.map((element) => resolveFormElementMetadata(element, options)),
|
|
316
|
+
typeRegistry: Object.fromEntries(
|
|
317
|
+
Object.entries(ir.typeRegistry).map(([name, definition]) => [
|
|
318
|
+
name,
|
|
319
|
+
resolveTypeDefinitionMetadata(definition, options)
|
|
320
|
+
])
|
|
321
|
+
)
|
|
322
|
+
};
|
|
323
|
+
}
|
|
324
|
+
var init_resolve = __esm({
|
|
325
|
+
"src/metadata/resolve.ts"() {
|
|
326
|
+
"use strict";
|
|
327
|
+
}
|
|
328
|
+
});
|
|
329
|
+
|
|
330
|
+
// src/metadata/index.ts
|
|
331
|
+
var init_metadata = __esm({
|
|
332
|
+
"src/metadata/index.ts"() {
|
|
333
|
+
"use strict";
|
|
334
|
+
init_policy();
|
|
335
|
+
init_resolve();
|
|
336
|
+
init_resolve();
|
|
337
|
+
}
|
|
338
|
+
});
|
|
339
|
+
|
|
12
340
|
// src/canonicalize/chain-dsl-canonicalizer.ts
|
|
13
|
-
import { IR_VERSION } from "@formspec/core/internals";
|
|
341
|
+
import { IR_VERSION, _getFormSpecMetadataPolicy } from "@formspec/core/internals";
|
|
14
342
|
function isGroup(el) {
|
|
15
343
|
return el._type === "group";
|
|
16
344
|
}
|
|
@@ -20,57 +348,60 @@ function isConditional(el) {
|
|
|
20
348
|
function isField(el) {
|
|
21
349
|
return el._type === "field";
|
|
22
350
|
}
|
|
23
|
-
function canonicalizeChainDSL(form) {
|
|
351
|
+
function canonicalizeChainDSL(form, options) {
|
|
352
|
+
const metadataPolicy = normalizeMetadataPolicy(
|
|
353
|
+
options?.metadata ?? _getFormSpecMetadataPolicy(form)
|
|
354
|
+
);
|
|
24
355
|
return {
|
|
25
356
|
kind: "form-ir",
|
|
26
357
|
irVersion: IR_VERSION,
|
|
27
|
-
elements: canonicalizeElements(form.elements),
|
|
358
|
+
elements: canonicalizeElements(form.elements, metadataPolicy),
|
|
28
359
|
rootAnnotations: [],
|
|
29
360
|
typeRegistry: {},
|
|
30
361
|
provenance: CHAIN_DSL_PROVENANCE
|
|
31
362
|
};
|
|
32
363
|
}
|
|
33
|
-
function canonicalizeElements(elements) {
|
|
34
|
-
return elements.map(canonicalizeElement);
|
|
364
|
+
function canonicalizeElements(elements, metadataPolicy) {
|
|
365
|
+
return elements.map((element) => canonicalizeElement(element, metadataPolicy));
|
|
35
366
|
}
|
|
36
|
-
function canonicalizeElement(element) {
|
|
367
|
+
function canonicalizeElement(element, metadataPolicy) {
|
|
37
368
|
if (isField(element)) {
|
|
38
|
-
return canonicalizeField(element);
|
|
369
|
+
return canonicalizeField(element, metadataPolicy);
|
|
39
370
|
}
|
|
40
371
|
if (isGroup(element)) {
|
|
41
|
-
return canonicalizeGroup(element);
|
|
372
|
+
return canonicalizeGroup(element, metadataPolicy);
|
|
42
373
|
}
|
|
43
374
|
if (isConditional(element)) {
|
|
44
|
-
return canonicalizeConditional(element);
|
|
375
|
+
return canonicalizeConditional(element, metadataPolicy);
|
|
45
376
|
}
|
|
46
377
|
const _exhaustive = element;
|
|
47
378
|
throw new Error(`Unknown element type: ${JSON.stringify(_exhaustive)}`);
|
|
48
379
|
}
|
|
49
|
-
function canonicalizeField(field) {
|
|
380
|
+
function canonicalizeField(field, metadataPolicy) {
|
|
50
381
|
switch (field._field) {
|
|
51
382
|
case "text":
|
|
52
|
-
return canonicalizeTextField(field);
|
|
383
|
+
return canonicalizeTextField(field, metadataPolicy);
|
|
53
384
|
case "number":
|
|
54
|
-
return canonicalizeNumberField(field);
|
|
385
|
+
return canonicalizeNumberField(field, metadataPolicy);
|
|
55
386
|
case "boolean":
|
|
56
|
-
return canonicalizeBooleanField(field);
|
|
387
|
+
return canonicalizeBooleanField(field, metadataPolicy);
|
|
57
388
|
case "enum":
|
|
58
|
-
return canonicalizeStaticEnumField(field);
|
|
389
|
+
return canonicalizeStaticEnumField(field, metadataPolicy);
|
|
59
390
|
case "dynamic_enum":
|
|
60
|
-
return canonicalizeDynamicEnumField(field);
|
|
391
|
+
return canonicalizeDynamicEnumField(field, metadataPolicy);
|
|
61
392
|
case "dynamic_schema":
|
|
62
|
-
return canonicalizeDynamicSchemaField(field);
|
|
393
|
+
return canonicalizeDynamicSchemaField(field, metadataPolicy);
|
|
63
394
|
case "array":
|
|
64
|
-
return canonicalizeArrayField(field);
|
|
395
|
+
return canonicalizeArrayField(field, metadataPolicy);
|
|
65
396
|
case "object":
|
|
66
|
-
return canonicalizeObjectField(field);
|
|
397
|
+
return canonicalizeObjectField(field, metadataPolicy);
|
|
67
398
|
default: {
|
|
68
399
|
const _exhaustive = field;
|
|
69
400
|
throw new Error(`Unknown field type: ${JSON.stringify(_exhaustive)}`);
|
|
70
401
|
}
|
|
71
402
|
}
|
|
72
403
|
}
|
|
73
|
-
function canonicalizeTextField(field) {
|
|
404
|
+
function canonicalizeTextField(field, metadataPolicy) {
|
|
74
405
|
const type = { kind: "primitive", primitiveKind: "string" };
|
|
75
406
|
const constraints = [];
|
|
76
407
|
if (field.minLength !== void 0) {
|
|
@@ -102,13 +433,14 @@ function canonicalizeTextField(field) {
|
|
|
102
433
|
}
|
|
103
434
|
return buildFieldNode(
|
|
104
435
|
field.name,
|
|
436
|
+
resolveFieldMetadata(field.name, field, metadataPolicy),
|
|
105
437
|
type,
|
|
106
438
|
field.required,
|
|
107
|
-
buildAnnotations(field
|
|
439
|
+
buildAnnotations(getExplicitDisplayName(field), field.placeholder),
|
|
108
440
|
constraints
|
|
109
441
|
);
|
|
110
442
|
}
|
|
111
|
-
function canonicalizeNumberField(field) {
|
|
443
|
+
function canonicalizeNumberField(field, metadataPolicy) {
|
|
112
444
|
const type = { kind: "primitive", primitiveKind: "number" };
|
|
113
445
|
const constraints = [];
|
|
114
446
|
if (field.min !== void 0) {
|
|
@@ -140,17 +472,24 @@ function canonicalizeNumberField(field) {
|
|
|
140
472
|
}
|
|
141
473
|
return buildFieldNode(
|
|
142
474
|
field.name,
|
|
475
|
+
resolveFieldMetadata(field.name, field, metadataPolicy),
|
|
143
476
|
type,
|
|
144
477
|
field.required,
|
|
145
|
-
buildAnnotations(field
|
|
478
|
+
buildAnnotations(getExplicitDisplayName(field)),
|
|
146
479
|
constraints
|
|
147
480
|
);
|
|
148
481
|
}
|
|
149
|
-
function canonicalizeBooleanField(field) {
|
|
482
|
+
function canonicalizeBooleanField(field, metadataPolicy) {
|
|
150
483
|
const type = { kind: "primitive", primitiveKind: "boolean" };
|
|
151
|
-
return buildFieldNode(
|
|
484
|
+
return buildFieldNode(
|
|
485
|
+
field.name,
|
|
486
|
+
resolveFieldMetadata(field.name, field, metadataPolicy),
|
|
487
|
+
type,
|
|
488
|
+
field.required,
|
|
489
|
+
buildAnnotations(getExplicitDisplayName(field))
|
|
490
|
+
);
|
|
152
491
|
}
|
|
153
|
-
function canonicalizeStaticEnumField(field) {
|
|
492
|
+
function canonicalizeStaticEnumField(field, metadataPolicy) {
|
|
154
493
|
const members = field.options.map((opt) => {
|
|
155
494
|
if (typeof opt === "string") {
|
|
156
495
|
return { value: opt };
|
|
@@ -158,28 +497,46 @@ function canonicalizeStaticEnumField(field) {
|
|
|
158
497
|
return { value: opt.id, displayName: opt.label };
|
|
159
498
|
});
|
|
160
499
|
const type = { kind: "enum", members };
|
|
161
|
-
return buildFieldNode(
|
|
500
|
+
return buildFieldNode(
|
|
501
|
+
field.name,
|
|
502
|
+
resolveFieldMetadata(field.name, field, metadataPolicy),
|
|
503
|
+
type,
|
|
504
|
+
field.required,
|
|
505
|
+
buildAnnotations(getExplicitDisplayName(field))
|
|
506
|
+
);
|
|
162
507
|
}
|
|
163
|
-
function canonicalizeDynamicEnumField(field) {
|
|
508
|
+
function canonicalizeDynamicEnumField(field, metadataPolicy) {
|
|
164
509
|
const type = {
|
|
165
510
|
kind: "dynamic",
|
|
166
511
|
dynamicKind: "enum",
|
|
167
512
|
sourceKey: field.source,
|
|
168
513
|
parameterFields: field.params ? [...field.params] : []
|
|
169
514
|
};
|
|
170
|
-
return buildFieldNode(
|
|
515
|
+
return buildFieldNode(
|
|
516
|
+
field.name,
|
|
517
|
+
resolveFieldMetadata(field.name, field, metadataPolicy),
|
|
518
|
+
type,
|
|
519
|
+
field.required,
|
|
520
|
+
buildAnnotations(getExplicitDisplayName(field))
|
|
521
|
+
);
|
|
171
522
|
}
|
|
172
|
-
function canonicalizeDynamicSchemaField(field) {
|
|
523
|
+
function canonicalizeDynamicSchemaField(field, metadataPolicy) {
|
|
173
524
|
const type = {
|
|
174
525
|
kind: "dynamic",
|
|
175
526
|
dynamicKind: "schema",
|
|
176
527
|
sourceKey: field.schemaSource,
|
|
177
528
|
parameterFields: []
|
|
178
529
|
};
|
|
179
|
-
return buildFieldNode(
|
|
530
|
+
return buildFieldNode(
|
|
531
|
+
field.name,
|
|
532
|
+
resolveFieldMetadata(field.name, field, metadataPolicy),
|
|
533
|
+
type,
|
|
534
|
+
field.required,
|
|
535
|
+
buildAnnotations(getExplicitDisplayName(field))
|
|
536
|
+
);
|
|
180
537
|
}
|
|
181
|
-
function canonicalizeArrayField(field) {
|
|
182
|
-
const itemProperties = buildObjectProperties(field.items);
|
|
538
|
+
function canonicalizeArrayField(field, metadataPolicy) {
|
|
539
|
+
const itemProperties = buildObjectProperties(field.items, metadataPolicy);
|
|
183
540
|
const itemsType = {
|
|
184
541
|
kind: "object",
|
|
185
542
|
properties: itemProperties,
|
|
@@ -207,37 +564,44 @@ function canonicalizeArrayField(field) {
|
|
|
207
564
|
}
|
|
208
565
|
return buildFieldNode(
|
|
209
566
|
field.name,
|
|
567
|
+
resolveFieldMetadata(field.name, field, metadataPolicy),
|
|
210
568
|
type,
|
|
211
569
|
field.required,
|
|
212
|
-
buildAnnotations(field
|
|
570
|
+
buildAnnotations(getExplicitDisplayName(field)),
|
|
213
571
|
constraints
|
|
214
572
|
);
|
|
215
573
|
}
|
|
216
|
-
function canonicalizeObjectField(field) {
|
|
217
|
-
const properties = buildObjectProperties(field.properties);
|
|
574
|
+
function canonicalizeObjectField(field, metadataPolicy) {
|
|
575
|
+
const properties = buildObjectProperties(field.properties, metadataPolicy);
|
|
218
576
|
const type = {
|
|
219
577
|
kind: "object",
|
|
220
578
|
properties,
|
|
221
579
|
additionalProperties: true
|
|
222
580
|
};
|
|
223
|
-
return buildFieldNode(
|
|
581
|
+
return buildFieldNode(
|
|
582
|
+
field.name,
|
|
583
|
+
resolveFieldMetadata(field.name, field, metadataPolicy),
|
|
584
|
+
type,
|
|
585
|
+
field.required,
|
|
586
|
+
buildAnnotations(getExplicitDisplayName(field))
|
|
587
|
+
);
|
|
224
588
|
}
|
|
225
|
-
function canonicalizeGroup(g) {
|
|
589
|
+
function canonicalizeGroup(g, metadataPolicy) {
|
|
226
590
|
return {
|
|
227
591
|
kind: "group",
|
|
228
592
|
label: g.label,
|
|
229
|
-
elements: canonicalizeElements(g.elements),
|
|
593
|
+
elements: canonicalizeElements(g.elements, metadataPolicy),
|
|
230
594
|
provenance: CHAIN_DSL_PROVENANCE
|
|
231
595
|
};
|
|
232
596
|
}
|
|
233
|
-
function canonicalizeConditional(c) {
|
|
597
|
+
function canonicalizeConditional(c, metadataPolicy) {
|
|
234
598
|
return {
|
|
235
599
|
kind: "conditional",
|
|
236
600
|
fieldName: c.field,
|
|
237
601
|
// Conditional values from the chain DSL are JSON-serializable primitives
|
|
238
602
|
// (strings, numbers, booleans) produced by the `is()` predicate helper.
|
|
239
603
|
value: assertJsonValue(c.value),
|
|
240
|
-
elements: canonicalizeElements(c.elements),
|
|
604
|
+
elements: canonicalizeElements(c.elements, metadataPolicy),
|
|
241
605
|
provenance: CHAIN_DSL_PROVENANCE
|
|
242
606
|
};
|
|
243
607
|
}
|
|
@@ -257,10 +621,11 @@ function assertJsonValue(v) {
|
|
|
257
621
|
}
|
|
258
622
|
throw new TypeError(`Conditional value is not a valid JsonValue: ${typeof v}`);
|
|
259
623
|
}
|
|
260
|
-
function buildFieldNode(name, type, required, annotations, constraints = []) {
|
|
624
|
+
function buildFieldNode(name, metadata, type, required, annotations, constraints = []) {
|
|
261
625
|
return {
|
|
262
626
|
kind: "field",
|
|
263
627
|
name,
|
|
628
|
+
...metadata !== void 0 && { metadata },
|
|
264
629
|
type,
|
|
265
630
|
required: required === true,
|
|
266
631
|
constraints,
|
|
@@ -290,13 +655,14 @@ function buildAnnotations(label, placeholder) {
|
|
|
290
655
|
}
|
|
291
656
|
return annotations;
|
|
292
657
|
}
|
|
293
|
-
function buildObjectProperties(elements, insideConditional = false) {
|
|
658
|
+
function buildObjectProperties(elements, metadataPolicy, insideConditional = false) {
|
|
294
659
|
const properties = [];
|
|
295
660
|
for (const el of elements) {
|
|
296
661
|
if (isField(el)) {
|
|
297
|
-
const fieldNode = canonicalizeField(el);
|
|
662
|
+
const fieldNode = canonicalizeField(el, metadataPolicy);
|
|
298
663
|
properties.push({
|
|
299
664
|
name: fieldNode.name,
|
|
665
|
+
...fieldNode.metadata !== void 0 && { metadata: fieldNode.metadata },
|
|
300
666
|
type: fieldNode.type,
|
|
301
667
|
// Fields inside a conditional branch are always optional in the
|
|
302
668
|
// data schema, regardless of their `required` flag — the condition
|
|
@@ -307,17 +673,35 @@ function buildObjectProperties(elements, insideConditional = false) {
|
|
|
307
673
|
provenance: CHAIN_DSL_PROVENANCE
|
|
308
674
|
});
|
|
309
675
|
} else if (isGroup(el)) {
|
|
310
|
-
properties.push(...buildObjectProperties(el.elements, insideConditional));
|
|
676
|
+
properties.push(...buildObjectProperties(el.elements, metadataPolicy, insideConditional));
|
|
311
677
|
} else if (isConditional(el)) {
|
|
312
|
-
properties.push(...buildObjectProperties(el.elements, true));
|
|
678
|
+
properties.push(...buildObjectProperties(el.elements, metadataPolicy, true));
|
|
313
679
|
}
|
|
314
680
|
}
|
|
315
681
|
return properties;
|
|
316
682
|
}
|
|
683
|
+
function getExplicitDisplayName(field) {
|
|
684
|
+
if (field.label !== void 0 && field.displayName !== void 0) {
|
|
685
|
+
throw new Error('Chain DSL fields cannot specify both "label" and "displayName".');
|
|
686
|
+
}
|
|
687
|
+
return field.displayName ?? field.label;
|
|
688
|
+
}
|
|
689
|
+
function resolveFieldMetadata(logicalName, field, metadataPolicy) {
|
|
690
|
+
const displayName = getExplicitDisplayName(field);
|
|
691
|
+
return resolveMetadata(
|
|
692
|
+
{
|
|
693
|
+
...field.apiName !== void 0 && { apiName: field.apiName },
|
|
694
|
+
...displayName !== void 0 && { displayName }
|
|
695
|
+
},
|
|
696
|
+
getDeclarationMetadataPolicy(metadataPolicy, "field"),
|
|
697
|
+
makeMetadataContext("chain-dsl", "field", logicalName)
|
|
698
|
+
);
|
|
699
|
+
}
|
|
317
700
|
var CHAIN_DSL_PROVENANCE;
|
|
318
701
|
var init_chain_dsl_canonicalizer = __esm({
|
|
319
702
|
"src/canonicalize/chain-dsl-canonicalizer.ts"() {
|
|
320
703
|
"use strict";
|
|
704
|
+
init_metadata();
|
|
321
705
|
CHAIN_DSL_PROVENANCE = {
|
|
322
706
|
surface: "chain-dsl",
|
|
323
707
|
file: "",
|
|
@@ -329,7 +713,7 @@ var init_chain_dsl_canonicalizer = __esm({
|
|
|
329
713
|
|
|
330
714
|
// src/canonicalize/tsdoc-canonicalizer.ts
|
|
331
715
|
import { IR_VERSION as IR_VERSION2 } from "@formspec/core/internals";
|
|
332
|
-
function canonicalizeTSDoc(analysis, source) {
|
|
716
|
+
function canonicalizeTSDoc(analysis, source, options) {
|
|
333
717
|
const file = source?.file ?? "";
|
|
334
718
|
const provenance = {
|
|
335
719
|
surface: "tsdoc",
|
|
@@ -338,15 +722,21 @@ function canonicalizeTSDoc(analysis, source) {
|
|
|
338
722
|
column: 0
|
|
339
723
|
};
|
|
340
724
|
const elements = assembleElements(analysis.fields, analysis.fieldLayouts, provenance);
|
|
341
|
-
|
|
725
|
+
const ir = {
|
|
342
726
|
kind: "form-ir",
|
|
727
|
+
name: analysis.name,
|
|
343
728
|
irVersion: IR_VERSION2,
|
|
344
729
|
elements,
|
|
730
|
+
...analysis.metadata !== void 0 && { metadata: analysis.metadata },
|
|
345
731
|
typeRegistry: analysis.typeRegistry,
|
|
346
732
|
...analysis.annotations !== void 0 && analysis.annotations.length > 0 && { rootAnnotations: analysis.annotations },
|
|
347
733
|
...analysis.annotations !== void 0 && analysis.annotations.length > 0 && { annotations: analysis.annotations },
|
|
348
734
|
provenance
|
|
349
735
|
};
|
|
736
|
+
return resolveFormIRMetadata(ir, {
|
|
737
|
+
policy: normalizeMetadataPolicy(options?.metadata),
|
|
738
|
+
surface: "tsdoc"
|
|
739
|
+
});
|
|
350
740
|
}
|
|
351
741
|
function assembleElements(fields, layouts, provenance) {
|
|
352
742
|
const elements = [];
|
|
@@ -405,6 +795,7 @@ function wrapInConditional(field, layout, provenance) {
|
|
|
405
795
|
var init_tsdoc_canonicalizer = __esm({
|
|
406
796
|
"src/canonicalize/tsdoc-canonicalizer.ts"() {
|
|
407
797
|
"use strict";
|
|
798
|
+
init_metadata();
|
|
408
799
|
}
|
|
409
800
|
});
|
|
410
801
|
|
|
@@ -417,6 +808,126 @@ var init_canonicalize = __esm({
|
|
|
417
808
|
}
|
|
418
809
|
});
|
|
419
810
|
|
|
811
|
+
// src/metadata/collision-guards.ts
|
|
812
|
+
function assertUniqueSerializedNames(entries, scope) {
|
|
813
|
+
const seen = /* @__PURE__ */ new Map();
|
|
814
|
+
for (const entry of entries) {
|
|
815
|
+
const previous = seen.get(entry.serializedName);
|
|
816
|
+
if (previous !== void 0) {
|
|
817
|
+
if (previous.logicalName === entry.logicalName && previous.category === entry.category) {
|
|
818
|
+
continue;
|
|
819
|
+
}
|
|
820
|
+
throw new Error(
|
|
821
|
+
`Serialized name collision in ${scope}: ${previous.category} "${previous.logicalName}" and ${entry.category} "${entry.logicalName}" both resolve to "${entry.serializedName}".`
|
|
822
|
+
);
|
|
823
|
+
}
|
|
824
|
+
seen.set(entry.serializedName, entry);
|
|
825
|
+
}
|
|
826
|
+
}
|
|
827
|
+
function collectFlattenedFields(elements) {
|
|
828
|
+
const fields = [];
|
|
829
|
+
for (const element of elements) {
|
|
830
|
+
switch (element.kind) {
|
|
831
|
+
case "field":
|
|
832
|
+
fields.push(element);
|
|
833
|
+
break;
|
|
834
|
+
case "group":
|
|
835
|
+
case "conditional":
|
|
836
|
+
fields.push(...collectFlattenedFields(element.elements));
|
|
837
|
+
break;
|
|
838
|
+
default: {
|
|
839
|
+
const exhaustive = element;
|
|
840
|
+
void exhaustive;
|
|
841
|
+
}
|
|
842
|
+
}
|
|
843
|
+
}
|
|
844
|
+
return fields;
|
|
845
|
+
}
|
|
846
|
+
function validateObjectProperties(properties, scope) {
|
|
847
|
+
assertUniqueSerializedNames(
|
|
848
|
+
properties.map((property) => ({
|
|
849
|
+
logicalName: property.name,
|
|
850
|
+
serializedName: getSerializedName(property.name, property.metadata),
|
|
851
|
+
category: "object property"
|
|
852
|
+
})),
|
|
853
|
+
scope
|
|
854
|
+
);
|
|
855
|
+
for (const property of properties) {
|
|
856
|
+
validateTypeNode(
|
|
857
|
+
property.type,
|
|
858
|
+
`${scope}.${getSerializedName(property.name, property.metadata)}`
|
|
859
|
+
);
|
|
860
|
+
}
|
|
861
|
+
}
|
|
862
|
+
function validateTypeNode(type, scope) {
|
|
863
|
+
switch (type.kind) {
|
|
864
|
+
case "array":
|
|
865
|
+
validateTypeNode(type.items, `${scope}[]`);
|
|
866
|
+
break;
|
|
867
|
+
case "object":
|
|
868
|
+
validateObjectProperties(type.properties, scope);
|
|
869
|
+
break;
|
|
870
|
+
case "record":
|
|
871
|
+
validateTypeNode(type.valueType, `${scope}.*`);
|
|
872
|
+
break;
|
|
873
|
+
case "union":
|
|
874
|
+
type.members.forEach((member, index) => {
|
|
875
|
+
validateTypeNode(member, `${scope}|${String(index)}`);
|
|
876
|
+
});
|
|
877
|
+
break;
|
|
878
|
+
case "reference":
|
|
879
|
+
case "primitive":
|
|
880
|
+
case "enum":
|
|
881
|
+
case "dynamic":
|
|
882
|
+
case "custom":
|
|
883
|
+
break;
|
|
884
|
+
default: {
|
|
885
|
+
const exhaustive = type;
|
|
886
|
+
void exhaustive;
|
|
887
|
+
}
|
|
888
|
+
}
|
|
889
|
+
}
|
|
890
|
+
function validateTypeDefinitions(typeRegistry) {
|
|
891
|
+
const definitions = Object.values(typeRegistry);
|
|
892
|
+
assertUniqueSerializedNames(
|
|
893
|
+
definitions.map((definition) => ({
|
|
894
|
+
logicalName: definition.name,
|
|
895
|
+
serializedName: getSerializedName(definition.name, definition.metadata),
|
|
896
|
+
category: "type definition"
|
|
897
|
+
})),
|
|
898
|
+
"$defs"
|
|
899
|
+
);
|
|
900
|
+
for (const definition of definitions) {
|
|
901
|
+
validateTypeDefinition(definition);
|
|
902
|
+
}
|
|
903
|
+
}
|
|
904
|
+
function validateTypeDefinition(definition) {
|
|
905
|
+
validateTypeNode(
|
|
906
|
+
definition.type,
|
|
907
|
+
`type "${getSerializedName(definition.name, definition.metadata)}"`
|
|
908
|
+
);
|
|
909
|
+
}
|
|
910
|
+
function assertNoSerializedNameCollisions(ir) {
|
|
911
|
+
assertUniqueSerializedNames(
|
|
912
|
+
collectFlattenedFields(ir.elements).map((field) => ({
|
|
913
|
+
logicalName: field.name,
|
|
914
|
+
serializedName: getSerializedName(field.name, field.metadata),
|
|
915
|
+
category: "field"
|
|
916
|
+
})),
|
|
917
|
+
"form root"
|
|
918
|
+
);
|
|
919
|
+
for (const field of collectFlattenedFields(ir.elements)) {
|
|
920
|
+
validateTypeNode(field.type, `field "${getSerializedName(field.name, field.metadata)}"`);
|
|
921
|
+
}
|
|
922
|
+
validateTypeDefinitions(ir.typeRegistry);
|
|
923
|
+
}
|
|
924
|
+
var init_collision_guards = __esm({
|
|
925
|
+
"src/metadata/collision-guards.ts"() {
|
|
926
|
+
"use strict";
|
|
927
|
+
init_resolve();
|
|
928
|
+
}
|
|
929
|
+
});
|
|
930
|
+
|
|
420
931
|
// src/json-schema/ir-generator.ts
|
|
421
932
|
function makeContext(options) {
|
|
422
933
|
const vendorPrefix = options?.vendorPrefix ?? "x-formspec";
|
|
@@ -427,19 +938,33 @@ function makeContext(options) {
|
|
|
427
938
|
}
|
|
428
939
|
return {
|
|
429
940
|
defs: {},
|
|
941
|
+
typeNameMap: {},
|
|
942
|
+
typeRegistry: {},
|
|
430
943
|
extensionRegistry: options?.extensionRegistry,
|
|
431
944
|
vendorPrefix
|
|
432
945
|
};
|
|
433
946
|
}
|
|
434
947
|
function generateJsonSchemaFromIR(ir, options) {
|
|
435
|
-
|
|
948
|
+
assertNoSerializedNameCollisions(ir);
|
|
949
|
+
const ctx = {
|
|
950
|
+
...makeContext(options),
|
|
951
|
+
typeRegistry: ir.typeRegistry,
|
|
952
|
+
typeNameMap: Object.fromEntries(
|
|
953
|
+
Object.entries(ir.typeRegistry).map(([name, typeDef]) => [
|
|
954
|
+
name,
|
|
955
|
+
getSerializedName(name, typeDef.metadata)
|
|
956
|
+
])
|
|
957
|
+
)
|
|
958
|
+
};
|
|
436
959
|
for (const [name, typeDef] of Object.entries(ir.typeRegistry)) {
|
|
437
|
-
ctx.
|
|
960
|
+
const schemaName = ctx.typeNameMap[name] ?? name;
|
|
961
|
+
ctx.defs[schemaName] = generateTypeNode(typeDef.type, ctx);
|
|
962
|
+
applyResolvedMetadata(ctx.defs[schemaName], typeDef.metadata);
|
|
438
963
|
if (typeDef.constraints && typeDef.constraints.length > 0) {
|
|
439
|
-
applyConstraints(ctx.defs[
|
|
964
|
+
applyConstraints(ctx.defs[schemaName], typeDef.constraints, ctx);
|
|
440
965
|
}
|
|
441
966
|
if (typeDef.annotations && typeDef.annotations.length > 0) {
|
|
442
|
-
applyAnnotations(ctx.defs[
|
|
967
|
+
applyAnnotations(ctx.defs[schemaName], typeDef.annotations, ctx);
|
|
443
968
|
}
|
|
444
969
|
}
|
|
445
970
|
const properties = {};
|
|
@@ -452,6 +977,7 @@ function generateJsonSchemaFromIR(ir, options) {
|
|
|
452
977
|
properties,
|
|
453
978
|
...uniqueRequired.length > 0 && { required: uniqueRequired }
|
|
454
979
|
};
|
|
980
|
+
applyResolvedMetadata(result, ir.metadata);
|
|
455
981
|
if (ir.annotations && ir.annotations.length > 0) {
|
|
456
982
|
applyAnnotations(result, ir.annotations, ctx);
|
|
457
983
|
}
|
|
@@ -464,9 +990,9 @@ function collectFields(elements, properties, required, ctx) {
|
|
|
464
990
|
for (const element of elements) {
|
|
465
991
|
switch (element.kind) {
|
|
466
992
|
case "field":
|
|
467
|
-
properties[element.name] = generateFieldSchema(element, ctx);
|
|
993
|
+
properties[getSerializedName(element.name, element.metadata)] = generateFieldSchema(element, ctx);
|
|
468
994
|
if (element.required) {
|
|
469
|
-
required.push(element.name);
|
|
995
|
+
required.push(getSerializedName(element.name, element.metadata));
|
|
470
996
|
}
|
|
471
997
|
break;
|
|
472
998
|
case "group":
|
|
@@ -510,6 +1036,7 @@ function generateFieldSchema(field, ctx) {
|
|
|
510
1036
|
rootAnnotations.push(annotation);
|
|
511
1037
|
}
|
|
512
1038
|
}
|
|
1039
|
+
applyResolvedMetadata(schema, field.metadata);
|
|
513
1040
|
applyAnnotations(schema, rootAnnotations, ctx);
|
|
514
1041
|
if (itemStringSchema !== void 0) {
|
|
515
1042
|
applyAnnotations(itemStringSchema, itemAnnotations, ctx);
|
|
@@ -517,7 +1044,7 @@ function generateFieldSchema(field, ctx) {
|
|
|
517
1044
|
if (pathConstraints.length === 0) {
|
|
518
1045
|
return schema;
|
|
519
1046
|
}
|
|
520
|
-
return applyPathTargetedConstraints(schema, pathConstraints, ctx);
|
|
1047
|
+
return applyPathTargetedConstraints(schema, pathConstraints, ctx, field.type);
|
|
521
1048
|
}
|
|
522
1049
|
function isStringItemConstraint(constraint) {
|
|
523
1050
|
switch (constraint.constraintKind) {
|
|
@@ -529,9 +1056,11 @@ function isStringItemConstraint(constraint) {
|
|
|
529
1056
|
return false;
|
|
530
1057
|
}
|
|
531
1058
|
}
|
|
532
|
-
function applyPathTargetedConstraints(schema, pathConstraints, ctx) {
|
|
1059
|
+
function applyPathTargetedConstraints(schema, pathConstraints, ctx, typeNode) {
|
|
533
1060
|
if (schema.type === "array" && schema.items) {
|
|
534
|
-
|
|
1061
|
+
const referencedType = typeNode?.kind === "reference" ? resolveReferencedType(typeNode, ctx) : void 0;
|
|
1062
|
+
const nestedType = typeNode?.kind === "array" ? typeNode.items : referencedType?.kind === "array" ? referencedType.items : void 0;
|
|
1063
|
+
schema.items = applyPathTargetedConstraints(schema.items, pathConstraints, ctx, nestedType);
|
|
535
1064
|
return schema;
|
|
536
1065
|
}
|
|
537
1066
|
const byTarget = /* @__PURE__ */ new Map();
|
|
@@ -546,7 +1075,7 @@ function applyPathTargetedConstraints(schema, pathConstraints, ctx) {
|
|
|
546
1075
|
for (const [target, constraints] of byTarget) {
|
|
547
1076
|
const subSchema = {};
|
|
548
1077
|
applyConstraints(subSchema, constraints, ctx);
|
|
549
|
-
propertyOverrides[target] = subSchema;
|
|
1078
|
+
propertyOverrides[resolveSerializedPropertyName(target, typeNode, ctx)] = subSchema;
|
|
550
1079
|
}
|
|
551
1080
|
if (schema.$ref) {
|
|
552
1081
|
const { $ref, ...rest } = schema;
|
|
@@ -594,7 +1123,7 @@ function generateTypeNode(type, ctx) {
|
|
|
594
1123
|
case "union":
|
|
595
1124
|
return generateUnionType(type, ctx);
|
|
596
1125
|
case "reference":
|
|
597
|
-
return generateReferenceType(type);
|
|
1126
|
+
return generateReferenceType(type, ctx);
|
|
598
1127
|
case "dynamic":
|
|
599
1128
|
return generateDynamicType(type);
|
|
600
1129
|
case "custom":
|
|
@@ -635,9 +1164,10 @@ function generateObjectType(type, ctx) {
|
|
|
635
1164
|
const properties = {};
|
|
636
1165
|
const required = [];
|
|
637
1166
|
for (const prop of type.properties) {
|
|
638
|
-
|
|
1167
|
+
const propertyName = getSerializedName(prop.name, prop.metadata);
|
|
1168
|
+
properties[propertyName] = generatePropertySchema(prop, ctx);
|
|
639
1169
|
if (!prop.optional) {
|
|
640
|
-
required.push(
|
|
1170
|
+
required.push(propertyName);
|
|
641
1171
|
}
|
|
642
1172
|
}
|
|
643
1173
|
const schema = { type: "object", properties };
|
|
@@ -658,6 +1188,7 @@ function generateRecordType(type, ctx) {
|
|
|
658
1188
|
function generatePropertySchema(prop, ctx) {
|
|
659
1189
|
const schema = generateTypeNode(prop.type, ctx);
|
|
660
1190
|
applyConstraints(schema, prop.constraints, ctx);
|
|
1191
|
+
applyResolvedMetadata(schema, prop.metadata);
|
|
661
1192
|
applyAnnotations(schema, prop.annotations, ctx);
|
|
662
1193
|
return schema;
|
|
663
1194
|
}
|
|
@@ -686,8 +1217,28 @@ function isNullableUnion(type) {
|
|
|
686
1217
|
).length;
|
|
687
1218
|
return nullCount === 1;
|
|
688
1219
|
}
|
|
689
|
-
function generateReferenceType(type) {
|
|
690
|
-
return { $ref: `#/$defs/${type.name}` };
|
|
1220
|
+
function generateReferenceType(type, ctx) {
|
|
1221
|
+
return { $ref: `#/$defs/${ctx.typeNameMap[type.name] ?? type.name}` };
|
|
1222
|
+
}
|
|
1223
|
+
function applyResolvedMetadata(schema, metadata) {
|
|
1224
|
+
const displayName = getDisplayName(metadata);
|
|
1225
|
+
if (displayName !== void 0) {
|
|
1226
|
+
schema.title = displayName;
|
|
1227
|
+
}
|
|
1228
|
+
}
|
|
1229
|
+
function resolveReferencedType(type, ctx) {
|
|
1230
|
+
return ctx.typeRegistry[type.name]?.type;
|
|
1231
|
+
}
|
|
1232
|
+
function resolveSerializedPropertyName(logicalName, typeNode, ctx) {
|
|
1233
|
+
if (typeNode?.kind === "object") {
|
|
1234
|
+
const property = typeNode.properties.find((candidate) => candidate.name === logicalName);
|
|
1235
|
+
return property === void 0 ? logicalName : getSerializedName(property.name, property.metadata);
|
|
1236
|
+
}
|
|
1237
|
+
if (typeNode?.kind === "reference") {
|
|
1238
|
+
const referencedType = resolveReferencedType(typeNode, ctx);
|
|
1239
|
+
return referencedType === void 0 ? logicalName : resolveSerializedPropertyName(logicalName, referencedType, ctx);
|
|
1240
|
+
}
|
|
1241
|
+
return logicalName;
|
|
691
1242
|
}
|
|
692
1243
|
function generateDynamicType(type) {
|
|
693
1244
|
if (type.dynamicKind === "enum") {
|
|
@@ -767,7 +1318,7 @@ function applyAnnotations(schema, annotations, ctx) {
|
|
|
767
1318
|
for (const annotation of annotations) {
|
|
768
1319
|
switch (annotation.annotationKind) {
|
|
769
1320
|
case "displayName":
|
|
770
|
-
schema.title
|
|
1321
|
+
schema.title ??= annotation.value;
|
|
771
1322
|
break;
|
|
772
1323
|
case "description":
|
|
773
1324
|
schema.description = annotation.value;
|
|
@@ -854,12 +1405,17 @@ function assignVendorPrefixedExtensionKeywords(schema, extensionSchema, vendorPr
|
|
|
854
1405
|
var init_ir_generator = __esm({
|
|
855
1406
|
"src/json-schema/ir-generator.ts"() {
|
|
856
1407
|
"use strict";
|
|
1408
|
+
init_metadata();
|
|
1409
|
+
init_collision_guards();
|
|
857
1410
|
}
|
|
858
1411
|
});
|
|
859
1412
|
|
|
860
1413
|
// src/json-schema/generator.ts
|
|
861
1414
|
function generateJsonSchema(form, options) {
|
|
862
|
-
const ir = canonicalizeChainDSL(
|
|
1415
|
+
const ir = canonicalizeChainDSL(
|
|
1416
|
+
form,
|
|
1417
|
+
options?.metadata !== void 0 ? { metadata: options.metadata } : void 0
|
|
1418
|
+
);
|
|
863
1419
|
const internalOptions = options?.vendorPrefix === void 0 ? void 0 : { vendorPrefix: options.vendorPrefix };
|
|
864
1420
|
return generateJsonSchemaFromIR(ir, internalOptions);
|
|
865
1421
|
}
|
|
@@ -1042,13 +1598,21 @@ function combineRules(parentRule, childRule) {
|
|
|
1042
1598
|
}
|
|
1043
1599
|
};
|
|
1044
1600
|
}
|
|
1045
|
-
function
|
|
1046
|
-
const
|
|
1601
|
+
function getFieldDisplayName(field) {
|
|
1602
|
+
const resolvedDisplayName = getDisplayName(field.metadata);
|
|
1603
|
+
if (resolvedDisplayName !== void 0) {
|
|
1604
|
+
return resolvedDisplayName;
|
|
1605
|
+
}
|
|
1606
|
+
return field.annotations.find((annotation) => annotation.annotationKind === "displayName")?.value;
|
|
1607
|
+
}
|
|
1608
|
+
function fieldNodeToControl(field, fieldNameMap, parentRule) {
|
|
1047
1609
|
const placeholderAnnotation = field.annotations.find((a) => a.annotationKind === "placeholder");
|
|
1610
|
+
const serializedName = fieldNameMap.get(field.name) ?? getSerializedName(field.name, field.metadata);
|
|
1611
|
+
const displayName = getFieldDisplayName(field);
|
|
1048
1612
|
const control = {
|
|
1049
1613
|
type: "Control",
|
|
1050
|
-
scope: fieldToScope(
|
|
1051
|
-
...
|
|
1614
|
+
scope: fieldToScope(serializedName),
|
|
1615
|
+
...displayName !== void 0 && { label: displayName },
|
|
1052
1616
|
...placeholderAnnotation !== void 0 && {
|
|
1053
1617
|
options: { placeholder: placeholderAnnotation.value }
|
|
1054
1618
|
},
|
|
@@ -1056,30 +1620,30 @@ function fieldNodeToControl(field, parentRule) {
|
|
|
1056
1620
|
};
|
|
1057
1621
|
return control;
|
|
1058
1622
|
}
|
|
1059
|
-
function groupNodeToLayout(group, parentRule) {
|
|
1623
|
+
function groupNodeToLayout(group, fieldNameMap, parentRule) {
|
|
1060
1624
|
return {
|
|
1061
1625
|
type: "Group",
|
|
1062
1626
|
label: group.label,
|
|
1063
|
-
elements: irElementsToUiSchema(group.elements, parentRule),
|
|
1627
|
+
elements: irElementsToUiSchema(group.elements, fieldNameMap, parentRule),
|
|
1064
1628
|
...parentRule !== void 0 && { rule: parentRule }
|
|
1065
1629
|
};
|
|
1066
1630
|
}
|
|
1067
|
-
function irElementsToUiSchema(elements, parentRule) {
|
|
1631
|
+
function irElementsToUiSchema(elements, fieldNameMap, parentRule) {
|
|
1068
1632
|
const result = [];
|
|
1069
1633
|
for (const element of elements) {
|
|
1070
1634
|
switch (element.kind) {
|
|
1071
1635
|
case "field": {
|
|
1072
|
-
result.push(fieldNodeToControl(element, parentRule));
|
|
1636
|
+
result.push(fieldNodeToControl(element, fieldNameMap, parentRule));
|
|
1073
1637
|
break;
|
|
1074
1638
|
}
|
|
1075
1639
|
case "group": {
|
|
1076
|
-
result.push(groupNodeToLayout(element, parentRule));
|
|
1640
|
+
result.push(groupNodeToLayout(element, fieldNameMap, parentRule));
|
|
1077
1641
|
break;
|
|
1078
1642
|
}
|
|
1079
1643
|
case "conditional": {
|
|
1080
|
-
const newRule = createShowRule(element.fieldName, element.value);
|
|
1644
|
+
const newRule = createShowRule(fieldNameMap.get(element.fieldName) ?? element.fieldName, element.value);
|
|
1081
1645
|
const combinedRule = parentRule !== void 0 ? combineRules(parentRule, newRule) : newRule;
|
|
1082
|
-
const childElements = irElementsToUiSchema(element.elements, combinedRule);
|
|
1646
|
+
const childElements = irElementsToUiSchema(element.elements, fieldNameMap, combinedRule);
|
|
1083
1647
|
result.push(...childElements);
|
|
1084
1648
|
break;
|
|
1085
1649
|
}
|
|
@@ -1093,22 +1657,50 @@ function irElementsToUiSchema(elements, parentRule) {
|
|
|
1093
1657
|
return result;
|
|
1094
1658
|
}
|
|
1095
1659
|
function generateUiSchemaFromIR(ir) {
|
|
1660
|
+
assertNoSerializedNameCollisions(ir);
|
|
1661
|
+
const fieldNameMap = collectFieldNameMap(ir.elements);
|
|
1096
1662
|
const result = {
|
|
1097
1663
|
type: "VerticalLayout",
|
|
1098
|
-
elements: irElementsToUiSchema(ir.elements)
|
|
1664
|
+
elements: irElementsToUiSchema(ir.elements, fieldNameMap)
|
|
1099
1665
|
};
|
|
1100
1666
|
return parseOrThrow(uiSchema, result, "UI Schema");
|
|
1101
1667
|
}
|
|
1668
|
+
function collectFieldNameMap(elements) {
|
|
1669
|
+
const map = /* @__PURE__ */ new Map();
|
|
1670
|
+
for (const element of elements) {
|
|
1671
|
+
switch (element.kind) {
|
|
1672
|
+
case "field":
|
|
1673
|
+
map.set(element.name, getSerializedName(element.name, element.metadata));
|
|
1674
|
+
break;
|
|
1675
|
+
case "group":
|
|
1676
|
+
case "conditional":
|
|
1677
|
+
for (const [key, value] of collectFieldNameMap(element.elements)) {
|
|
1678
|
+
map.set(key, value);
|
|
1679
|
+
}
|
|
1680
|
+
break;
|
|
1681
|
+
default: {
|
|
1682
|
+
const _exhaustive = element;
|
|
1683
|
+
void _exhaustive;
|
|
1684
|
+
}
|
|
1685
|
+
}
|
|
1686
|
+
}
|
|
1687
|
+
return map;
|
|
1688
|
+
}
|
|
1102
1689
|
var init_ir_generator2 = __esm({
|
|
1103
1690
|
"src/ui-schema/ir-generator.ts"() {
|
|
1104
1691
|
"use strict";
|
|
1692
|
+
init_metadata();
|
|
1693
|
+
init_collision_guards();
|
|
1105
1694
|
init_schema();
|
|
1106
1695
|
}
|
|
1107
1696
|
});
|
|
1108
1697
|
|
|
1109
1698
|
// src/ui-schema/generator.ts
|
|
1110
|
-
function generateUiSchema(form) {
|
|
1111
|
-
const ir = canonicalizeChainDSL(
|
|
1699
|
+
function generateUiSchema(form, options) {
|
|
1700
|
+
const ir = canonicalizeChainDSL(
|
|
1701
|
+
form,
|
|
1702
|
+
options?.metadata !== void 0 ? { metadata: options.metadata } : void 0
|
|
1703
|
+
);
|
|
1112
1704
|
return generateUiSchemaFromIR(ir);
|
|
1113
1705
|
}
|
|
1114
1706
|
var init_generator2 = __esm({
|
|
@@ -2190,7 +2782,76 @@ function makeParseOptions(extensionRegistry, fieldType, checker, subjectType, ho
|
|
|
2190
2782
|
...hostType !== void 0 && { hostType }
|
|
2191
2783
|
};
|
|
2192
2784
|
}
|
|
2193
|
-
function
|
|
2785
|
+
function makeExplicitScalarMetadata(value) {
|
|
2786
|
+
return value === void 0 || value === "" ? void 0 : { value, source: "explicit" };
|
|
2787
|
+
}
|
|
2788
|
+
function extractExplicitMetadata(node) {
|
|
2789
|
+
let apiName;
|
|
2790
|
+
let displayName;
|
|
2791
|
+
let apiNamePlural;
|
|
2792
|
+
let displayNamePlural;
|
|
2793
|
+
for (const tag of getLeadingParsedTags(node)) {
|
|
2794
|
+
const value = tag.argumentText.trim();
|
|
2795
|
+
if (value === "") {
|
|
2796
|
+
continue;
|
|
2797
|
+
}
|
|
2798
|
+
if (tag.normalizedTagName === "apiName") {
|
|
2799
|
+
if (tag.target === null) {
|
|
2800
|
+
apiName ??= value;
|
|
2801
|
+
} else if (tag.target.kind === "variant") {
|
|
2802
|
+
if (tag.target.rawText === "singular") {
|
|
2803
|
+
apiName ??= value;
|
|
2804
|
+
} else if (tag.target.rawText === "plural") {
|
|
2805
|
+
apiNamePlural ??= value;
|
|
2806
|
+
}
|
|
2807
|
+
}
|
|
2808
|
+
continue;
|
|
2809
|
+
}
|
|
2810
|
+
if (tag.normalizedTagName === "displayName") {
|
|
2811
|
+
if (tag.target === null) {
|
|
2812
|
+
displayName ??= value;
|
|
2813
|
+
} else if (tag.target.kind === "variant") {
|
|
2814
|
+
if (tag.target.rawText === "singular") {
|
|
2815
|
+
displayName ??= value;
|
|
2816
|
+
} else if (tag.target.rawText === "plural") {
|
|
2817
|
+
displayNamePlural ??= value;
|
|
2818
|
+
}
|
|
2819
|
+
}
|
|
2820
|
+
}
|
|
2821
|
+
}
|
|
2822
|
+
const resolvedApiName = makeExplicitScalarMetadata(apiName);
|
|
2823
|
+
const resolvedDisplayName = makeExplicitScalarMetadata(displayName);
|
|
2824
|
+
const resolvedApiNamePlural = makeExplicitScalarMetadata(apiNamePlural);
|
|
2825
|
+
const resolvedDisplayNamePlural = makeExplicitScalarMetadata(displayNamePlural);
|
|
2826
|
+
const metadata = {
|
|
2827
|
+
...resolvedApiName !== void 0 && { apiName: resolvedApiName },
|
|
2828
|
+
...resolvedDisplayName !== void 0 && { displayName: resolvedDisplayName },
|
|
2829
|
+
...resolvedApiNamePlural !== void 0 && { apiNamePlural: resolvedApiNamePlural },
|
|
2830
|
+
...resolvedDisplayNamePlural !== void 0 && {
|
|
2831
|
+
displayNamePlural: resolvedDisplayNamePlural
|
|
2832
|
+
}
|
|
2833
|
+
};
|
|
2834
|
+
return Object.keys(metadata).length === 0 ? void 0 : metadata;
|
|
2835
|
+
}
|
|
2836
|
+
function resolveNodeMetadata(metadataPolicy, declarationKind, logicalName, node, buildContext) {
|
|
2837
|
+
const explicit = extractExplicitMetadata(node);
|
|
2838
|
+
return resolveMetadata(
|
|
2839
|
+
{
|
|
2840
|
+
...explicit?.apiName !== void 0 && { apiName: explicit.apiName.value },
|
|
2841
|
+
...explicit?.displayName !== void 0 && { displayName: explicit.displayName.value },
|
|
2842
|
+
...explicit?.apiNamePlural !== void 0 && {
|
|
2843
|
+
apiNamePlural: explicit.apiNamePlural.value
|
|
2844
|
+
},
|
|
2845
|
+
...explicit?.displayNamePlural !== void 0 && {
|
|
2846
|
+
displayNamePlural: explicit.displayNamePlural.value
|
|
2847
|
+
}
|
|
2848
|
+
},
|
|
2849
|
+
getDeclarationMetadataPolicy(metadataPolicy, declarationKind),
|
|
2850
|
+
makeMetadataContext("tsdoc", declarationKind, logicalName, buildContext)
|
|
2851
|
+
);
|
|
2852
|
+
}
|
|
2853
|
+
function analyzeClassToIR(classDecl, checker, file = "", extensionRegistry, metadataPolicy) {
|
|
2854
|
+
const normalizedMetadataPolicy = normalizeMetadataPolicy(metadataPolicy);
|
|
2194
2855
|
const name = classDecl.name?.text ?? "AnonymousClass";
|
|
2195
2856
|
const fields = [];
|
|
2196
2857
|
const fieldLayouts = [];
|
|
@@ -2217,6 +2878,7 @@ function analyzeClassToIR(classDecl, checker, file = "", extensionRegistry) {
|
|
|
2217
2878
|
visiting,
|
|
2218
2879
|
diagnostics,
|
|
2219
2880
|
classType,
|
|
2881
|
+
normalizedMetadataPolicy,
|
|
2220
2882
|
extensionRegistry
|
|
2221
2883
|
);
|
|
2222
2884
|
if (fieldNode) {
|
|
@@ -2241,10 +2903,18 @@ function analyzeClassToIR(classDecl, checker, file = "", extensionRegistry) {
|
|
|
2241
2903
|
classType,
|
|
2242
2904
|
checker,
|
|
2243
2905
|
file,
|
|
2244
|
-
diagnostics
|
|
2906
|
+
diagnostics,
|
|
2907
|
+
normalizedMetadataPolicy
|
|
2245
2908
|
);
|
|
2909
|
+
const metadata = resolveNodeMetadata(normalizedMetadataPolicy, "type", name, classDecl, {
|
|
2910
|
+
checker,
|
|
2911
|
+
declaration: classDecl,
|
|
2912
|
+
subjectType: classType,
|
|
2913
|
+
hostType: classType
|
|
2914
|
+
});
|
|
2246
2915
|
return {
|
|
2247
2916
|
name,
|
|
2917
|
+
...metadata !== void 0 && { metadata },
|
|
2248
2918
|
fields: specializedFields,
|
|
2249
2919
|
fieldLayouts,
|
|
2250
2920
|
typeRegistry,
|
|
@@ -2254,7 +2924,8 @@ function analyzeClassToIR(classDecl, checker, file = "", extensionRegistry) {
|
|
|
2254
2924
|
staticMethods
|
|
2255
2925
|
};
|
|
2256
2926
|
}
|
|
2257
|
-
function analyzeInterfaceToIR(interfaceDecl, checker, file = "", extensionRegistry) {
|
|
2927
|
+
function analyzeInterfaceToIR(interfaceDecl, checker, file = "", extensionRegistry, metadataPolicy) {
|
|
2928
|
+
const normalizedMetadataPolicy = normalizeMetadataPolicy(metadataPolicy);
|
|
2258
2929
|
const name = interfaceDecl.name.text;
|
|
2259
2930
|
const fields = [];
|
|
2260
2931
|
const typeRegistry = {};
|
|
@@ -2278,6 +2949,7 @@ function analyzeInterfaceToIR(interfaceDecl, checker, file = "", extensionRegist
|
|
|
2278
2949
|
visiting,
|
|
2279
2950
|
diagnostics,
|
|
2280
2951
|
interfaceType,
|
|
2952
|
+
normalizedMetadataPolicy,
|
|
2281
2953
|
extensionRegistry
|
|
2282
2954
|
);
|
|
2283
2955
|
if (fieldNode) {
|
|
@@ -2291,11 +2963,19 @@ function analyzeInterfaceToIR(interfaceDecl, checker, file = "", extensionRegist
|
|
|
2291
2963
|
interfaceType,
|
|
2292
2964
|
checker,
|
|
2293
2965
|
file,
|
|
2294
|
-
diagnostics
|
|
2966
|
+
diagnostics,
|
|
2967
|
+
normalizedMetadataPolicy
|
|
2295
2968
|
);
|
|
2296
2969
|
const fieldLayouts = specializedFields.map(() => ({}));
|
|
2970
|
+
const metadata = resolveNodeMetadata(normalizedMetadataPolicy, "type", name, interfaceDecl, {
|
|
2971
|
+
checker,
|
|
2972
|
+
declaration: interfaceDecl,
|
|
2973
|
+
subjectType: interfaceType,
|
|
2974
|
+
hostType: interfaceType
|
|
2975
|
+
});
|
|
2297
2976
|
return {
|
|
2298
2977
|
name,
|
|
2978
|
+
...metadata !== void 0 && { metadata },
|
|
2299
2979
|
fields: specializedFields,
|
|
2300
2980
|
fieldLayouts,
|
|
2301
2981
|
typeRegistry,
|
|
@@ -2305,7 +2985,7 @@ function analyzeInterfaceToIR(interfaceDecl, checker, file = "", extensionRegist
|
|
|
2305
2985
|
staticMethods: []
|
|
2306
2986
|
};
|
|
2307
2987
|
}
|
|
2308
|
-
function analyzeTypeAliasToIR(typeAlias, checker, file = "", extensionRegistry) {
|
|
2988
|
+
function analyzeTypeAliasToIR(typeAlias, checker, file = "", extensionRegistry, metadataPolicy) {
|
|
2309
2989
|
if (!ts3.isTypeLiteralNode(typeAlias.type)) {
|
|
2310
2990
|
const sourceFile = typeAlias.getSourceFile();
|
|
2311
2991
|
const { line } = sourceFile.getLineAndCharacterOfPosition(typeAlias.getStart());
|
|
@@ -2315,6 +2995,8 @@ function analyzeTypeAliasToIR(typeAlias, checker, file = "", extensionRegistry)
|
|
|
2315
2995
|
error: `Type alias "${typeAlias.name.text}" at line ${String(line + 1)} is not an object type literal (found ${kindDesc})`
|
|
2316
2996
|
};
|
|
2317
2997
|
}
|
|
2998
|
+
const typeLiteral = typeAlias.type;
|
|
2999
|
+
const normalizedMetadataPolicy = normalizeMetadataPolicy(metadataPolicy);
|
|
2318
3000
|
const name = typeAlias.name.text;
|
|
2319
3001
|
const fields = [];
|
|
2320
3002
|
const typeRegistry = {};
|
|
@@ -2328,7 +3010,7 @@ function analyzeTypeAliasToIR(typeAlias, checker, file = "", extensionRegistry)
|
|
|
2328
3010
|
const annotations = [...typeAliasDoc.annotations];
|
|
2329
3011
|
diagnostics.push(...typeAliasDoc.diagnostics);
|
|
2330
3012
|
const visiting = /* @__PURE__ */ new Set();
|
|
2331
|
-
for (const member of
|
|
3013
|
+
for (const member of typeLiteral.members) {
|
|
2332
3014
|
if (ts3.isPropertySignature(member)) {
|
|
2333
3015
|
const fieldNode = analyzeInterfacePropertyToIR(
|
|
2334
3016
|
member,
|
|
@@ -2338,6 +3020,7 @@ function analyzeTypeAliasToIR(typeAlias, checker, file = "", extensionRegistry)
|
|
|
2338
3020
|
visiting,
|
|
2339
3021
|
diagnostics,
|
|
2340
3022
|
aliasType,
|
|
3023
|
+
normalizedMetadataPolicy,
|
|
2341
3024
|
extensionRegistry
|
|
2342
3025
|
);
|
|
2343
3026
|
if (fieldNode) {
|
|
@@ -2351,12 +3034,20 @@ function analyzeTypeAliasToIR(typeAlias, checker, file = "", extensionRegistry)
|
|
|
2351
3034
|
aliasType,
|
|
2352
3035
|
checker,
|
|
2353
3036
|
file,
|
|
2354
|
-
diagnostics
|
|
3037
|
+
diagnostics,
|
|
3038
|
+
normalizedMetadataPolicy
|
|
2355
3039
|
);
|
|
3040
|
+
const metadata = resolveNodeMetadata(normalizedMetadataPolicy, "type", name, typeAlias, {
|
|
3041
|
+
checker,
|
|
3042
|
+
declaration: typeAlias,
|
|
3043
|
+
subjectType: aliasType,
|
|
3044
|
+
hostType: aliasType
|
|
3045
|
+
});
|
|
2356
3046
|
return {
|
|
2357
3047
|
ok: true,
|
|
2358
3048
|
analysis: {
|
|
2359
3049
|
name,
|
|
3050
|
+
...metadata !== void 0 && { metadata },
|
|
2360
3051
|
fields: specializedFields,
|
|
2361
3052
|
fieldLayouts: specializedFields.map(() => ({})),
|
|
2362
3053
|
typeRegistry,
|
|
@@ -2396,31 +3087,20 @@ function getLeadingParsedTags(node) {
|
|
|
2396
3087
|
}
|
|
2397
3088
|
return parsedTags;
|
|
2398
3089
|
}
|
|
2399
|
-
function
|
|
2400
|
-
|
|
2401
|
-
|
|
2402
|
-
|
|
2403
|
-
return member;
|
|
2404
|
-
}
|
|
2405
|
-
}
|
|
2406
|
-
return null;
|
|
2407
|
-
}
|
|
2408
|
-
if (ts3.isInterfaceDeclaration(node)) {
|
|
2409
|
-
for (const member of node.members) {
|
|
2410
|
-
if (ts3.isPropertySignature(member) && ts3.isIdentifier(member.name) && member.name.text === fieldName) {
|
|
2411
|
-
return member;
|
|
2412
|
-
}
|
|
2413
|
-
}
|
|
3090
|
+
function resolveDiscriminatorProperty(node, checker, fieldName) {
|
|
3091
|
+
const subjectType = checker.getTypeAtLocation(node);
|
|
3092
|
+
const propertySymbol = subjectType.getProperty(fieldName);
|
|
3093
|
+
if (propertySymbol === void 0) {
|
|
2414
3094
|
return null;
|
|
2415
3095
|
}
|
|
2416
|
-
|
|
2417
|
-
|
|
2418
|
-
|
|
2419
|
-
|
|
2420
|
-
|
|
2421
|
-
|
|
2422
|
-
|
|
2423
|
-
|
|
3096
|
+
const declaration = propertySymbol.valueDeclaration ?? propertySymbol.declarations?.find(
|
|
3097
|
+
(candidate) => ts3.isPropertyDeclaration(candidate) || ts3.isPropertySignature(candidate)
|
|
3098
|
+
) ?? propertySymbol.declarations?.[0];
|
|
3099
|
+
return {
|
|
3100
|
+
declaration,
|
|
3101
|
+
type: checker.getTypeOfSymbolAtLocation(propertySymbol, declaration ?? node),
|
|
3102
|
+
optional: !!(propertySymbol.flags & ts3.SymbolFlags.Optional) || declaration !== void 0 && "questionToken" in declaration && declaration.questionToken !== void 0
|
|
3103
|
+
};
|
|
2424
3104
|
}
|
|
2425
3105
|
function isLocalTypeParameterName(node, typeParameterName) {
|
|
2426
3106
|
return node.typeParameters?.some((typeParameter) => typeParameter.name.text === typeParameterName) ?? false;
|
|
@@ -2513,8 +3193,8 @@ function validateDiscriminatorDirective(node, checker, file, diagnostics) {
|
|
|
2513
3193
|
);
|
|
2514
3194
|
return null;
|
|
2515
3195
|
}
|
|
2516
|
-
const
|
|
2517
|
-
if (
|
|
3196
|
+
const property = resolveDiscriminatorProperty(node, checker, directive.fieldName);
|
|
3197
|
+
if (property === null) {
|
|
2518
3198
|
diagnostics.push(
|
|
2519
3199
|
makeAnalysisDiagnostic(
|
|
2520
3200
|
"UNKNOWN_PATH_TARGET",
|
|
@@ -2524,36 +3204,35 @@ function validateDiscriminatorDirective(node, checker, file, diagnostics) {
|
|
|
2524
3204
|
);
|
|
2525
3205
|
return null;
|
|
2526
3206
|
}
|
|
2527
|
-
if (
|
|
3207
|
+
if (property.optional) {
|
|
2528
3208
|
diagnostics.push(
|
|
2529
3209
|
makeAnalysisDiagnostic(
|
|
2530
3210
|
"TYPE_MISMATCH",
|
|
2531
3211
|
`Discriminator field "${directive.fieldName}" must be required; optional discriminator fields are not supported.`,
|
|
2532
3212
|
directive.provenance,
|
|
2533
|
-
[provenanceForNode(
|
|
3213
|
+
property.declaration !== void 0 ? [provenanceForNode(property.declaration, file)] : []
|
|
2534
3214
|
)
|
|
2535
3215
|
);
|
|
2536
3216
|
return null;
|
|
2537
3217
|
}
|
|
2538
|
-
|
|
2539
|
-
if (isNullishSemanticType(propertyType)) {
|
|
3218
|
+
if (isNullishSemanticType(property.type)) {
|
|
2540
3219
|
diagnostics.push(
|
|
2541
3220
|
makeAnalysisDiagnostic(
|
|
2542
3221
|
"TYPE_MISMATCH",
|
|
2543
3222
|
`Discriminator field "${directive.fieldName}" must not be nullable.`,
|
|
2544
3223
|
directive.provenance,
|
|
2545
|
-
[provenanceForNode(
|
|
3224
|
+
property.declaration !== void 0 ? [provenanceForNode(property.declaration, file)] : []
|
|
2546
3225
|
)
|
|
2547
3226
|
);
|
|
2548
3227
|
return null;
|
|
2549
3228
|
}
|
|
2550
|
-
if (!isStringLikeSemanticType(
|
|
3229
|
+
if (!isStringLikeSemanticType(property.type)) {
|
|
2551
3230
|
diagnostics.push(
|
|
2552
3231
|
makeAnalysisDiagnostic(
|
|
2553
3232
|
"TYPE_MISMATCH",
|
|
2554
3233
|
`Discriminator field "${directive.fieldName}" must be string-like.`,
|
|
2555
3234
|
directive.provenance,
|
|
2556
|
-
[provenanceForNode(
|
|
3235
|
+
property.declaration !== void 0 ? [provenanceForNode(property.declaration, file)] : []
|
|
2557
3236
|
)
|
|
2558
3237
|
);
|
|
2559
3238
|
return null;
|
|
@@ -2574,25 +3253,58 @@ function getConcreteTypeArgumentForDiscriminator(node, subjectType, checker, typ
|
|
|
2574
3253
|
const localTypeParameter = node.typeParameters?.[typeParameterIndex];
|
|
2575
3254
|
return localTypeParameter === void 0 ? null : checker.getTypeAtLocation(localTypeParameter);
|
|
2576
3255
|
}
|
|
2577
|
-
function
|
|
2578
|
-
|
|
2579
|
-
|
|
2580
|
-
|
|
2581
|
-
|
|
2582
|
-
|
|
2583
|
-
|
|
2584
|
-
|
|
2585
|
-
|
|
2586
|
-
|
|
2587
|
-
|
|
2588
|
-
|
|
2589
|
-
|
|
3256
|
+
function resolveLiteralDiscriminatorPropertyValue(boundType, fieldName, checker, provenance, diagnostics) {
|
|
3257
|
+
const propertySymbol = boundType.getProperty(fieldName);
|
|
3258
|
+
if (propertySymbol === void 0) {
|
|
3259
|
+
return void 0;
|
|
3260
|
+
}
|
|
3261
|
+
const declaration = propertySymbol.valueDeclaration ?? propertySymbol.declarations?.[0];
|
|
3262
|
+
const anchorNode = declaration ?? boundType.symbol.declarations?.[0] ?? null;
|
|
3263
|
+
const resolvedAnchorNode = anchorNode ?? resolveNamedDiscriminatorDeclaration(boundType, checker);
|
|
3264
|
+
if (resolvedAnchorNode === null) {
|
|
3265
|
+
return void 0;
|
|
3266
|
+
}
|
|
3267
|
+
const propertyType = checker.getTypeOfSymbolAtLocation(
|
|
3268
|
+
propertySymbol,
|
|
3269
|
+
resolvedAnchorNode
|
|
3270
|
+
);
|
|
3271
|
+
if (propertyType.isStringLiteral()) {
|
|
3272
|
+
return propertyType.value;
|
|
3273
|
+
}
|
|
3274
|
+
if (propertyType.isUnion()) {
|
|
3275
|
+
const nonNullMembers = propertyType.types.filter(
|
|
3276
|
+
(member) => !(member.flags & (ts3.TypeFlags.Null | ts3.TypeFlags.Undefined))
|
|
3277
|
+
);
|
|
3278
|
+
if (nonNullMembers.length > 0 && nonNullMembers.every((member) => member.isStringLiteral())) {
|
|
3279
|
+
diagnostics.push(
|
|
3280
|
+
makeAnalysisDiagnostic(
|
|
3281
|
+
"INVALID_TAG_ARGUMENT",
|
|
3282
|
+
"Discriminator resolution for union-valued identity properties is out of scope for v1.",
|
|
3283
|
+
provenance
|
|
3284
|
+
)
|
|
3285
|
+
);
|
|
3286
|
+
return null;
|
|
2590
3287
|
}
|
|
2591
3288
|
}
|
|
2592
|
-
return
|
|
3289
|
+
return void 0;
|
|
2593
3290
|
}
|
|
2594
|
-
function
|
|
2595
|
-
|
|
3291
|
+
function resolveDiscriminatorApiName(boundType, checker, metadataPolicy) {
|
|
3292
|
+
const declaration = resolveNamedDiscriminatorDeclaration(boundType, checker);
|
|
3293
|
+
if (declaration === null) {
|
|
3294
|
+
return void 0;
|
|
3295
|
+
}
|
|
3296
|
+
const metadata = resolveNodeMetadata(
|
|
3297
|
+
metadataPolicy,
|
|
3298
|
+
"type",
|
|
3299
|
+
getDiscriminatorLogicalName(boundType, declaration, checker),
|
|
3300
|
+
declaration,
|
|
3301
|
+
{
|
|
3302
|
+
checker,
|
|
3303
|
+
declaration,
|
|
3304
|
+
subjectType: boundType
|
|
3305
|
+
}
|
|
3306
|
+
);
|
|
3307
|
+
return metadata?.apiName;
|
|
2596
3308
|
}
|
|
2597
3309
|
function resolveNamedDiscriminatorDeclaration(type, checker, seen = /* @__PURE__ */ new Set()) {
|
|
2598
3310
|
if (seen.has(type)) {
|
|
@@ -2619,7 +3331,7 @@ function resolveNamedDiscriminatorDeclaration(type, checker, seen = /* @__PURE__
|
|
|
2619
3331
|
}
|
|
2620
3332
|
return null;
|
|
2621
3333
|
}
|
|
2622
|
-
function resolveDiscriminatorValue(boundType, checker, provenance, diagnostics) {
|
|
3334
|
+
function resolveDiscriminatorValue(boundType, fieldName, checker, provenance, diagnostics, metadataPolicy) {
|
|
2623
3335
|
if (boundType === null) {
|
|
2624
3336
|
diagnostics.push(
|
|
2625
3337
|
makeAnalysisDiagnostic(
|
|
@@ -2648,9 +3360,22 @@ function resolveDiscriminatorValue(boundType, checker, provenance, diagnostics)
|
|
|
2648
3360
|
return null;
|
|
2649
3361
|
}
|
|
2650
3362
|
}
|
|
2651
|
-
const
|
|
2652
|
-
|
|
2653
|
-
|
|
3363
|
+
const literalIdentityValue = resolveLiteralDiscriminatorPropertyValue(
|
|
3364
|
+
boundType,
|
|
3365
|
+
fieldName,
|
|
3366
|
+
checker,
|
|
3367
|
+
provenance,
|
|
3368
|
+
diagnostics
|
|
3369
|
+
);
|
|
3370
|
+
if (literalIdentityValue !== void 0) {
|
|
3371
|
+
return literalIdentityValue;
|
|
3372
|
+
}
|
|
3373
|
+
const apiName = resolveDiscriminatorApiName(boundType, checker, metadataPolicy);
|
|
3374
|
+
if (apiName?.source === "explicit") {
|
|
3375
|
+
return apiName.value;
|
|
3376
|
+
}
|
|
3377
|
+
if (apiName?.source === "inferred") {
|
|
3378
|
+
return apiName.value;
|
|
2654
3379
|
}
|
|
2655
3380
|
diagnostics.push(
|
|
2656
3381
|
makeAnalysisDiagnostic(
|
|
@@ -2667,7 +3392,15 @@ function getDeclarationName(node) {
|
|
|
2667
3392
|
}
|
|
2668
3393
|
return "anonymous";
|
|
2669
3394
|
}
|
|
2670
|
-
function
|
|
3395
|
+
function getResolvedTypeArguments(type) {
|
|
3396
|
+
return (isTypeReference(type) ? type.typeArguments : void 0) ?? type.aliasTypeArguments ?? [];
|
|
3397
|
+
}
|
|
3398
|
+
function getDiscriminatorLogicalName(type, declaration, checker) {
|
|
3399
|
+
const baseName = getDeclarationName(declaration);
|
|
3400
|
+
const typeArguments = getResolvedTypeArguments(type);
|
|
3401
|
+
return typeArguments.length === 0 ? baseName : buildInstantiatedReferenceName(baseName, typeArguments, checker);
|
|
3402
|
+
}
|
|
3403
|
+
function applyDeclarationDiscriminatorToFields(fields, node, subjectType, checker, file, diagnostics, metadataPolicy) {
|
|
2671
3404
|
const directive = validateDiscriminatorDirective(node, checker, file, diagnostics);
|
|
2672
3405
|
if (directive === null) {
|
|
2673
3406
|
return [...fields];
|
|
@@ -2679,9 +3412,11 @@ function applyDeclarationDiscriminatorToFields(fields, node, subjectType, checke
|
|
|
2679
3412
|
checker,
|
|
2680
3413
|
directive.typeParameterName
|
|
2681
3414
|
),
|
|
3415
|
+
directive.fieldName,
|
|
2682
3416
|
checker,
|
|
2683
3417
|
directive.provenance,
|
|
2684
|
-
diagnostics
|
|
3418
|
+
diagnostics,
|
|
3419
|
+
metadataPolicy
|
|
2685
3420
|
);
|
|
2686
3421
|
if (discriminatorValue === null) {
|
|
2687
3422
|
return [...fields];
|
|
@@ -2702,7 +3437,7 @@ function buildInstantiatedReferenceName(baseName, typeArguments, checker) {
|
|
|
2702
3437
|
).filter((value) => value !== "");
|
|
2703
3438
|
return renderedArguments.length === 0 ? baseName : `${baseName}__${renderedArguments.join("__")}`;
|
|
2704
3439
|
}
|
|
2705
|
-
function extractReferenceTypeArguments(type, checker, file, typeRegistry, visiting, sourceNode, extensionRegistry, diagnostics) {
|
|
3440
|
+
function extractReferenceTypeArguments(type, checker, file, typeRegistry, visiting, sourceNode, metadataPolicy, extensionRegistry, diagnostics) {
|
|
2706
3441
|
const typeNode = sourceNode === void 0 ? void 0 : extractTypeNodeFromSource(sourceNode);
|
|
2707
3442
|
if (typeNode === void 0) {
|
|
2708
3443
|
return [];
|
|
@@ -2722,13 +3457,14 @@ function extractReferenceTypeArguments(type, checker, file, typeRegistry, visiti
|
|
|
2722
3457
|
typeRegistry,
|
|
2723
3458
|
visiting,
|
|
2724
3459
|
argumentNode,
|
|
3460
|
+
metadataPolicy,
|
|
2725
3461
|
extensionRegistry,
|
|
2726
3462
|
diagnostics
|
|
2727
3463
|
)
|
|
2728
3464
|
};
|
|
2729
3465
|
});
|
|
2730
3466
|
}
|
|
2731
|
-
function applyDiscriminatorToObjectProperties(properties, node, subjectType, checker, file, diagnostics) {
|
|
3467
|
+
function applyDiscriminatorToObjectProperties(properties, node, subjectType, checker, file, diagnostics, metadataPolicy) {
|
|
2732
3468
|
const directive = validateDiscriminatorDirective(node, checker, file, diagnostics);
|
|
2733
3469
|
if (directive === null) {
|
|
2734
3470
|
return properties;
|
|
@@ -2740,9 +3476,11 @@ function applyDiscriminatorToObjectProperties(properties, node, subjectType, che
|
|
|
2740
3476
|
checker,
|
|
2741
3477
|
directive.typeParameterName
|
|
2742
3478
|
),
|
|
3479
|
+
directive.fieldName,
|
|
2743
3480
|
checker,
|
|
2744
3481
|
directive.provenance,
|
|
2745
|
-
diagnostics
|
|
3482
|
+
diagnostics,
|
|
3483
|
+
metadataPolicy
|
|
2746
3484
|
);
|
|
2747
3485
|
if (discriminatorValue === null) {
|
|
2748
3486
|
return properties;
|
|
@@ -2757,7 +3495,7 @@ function applyDiscriminatorToObjectProperties(properties, node, subjectType, che
|
|
|
2757
3495
|
} : property
|
|
2758
3496
|
);
|
|
2759
3497
|
}
|
|
2760
|
-
function analyzeFieldToIR(prop, checker, file, typeRegistry, visiting, diagnostics, hostType, extensionRegistry) {
|
|
3498
|
+
function analyzeFieldToIR(prop, checker, file, typeRegistry, visiting, diagnostics, hostType, metadataPolicy, extensionRegistry) {
|
|
2761
3499
|
if (!ts3.isIdentifier(prop.name)) {
|
|
2762
3500
|
return null;
|
|
2763
3501
|
}
|
|
@@ -2772,6 +3510,7 @@ function analyzeFieldToIR(prop, checker, file, typeRegistry, visiting, diagnosti
|
|
|
2772
3510
|
typeRegistry,
|
|
2773
3511
|
visiting,
|
|
2774
3512
|
prop,
|
|
3513
|
+
metadataPolicy,
|
|
2775
3514
|
extensionRegistry,
|
|
2776
3515
|
diagnostics
|
|
2777
3516
|
);
|
|
@@ -2795,9 +3534,16 @@ function analyzeFieldToIR(prop, checker, file, typeRegistry, visiting, diagnosti
|
|
|
2795
3534
|
annotations.push(defaultAnnotation);
|
|
2796
3535
|
}
|
|
2797
3536
|
({ type, annotations } = applyEnumMemberDisplayNames(type, annotations));
|
|
3537
|
+
const metadata = resolveNodeMetadata(metadataPolicy, "field", name, prop, {
|
|
3538
|
+
checker,
|
|
3539
|
+
declaration: prop,
|
|
3540
|
+
subjectType: tsType,
|
|
3541
|
+
hostType
|
|
3542
|
+
});
|
|
2798
3543
|
return {
|
|
2799
3544
|
kind: "field",
|
|
2800
3545
|
name,
|
|
3546
|
+
...metadata !== void 0 && { metadata },
|
|
2801
3547
|
type,
|
|
2802
3548
|
required: !optional,
|
|
2803
3549
|
constraints,
|
|
@@ -2805,7 +3551,7 @@ function analyzeFieldToIR(prop, checker, file, typeRegistry, visiting, diagnosti
|
|
|
2805
3551
|
provenance
|
|
2806
3552
|
};
|
|
2807
3553
|
}
|
|
2808
|
-
function analyzeInterfacePropertyToIR(prop, checker, file, typeRegistry, visiting, diagnostics, hostType, extensionRegistry) {
|
|
3554
|
+
function analyzeInterfacePropertyToIR(prop, checker, file, typeRegistry, visiting, diagnostics, hostType, metadataPolicy, extensionRegistry) {
|
|
2809
3555
|
if (!ts3.isIdentifier(prop.name)) {
|
|
2810
3556
|
return null;
|
|
2811
3557
|
}
|
|
@@ -2820,6 +3566,7 @@ function analyzeInterfacePropertyToIR(prop, checker, file, typeRegistry, visitin
|
|
|
2820
3566
|
typeRegistry,
|
|
2821
3567
|
visiting,
|
|
2822
3568
|
prop,
|
|
3569
|
+
metadataPolicy,
|
|
2823
3570
|
extensionRegistry,
|
|
2824
3571
|
diagnostics
|
|
2825
3572
|
);
|
|
@@ -2839,9 +3586,16 @@ function analyzeInterfacePropertyToIR(prop, checker, file, typeRegistry, visitin
|
|
|
2839
3586
|
let annotations = [];
|
|
2840
3587
|
annotations.push(...docResult.annotations);
|
|
2841
3588
|
({ type, annotations } = applyEnumMemberDisplayNames(type, annotations));
|
|
3589
|
+
const metadata = resolveNodeMetadata(metadataPolicy, "field", name, prop, {
|
|
3590
|
+
checker,
|
|
3591
|
+
declaration: prop,
|
|
3592
|
+
subjectType: tsType,
|
|
3593
|
+
hostType
|
|
3594
|
+
});
|
|
2842
3595
|
return {
|
|
2843
3596
|
kind: "field",
|
|
2844
3597
|
name,
|
|
3598
|
+
...metadata !== void 0 && { metadata },
|
|
2845
3599
|
type,
|
|
2846
3600
|
required: !optional,
|
|
2847
3601
|
constraints,
|
|
@@ -2966,7 +3720,7 @@ function getTypeNodeRegistrationName(typeNode) {
|
|
|
2966
3720
|
}
|
|
2967
3721
|
return null;
|
|
2968
3722
|
}
|
|
2969
|
-
function resolveTypeNode(type, checker, file, typeRegistry, visiting, sourceNode, extensionRegistry, diagnostics) {
|
|
3723
|
+
function resolveTypeNode(type, checker, file, typeRegistry, visiting, sourceNode, metadataPolicy = normalizeMetadataPolicy(void 0), extensionRegistry, diagnostics) {
|
|
2970
3724
|
const customType = resolveRegisteredCustomType(sourceNode, extensionRegistry, checker);
|
|
2971
3725
|
if (customType) {
|
|
2972
3726
|
return customType;
|
|
@@ -2978,6 +3732,7 @@ function resolveTypeNode(type, checker, file, typeRegistry, visiting, sourceNode
|
|
|
2978
3732
|
typeRegistry,
|
|
2979
3733
|
visiting,
|
|
2980
3734
|
sourceNode,
|
|
3735
|
+
metadataPolicy,
|
|
2981
3736
|
extensionRegistry,
|
|
2982
3737
|
diagnostics
|
|
2983
3738
|
);
|
|
@@ -3022,6 +3777,7 @@ function resolveTypeNode(type, checker, file, typeRegistry, visiting, sourceNode
|
|
|
3022
3777
|
typeRegistry,
|
|
3023
3778
|
visiting,
|
|
3024
3779
|
sourceNode,
|
|
3780
|
+
metadataPolicy,
|
|
3025
3781
|
extensionRegistry,
|
|
3026
3782
|
diagnostics
|
|
3027
3783
|
);
|
|
@@ -3034,6 +3790,7 @@ function resolveTypeNode(type, checker, file, typeRegistry, visiting, sourceNode
|
|
|
3034
3790
|
typeRegistry,
|
|
3035
3791
|
visiting,
|
|
3036
3792
|
sourceNode,
|
|
3793
|
+
metadataPolicy,
|
|
3037
3794
|
extensionRegistry,
|
|
3038
3795
|
diagnostics
|
|
3039
3796
|
);
|
|
@@ -3046,13 +3803,14 @@ function resolveTypeNode(type, checker, file, typeRegistry, visiting, sourceNode
|
|
|
3046
3803
|
typeRegistry,
|
|
3047
3804
|
visiting,
|
|
3048
3805
|
sourceNode,
|
|
3806
|
+
metadataPolicy,
|
|
3049
3807
|
extensionRegistry,
|
|
3050
3808
|
diagnostics
|
|
3051
3809
|
);
|
|
3052
3810
|
}
|
|
3053
3811
|
return { kind: "primitive", primitiveKind: "string" };
|
|
3054
3812
|
}
|
|
3055
|
-
function tryResolveNamedPrimitiveAlias(type, checker, file, typeRegistry, visiting, sourceNode, extensionRegistry, diagnostics) {
|
|
3813
|
+
function tryResolveNamedPrimitiveAlias(type, checker, file, typeRegistry, visiting, sourceNode, metadataPolicy = normalizeMetadataPolicy(void 0), extensionRegistry, diagnostics) {
|
|
3056
3814
|
if (!(type.flags & (ts3.TypeFlags.String | ts3.TypeFlags.Number | ts3.TypeFlags.BigInt | ts3.TypeFlags.BigIntLiteral | ts3.TypeFlags.Boolean | ts3.TypeFlags.Null))) {
|
|
3057
3815
|
return null;
|
|
3058
3816
|
}
|
|
@@ -3072,14 +3830,21 @@ function tryResolveNamedPrimitiveAlias(type, checker, file, typeRegistry, visiti
|
|
|
3072
3830
|
file,
|
|
3073
3831
|
makeParseOptions(extensionRegistry)
|
|
3074
3832
|
);
|
|
3833
|
+
const metadata = resolveNodeMetadata(metadataPolicy, "type", aliasName, aliasDecl, {
|
|
3834
|
+
checker,
|
|
3835
|
+
declaration: aliasDecl,
|
|
3836
|
+
subjectType: aliasType
|
|
3837
|
+
});
|
|
3075
3838
|
typeRegistry[aliasName] = {
|
|
3076
3839
|
name: aliasName,
|
|
3840
|
+
...metadata !== void 0 && { metadata },
|
|
3077
3841
|
type: resolveAliasedPrimitiveTarget(
|
|
3078
3842
|
aliasType,
|
|
3079
3843
|
checker,
|
|
3080
3844
|
file,
|
|
3081
3845
|
typeRegistry,
|
|
3082
3846
|
visiting,
|
|
3847
|
+
metadataPolicy,
|
|
3083
3848
|
extensionRegistry,
|
|
3084
3849
|
diagnostics
|
|
3085
3850
|
),
|
|
@@ -3108,7 +3873,7 @@ function shouldEmitPrimitiveAliasDefinition(typeNode, checker) {
|
|
|
3108
3873
|
const resolved = checker.getTypeFromTypeNode(aliasDecl.type);
|
|
3109
3874
|
return !!(resolved.flags & (ts3.TypeFlags.String | ts3.TypeFlags.Number | ts3.TypeFlags.BigInt | ts3.TypeFlags.BigIntLiteral | ts3.TypeFlags.Boolean | ts3.TypeFlags.Null));
|
|
3110
3875
|
}
|
|
3111
|
-
function resolveAliasedPrimitiveTarget(type, checker, file, typeRegistry, visiting, extensionRegistry, diagnostics) {
|
|
3876
|
+
function resolveAliasedPrimitiveTarget(type, checker, file, typeRegistry, visiting, metadataPolicy = normalizeMetadataPolicy(void 0), extensionRegistry, diagnostics) {
|
|
3112
3877
|
const nestedAliasDecl = type.aliasSymbol?.declarations?.find(ts3.isTypeAliasDeclaration);
|
|
3113
3878
|
if (nestedAliasDecl !== void 0) {
|
|
3114
3879
|
return resolveAliasedPrimitiveTarget(
|
|
@@ -3117,6 +3882,7 @@ function resolveAliasedPrimitiveTarget(type, checker, file, typeRegistry, visiti
|
|
|
3117
3882
|
file,
|
|
3118
3883
|
typeRegistry,
|
|
3119
3884
|
visiting,
|
|
3885
|
+
metadataPolicy,
|
|
3120
3886
|
extensionRegistry,
|
|
3121
3887
|
diagnostics
|
|
3122
3888
|
);
|
|
@@ -3128,11 +3894,12 @@ function resolveAliasedPrimitiveTarget(type, checker, file, typeRegistry, visiti
|
|
|
3128
3894
|
typeRegistry,
|
|
3129
3895
|
visiting,
|
|
3130
3896
|
void 0,
|
|
3897
|
+
metadataPolicy,
|
|
3131
3898
|
extensionRegistry,
|
|
3132
3899
|
diagnostics
|
|
3133
3900
|
);
|
|
3134
3901
|
}
|
|
3135
|
-
function resolveUnionType(type, checker, file, typeRegistry, visiting, sourceNode, extensionRegistry, diagnostics) {
|
|
3902
|
+
function resolveUnionType(type, checker, file, typeRegistry, visiting, sourceNode, metadataPolicy = normalizeMetadataPolicy(void 0), extensionRegistry, diagnostics) {
|
|
3136
3903
|
const typeName = getNamedTypeName(type);
|
|
3137
3904
|
const namedDecl = getNamedTypeDeclaration(type);
|
|
3138
3905
|
if (typeName && typeName in typeRegistry) {
|
|
@@ -3167,8 +3934,14 @@ function resolveUnionType(type, checker, file, typeRegistry, visiting, sourceNod
|
|
|
3167
3934
|
return result;
|
|
3168
3935
|
}
|
|
3169
3936
|
const annotations = namedDecl ? extractJSDocAnnotationNodes(namedDecl, file, makeParseOptions(extensionRegistry)) : void 0;
|
|
3937
|
+
const metadata = namedDecl !== void 0 ? resolveNodeMetadata(metadataPolicy, "type", typeName, namedDecl, {
|
|
3938
|
+
checker,
|
|
3939
|
+
declaration: namedDecl,
|
|
3940
|
+
subjectType: type
|
|
3941
|
+
}) : void 0;
|
|
3170
3942
|
typeRegistry[typeName] = {
|
|
3171
3943
|
name: typeName,
|
|
3944
|
+
...metadata !== void 0 && { metadata },
|
|
3172
3945
|
type: result,
|
|
3173
3946
|
...annotations !== void 0 && annotations.length > 0 && { annotations },
|
|
3174
3947
|
provenance: provenanceForDeclaration(namedDecl ?? sourceNode, file)
|
|
@@ -3222,6 +3995,7 @@ function resolveUnionType(type, checker, file, typeRegistry, visiting, sourceNod
|
|
|
3222
3995
|
typeRegistry,
|
|
3223
3996
|
visiting,
|
|
3224
3997
|
nonNullMembers[0].sourceNode ?? sourceNode,
|
|
3998
|
+
metadataPolicy,
|
|
3225
3999
|
extensionRegistry,
|
|
3226
4000
|
diagnostics
|
|
3227
4001
|
);
|
|
@@ -3239,6 +4013,7 @@ function resolveUnionType(type, checker, file, typeRegistry, visiting, sourceNod
|
|
|
3239
4013
|
typeRegistry,
|
|
3240
4014
|
visiting,
|
|
3241
4015
|
memberSourceNode ?? sourceNode,
|
|
4016
|
+
metadataPolicy,
|
|
3242
4017
|
extensionRegistry,
|
|
3243
4018
|
diagnostics
|
|
3244
4019
|
)
|
|
@@ -3248,7 +4023,7 @@ function resolveUnionType(type, checker, file, typeRegistry, visiting, sourceNod
|
|
|
3248
4023
|
}
|
|
3249
4024
|
return registerNamed({ kind: "union", members });
|
|
3250
4025
|
}
|
|
3251
|
-
function resolveArrayType(type, checker, file, typeRegistry, visiting, sourceNode, extensionRegistry, diagnostics) {
|
|
4026
|
+
function resolveArrayType(type, checker, file, typeRegistry, visiting, sourceNode, metadataPolicy = normalizeMetadataPolicy(void 0), extensionRegistry, diagnostics) {
|
|
3252
4027
|
const typeArgs = isTypeReference(type) ? type.typeArguments : void 0;
|
|
3253
4028
|
const elementType = typeArgs?.[0];
|
|
3254
4029
|
const elementSourceNode = extractArrayElementTypeNode(sourceNode, checker);
|
|
@@ -3259,12 +4034,13 @@ function resolveArrayType(type, checker, file, typeRegistry, visiting, sourceNod
|
|
|
3259
4034
|
typeRegistry,
|
|
3260
4035
|
visiting,
|
|
3261
4036
|
elementSourceNode,
|
|
4037
|
+
metadataPolicy,
|
|
3262
4038
|
extensionRegistry,
|
|
3263
4039
|
diagnostics
|
|
3264
4040
|
) : { kind: "primitive", primitiveKind: "string" };
|
|
3265
4041
|
return { kind: "array", items };
|
|
3266
4042
|
}
|
|
3267
|
-
function tryResolveRecordType(type, checker, file, typeRegistry, visiting, extensionRegistry, diagnostics) {
|
|
4043
|
+
function tryResolveRecordType(type, checker, file, typeRegistry, visiting, metadataPolicy = normalizeMetadataPolicy(void 0), extensionRegistry, diagnostics) {
|
|
3268
4044
|
if (type.getProperties().length > 0) {
|
|
3269
4045
|
return null;
|
|
3270
4046
|
}
|
|
@@ -3279,6 +4055,7 @@ function tryResolveRecordType(type, checker, file, typeRegistry, visiting, exten
|
|
|
3279
4055
|
typeRegistry,
|
|
3280
4056
|
visiting,
|
|
3281
4057
|
void 0,
|
|
4058
|
+
metadataPolicy,
|
|
3282
4059
|
extensionRegistry,
|
|
3283
4060
|
diagnostics
|
|
3284
4061
|
);
|
|
@@ -3309,7 +4086,22 @@ function typeNodeContainsReference(type, targetName) {
|
|
|
3309
4086
|
}
|
|
3310
4087
|
}
|
|
3311
4088
|
}
|
|
3312
|
-
function
|
|
4089
|
+
function shouldEmitResolvedObjectProperty(property, declaration) {
|
|
4090
|
+
if (property.name.startsWith("__@")) {
|
|
4091
|
+
return false;
|
|
4092
|
+
}
|
|
4093
|
+
if (declaration !== void 0 && "name" in declaration && declaration.name !== void 0) {
|
|
4094
|
+
const name = declaration.name;
|
|
4095
|
+
if (ts3.isComputedPropertyName(name) || ts3.isPrivateIdentifier(name)) {
|
|
4096
|
+
return false;
|
|
4097
|
+
}
|
|
4098
|
+
if (!ts3.isIdentifier(name) && !ts3.isStringLiteral(name) && !ts3.isNumericLiteral(name)) {
|
|
4099
|
+
return false;
|
|
4100
|
+
}
|
|
4101
|
+
}
|
|
4102
|
+
return true;
|
|
4103
|
+
}
|
|
4104
|
+
function resolveObjectType(type, checker, file, typeRegistry, visiting, sourceNode, metadataPolicy = normalizeMetadataPolicy(void 0), extensionRegistry, diagnostics) {
|
|
3313
4105
|
const collectedDiagnostics = diagnostics ?? [];
|
|
3314
4106
|
const typeName = getNamedTypeName(type);
|
|
3315
4107
|
const namedTypeName = typeName ?? void 0;
|
|
@@ -3321,6 +4113,7 @@ function resolveObjectType(type, checker, file, typeRegistry, visiting, sourceNo
|
|
|
3321
4113
|
typeRegistry,
|
|
3322
4114
|
visiting,
|
|
3323
4115
|
sourceNode,
|
|
4116
|
+
metadataPolicy,
|
|
3324
4117
|
extensionRegistry,
|
|
3325
4118
|
collectedDiagnostics
|
|
3326
4119
|
);
|
|
@@ -3371,6 +4164,7 @@ function resolveObjectType(type, checker, file, typeRegistry, visiting, sourceNo
|
|
|
3371
4164
|
file,
|
|
3372
4165
|
typeRegistry,
|
|
3373
4166
|
visiting,
|
|
4167
|
+
metadataPolicy,
|
|
3374
4168
|
extensionRegistry,
|
|
3375
4169
|
collectedDiagnostics
|
|
3376
4170
|
);
|
|
@@ -3383,8 +4177,14 @@ function resolveObjectType(type, checker, file, typeRegistry, visiting, sourceNo
|
|
|
3383
4177
|
return recordNode;
|
|
3384
4178
|
}
|
|
3385
4179
|
const annotations = namedDecl ? extractJSDocAnnotationNodes(namedDecl, file, makeParseOptions(extensionRegistry)) : void 0;
|
|
4180
|
+
const metadata = namedDecl !== void 0 ? resolveNodeMetadata(metadataPolicy, "type", registryTypeName, namedDecl, {
|
|
4181
|
+
checker,
|
|
4182
|
+
declaration: namedDecl,
|
|
4183
|
+
subjectType: type
|
|
4184
|
+
}) : void 0;
|
|
3386
4185
|
typeRegistry[registryTypeName] = {
|
|
3387
4186
|
name: registryTypeName,
|
|
4187
|
+
...metadata !== void 0 && { metadata },
|
|
3388
4188
|
type: recordNode,
|
|
3389
4189
|
...annotations !== void 0 && annotations.length > 0 && { annotations },
|
|
3390
4190
|
provenance: provenanceForDeclaration(namedDecl, file)
|
|
@@ -3404,12 +4204,14 @@ function resolveObjectType(type, checker, file, typeRegistry, visiting, sourceNo
|
|
|
3404
4204
|
file,
|
|
3405
4205
|
typeRegistry,
|
|
3406
4206
|
visiting,
|
|
4207
|
+
metadataPolicy,
|
|
3407
4208
|
collectedDiagnostics,
|
|
3408
4209
|
extensionRegistry
|
|
3409
4210
|
);
|
|
3410
4211
|
for (const prop of type.getProperties()) {
|
|
3411
4212
|
const declaration = prop.valueDeclaration ?? prop.declarations?.[0];
|
|
3412
4213
|
if (!declaration) continue;
|
|
4214
|
+
if (!shouldEmitResolvedObjectProperty(prop, declaration)) continue;
|
|
3413
4215
|
const propType = checker.getTypeOfSymbolAtLocation(prop, declaration);
|
|
3414
4216
|
const optional = !!(prop.flags & ts3.SymbolFlags.Optional);
|
|
3415
4217
|
const propTypeNode = resolveTypeNode(
|
|
@@ -3419,12 +4221,14 @@ function resolveObjectType(type, checker, file, typeRegistry, visiting, sourceNo
|
|
|
3419
4221
|
typeRegistry,
|
|
3420
4222
|
visiting,
|
|
3421
4223
|
declaration,
|
|
4224
|
+
metadataPolicy,
|
|
3422
4225
|
extensionRegistry,
|
|
3423
4226
|
collectedDiagnostics
|
|
3424
4227
|
);
|
|
3425
4228
|
const fieldNodeInfo = fieldInfoMap?.get(prop.name);
|
|
3426
4229
|
properties.push({
|
|
3427
4230
|
name: prop.name,
|
|
4231
|
+
...fieldNodeInfo?.metadata !== void 0 && { metadata: fieldNodeInfo.metadata },
|
|
3428
4232
|
type: propTypeNode,
|
|
3429
4233
|
optional,
|
|
3430
4234
|
constraints: fieldNodeInfo?.constraints ?? [],
|
|
@@ -3441,14 +4245,21 @@ function resolveObjectType(type, checker, file, typeRegistry, visiting, sourceNo
|
|
|
3441
4245
|
type,
|
|
3442
4246
|
checker,
|
|
3443
4247
|
file,
|
|
3444
|
-
collectedDiagnostics
|
|
4248
|
+
collectedDiagnostics,
|
|
4249
|
+
metadataPolicy
|
|
3445
4250
|
) : properties,
|
|
3446
4251
|
additionalProperties: true
|
|
3447
4252
|
};
|
|
3448
4253
|
if (registryTypeName !== void 0 && shouldRegisterNamedType) {
|
|
3449
4254
|
const annotations = namedDecl ? extractJSDocAnnotationNodes(namedDecl, file, makeParseOptions(extensionRegistry)) : void 0;
|
|
4255
|
+
const metadata = namedDecl !== void 0 ? resolveNodeMetadata(metadataPolicy, "type", registryTypeName, namedDecl, {
|
|
4256
|
+
checker,
|
|
4257
|
+
declaration: namedDecl,
|
|
4258
|
+
subjectType: type
|
|
4259
|
+
}) : void 0;
|
|
3450
4260
|
typeRegistry[registryTypeName] = {
|
|
3451
4261
|
name: registryTypeName,
|
|
4262
|
+
...metadata !== void 0 && { metadata },
|
|
3452
4263
|
type: objectNode,
|
|
3453
4264
|
...annotations !== void 0 && annotations.length > 0 && { annotations },
|
|
3454
4265
|
provenance: provenanceForDeclaration(namedDecl, file)
|
|
@@ -3461,7 +4272,7 @@ function resolveObjectType(type, checker, file, typeRegistry, visiting, sourceNo
|
|
|
3461
4272
|
}
|
|
3462
4273
|
return objectNode;
|
|
3463
4274
|
}
|
|
3464
|
-
function getNamedTypeFieldNodeInfoMap(type, checker, file, typeRegistry, visiting, diagnostics, extensionRegistry) {
|
|
4275
|
+
function getNamedTypeFieldNodeInfoMap(type, checker, file, typeRegistry, visiting, metadataPolicy, diagnostics, extensionRegistry) {
|
|
3465
4276
|
const symbols = [type.getSymbol(), type.aliasSymbol].filter(
|
|
3466
4277
|
(s) => s?.declarations != null && s.declarations.length > 0
|
|
3467
4278
|
);
|
|
@@ -3482,10 +4293,12 @@ function getNamedTypeFieldNodeInfoMap(type, checker, file, typeRegistry, visitin
|
|
|
3482
4293
|
visiting,
|
|
3483
4294
|
diagnostics,
|
|
3484
4295
|
hostType,
|
|
4296
|
+
metadataPolicy,
|
|
3485
4297
|
extensionRegistry
|
|
3486
4298
|
);
|
|
3487
4299
|
if (fieldNode) {
|
|
3488
4300
|
map.set(fieldNode.name, {
|
|
4301
|
+
...fieldNode.metadata !== void 0 && { metadata: fieldNode.metadata },
|
|
3489
4302
|
constraints: [...fieldNode.constraints],
|
|
3490
4303
|
annotations: [...fieldNode.annotations],
|
|
3491
4304
|
provenance: fieldNode.provenance
|
|
@@ -3503,6 +4316,7 @@ function getNamedTypeFieldNodeInfoMap(type, checker, file, typeRegistry, visitin
|
|
|
3503
4316
|
file,
|
|
3504
4317
|
typeRegistry,
|
|
3505
4318
|
visiting,
|
|
4319
|
+
metadataPolicy,
|
|
3506
4320
|
checker.getTypeAtLocation(interfaceDecl),
|
|
3507
4321
|
diagnostics,
|
|
3508
4322
|
extensionRegistry
|
|
@@ -3516,6 +4330,7 @@ function getNamedTypeFieldNodeInfoMap(type, checker, file, typeRegistry, visitin
|
|
|
3516
4330
|
file,
|
|
3517
4331
|
typeRegistry,
|
|
3518
4332
|
visiting,
|
|
4333
|
+
metadataPolicy,
|
|
3519
4334
|
checker.getTypeAtLocation(typeAliasDecl),
|
|
3520
4335
|
diagnostics,
|
|
3521
4336
|
extensionRegistry
|
|
@@ -3567,7 +4382,7 @@ function isNullishTypeNode(typeNode) {
|
|
|
3567
4382
|
}
|
|
3568
4383
|
return ts3.isLiteralTypeNode(typeNode) && (typeNode.literal.kind === ts3.SyntaxKind.NullKeyword || typeNode.literal.kind === ts3.SyntaxKind.UndefinedKeyword);
|
|
3569
4384
|
}
|
|
3570
|
-
function buildFieldNodeInfoMap(members, checker, file, typeRegistry, visiting, hostType, diagnostics, extensionRegistry) {
|
|
4385
|
+
function buildFieldNodeInfoMap(members, checker, file, typeRegistry, visiting, metadataPolicy, hostType, diagnostics, extensionRegistry) {
|
|
3571
4386
|
const map = /* @__PURE__ */ new Map();
|
|
3572
4387
|
for (const member of members) {
|
|
3573
4388
|
if (ts3.isPropertySignature(member)) {
|
|
@@ -3579,10 +4394,12 @@ function buildFieldNodeInfoMap(members, checker, file, typeRegistry, visiting, h
|
|
|
3579
4394
|
visiting,
|
|
3580
4395
|
diagnostics,
|
|
3581
4396
|
hostType,
|
|
4397
|
+
metadataPolicy,
|
|
3582
4398
|
extensionRegistry
|
|
3583
4399
|
);
|
|
3584
4400
|
if (fieldNode) {
|
|
3585
4401
|
map.set(fieldNode.name, {
|
|
4402
|
+
...fieldNode.metadata !== void 0 && { metadata: fieldNode.metadata },
|
|
3586
4403
|
constraints: [...fieldNode.constraints],
|
|
3587
4404
|
annotations: [...fieldNode.annotations],
|
|
3588
4405
|
provenance: fieldNode.provenance
|
|
@@ -3612,6 +4429,7 @@ function extractTypeAliasConstraintNodes(typeNode, checker, file, extensionRegis
|
|
|
3612
4429
|
{},
|
|
3613
4430
|
/* @__PURE__ */ new Set(),
|
|
3614
4431
|
aliasDecl.type,
|
|
4432
|
+
void 0,
|
|
3615
4433
|
extensionRegistry
|
|
3616
4434
|
);
|
|
3617
4435
|
const constraints = extractJSDocConstraintNodes(
|
|
@@ -3721,6 +4539,7 @@ var init_class_analyzer = __esm({
|
|
|
3721
4539
|
"use strict";
|
|
3722
4540
|
init_jsdoc_constraints();
|
|
3723
4541
|
init_tsdoc_parser();
|
|
4542
|
+
init_metadata();
|
|
3724
4543
|
RESOLVING_TYPE_PLACEHOLDER = {
|
|
3725
4544
|
kind: "object",
|
|
3726
4545
|
properties: [],
|
|
@@ -3813,19 +4632,37 @@ function findInterfaceByName(sourceFile, interfaceName) {
|
|
|
3813
4632
|
function findTypeAliasByName(sourceFile, aliasName) {
|
|
3814
4633
|
return findNodeByName(sourceFile, aliasName, ts4.isTypeAliasDeclaration, (n) => n.name.text);
|
|
3815
4634
|
}
|
|
3816
|
-
function analyzeNamedTypeToIR(filePath, typeName, extensionRegistry) {
|
|
4635
|
+
function analyzeNamedTypeToIR(filePath, typeName, extensionRegistry, metadataPolicy) {
|
|
3817
4636
|
const ctx = createProgramContext(filePath);
|
|
3818
|
-
return analyzeNamedTypeToIRFromProgramContext(
|
|
4637
|
+
return analyzeNamedTypeToIRFromProgramContext(
|
|
4638
|
+
ctx,
|
|
4639
|
+
filePath,
|
|
4640
|
+
typeName,
|
|
4641
|
+
extensionRegistry,
|
|
4642
|
+
metadataPolicy
|
|
4643
|
+
);
|
|
3819
4644
|
}
|
|
3820
|
-
function analyzeNamedTypeToIRFromProgramContext(ctx, filePath, typeName, extensionRegistry) {
|
|
4645
|
+
function analyzeNamedTypeToIRFromProgramContext(ctx, filePath, typeName, extensionRegistry, metadataPolicy) {
|
|
3821
4646
|
const analysisFilePath = path.resolve(filePath);
|
|
3822
4647
|
const classDecl = findClassByName(ctx.sourceFile, typeName);
|
|
3823
4648
|
if (classDecl !== null) {
|
|
3824
|
-
return analyzeClassToIR(
|
|
4649
|
+
return analyzeClassToIR(
|
|
4650
|
+
classDecl,
|
|
4651
|
+
ctx.checker,
|
|
4652
|
+
analysisFilePath,
|
|
4653
|
+
extensionRegistry,
|
|
4654
|
+
metadataPolicy
|
|
4655
|
+
);
|
|
3825
4656
|
}
|
|
3826
4657
|
const interfaceDecl = findInterfaceByName(ctx.sourceFile, typeName);
|
|
3827
4658
|
if (interfaceDecl !== null) {
|
|
3828
|
-
return analyzeInterfaceToIR(
|
|
4659
|
+
return analyzeInterfaceToIR(
|
|
4660
|
+
interfaceDecl,
|
|
4661
|
+
ctx.checker,
|
|
4662
|
+
analysisFilePath,
|
|
4663
|
+
extensionRegistry,
|
|
4664
|
+
metadataPolicy
|
|
4665
|
+
);
|
|
3829
4666
|
}
|
|
3830
4667
|
const typeAlias = findTypeAliasByName(ctx.sourceFile, typeName);
|
|
3831
4668
|
if (typeAlias !== null) {
|
|
@@ -3833,7 +4670,8 @@ function analyzeNamedTypeToIRFromProgramContext(ctx, filePath, typeName, extensi
|
|
|
3833
4670
|
typeAlias,
|
|
3834
4671
|
ctx.checker,
|
|
3835
4672
|
analysisFilePath,
|
|
3836
|
-
extensionRegistry
|
|
4673
|
+
extensionRegistry,
|
|
4674
|
+
metadataPolicy
|
|
3837
4675
|
);
|
|
3838
4676
|
if (result.ok) {
|
|
3839
4677
|
return result.analysis;
|
|
@@ -3948,7 +4786,11 @@ function generateClassSchemas(analysis, source, options) {
|
|
|
3948
4786
|
if (errorDiagnostics !== void 0 && errorDiagnostics.length > 0) {
|
|
3949
4787
|
throw new Error(formatValidationError(errorDiagnostics));
|
|
3950
4788
|
}
|
|
3951
|
-
const ir = canonicalizeTSDoc(
|
|
4789
|
+
const ir = canonicalizeTSDoc(
|
|
4790
|
+
analysis,
|
|
4791
|
+
source,
|
|
4792
|
+
options?.metadata !== void 0 ? { metadata: options.metadata } : void 0
|
|
4793
|
+
);
|
|
3952
4794
|
const validationResult = validateIR(ir, {
|
|
3953
4795
|
...options?.extensionRegistry !== void 0 && {
|
|
3954
4796
|
extensionRegistry: options.extensionRegistry
|
|
@@ -3985,13 +4827,15 @@ function generateSchemasFromClass(options) {
|
|
|
3985
4827
|
classDecl,
|
|
3986
4828
|
ctx.checker,
|
|
3987
4829
|
options.filePath,
|
|
3988
|
-
options.extensionRegistry
|
|
4830
|
+
options.extensionRegistry,
|
|
4831
|
+
options.metadata
|
|
3989
4832
|
);
|
|
3990
4833
|
return generateClassSchemas(
|
|
3991
4834
|
analysis,
|
|
3992
4835
|
{ file: options.filePath },
|
|
3993
4836
|
{
|
|
3994
4837
|
extensionRegistry: options.extensionRegistry,
|
|
4838
|
+
metadata: options.metadata,
|
|
3995
4839
|
vendorPrefix: options.vendorPrefix
|
|
3996
4840
|
}
|
|
3997
4841
|
);
|
|
@@ -4009,13 +4853,15 @@ function generateSchemasFromProgram(options) {
|
|
|
4009
4853
|
ctx,
|
|
4010
4854
|
options.filePath,
|
|
4011
4855
|
options.typeName,
|
|
4012
|
-
options.extensionRegistry
|
|
4856
|
+
options.extensionRegistry,
|
|
4857
|
+
options.metadata
|
|
4013
4858
|
);
|
|
4014
4859
|
return generateClassSchemas(
|
|
4015
4860
|
analysis,
|
|
4016
4861
|
{ file: options.filePath },
|
|
4017
4862
|
{
|
|
4018
4863
|
extensionRegistry: options.extensionRegistry,
|
|
4864
|
+
metadata: options.metadata,
|
|
4019
4865
|
vendorPrefix: options.vendorPrefix
|
|
4020
4866
|
}
|
|
4021
4867
|
);
|
|
@@ -4035,16 +4881,28 @@ var init_class_schema = __esm({
|
|
|
4035
4881
|
// src/generators/mixed-authoring.ts
|
|
4036
4882
|
function buildMixedAuthoringSchemas(options) {
|
|
4037
4883
|
const { filePath, typeName, overlays, ...schemaOptions } = options;
|
|
4038
|
-
const analysis = analyzeNamedTypeToIR(
|
|
4039
|
-
|
|
4040
|
-
|
|
4884
|
+
const analysis = analyzeNamedTypeToIR(
|
|
4885
|
+
filePath,
|
|
4886
|
+
typeName,
|
|
4887
|
+
schemaOptions.extensionRegistry,
|
|
4888
|
+
schemaOptions.metadata
|
|
4889
|
+
);
|
|
4890
|
+
const composedAnalysis = composeAnalysisWithOverlays(analysis, overlays, schemaOptions.metadata);
|
|
4891
|
+
const ir = canonicalizeTSDoc(
|
|
4892
|
+
composedAnalysis,
|
|
4893
|
+
{ file: filePath },
|
|
4894
|
+
schemaOptions.metadata !== void 0 ? { metadata: schemaOptions.metadata } : void 0
|
|
4895
|
+
);
|
|
4041
4896
|
return {
|
|
4042
4897
|
jsonSchema: generateJsonSchemaFromIR(ir, schemaOptions),
|
|
4043
4898
|
uiSchema: generateUiSchemaFromIR(ir)
|
|
4044
4899
|
};
|
|
4045
4900
|
}
|
|
4046
|
-
function composeAnalysisWithOverlays(analysis, overlays) {
|
|
4047
|
-
const overlayIR = canonicalizeChainDSL(
|
|
4901
|
+
function composeAnalysisWithOverlays(analysis, overlays, metadata) {
|
|
4902
|
+
const overlayIR = canonicalizeChainDSL(
|
|
4903
|
+
overlays,
|
|
4904
|
+
metadata !== void 0 ? { metadata } : void 0
|
|
4905
|
+
);
|
|
4048
4906
|
const overlayFields = collectOverlayFields(overlayIR.elements);
|
|
4049
4907
|
if (overlayFields.length === 0) {
|
|
4050
4908
|
return analysis;
|
|
@@ -4100,8 +4958,10 @@ function collectOverlayFields(elements) {
|
|
|
4100
4958
|
}
|
|
4101
4959
|
function mergeFieldOverlay(baseField, overlayField, typeRegistry) {
|
|
4102
4960
|
assertSupportedOverlayField(baseField, overlayField);
|
|
4961
|
+
const metadata = mergeResolvedMetadata(baseField.metadata, overlayField.metadata);
|
|
4103
4962
|
return {
|
|
4104
4963
|
...baseField,
|
|
4964
|
+
...metadata !== void 0 && { metadata },
|
|
4105
4965
|
type: mergeFieldType(baseField, overlayField, typeRegistry),
|
|
4106
4966
|
annotations: mergeAnnotations(baseField.annotations, overlayField.annotations)
|
|
4107
4967
|
};
|
|
@@ -4214,6 +5074,7 @@ var init_mixed_authoring = __esm({
|
|
|
4214
5074
|
init_ir_generator2();
|
|
4215
5075
|
init_canonicalize();
|
|
4216
5076
|
init_program();
|
|
5077
|
+
init_metadata();
|
|
4217
5078
|
}
|
|
4218
5079
|
});
|
|
4219
5080
|
|
|
@@ -4237,12 +5098,12 @@ import * as path2 from "path";
|
|
|
4237
5098
|
function buildFormSchemas(form, options) {
|
|
4238
5099
|
return {
|
|
4239
5100
|
jsonSchema: generateJsonSchema(form, options),
|
|
4240
|
-
uiSchema: generateUiSchema(form)
|
|
5101
|
+
uiSchema: generateUiSchema(form, options)
|
|
4241
5102
|
};
|
|
4242
5103
|
}
|
|
4243
5104
|
function writeSchemas(form, options) {
|
|
4244
|
-
const { outDir, name = "schema", indent = 2, vendorPrefix } = options;
|
|
4245
|
-
const buildOptions = vendorPrefix === void 0 ? void 0 : { vendorPrefix };
|
|
5105
|
+
const { outDir, name = "schema", indent = 2, vendorPrefix, metadata } = options;
|
|
5106
|
+
const buildOptions = vendorPrefix === void 0 && metadata === void 0 ? void 0 : { vendorPrefix, metadata };
|
|
4246
5107
|
const { jsonSchema, uiSchema: uiSchema2 } = buildFormSchemas(form, buildOptions);
|
|
4247
5108
|
if (!fs.existsSync(outDir)) {
|
|
4248
5109
|
fs.mkdirSync(outDir, { recursive: true });
|