@formspec/build 0.1.0-alpha.40 → 0.1.0-alpha.41
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/browser.cjs +226 -17
- package/dist/browser.cjs.map +1 -1
- package/dist/browser.js +226 -17
- package/dist/browser.js.map +1 -1
- package/dist/build-alpha.d.ts +10 -0
- package/dist/build-beta.d.ts +10 -0
- package/dist/build-internal.d.ts +10 -0
- package/dist/build.d.ts +10 -0
- package/dist/canonicalize/chain-dsl-canonicalizer.d.ts.map +1 -1
- package/dist/cli.cjs +163 -27
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +163 -27
- package/dist/cli.js.map +1 -1
- package/dist/generators/class-schema.d.ts +5 -0
- package/dist/generators/class-schema.d.ts.map +1 -1
- package/dist/generators/discovered-schema.d.ts.map +1 -1
- package/dist/generators/method-schema.d.ts +9 -2
- package/dist/generators/method-schema.d.ts.map +1 -1
- package/dist/index.cjs +143 -24
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +143 -24
- package/dist/index.js.map +1 -1
- package/dist/internals.cjs +120 -27
- package/dist/internals.cjs.map +1 -1
- package/dist/internals.js +120 -27
- package/dist/internals.js.map +1 -1
- package/dist/json-schema/generator.d.ts +5 -0
- package/dist/json-schema/generator.d.ts.map +1 -1
- package/dist/json-schema/ir-generator.d.ts +5 -0
- package/dist/json-schema/ir-generator.d.ts.map +1 -1
- package/dist/metadata/policy.d.ts +3 -2
- package/dist/metadata/policy.d.ts.map +1 -1
- package/dist/metadata/resolve.d.ts +1 -0
- package/dist/metadata/resolve.d.ts.map +1 -1
- package/package.json +4 -4
package/dist/internals.cjs
CHANGED
|
@@ -106,11 +106,35 @@ function normalizeDeclarationPolicy(input) {
|
|
|
106
106
|
displayName: normalizeScalarPolicy(input?.displayName)
|
|
107
107
|
};
|
|
108
108
|
}
|
|
109
|
+
function normalizeEnumMemberDisplayNamePolicy(input) {
|
|
110
|
+
if (input?.mode === "infer-if-missing") {
|
|
111
|
+
return {
|
|
112
|
+
mode: "infer-if-missing",
|
|
113
|
+
infer: input.infer
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
if (input?.mode === "require-explicit") {
|
|
117
|
+
return {
|
|
118
|
+
mode: "require-explicit",
|
|
119
|
+
infer: () => ""
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
return {
|
|
123
|
+
mode: "disabled",
|
|
124
|
+
infer: () => ""
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
function normalizeEnumMemberPolicy(input) {
|
|
128
|
+
return {
|
|
129
|
+
displayName: normalizeEnumMemberDisplayNamePolicy(input?.displayName)
|
|
130
|
+
};
|
|
131
|
+
}
|
|
109
132
|
function normalizeMetadataPolicy(input) {
|
|
110
133
|
return {
|
|
111
134
|
type: normalizeDeclarationPolicy(input?.type),
|
|
112
135
|
field: normalizeDeclarationPolicy(input?.field),
|
|
113
|
-
method: normalizeDeclarationPolicy(input?.method)
|
|
136
|
+
method: normalizeDeclarationPolicy(input?.method),
|
|
137
|
+
enumMember: normalizeEnumMemberPolicy(input?.enumMember)
|
|
114
138
|
};
|
|
115
139
|
}
|
|
116
140
|
function getDeclarationMetadataPolicy(policy, declarationKind) {
|
|
@@ -207,6 +231,40 @@ function resolveResolvedMetadata(current, policy, context) {
|
|
|
207
231
|
...displayNamePlural !== void 0 && { displayNamePlural }
|
|
208
232
|
};
|
|
209
233
|
}
|
|
234
|
+
function resolveEnumMemberDisplayName(current, policy, context) {
|
|
235
|
+
if (current !== void 0) {
|
|
236
|
+
return current;
|
|
237
|
+
}
|
|
238
|
+
if (policy.mode === "require-explicit") {
|
|
239
|
+
throw new Error(
|
|
240
|
+
`Metadata policy requires explicit displayName for enum member "${context.logicalName}" on the ${context.surface} surface.`
|
|
241
|
+
);
|
|
242
|
+
}
|
|
243
|
+
if (policy.mode !== "infer-if-missing") {
|
|
244
|
+
return void 0;
|
|
245
|
+
}
|
|
246
|
+
const inferredValue = policy.infer(context).trim();
|
|
247
|
+
return inferredValue !== "" ? inferredValue : void 0;
|
|
248
|
+
}
|
|
249
|
+
function resolveEnumTypeMetadata(type, options) {
|
|
250
|
+
const members = type.members.map((member) => {
|
|
251
|
+
const displayName = resolveEnumMemberDisplayName(
|
|
252
|
+
member.displayName,
|
|
253
|
+
options.policy.enumMember.displayName,
|
|
254
|
+
{
|
|
255
|
+
surface: options.surface,
|
|
256
|
+
logicalName: String(member.value),
|
|
257
|
+
memberValue: member.value,
|
|
258
|
+
...options.buildContext !== void 0 && { buildContext: options.buildContext }
|
|
259
|
+
}
|
|
260
|
+
);
|
|
261
|
+
if (displayName === member.displayName) {
|
|
262
|
+
return member;
|
|
263
|
+
}
|
|
264
|
+
return displayName === void 0 ? { value: member.value } : { value: member.value, displayName };
|
|
265
|
+
});
|
|
266
|
+
return members.some((member, index) => member !== type.members[index]) ? { ...type, members } : type;
|
|
267
|
+
}
|
|
210
268
|
function resolveTypeNodeMetadata(type, options) {
|
|
211
269
|
switch (type.kind) {
|
|
212
270
|
case "array":
|
|
@@ -229,9 +287,10 @@ function resolveTypeNodeMetadata(type, options) {
|
|
|
229
287
|
...type,
|
|
230
288
|
members: type.members.map((member) => resolveTypeNodeMetadata(member, options))
|
|
231
289
|
};
|
|
290
|
+
case "enum":
|
|
291
|
+
return resolveEnumTypeMetadata(type, options);
|
|
232
292
|
case "reference":
|
|
233
293
|
case "primitive":
|
|
234
|
-
case "enum":
|
|
235
294
|
case "dynamic":
|
|
236
295
|
case "custom":
|
|
237
296
|
return type;
|
|
@@ -310,11 +369,10 @@ function getDisplayName(metadata) {
|
|
|
310
369
|
return metadata?.displayName?.value;
|
|
311
370
|
}
|
|
312
371
|
function resolveFormIRMetadata(ir, options) {
|
|
313
|
-
const
|
|
314
|
-
const metadata = resolveResolvedMetadata(ir.metadata, options.policy.type, {
|
|
372
|
+
const metadata = options.resolveRootTypeMetadata === false ? ir.metadata : resolveResolvedMetadata(ir.metadata, options.policy.type, {
|
|
315
373
|
surface: options.surface,
|
|
316
374
|
declarationKind: "type",
|
|
317
|
-
logicalName: rootLogicalName,
|
|
375
|
+
logicalName: options.rootLogicalName ?? ir.name ?? "FormSpec",
|
|
318
376
|
...options.buildContext !== void 0 && { buildContext: options.buildContext }
|
|
319
377
|
});
|
|
320
378
|
return {
|
|
@@ -350,7 +408,7 @@ function canonicalizeChainDSL(form, options) {
|
|
|
350
408
|
const metadataPolicy = normalizeMetadataPolicy(
|
|
351
409
|
options?.metadata ?? (0, import_internals._getFormSpecMetadataPolicy)(form)
|
|
352
410
|
);
|
|
353
|
-
|
|
411
|
+
const ir = {
|
|
354
412
|
kind: "form-ir",
|
|
355
413
|
irVersion: import_internals.IR_VERSION,
|
|
356
414
|
elements: canonicalizeElements(form.elements, metadataPolicy),
|
|
@@ -358,6 +416,13 @@ function canonicalizeChainDSL(form, options) {
|
|
|
358
416
|
typeRegistry: {},
|
|
359
417
|
provenance: CHAIN_DSL_PROVENANCE
|
|
360
418
|
};
|
|
419
|
+
return resolveFormIRMetadata(ir, {
|
|
420
|
+
policy: metadataPolicy,
|
|
421
|
+
surface: "chain-dsl",
|
|
422
|
+
// Chain DSL has no root/type-metadata authoring surface, so only resolve
|
|
423
|
+
// field/type-registry metadata and enum-member labels here.
|
|
424
|
+
resolveRootTypeMetadata: false
|
|
425
|
+
});
|
|
361
426
|
}
|
|
362
427
|
function canonicalizeElements(elements, metadataPolicy) {
|
|
363
428
|
return elements.map((element) => canonicalizeElement(element, metadataPolicy));
|
|
@@ -4197,17 +4262,25 @@ function assertNoSerializedNameCollisions(ir) {
|
|
|
4197
4262
|
// src/json-schema/ir-generator.ts
|
|
4198
4263
|
function makeContext(options) {
|
|
4199
4264
|
const vendorPrefix = options?.vendorPrefix ?? "x-formspec";
|
|
4265
|
+
const rawEnumSerialization = options?.enumSerialization;
|
|
4200
4266
|
if (!vendorPrefix.startsWith("x-")) {
|
|
4201
4267
|
throw new Error(
|
|
4202
4268
|
`Invalid vendorPrefix "${vendorPrefix}". Extension JSON Schema keywords must start with "x-".`
|
|
4203
4269
|
);
|
|
4204
4270
|
}
|
|
4271
|
+
if (rawEnumSerialization !== void 0 && rawEnumSerialization !== "enum" && rawEnumSerialization !== "oneOf") {
|
|
4272
|
+
throw new Error(
|
|
4273
|
+
`Invalid enumSerialization "${rawEnumSerialization}". Expected "enum" or "oneOf".`
|
|
4274
|
+
);
|
|
4275
|
+
}
|
|
4276
|
+
const enumSerialization = rawEnumSerialization ?? "enum";
|
|
4205
4277
|
return {
|
|
4206
4278
|
defs: {},
|
|
4207
4279
|
typeNameMap: {},
|
|
4208
4280
|
typeRegistry: {},
|
|
4209
4281
|
extensionRegistry: options?.extensionRegistry,
|
|
4210
|
-
vendorPrefix
|
|
4282
|
+
vendorPrefix,
|
|
4283
|
+
enumSerialization
|
|
4211
4284
|
};
|
|
4212
4285
|
}
|
|
4213
4286
|
function generateJsonSchemaFromIR(ir, options) {
|
|
@@ -4381,7 +4454,7 @@ function generateTypeNode(type, ctx) {
|
|
|
4381
4454
|
case "primitive":
|
|
4382
4455
|
return generatePrimitiveType(type);
|
|
4383
4456
|
case "enum":
|
|
4384
|
-
return generateEnumType(type);
|
|
4457
|
+
return generateEnumType(type, ctx);
|
|
4385
4458
|
case "array":
|
|
4386
4459
|
return generateArrayType(type, ctx);
|
|
4387
4460
|
case "object":
|
|
@@ -4407,20 +4480,37 @@ function generatePrimitiveType(type) {
|
|
|
4407
4480
|
type: type.primitiveKind === "integer" || type.primitiveKind === "bigint" ? "integer" : type.primitiveKind
|
|
4408
4481
|
};
|
|
4409
4482
|
}
|
|
4410
|
-
function generateEnumType(type) {
|
|
4411
|
-
|
|
4412
|
-
if (hasDisplayNames) {
|
|
4483
|
+
function generateEnumType(type, ctx) {
|
|
4484
|
+
if (ctx.enumSerialization === "oneOf") {
|
|
4413
4485
|
return {
|
|
4414
|
-
oneOf: type.members.map((m) => {
|
|
4415
|
-
const
|
|
4416
|
-
|
|
4417
|
-
|
|
4418
|
-
}
|
|
4419
|
-
return entry;
|
|
4420
|
-
})
|
|
4486
|
+
oneOf: type.members.map((m) => ({
|
|
4487
|
+
const: m.value,
|
|
4488
|
+
title: m.displayName ?? String(m.value)
|
|
4489
|
+
}))
|
|
4421
4490
|
};
|
|
4422
4491
|
}
|
|
4423
|
-
|
|
4492
|
+
const schema = { enum: type.members.map((m) => m.value) };
|
|
4493
|
+
const displayNames = buildEnumDisplayNameExtension(type);
|
|
4494
|
+
if (displayNames !== void 0) {
|
|
4495
|
+
schema[`${ctx.vendorPrefix}-display-names`] = displayNames;
|
|
4496
|
+
}
|
|
4497
|
+
return schema;
|
|
4498
|
+
}
|
|
4499
|
+
function buildEnumDisplayNameExtension(type) {
|
|
4500
|
+
if (!type.members.some((member) => member.displayName !== void 0)) {
|
|
4501
|
+
return void 0;
|
|
4502
|
+
}
|
|
4503
|
+
const displayNames = /* @__PURE__ */ Object.create(null);
|
|
4504
|
+
for (const member of type.members) {
|
|
4505
|
+
const key = String(member.value);
|
|
4506
|
+
if (Object.hasOwn(displayNames, key)) {
|
|
4507
|
+
throw new Error(
|
|
4508
|
+
`Enum display-name key "${key}" is ambiguous after stringification. Use oneOf serialization for mixed string/number enum values that collide.`
|
|
4509
|
+
);
|
|
4510
|
+
}
|
|
4511
|
+
displayNames[key] = member.displayName ?? key;
|
|
4512
|
+
}
|
|
4513
|
+
return displayNames;
|
|
4424
4514
|
}
|
|
4425
4515
|
function generateArrayType(type, ctx) {
|
|
4426
4516
|
return {
|
|
@@ -5337,7 +5427,7 @@ function createExtensionRegistry(extensions) {
|
|
|
5337
5427
|
|
|
5338
5428
|
// src/generators/method-schema.ts
|
|
5339
5429
|
var import_internals6 = require("@formspec/core/internals");
|
|
5340
|
-
function typeToJsonSchema(type, checker) {
|
|
5430
|
+
function typeToJsonSchema(type, checker, options) {
|
|
5341
5431
|
const typeRegistry = {};
|
|
5342
5432
|
const visiting = /* @__PURE__ */ new Set();
|
|
5343
5433
|
const diagnostics = [];
|
|
@@ -5377,7 +5467,10 @@ function typeToJsonSchema(type, checker) {
|
|
|
5377
5467
|
typeRegistry,
|
|
5378
5468
|
provenance: fieldProvenance
|
|
5379
5469
|
};
|
|
5380
|
-
const schema = generateJsonSchemaFromIR(
|
|
5470
|
+
const schema = generateJsonSchemaFromIR(
|
|
5471
|
+
ir,
|
|
5472
|
+
options?.enumSerialization === void 0 ? void 0 : { enumSerialization: options.enumSerialization }
|
|
5473
|
+
);
|
|
5381
5474
|
const fieldSchema = schema.properties?.["__result"];
|
|
5382
5475
|
if (fieldSchema) {
|
|
5383
5476
|
if (schema.$defs && Object.keys(schema.$defs).length > 0) {
|
|
@@ -5387,16 +5480,16 @@ function typeToJsonSchema(type, checker) {
|
|
|
5387
5480
|
}
|
|
5388
5481
|
return { type: "object" };
|
|
5389
5482
|
}
|
|
5390
|
-
function generateMethodSchemas(method, checker, loadedFormSpecs) {
|
|
5391
|
-
const returnType = typeToJsonSchema(method.returnType, checker);
|
|
5392
|
-
const params = generateParamsSchemas(method.parameters, checker, loadedFormSpecs);
|
|
5483
|
+
function generateMethodSchemas(method, checker, loadedFormSpecs, options) {
|
|
5484
|
+
const returnType = typeToJsonSchema(method.returnType, checker, options);
|
|
5485
|
+
const params = generateParamsSchemas(method.parameters, checker, loadedFormSpecs, options);
|
|
5393
5486
|
return {
|
|
5394
5487
|
name: method.name,
|
|
5395
5488
|
params,
|
|
5396
5489
|
returnType
|
|
5397
5490
|
};
|
|
5398
5491
|
}
|
|
5399
|
-
function generateParamsSchemas(parameters, checker, loadedFormSpecs) {
|
|
5492
|
+
function generateParamsSchemas(parameters, checker, loadedFormSpecs, options) {
|
|
5400
5493
|
if (parameters.length === 0) {
|
|
5401
5494
|
return null;
|
|
5402
5495
|
}
|
|
@@ -5417,7 +5510,7 @@ function generateParamsSchemas(parameters, checker, loadedFormSpecs) {
|
|
|
5417
5510
|
}
|
|
5418
5511
|
if (parameters.length === 1 && parameters[0]) {
|
|
5419
5512
|
const param = parameters[0];
|
|
5420
|
-
const jsonSchema = typeToJsonSchema(param.type, checker);
|
|
5513
|
+
const jsonSchema = typeToJsonSchema(param.type, checker, options);
|
|
5421
5514
|
return {
|
|
5422
5515
|
jsonSchema,
|
|
5423
5516
|
uiSchema: null,
|
|
@@ -5427,7 +5520,7 @@ function generateParamsSchemas(parameters, checker, loadedFormSpecs) {
|
|
|
5427
5520
|
const properties = {};
|
|
5428
5521
|
const required = [];
|
|
5429
5522
|
for (const param of parameters) {
|
|
5430
|
-
const paramSchema = typeToJsonSchema(param.type, checker);
|
|
5523
|
+
const paramSchema = typeToJsonSchema(param.type, checker, options);
|
|
5431
5524
|
properties[param.name] = paramSchema;
|
|
5432
5525
|
if (!param.optional) {
|
|
5433
5526
|
required.push(param.name);
|