@formspec/build 0.1.0-alpha.28 → 0.1.0-alpha.29
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/analyzer/class-analyzer.d.ts +11 -5
- package/dist/analyzer/class-analyzer.d.ts.map +1 -1
- package/dist/analyzer/program.d.ts +3 -2
- package/dist/analyzer/program.d.ts.map +1 -1
- package/dist/browser.cjs +485 -76
- package/dist/browser.cjs.map +1 -1
- package/dist/browser.js +486 -77
- package/dist/browser.js.map +1 -1
- package/dist/build-alpha.d.ts +18 -2
- package/dist/build-beta.d.ts +18 -2
- package/dist/build-internal.d.ts +18 -2
- package/dist/build.d.ts +18 -2
- package/dist/canonicalize/chain-dsl-canonicalizer.d.ts +5 -2
- package/dist/canonicalize/chain-dsl-canonicalizer.d.ts.map +1 -1
- package/dist/canonicalize/tsdoc-canonicalizer.d.ts +5 -1
- package/dist/canonicalize/tsdoc-canonicalizer.d.ts.map +1 -1
- package/dist/cli.cjs +1031 -170
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +1032 -171
- package/dist/cli.js.map +1 -1
- package/dist/generators/class-schema.d.ts +6 -1
- package/dist/generators/class-schema.d.ts.map +1 -1
- package/dist/generators/method-schema.d.ts.map +1 -1
- package/dist/generators/mixed-authoring.d.ts.map +1 -1
- package/dist/index.cjs +998 -170
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +4 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +999 -171
- package/dist/index.js.map +1 -1
- package/dist/internals.cjs +921 -155
- package/dist/internals.cjs.map +1 -1
- package/dist/internals.js +922 -156
- package/dist/internals.js.map +1 -1
- package/dist/json-schema/generator.d.ts +3 -1
- package/dist/json-schema/generator.d.ts.map +1 -1
- package/dist/json-schema/ir-generator.d.ts.map +1 -1
- package/dist/metadata/collision-guards.d.ts +3 -0
- package/dist/metadata/collision-guards.d.ts.map +1 -0
- package/dist/metadata/index.d.ts +7 -0
- package/dist/metadata/index.d.ts.map +1 -0
- package/dist/metadata/policy.d.ts +11 -0
- package/dist/metadata/policy.d.ts.map +1 -0
- package/dist/metadata/resolve.d.ts +20 -0
- package/dist/metadata/resolve.d.ts.map +1 -0
- package/dist/ui-schema/generator.d.ts +11 -2
- package/dist/ui-schema/generator.d.ts.map +1 -1
- package/dist/ui-schema/ir-generator.d.ts +2 -1
- package/dist/ui-schema/ir-generator.d.ts.map +1 -1
- package/package.json +4 -4
package/dist/browser.cjs
CHANGED
|
@@ -50,6 +50,169 @@ module.exports = __toCommonJS(browser_exports);
|
|
|
50
50
|
|
|
51
51
|
// src/canonicalize/chain-dsl-canonicalizer.ts
|
|
52
52
|
var import_internals = require("@formspec/core/internals");
|
|
53
|
+
|
|
54
|
+
// src/metadata/policy.ts
|
|
55
|
+
var NOOP_INFLECT = () => "";
|
|
56
|
+
function normalizePluralization(input) {
|
|
57
|
+
if (input?.mode === "infer-if-missing") {
|
|
58
|
+
return {
|
|
59
|
+
mode: "infer-if-missing",
|
|
60
|
+
infer: () => "",
|
|
61
|
+
inflect: input.inflect
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
if (input?.mode === "require-explicit") {
|
|
65
|
+
return {
|
|
66
|
+
mode: "require-explicit",
|
|
67
|
+
infer: () => "",
|
|
68
|
+
inflect: NOOP_INFLECT
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
return {
|
|
72
|
+
mode: "disabled",
|
|
73
|
+
infer: () => "",
|
|
74
|
+
inflect: NOOP_INFLECT
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
function normalizeScalarPolicy(input) {
|
|
78
|
+
if (input?.mode === "infer-if-missing") {
|
|
79
|
+
return {
|
|
80
|
+
mode: "infer-if-missing",
|
|
81
|
+
infer: input.infer,
|
|
82
|
+
pluralization: normalizePluralization(input.pluralization)
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
if (input?.mode === "require-explicit") {
|
|
86
|
+
return {
|
|
87
|
+
mode: "require-explicit",
|
|
88
|
+
infer: () => "",
|
|
89
|
+
pluralization: normalizePluralization(input.pluralization)
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
return {
|
|
93
|
+
mode: "disabled",
|
|
94
|
+
infer: () => "",
|
|
95
|
+
pluralization: normalizePluralization(input?.pluralization)
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
function normalizeDeclarationPolicy(input) {
|
|
99
|
+
return {
|
|
100
|
+
apiName: normalizeScalarPolicy(input?.apiName),
|
|
101
|
+
displayName: normalizeScalarPolicy(input?.displayName)
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
function normalizeMetadataPolicy(input) {
|
|
105
|
+
return {
|
|
106
|
+
type: normalizeDeclarationPolicy(input?.type),
|
|
107
|
+
field: normalizeDeclarationPolicy(input?.field),
|
|
108
|
+
method: normalizeDeclarationPolicy(input?.method)
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
function getDeclarationMetadataPolicy(policy, declarationKind) {
|
|
112
|
+
return policy[declarationKind];
|
|
113
|
+
}
|
|
114
|
+
function makeMetadataContext(surface, declarationKind, logicalName, buildContext) {
|
|
115
|
+
return {
|
|
116
|
+
surface,
|
|
117
|
+
declarationKind,
|
|
118
|
+
logicalName,
|
|
119
|
+
...buildContext !== void 0 && { buildContext }
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// src/metadata/resolve.ts
|
|
124
|
+
function toExplicitScalar(value) {
|
|
125
|
+
return value !== void 0 && value.trim() !== "" ? { value, source: "explicit" } : void 0;
|
|
126
|
+
}
|
|
127
|
+
function toExplicitResolvedMetadata(explicit) {
|
|
128
|
+
if (explicit === void 0) {
|
|
129
|
+
return void 0;
|
|
130
|
+
}
|
|
131
|
+
const apiName = toExplicitScalar(explicit.apiName);
|
|
132
|
+
const displayName = toExplicitScalar(explicit.displayName);
|
|
133
|
+
const apiNamePlural = toExplicitScalar(explicit.apiNamePlural);
|
|
134
|
+
const displayNamePlural = toExplicitScalar(explicit.displayNamePlural);
|
|
135
|
+
const metadata = {
|
|
136
|
+
...apiName !== void 0 && { apiName },
|
|
137
|
+
...displayName !== void 0 && { displayName },
|
|
138
|
+
...apiNamePlural !== void 0 && { apiNamePlural },
|
|
139
|
+
...displayNamePlural !== void 0 && { displayNamePlural }
|
|
140
|
+
};
|
|
141
|
+
return Object.keys(metadata).length > 0 ? metadata : void 0;
|
|
142
|
+
}
|
|
143
|
+
function resolveScalar(current, policy, context, metadataLabel) {
|
|
144
|
+
if (current !== void 0) {
|
|
145
|
+
return current;
|
|
146
|
+
}
|
|
147
|
+
if (policy.mode === "require-explicit") {
|
|
148
|
+
throw new Error(
|
|
149
|
+
`Metadata policy requires explicit ${metadataLabel} for ${context.declarationKind} "${context.logicalName}" on the ${context.surface} surface.`
|
|
150
|
+
);
|
|
151
|
+
}
|
|
152
|
+
if (policy.mode !== "infer-if-missing") {
|
|
153
|
+
return void 0;
|
|
154
|
+
}
|
|
155
|
+
const inferredValue = policy.infer(context);
|
|
156
|
+
return inferredValue.trim() !== "" ? { value: inferredValue, source: "inferred" } : void 0;
|
|
157
|
+
}
|
|
158
|
+
function resolvePlural(current, singular, policy, context, metadataLabel) {
|
|
159
|
+
if (current !== void 0) {
|
|
160
|
+
return current;
|
|
161
|
+
}
|
|
162
|
+
if (policy.mode === "require-explicit") {
|
|
163
|
+
throw new Error(
|
|
164
|
+
`Metadata policy requires explicit ${metadataLabel} for ${context.declarationKind} "${context.logicalName}" on the ${context.surface} surface.`
|
|
165
|
+
);
|
|
166
|
+
}
|
|
167
|
+
if (singular === void 0 || policy.mode !== "infer-if-missing") {
|
|
168
|
+
return void 0;
|
|
169
|
+
}
|
|
170
|
+
const pluralValue = policy.inflect({ ...context, singular: singular.value });
|
|
171
|
+
return pluralValue.trim() !== "" ? { value: pluralValue, source: "inferred" } : void 0;
|
|
172
|
+
}
|
|
173
|
+
function resolveResolvedMetadata(current, policy, context) {
|
|
174
|
+
const apiName = resolveScalar(current?.apiName, policy.apiName, context, "apiName");
|
|
175
|
+
const displayName = resolveScalar(
|
|
176
|
+
current?.displayName,
|
|
177
|
+
policy.displayName,
|
|
178
|
+
context,
|
|
179
|
+
"displayName"
|
|
180
|
+
);
|
|
181
|
+
const apiNamePlural = resolvePlural(
|
|
182
|
+
current?.apiNamePlural,
|
|
183
|
+
apiName,
|
|
184
|
+
policy.apiName.pluralization,
|
|
185
|
+
context,
|
|
186
|
+
"apiNamePlural"
|
|
187
|
+
);
|
|
188
|
+
const displayNamePlural = resolvePlural(
|
|
189
|
+
current?.displayNamePlural,
|
|
190
|
+
displayName,
|
|
191
|
+
policy.displayName.pluralization,
|
|
192
|
+
context,
|
|
193
|
+
"displayNamePlural"
|
|
194
|
+
);
|
|
195
|
+
if (apiName === void 0 && displayName === void 0 && apiNamePlural === void 0 && displayNamePlural === void 0) {
|
|
196
|
+
return void 0;
|
|
197
|
+
}
|
|
198
|
+
return {
|
|
199
|
+
...apiName !== void 0 && { apiName },
|
|
200
|
+
...displayName !== void 0 && { displayName },
|
|
201
|
+
...apiNamePlural !== void 0 && { apiNamePlural },
|
|
202
|
+
...displayNamePlural !== void 0 && { displayNamePlural }
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
function resolveMetadata(explicit, policy, context) {
|
|
206
|
+
return resolveResolvedMetadata(toExplicitResolvedMetadata(explicit), policy, context);
|
|
207
|
+
}
|
|
208
|
+
function getSerializedName(logicalName, metadata) {
|
|
209
|
+
return metadata?.apiName?.value ?? logicalName;
|
|
210
|
+
}
|
|
211
|
+
function getDisplayName(metadata) {
|
|
212
|
+
return metadata?.displayName?.value;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
// src/canonicalize/chain-dsl-canonicalizer.ts
|
|
53
216
|
var CHAIN_DSL_PROVENANCE = {
|
|
54
217
|
surface: "chain-dsl",
|
|
55
218
|
file: "",
|
|
@@ -65,57 +228,60 @@ function isConditional(el) {
|
|
|
65
228
|
function isField(el) {
|
|
66
229
|
return el._type === "field";
|
|
67
230
|
}
|
|
68
|
-
function canonicalizeChainDSL(form) {
|
|
231
|
+
function canonicalizeChainDSL(form, options) {
|
|
232
|
+
const metadataPolicy = normalizeMetadataPolicy(
|
|
233
|
+
options?.metadata ?? (0, import_internals._getFormSpecMetadataPolicy)(form)
|
|
234
|
+
);
|
|
69
235
|
return {
|
|
70
236
|
kind: "form-ir",
|
|
71
237
|
irVersion: import_internals.IR_VERSION,
|
|
72
|
-
elements: canonicalizeElements(form.elements),
|
|
238
|
+
elements: canonicalizeElements(form.elements, metadataPolicy),
|
|
73
239
|
rootAnnotations: [],
|
|
74
240
|
typeRegistry: {},
|
|
75
241
|
provenance: CHAIN_DSL_PROVENANCE
|
|
76
242
|
};
|
|
77
243
|
}
|
|
78
|
-
function canonicalizeElements(elements) {
|
|
79
|
-
return elements.map(canonicalizeElement);
|
|
244
|
+
function canonicalizeElements(elements, metadataPolicy) {
|
|
245
|
+
return elements.map((element) => canonicalizeElement(element, metadataPolicy));
|
|
80
246
|
}
|
|
81
|
-
function canonicalizeElement(element) {
|
|
247
|
+
function canonicalizeElement(element, metadataPolicy) {
|
|
82
248
|
if (isField(element)) {
|
|
83
|
-
return canonicalizeField(element);
|
|
249
|
+
return canonicalizeField(element, metadataPolicy);
|
|
84
250
|
}
|
|
85
251
|
if (isGroup(element)) {
|
|
86
|
-
return canonicalizeGroup(element);
|
|
252
|
+
return canonicalizeGroup(element, metadataPolicy);
|
|
87
253
|
}
|
|
88
254
|
if (isConditional(element)) {
|
|
89
|
-
return canonicalizeConditional(element);
|
|
255
|
+
return canonicalizeConditional(element, metadataPolicy);
|
|
90
256
|
}
|
|
91
257
|
const _exhaustive = element;
|
|
92
258
|
throw new Error(`Unknown element type: ${JSON.stringify(_exhaustive)}`);
|
|
93
259
|
}
|
|
94
|
-
function canonicalizeField(field) {
|
|
260
|
+
function canonicalizeField(field, metadataPolicy) {
|
|
95
261
|
switch (field._field) {
|
|
96
262
|
case "text":
|
|
97
|
-
return canonicalizeTextField(field);
|
|
263
|
+
return canonicalizeTextField(field, metadataPolicy);
|
|
98
264
|
case "number":
|
|
99
|
-
return canonicalizeNumberField(field);
|
|
265
|
+
return canonicalizeNumberField(field, metadataPolicy);
|
|
100
266
|
case "boolean":
|
|
101
|
-
return canonicalizeBooleanField(field);
|
|
267
|
+
return canonicalizeBooleanField(field, metadataPolicy);
|
|
102
268
|
case "enum":
|
|
103
|
-
return canonicalizeStaticEnumField(field);
|
|
269
|
+
return canonicalizeStaticEnumField(field, metadataPolicy);
|
|
104
270
|
case "dynamic_enum":
|
|
105
|
-
return canonicalizeDynamicEnumField(field);
|
|
271
|
+
return canonicalizeDynamicEnumField(field, metadataPolicy);
|
|
106
272
|
case "dynamic_schema":
|
|
107
|
-
return canonicalizeDynamicSchemaField(field);
|
|
273
|
+
return canonicalizeDynamicSchemaField(field, metadataPolicy);
|
|
108
274
|
case "array":
|
|
109
|
-
return canonicalizeArrayField(field);
|
|
275
|
+
return canonicalizeArrayField(field, metadataPolicy);
|
|
110
276
|
case "object":
|
|
111
|
-
return canonicalizeObjectField(field);
|
|
277
|
+
return canonicalizeObjectField(field, metadataPolicy);
|
|
112
278
|
default: {
|
|
113
279
|
const _exhaustive = field;
|
|
114
280
|
throw new Error(`Unknown field type: ${JSON.stringify(_exhaustive)}`);
|
|
115
281
|
}
|
|
116
282
|
}
|
|
117
283
|
}
|
|
118
|
-
function canonicalizeTextField(field) {
|
|
284
|
+
function canonicalizeTextField(field, metadataPolicy) {
|
|
119
285
|
const type = { kind: "primitive", primitiveKind: "string" };
|
|
120
286
|
const constraints = [];
|
|
121
287
|
if (field.minLength !== void 0) {
|
|
@@ -147,13 +313,14 @@ function canonicalizeTextField(field) {
|
|
|
147
313
|
}
|
|
148
314
|
return buildFieldNode(
|
|
149
315
|
field.name,
|
|
316
|
+
resolveFieldMetadata(field.name, field, metadataPolicy),
|
|
150
317
|
type,
|
|
151
318
|
field.required,
|
|
152
|
-
buildAnnotations(field
|
|
319
|
+
buildAnnotations(getExplicitDisplayName(field), field.placeholder),
|
|
153
320
|
constraints
|
|
154
321
|
);
|
|
155
322
|
}
|
|
156
|
-
function canonicalizeNumberField(field) {
|
|
323
|
+
function canonicalizeNumberField(field, metadataPolicy) {
|
|
157
324
|
const type = { kind: "primitive", primitiveKind: "number" };
|
|
158
325
|
const constraints = [];
|
|
159
326
|
if (field.min !== void 0) {
|
|
@@ -185,17 +352,24 @@ function canonicalizeNumberField(field) {
|
|
|
185
352
|
}
|
|
186
353
|
return buildFieldNode(
|
|
187
354
|
field.name,
|
|
355
|
+
resolveFieldMetadata(field.name, field, metadataPolicy),
|
|
188
356
|
type,
|
|
189
357
|
field.required,
|
|
190
|
-
buildAnnotations(field
|
|
358
|
+
buildAnnotations(getExplicitDisplayName(field)),
|
|
191
359
|
constraints
|
|
192
360
|
);
|
|
193
361
|
}
|
|
194
|
-
function canonicalizeBooleanField(field) {
|
|
362
|
+
function canonicalizeBooleanField(field, metadataPolicy) {
|
|
195
363
|
const type = { kind: "primitive", primitiveKind: "boolean" };
|
|
196
|
-
return buildFieldNode(
|
|
364
|
+
return buildFieldNode(
|
|
365
|
+
field.name,
|
|
366
|
+
resolveFieldMetadata(field.name, field, metadataPolicy),
|
|
367
|
+
type,
|
|
368
|
+
field.required,
|
|
369
|
+
buildAnnotations(getExplicitDisplayName(field))
|
|
370
|
+
);
|
|
197
371
|
}
|
|
198
|
-
function canonicalizeStaticEnumField(field) {
|
|
372
|
+
function canonicalizeStaticEnumField(field, metadataPolicy) {
|
|
199
373
|
const members = field.options.map((opt) => {
|
|
200
374
|
if (typeof opt === "string") {
|
|
201
375
|
return { value: opt };
|
|
@@ -203,28 +377,46 @@ function canonicalizeStaticEnumField(field) {
|
|
|
203
377
|
return { value: opt.id, displayName: opt.label };
|
|
204
378
|
});
|
|
205
379
|
const type = { kind: "enum", members };
|
|
206
|
-
return buildFieldNode(
|
|
380
|
+
return buildFieldNode(
|
|
381
|
+
field.name,
|
|
382
|
+
resolveFieldMetadata(field.name, field, metadataPolicy),
|
|
383
|
+
type,
|
|
384
|
+
field.required,
|
|
385
|
+
buildAnnotations(getExplicitDisplayName(field))
|
|
386
|
+
);
|
|
207
387
|
}
|
|
208
|
-
function canonicalizeDynamicEnumField(field) {
|
|
388
|
+
function canonicalizeDynamicEnumField(field, metadataPolicy) {
|
|
209
389
|
const type = {
|
|
210
390
|
kind: "dynamic",
|
|
211
391
|
dynamicKind: "enum",
|
|
212
392
|
sourceKey: field.source,
|
|
213
393
|
parameterFields: field.params ? [...field.params] : []
|
|
214
394
|
};
|
|
215
|
-
return buildFieldNode(
|
|
395
|
+
return buildFieldNode(
|
|
396
|
+
field.name,
|
|
397
|
+
resolveFieldMetadata(field.name, field, metadataPolicy),
|
|
398
|
+
type,
|
|
399
|
+
field.required,
|
|
400
|
+
buildAnnotations(getExplicitDisplayName(field))
|
|
401
|
+
);
|
|
216
402
|
}
|
|
217
|
-
function canonicalizeDynamicSchemaField(field) {
|
|
403
|
+
function canonicalizeDynamicSchemaField(field, metadataPolicy) {
|
|
218
404
|
const type = {
|
|
219
405
|
kind: "dynamic",
|
|
220
406
|
dynamicKind: "schema",
|
|
221
407
|
sourceKey: field.schemaSource,
|
|
222
408
|
parameterFields: []
|
|
223
409
|
};
|
|
224
|
-
return buildFieldNode(
|
|
410
|
+
return buildFieldNode(
|
|
411
|
+
field.name,
|
|
412
|
+
resolveFieldMetadata(field.name, field, metadataPolicy),
|
|
413
|
+
type,
|
|
414
|
+
field.required,
|
|
415
|
+
buildAnnotations(getExplicitDisplayName(field))
|
|
416
|
+
);
|
|
225
417
|
}
|
|
226
|
-
function canonicalizeArrayField(field) {
|
|
227
|
-
const itemProperties = buildObjectProperties(field.items);
|
|
418
|
+
function canonicalizeArrayField(field, metadataPolicy) {
|
|
419
|
+
const itemProperties = buildObjectProperties(field.items, metadataPolicy);
|
|
228
420
|
const itemsType = {
|
|
229
421
|
kind: "object",
|
|
230
422
|
properties: itemProperties,
|
|
@@ -252,37 +444,44 @@ function canonicalizeArrayField(field) {
|
|
|
252
444
|
}
|
|
253
445
|
return buildFieldNode(
|
|
254
446
|
field.name,
|
|
447
|
+
resolveFieldMetadata(field.name, field, metadataPolicy),
|
|
255
448
|
type,
|
|
256
449
|
field.required,
|
|
257
|
-
buildAnnotations(field
|
|
450
|
+
buildAnnotations(getExplicitDisplayName(field)),
|
|
258
451
|
constraints
|
|
259
452
|
);
|
|
260
453
|
}
|
|
261
|
-
function canonicalizeObjectField(field) {
|
|
262
|
-
const properties = buildObjectProperties(field.properties);
|
|
454
|
+
function canonicalizeObjectField(field, metadataPolicy) {
|
|
455
|
+
const properties = buildObjectProperties(field.properties, metadataPolicy);
|
|
263
456
|
const type = {
|
|
264
457
|
kind: "object",
|
|
265
458
|
properties,
|
|
266
459
|
additionalProperties: true
|
|
267
460
|
};
|
|
268
|
-
return buildFieldNode(
|
|
461
|
+
return buildFieldNode(
|
|
462
|
+
field.name,
|
|
463
|
+
resolveFieldMetadata(field.name, field, metadataPolicy),
|
|
464
|
+
type,
|
|
465
|
+
field.required,
|
|
466
|
+
buildAnnotations(getExplicitDisplayName(field))
|
|
467
|
+
);
|
|
269
468
|
}
|
|
270
|
-
function canonicalizeGroup(g) {
|
|
469
|
+
function canonicalizeGroup(g, metadataPolicy) {
|
|
271
470
|
return {
|
|
272
471
|
kind: "group",
|
|
273
472
|
label: g.label,
|
|
274
|
-
elements: canonicalizeElements(g.elements),
|
|
473
|
+
elements: canonicalizeElements(g.elements, metadataPolicy),
|
|
275
474
|
provenance: CHAIN_DSL_PROVENANCE
|
|
276
475
|
};
|
|
277
476
|
}
|
|
278
|
-
function canonicalizeConditional(c) {
|
|
477
|
+
function canonicalizeConditional(c, metadataPolicy) {
|
|
279
478
|
return {
|
|
280
479
|
kind: "conditional",
|
|
281
480
|
fieldName: c.field,
|
|
282
481
|
// Conditional values from the chain DSL are JSON-serializable primitives
|
|
283
482
|
// (strings, numbers, booleans) produced by the `is()` predicate helper.
|
|
284
483
|
value: assertJsonValue(c.value),
|
|
285
|
-
elements: canonicalizeElements(c.elements),
|
|
484
|
+
elements: canonicalizeElements(c.elements, metadataPolicy),
|
|
286
485
|
provenance: CHAIN_DSL_PROVENANCE
|
|
287
486
|
};
|
|
288
487
|
}
|
|
@@ -302,10 +501,11 @@ function assertJsonValue(v) {
|
|
|
302
501
|
}
|
|
303
502
|
throw new TypeError(`Conditional value is not a valid JsonValue: ${typeof v}`);
|
|
304
503
|
}
|
|
305
|
-
function buildFieldNode(name, type, required, annotations, constraints = []) {
|
|
504
|
+
function buildFieldNode(name, metadata, type, required, annotations, constraints = []) {
|
|
306
505
|
return {
|
|
307
506
|
kind: "field",
|
|
308
507
|
name,
|
|
508
|
+
...metadata !== void 0 && { metadata },
|
|
309
509
|
type,
|
|
310
510
|
required: required === true,
|
|
311
511
|
constraints,
|
|
@@ -335,13 +535,14 @@ function buildAnnotations(label, placeholder) {
|
|
|
335
535
|
}
|
|
336
536
|
return annotations;
|
|
337
537
|
}
|
|
338
|
-
function buildObjectProperties(elements, insideConditional = false) {
|
|
538
|
+
function buildObjectProperties(elements, metadataPolicy, insideConditional = false) {
|
|
339
539
|
const properties = [];
|
|
340
540
|
for (const el of elements) {
|
|
341
541
|
if (isField(el)) {
|
|
342
|
-
const fieldNode = canonicalizeField(el);
|
|
542
|
+
const fieldNode = canonicalizeField(el, metadataPolicy);
|
|
343
543
|
properties.push({
|
|
344
544
|
name: fieldNode.name,
|
|
545
|
+
...fieldNode.metadata !== void 0 && { metadata: fieldNode.metadata },
|
|
345
546
|
type: fieldNode.type,
|
|
346
547
|
// Fields inside a conditional branch are always optional in the
|
|
347
548
|
// data schema, regardless of their `required` flag — the condition
|
|
@@ -352,17 +553,148 @@ function buildObjectProperties(elements, insideConditional = false) {
|
|
|
352
553
|
provenance: CHAIN_DSL_PROVENANCE
|
|
353
554
|
});
|
|
354
555
|
} else if (isGroup(el)) {
|
|
355
|
-
properties.push(...buildObjectProperties(el.elements, insideConditional));
|
|
556
|
+
properties.push(...buildObjectProperties(el.elements, metadataPolicy, insideConditional));
|
|
356
557
|
} else if (isConditional(el)) {
|
|
357
|
-
properties.push(...buildObjectProperties(el.elements, true));
|
|
558
|
+
properties.push(...buildObjectProperties(el.elements, metadataPolicy, true));
|
|
358
559
|
}
|
|
359
560
|
}
|
|
360
561
|
return properties;
|
|
361
562
|
}
|
|
563
|
+
function getExplicitDisplayName(field) {
|
|
564
|
+
if (field.label !== void 0 && field.displayName !== void 0) {
|
|
565
|
+
throw new Error('Chain DSL fields cannot specify both "label" and "displayName".');
|
|
566
|
+
}
|
|
567
|
+
return field.displayName ?? field.label;
|
|
568
|
+
}
|
|
569
|
+
function resolveFieldMetadata(logicalName, field, metadataPolicy) {
|
|
570
|
+
const displayName = getExplicitDisplayName(field);
|
|
571
|
+
return resolveMetadata(
|
|
572
|
+
{
|
|
573
|
+
...field.apiName !== void 0 && { apiName: field.apiName },
|
|
574
|
+
...displayName !== void 0 && { displayName }
|
|
575
|
+
},
|
|
576
|
+
getDeclarationMetadataPolicy(metadataPolicy, "field"),
|
|
577
|
+
makeMetadataContext("chain-dsl", "field", logicalName)
|
|
578
|
+
);
|
|
579
|
+
}
|
|
362
580
|
|
|
363
581
|
// src/canonicalize/tsdoc-canonicalizer.ts
|
|
364
582
|
var import_internals2 = require("@formspec/core/internals");
|
|
365
583
|
|
|
584
|
+
// src/metadata/collision-guards.ts
|
|
585
|
+
function assertUniqueSerializedNames(entries, scope) {
|
|
586
|
+
const seen = /* @__PURE__ */ new Map();
|
|
587
|
+
for (const entry of entries) {
|
|
588
|
+
const previous = seen.get(entry.serializedName);
|
|
589
|
+
if (previous !== void 0) {
|
|
590
|
+
if (previous.logicalName === entry.logicalName && previous.category === entry.category) {
|
|
591
|
+
continue;
|
|
592
|
+
}
|
|
593
|
+
throw new Error(
|
|
594
|
+
`Serialized name collision in ${scope}: ${previous.category} "${previous.logicalName}" and ${entry.category} "${entry.logicalName}" both resolve to "${entry.serializedName}".`
|
|
595
|
+
);
|
|
596
|
+
}
|
|
597
|
+
seen.set(entry.serializedName, entry);
|
|
598
|
+
}
|
|
599
|
+
}
|
|
600
|
+
function collectFlattenedFields(elements) {
|
|
601
|
+
const fields = [];
|
|
602
|
+
for (const element of elements) {
|
|
603
|
+
switch (element.kind) {
|
|
604
|
+
case "field":
|
|
605
|
+
fields.push(element);
|
|
606
|
+
break;
|
|
607
|
+
case "group":
|
|
608
|
+
case "conditional":
|
|
609
|
+
fields.push(...collectFlattenedFields(element.elements));
|
|
610
|
+
break;
|
|
611
|
+
default: {
|
|
612
|
+
const exhaustive = element;
|
|
613
|
+
void exhaustive;
|
|
614
|
+
}
|
|
615
|
+
}
|
|
616
|
+
}
|
|
617
|
+
return fields;
|
|
618
|
+
}
|
|
619
|
+
function validateObjectProperties(properties, scope) {
|
|
620
|
+
assertUniqueSerializedNames(
|
|
621
|
+
properties.map((property) => ({
|
|
622
|
+
logicalName: property.name,
|
|
623
|
+
serializedName: getSerializedName(property.name, property.metadata),
|
|
624
|
+
category: "object property"
|
|
625
|
+
})),
|
|
626
|
+
scope
|
|
627
|
+
);
|
|
628
|
+
for (const property of properties) {
|
|
629
|
+
validateTypeNode(
|
|
630
|
+
property.type,
|
|
631
|
+
`${scope}.${getSerializedName(property.name, property.metadata)}`
|
|
632
|
+
);
|
|
633
|
+
}
|
|
634
|
+
}
|
|
635
|
+
function validateTypeNode(type, scope) {
|
|
636
|
+
switch (type.kind) {
|
|
637
|
+
case "array":
|
|
638
|
+
validateTypeNode(type.items, `${scope}[]`);
|
|
639
|
+
break;
|
|
640
|
+
case "object":
|
|
641
|
+
validateObjectProperties(type.properties, scope);
|
|
642
|
+
break;
|
|
643
|
+
case "record":
|
|
644
|
+
validateTypeNode(type.valueType, `${scope}.*`);
|
|
645
|
+
break;
|
|
646
|
+
case "union":
|
|
647
|
+
type.members.forEach((member, index) => {
|
|
648
|
+
validateTypeNode(member, `${scope}|${String(index)}`);
|
|
649
|
+
});
|
|
650
|
+
break;
|
|
651
|
+
case "reference":
|
|
652
|
+
case "primitive":
|
|
653
|
+
case "enum":
|
|
654
|
+
case "dynamic":
|
|
655
|
+
case "custom":
|
|
656
|
+
break;
|
|
657
|
+
default: {
|
|
658
|
+
const exhaustive = type;
|
|
659
|
+
void exhaustive;
|
|
660
|
+
}
|
|
661
|
+
}
|
|
662
|
+
}
|
|
663
|
+
function validateTypeDefinitions(typeRegistry) {
|
|
664
|
+
const definitions = Object.values(typeRegistry);
|
|
665
|
+
assertUniqueSerializedNames(
|
|
666
|
+
definitions.map((definition) => ({
|
|
667
|
+
logicalName: definition.name,
|
|
668
|
+
serializedName: getSerializedName(definition.name, definition.metadata),
|
|
669
|
+
category: "type definition"
|
|
670
|
+
})),
|
|
671
|
+
"$defs"
|
|
672
|
+
);
|
|
673
|
+
for (const definition of definitions) {
|
|
674
|
+
validateTypeDefinition(definition);
|
|
675
|
+
}
|
|
676
|
+
}
|
|
677
|
+
function validateTypeDefinition(definition) {
|
|
678
|
+
validateTypeNode(
|
|
679
|
+
definition.type,
|
|
680
|
+
`type "${getSerializedName(definition.name, definition.metadata)}"`
|
|
681
|
+
);
|
|
682
|
+
}
|
|
683
|
+
function assertNoSerializedNameCollisions(ir) {
|
|
684
|
+
assertUniqueSerializedNames(
|
|
685
|
+
collectFlattenedFields(ir.elements).map((field) => ({
|
|
686
|
+
logicalName: field.name,
|
|
687
|
+
serializedName: getSerializedName(field.name, field.metadata),
|
|
688
|
+
category: "field"
|
|
689
|
+
})),
|
|
690
|
+
"form root"
|
|
691
|
+
);
|
|
692
|
+
for (const field of collectFlattenedFields(ir.elements)) {
|
|
693
|
+
validateTypeNode(field.type, `field "${getSerializedName(field.name, field.metadata)}"`);
|
|
694
|
+
}
|
|
695
|
+
validateTypeDefinitions(ir.typeRegistry);
|
|
696
|
+
}
|
|
697
|
+
|
|
366
698
|
// src/json-schema/ir-generator.ts
|
|
367
699
|
function makeContext(options) {
|
|
368
700
|
const vendorPrefix = options?.vendorPrefix ?? "x-formspec";
|
|
@@ -373,19 +705,33 @@ function makeContext(options) {
|
|
|
373
705
|
}
|
|
374
706
|
return {
|
|
375
707
|
defs: {},
|
|
708
|
+
typeNameMap: {},
|
|
709
|
+
typeRegistry: {},
|
|
376
710
|
extensionRegistry: options?.extensionRegistry,
|
|
377
711
|
vendorPrefix
|
|
378
712
|
};
|
|
379
713
|
}
|
|
380
714
|
function generateJsonSchemaFromIR(ir, options) {
|
|
381
|
-
|
|
715
|
+
assertNoSerializedNameCollisions(ir);
|
|
716
|
+
const ctx = {
|
|
717
|
+
...makeContext(options),
|
|
718
|
+
typeRegistry: ir.typeRegistry,
|
|
719
|
+
typeNameMap: Object.fromEntries(
|
|
720
|
+
Object.entries(ir.typeRegistry).map(([name, typeDef]) => [
|
|
721
|
+
name,
|
|
722
|
+
getSerializedName(name, typeDef.metadata)
|
|
723
|
+
])
|
|
724
|
+
)
|
|
725
|
+
};
|
|
382
726
|
for (const [name, typeDef] of Object.entries(ir.typeRegistry)) {
|
|
383
|
-
ctx.
|
|
727
|
+
const schemaName = ctx.typeNameMap[name] ?? name;
|
|
728
|
+
ctx.defs[schemaName] = generateTypeNode(typeDef.type, ctx);
|
|
729
|
+
applyResolvedMetadata(ctx.defs[schemaName], typeDef.metadata);
|
|
384
730
|
if (typeDef.constraints && typeDef.constraints.length > 0) {
|
|
385
|
-
applyConstraints(ctx.defs[
|
|
731
|
+
applyConstraints(ctx.defs[schemaName], typeDef.constraints, ctx);
|
|
386
732
|
}
|
|
387
733
|
if (typeDef.annotations && typeDef.annotations.length > 0) {
|
|
388
|
-
applyAnnotations(ctx.defs[
|
|
734
|
+
applyAnnotations(ctx.defs[schemaName], typeDef.annotations, ctx);
|
|
389
735
|
}
|
|
390
736
|
}
|
|
391
737
|
const properties = {};
|
|
@@ -398,6 +744,7 @@ function generateJsonSchemaFromIR(ir, options) {
|
|
|
398
744
|
properties,
|
|
399
745
|
...uniqueRequired.length > 0 && { required: uniqueRequired }
|
|
400
746
|
};
|
|
747
|
+
applyResolvedMetadata(result, ir.metadata);
|
|
401
748
|
if (ir.annotations && ir.annotations.length > 0) {
|
|
402
749
|
applyAnnotations(result, ir.annotations, ctx);
|
|
403
750
|
}
|
|
@@ -410,9 +757,9 @@ function collectFields(elements, properties, required, ctx) {
|
|
|
410
757
|
for (const element of elements) {
|
|
411
758
|
switch (element.kind) {
|
|
412
759
|
case "field":
|
|
413
|
-
properties[element.name] = generateFieldSchema(element, ctx);
|
|
760
|
+
properties[getSerializedName(element.name, element.metadata)] = generateFieldSchema(element, ctx);
|
|
414
761
|
if (element.required) {
|
|
415
|
-
required.push(element.name);
|
|
762
|
+
required.push(getSerializedName(element.name, element.metadata));
|
|
416
763
|
}
|
|
417
764
|
break;
|
|
418
765
|
case "group":
|
|
@@ -456,6 +803,7 @@ function generateFieldSchema(field, ctx) {
|
|
|
456
803
|
rootAnnotations.push(annotation);
|
|
457
804
|
}
|
|
458
805
|
}
|
|
806
|
+
applyResolvedMetadata(schema, field.metadata);
|
|
459
807
|
applyAnnotations(schema, rootAnnotations, ctx);
|
|
460
808
|
if (itemStringSchema !== void 0) {
|
|
461
809
|
applyAnnotations(itemStringSchema, itemAnnotations, ctx);
|
|
@@ -463,7 +811,7 @@ function generateFieldSchema(field, ctx) {
|
|
|
463
811
|
if (pathConstraints.length === 0) {
|
|
464
812
|
return schema;
|
|
465
813
|
}
|
|
466
|
-
return applyPathTargetedConstraints(schema, pathConstraints, ctx);
|
|
814
|
+
return applyPathTargetedConstraints(schema, pathConstraints, ctx, field.type);
|
|
467
815
|
}
|
|
468
816
|
function isStringItemConstraint(constraint) {
|
|
469
817
|
switch (constraint.constraintKind) {
|
|
@@ -475,9 +823,11 @@ function isStringItemConstraint(constraint) {
|
|
|
475
823
|
return false;
|
|
476
824
|
}
|
|
477
825
|
}
|
|
478
|
-
function applyPathTargetedConstraints(schema, pathConstraints, ctx) {
|
|
826
|
+
function applyPathTargetedConstraints(schema, pathConstraints, ctx, typeNode) {
|
|
479
827
|
if (schema.type === "array" && schema.items) {
|
|
480
|
-
|
|
828
|
+
const referencedType = typeNode?.kind === "reference" ? resolveReferencedType(typeNode, ctx) : void 0;
|
|
829
|
+
const nestedType = typeNode?.kind === "array" ? typeNode.items : referencedType?.kind === "array" ? referencedType.items : void 0;
|
|
830
|
+
schema.items = applyPathTargetedConstraints(schema.items, pathConstraints, ctx, nestedType);
|
|
481
831
|
return schema;
|
|
482
832
|
}
|
|
483
833
|
const byTarget = /* @__PURE__ */ new Map();
|
|
@@ -492,7 +842,7 @@ function applyPathTargetedConstraints(schema, pathConstraints, ctx) {
|
|
|
492
842
|
for (const [target, constraints] of byTarget) {
|
|
493
843
|
const subSchema = {};
|
|
494
844
|
applyConstraints(subSchema, constraints, ctx);
|
|
495
|
-
propertyOverrides[target] = subSchema;
|
|
845
|
+
propertyOverrides[resolveSerializedPropertyName(target, typeNode, ctx)] = subSchema;
|
|
496
846
|
}
|
|
497
847
|
if (schema.$ref) {
|
|
498
848
|
const { $ref, ...rest } = schema;
|
|
@@ -540,7 +890,7 @@ function generateTypeNode(type, ctx) {
|
|
|
540
890
|
case "union":
|
|
541
891
|
return generateUnionType(type, ctx);
|
|
542
892
|
case "reference":
|
|
543
|
-
return generateReferenceType(type);
|
|
893
|
+
return generateReferenceType(type, ctx);
|
|
544
894
|
case "dynamic":
|
|
545
895
|
return generateDynamicType(type);
|
|
546
896
|
case "custom":
|
|
@@ -581,9 +931,10 @@ function generateObjectType(type, ctx) {
|
|
|
581
931
|
const properties = {};
|
|
582
932
|
const required = [];
|
|
583
933
|
for (const prop of type.properties) {
|
|
584
|
-
|
|
934
|
+
const propertyName = getSerializedName(prop.name, prop.metadata);
|
|
935
|
+
properties[propertyName] = generatePropertySchema(prop, ctx);
|
|
585
936
|
if (!prop.optional) {
|
|
586
|
-
required.push(
|
|
937
|
+
required.push(propertyName);
|
|
587
938
|
}
|
|
588
939
|
}
|
|
589
940
|
const schema = { type: "object", properties };
|
|
@@ -604,6 +955,7 @@ function generateRecordType(type, ctx) {
|
|
|
604
955
|
function generatePropertySchema(prop, ctx) {
|
|
605
956
|
const schema = generateTypeNode(prop.type, ctx);
|
|
606
957
|
applyConstraints(schema, prop.constraints, ctx);
|
|
958
|
+
applyResolvedMetadata(schema, prop.metadata);
|
|
607
959
|
applyAnnotations(schema, prop.annotations, ctx);
|
|
608
960
|
return schema;
|
|
609
961
|
}
|
|
@@ -632,8 +984,28 @@ function isNullableUnion(type) {
|
|
|
632
984
|
).length;
|
|
633
985
|
return nullCount === 1;
|
|
634
986
|
}
|
|
635
|
-
function generateReferenceType(type) {
|
|
636
|
-
return { $ref: `#/$defs/${type.name}` };
|
|
987
|
+
function generateReferenceType(type, ctx) {
|
|
988
|
+
return { $ref: `#/$defs/${ctx.typeNameMap[type.name] ?? type.name}` };
|
|
989
|
+
}
|
|
990
|
+
function applyResolvedMetadata(schema, metadata) {
|
|
991
|
+
const displayName = getDisplayName(metadata);
|
|
992
|
+
if (displayName !== void 0) {
|
|
993
|
+
schema.title = displayName;
|
|
994
|
+
}
|
|
995
|
+
}
|
|
996
|
+
function resolveReferencedType(type, ctx) {
|
|
997
|
+
return ctx.typeRegistry[type.name]?.type;
|
|
998
|
+
}
|
|
999
|
+
function resolveSerializedPropertyName(logicalName, typeNode, ctx) {
|
|
1000
|
+
if (typeNode?.kind === "object") {
|
|
1001
|
+
const property = typeNode.properties.find((candidate) => candidate.name === logicalName);
|
|
1002
|
+
return property === void 0 ? logicalName : getSerializedName(property.name, property.metadata);
|
|
1003
|
+
}
|
|
1004
|
+
if (typeNode?.kind === "reference") {
|
|
1005
|
+
const referencedType = resolveReferencedType(typeNode, ctx);
|
|
1006
|
+
return referencedType === void 0 ? logicalName : resolveSerializedPropertyName(logicalName, referencedType, ctx);
|
|
1007
|
+
}
|
|
1008
|
+
return logicalName;
|
|
637
1009
|
}
|
|
638
1010
|
function generateDynamicType(type) {
|
|
639
1011
|
if (type.dynamicKind === "enum") {
|
|
@@ -713,7 +1085,7 @@ function applyAnnotations(schema, annotations, ctx) {
|
|
|
713
1085
|
for (const annotation of annotations) {
|
|
714
1086
|
switch (annotation.annotationKind) {
|
|
715
1087
|
case "displayName":
|
|
716
|
-
schema.title
|
|
1088
|
+
schema.title ??= annotation.value;
|
|
717
1089
|
break;
|
|
718
1090
|
case "description":
|
|
719
1091
|
schema.description = annotation.value;
|
|
@@ -800,7 +1172,10 @@ function assignVendorPrefixedExtensionKeywords(schema, extensionSchema, vendorPr
|
|
|
800
1172
|
|
|
801
1173
|
// src/json-schema/generator.ts
|
|
802
1174
|
function generateJsonSchema(form, options) {
|
|
803
|
-
const ir = canonicalizeChainDSL(
|
|
1175
|
+
const ir = canonicalizeChainDSL(
|
|
1176
|
+
form,
|
|
1177
|
+
options?.metadata !== void 0 ? { metadata: options.metadata } : void 0
|
|
1178
|
+
);
|
|
804
1179
|
const internalOptions = options?.vendorPrefix === void 0 ? void 0 : { vendorPrefix: options.vendorPrefix };
|
|
805
1180
|
return generateJsonSchemaFromIR(ir, internalOptions);
|
|
806
1181
|
}
|
|
@@ -970,13 +1345,21 @@ function combineRules(parentRule, childRule) {
|
|
|
970
1345
|
}
|
|
971
1346
|
};
|
|
972
1347
|
}
|
|
973
|
-
function
|
|
974
|
-
const
|
|
1348
|
+
function getFieldDisplayName(field) {
|
|
1349
|
+
const resolvedDisplayName = getDisplayName(field.metadata);
|
|
1350
|
+
if (resolvedDisplayName !== void 0) {
|
|
1351
|
+
return resolvedDisplayName;
|
|
1352
|
+
}
|
|
1353
|
+
return field.annotations.find((annotation) => annotation.annotationKind === "displayName")?.value;
|
|
1354
|
+
}
|
|
1355
|
+
function fieldNodeToControl(field, fieldNameMap, parentRule) {
|
|
975
1356
|
const placeholderAnnotation = field.annotations.find((a) => a.annotationKind === "placeholder");
|
|
1357
|
+
const serializedName = fieldNameMap.get(field.name) ?? getSerializedName(field.name, field.metadata);
|
|
1358
|
+
const displayName = getFieldDisplayName(field);
|
|
976
1359
|
const control = {
|
|
977
1360
|
type: "Control",
|
|
978
|
-
scope: fieldToScope(
|
|
979
|
-
...
|
|
1361
|
+
scope: fieldToScope(serializedName),
|
|
1362
|
+
...displayName !== void 0 && { label: displayName },
|
|
980
1363
|
...placeholderAnnotation !== void 0 && {
|
|
981
1364
|
options: { placeholder: placeholderAnnotation.value }
|
|
982
1365
|
},
|
|
@@ -984,30 +1367,30 @@ function fieldNodeToControl(field, parentRule) {
|
|
|
984
1367
|
};
|
|
985
1368
|
return control;
|
|
986
1369
|
}
|
|
987
|
-
function groupNodeToLayout(group, parentRule) {
|
|
1370
|
+
function groupNodeToLayout(group, fieldNameMap, parentRule) {
|
|
988
1371
|
return {
|
|
989
1372
|
type: "Group",
|
|
990
1373
|
label: group.label,
|
|
991
|
-
elements: irElementsToUiSchema(group.elements, parentRule),
|
|
1374
|
+
elements: irElementsToUiSchema(group.elements, fieldNameMap, parentRule),
|
|
992
1375
|
...parentRule !== void 0 && { rule: parentRule }
|
|
993
1376
|
};
|
|
994
1377
|
}
|
|
995
|
-
function irElementsToUiSchema(elements, parentRule) {
|
|
1378
|
+
function irElementsToUiSchema(elements, fieldNameMap, parentRule) {
|
|
996
1379
|
const result = [];
|
|
997
1380
|
for (const element of elements) {
|
|
998
1381
|
switch (element.kind) {
|
|
999
1382
|
case "field": {
|
|
1000
|
-
result.push(fieldNodeToControl(element, parentRule));
|
|
1383
|
+
result.push(fieldNodeToControl(element, fieldNameMap, parentRule));
|
|
1001
1384
|
break;
|
|
1002
1385
|
}
|
|
1003
1386
|
case "group": {
|
|
1004
|
-
result.push(groupNodeToLayout(element, parentRule));
|
|
1387
|
+
result.push(groupNodeToLayout(element, fieldNameMap, parentRule));
|
|
1005
1388
|
break;
|
|
1006
1389
|
}
|
|
1007
1390
|
case "conditional": {
|
|
1008
|
-
const newRule = createShowRule(element.fieldName, element.value);
|
|
1391
|
+
const newRule = createShowRule(fieldNameMap.get(element.fieldName) ?? element.fieldName, element.value);
|
|
1009
1392
|
const combinedRule = parentRule !== void 0 ? combineRules(parentRule, newRule) : newRule;
|
|
1010
|
-
const childElements = irElementsToUiSchema(element.elements, combinedRule);
|
|
1393
|
+
const childElements = irElementsToUiSchema(element.elements, fieldNameMap, combinedRule);
|
|
1011
1394
|
result.push(...childElements);
|
|
1012
1395
|
break;
|
|
1013
1396
|
}
|
|
@@ -1021,16 +1404,42 @@ function irElementsToUiSchema(elements, parentRule) {
|
|
|
1021
1404
|
return result;
|
|
1022
1405
|
}
|
|
1023
1406
|
function generateUiSchemaFromIR(ir) {
|
|
1407
|
+
assertNoSerializedNameCollisions(ir);
|
|
1408
|
+
const fieldNameMap = collectFieldNameMap(ir.elements);
|
|
1024
1409
|
const result = {
|
|
1025
1410
|
type: "VerticalLayout",
|
|
1026
|
-
elements: irElementsToUiSchema(ir.elements)
|
|
1411
|
+
elements: irElementsToUiSchema(ir.elements, fieldNameMap)
|
|
1027
1412
|
};
|
|
1028
1413
|
return parseOrThrow(uiSchema, result, "UI Schema");
|
|
1029
1414
|
}
|
|
1415
|
+
function collectFieldNameMap(elements) {
|
|
1416
|
+
const map = /* @__PURE__ */ new Map();
|
|
1417
|
+
for (const element of elements) {
|
|
1418
|
+
switch (element.kind) {
|
|
1419
|
+
case "field":
|
|
1420
|
+
map.set(element.name, getSerializedName(element.name, element.metadata));
|
|
1421
|
+
break;
|
|
1422
|
+
case "group":
|
|
1423
|
+
case "conditional":
|
|
1424
|
+
for (const [key, value] of collectFieldNameMap(element.elements)) {
|
|
1425
|
+
map.set(key, value);
|
|
1426
|
+
}
|
|
1427
|
+
break;
|
|
1428
|
+
default: {
|
|
1429
|
+
const _exhaustive = element;
|
|
1430
|
+
void _exhaustive;
|
|
1431
|
+
}
|
|
1432
|
+
}
|
|
1433
|
+
}
|
|
1434
|
+
return map;
|
|
1435
|
+
}
|
|
1030
1436
|
|
|
1031
1437
|
// src/ui-schema/generator.ts
|
|
1032
|
-
function generateUiSchema(form) {
|
|
1033
|
-
const ir = canonicalizeChainDSL(
|
|
1438
|
+
function generateUiSchema(form, options) {
|
|
1439
|
+
const ir = canonicalizeChainDSL(
|
|
1440
|
+
form,
|
|
1441
|
+
options?.metadata !== void 0 ? { metadata: options.metadata } : void 0
|
|
1442
|
+
);
|
|
1034
1443
|
return generateUiSchemaFromIR(ir);
|
|
1035
1444
|
}
|
|
1036
1445
|
|
|
@@ -1261,7 +1670,7 @@ function validateIR(ir, options) {
|
|
|
1261
1670
|
function buildFormSchemas(form, options) {
|
|
1262
1671
|
return {
|
|
1263
1672
|
jsonSchema: generateJsonSchema(form, options),
|
|
1264
|
-
uiSchema: generateUiSchema(form)
|
|
1673
|
+
uiSchema: generateUiSchema(form, options)
|
|
1265
1674
|
};
|
|
1266
1675
|
}
|
|
1267
1676
|
// Annotate the CommonJS export names for ESM import in node:
|