@formspec/build 0.1.0-alpha.30 → 0.1.0-alpha.31
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 +166 -24
- package/dist/browser.cjs.map +1 -1
- package/dist/browser.js +166 -24
- package/dist/browser.js.map +1 -1
- package/dist/cli.cjs +166 -24
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +166 -24
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +166 -24
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +166 -24
- package/dist/index.js.map +1 -1
- package/dist/internals.cjs +166 -24
- package/dist/internals.cjs.map +1 -1
- package/dist/internals.js +166 -24
- package/dist/internals.js.map +1 -1
- package/package.json +1 -1
package/dist/cli.cjs
CHANGED
|
@@ -1012,9 +1012,9 @@ function collectFields(elements, properties, required, ctx) {
|
|
|
1012
1012
|
for (const element of elements) {
|
|
1013
1013
|
switch (element.kind) {
|
|
1014
1014
|
case "field":
|
|
1015
|
-
properties[
|
|
1015
|
+
properties[getSerializedFieldName(element)] = generateFieldSchema(element, ctx);
|
|
1016
1016
|
if (element.required) {
|
|
1017
|
-
required.push(
|
|
1017
|
+
required.push(getSerializedFieldName(element));
|
|
1018
1018
|
}
|
|
1019
1019
|
break;
|
|
1020
1020
|
case "group":
|
|
@@ -1085,19 +1085,21 @@ function applyPathTargetedConstraints(schema, pathConstraints, ctx, typeNode) {
|
|
|
1085
1085
|
schema.items = applyPathTargetedConstraints(schema.items, pathConstraints, ctx, nestedType);
|
|
1086
1086
|
return schema;
|
|
1087
1087
|
}
|
|
1088
|
-
const
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1088
|
+
const propertyOverrides = buildPropertyOverrides(pathConstraints, typeNode, ctx);
|
|
1089
|
+
const nullableValueBranch = getNullableUnionValueSchema(schema);
|
|
1090
|
+
if (nullableValueBranch !== void 0) {
|
|
1091
|
+
const updatedNullableValueBranch = applyPathTargetedConstraints(
|
|
1092
|
+
nullableValueBranch,
|
|
1093
|
+
pathConstraints,
|
|
1094
|
+
ctx,
|
|
1095
|
+
resolveTraversableTypeNode(typeNode, ctx)
|
|
1096
|
+
);
|
|
1097
|
+
if (schema.oneOf !== void 0) {
|
|
1098
|
+
schema.oneOf = schema.oneOf.map(
|
|
1099
|
+
(branch) => branch === nullableValueBranch ? updatedNullableValueBranch : branch
|
|
1100
|
+
);
|
|
1101
|
+
}
|
|
1102
|
+
return schema;
|
|
1101
1103
|
}
|
|
1102
1104
|
if (schema.$ref) {
|
|
1103
1105
|
const { $ref, ...rest } = schema;
|
|
@@ -1112,7 +1114,7 @@ function applyPathTargetedConstraints(schema, pathConstraints, ctx, typeNode) {
|
|
|
1112
1114
|
const missingOverrides = {};
|
|
1113
1115
|
for (const [target, overrideSchema] of Object.entries(propertyOverrides)) {
|
|
1114
1116
|
if (schema.properties[target]) {
|
|
1115
|
-
|
|
1117
|
+
mergeSchemaOverride(schema.properties[target], overrideSchema);
|
|
1116
1118
|
} else {
|
|
1117
1119
|
missingOverrides[target] = overrideSchema;
|
|
1118
1120
|
}
|
|
@@ -1186,7 +1188,7 @@ function generateObjectType(type, ctx) {
|
|
|
1186
1188
|
const properties = {};
|
|
1187
1189
|
const required = [];
|
|
1188
1190
|
for (const prop of type.properties) {
|
|
1189
|
-
const propertyName =
|
|
1191
|
+
const propertyName = getSerializedObjectPropertyName(prop);
|
|
1190
1192
|
properties[propertyName] = generatePropertySchema(prop, ctx);
|
|
1191
1193
|
if (!prop.optional) {
|
|
1192
1194
|
required.push(propertyName);
|
|
@@ -1240,7 +1242,16 @@ function isNullableUnion(type) {
|
|
|
1240
1242
|
return nullCount === 1;
|
|
1241
1243
|
}
|
|
1242
1244
|
function generateReferenceType(type, ctx) {
|
|
1243
|
-
return { $ref: `#/$defs/${
|
|
1245
|
+
return { $ref: `#/$defs/${getSerializedTypeName(type.name, ctx)}` };
|
|
1246
|
+
}
|
|
1247
|
+
function getSerializedFieldName(field) {
|
|
1248
|
+
return getSerializedName(field.name, field.metadata);
|
|
1249
|
+
}
|
|
1250
|
+
function getSerializedObjectPropertyName(property) {
|
|
1251
|
+
return getSerializedName(property.name, property.metadata);
|
|
1252
|
+
}
|
|
1253
|
+
function getSerializedTypeName(logicalName, ctx) {
|
|
1254
|
+
return ctx.typeNameMap[logicalName] ?? logicalName;
|
|
1244
1255
|
}
|
|
1245
1256
|
function applyResolvedMetadata(schema, metadata) {
|
|
1246
1257
|
const displayName = getDisplayName(metadata);
|
|
@@ -1251,17 +1262,148 @@ function applyResolvedMetadata(schema, metadata) {
|
|
|
1251
1262
|
function resolveReferencedType(type, ctx) {
|
|
1252
1263
|
return ctx.typeRegistry[type.name]?.type;
|
|
1253
1264
|
}
|
|
1265
|
+
function dereferenceTypeNode(typeNode, ctx) {
|
|
1266
|
+
if (typeNode?.kind !== "reference") {
|
|
1267
|
+
return typeNode;
|
|
1268
|
+
}
|
|
1269
|
+
return resolveReferencedType(typeNode, ctx);
|
|
1270
|
+
}
|
|
1271
|
+
function unwrapNullableTypeNode(typeNode) {
|
|
1272
|
+
if (typeNode?.kind !== "union" || !isNullableUnion(typeNode)) {
|
|
1273
|
+
return typeNode;
|
|
1274
|
+
}
|
|
1275
|
+
return typeNode.members.find(
|
|
1276
|
+
(member) => !(member.kind === "primitive" && member.primitiveKind === "null")
|
|
1277
|
+
);
|
|
1278
|
+
}
|
|
1279
|
+
function resolveTraversableTypeNode(typeNode, ctx) {
|
|
1280
|
+
const dereferenced = dereferenceTypeNode(typeNode, ctx);
|
|
1281
|
+
const unwrapped = unwrapNullableTypeNode(dereferenced);
|
|
1282
|
+
if (unwrapped !== dereferenced) {
|
|
1283
|
+
return resolveTraversableTypeNode(unwrapped, ctx);
|
|
1284
|
+
}
|
|
1285
|
+
return dereferenced;
|
|
1286
|
+
}
|
|
1254
1287
|
function resolveSerializedPropertyName(logicalName, typeNode, ctx) {
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
return
|
|
1288
|
+
const effectiveType = resolveTraversableTypeNode(typeNode, ctx);
|
|
1289
|
+
if (effectiveType?.kind === "array") {
|
|
1290
|
+
return resolveSerializedPropertyName(logicalName, effectiveType.items, ctx);
|
|
1258
1291
|
}
|
|
1259
|
-
if (
|
|
1260
|
-
const
|
|
1261
|
-
return
|
|
1292
|
+
if (effectiveType?.kind === "object") {
|
|
1293
|
+
const property = effectiveType.properties.find((candidate) => candidate.name === logicalName);
|
|
1294
|
+
return property === void 0 ? logicalName : getSerializedObjectPropertyName(property);
|
|
1262
1295
|
}
|
|
1263
1296
|
return logicalName;
|
|
1264
1297
|
}
|
|
1298
|
+
function resolveTargetTypeNode(logicalName, typeNode, ctx) {
|
|
1299
|
+
const effectiveType = resolveTraversableTypeNode(typeNode, ctx);
|
|
1300
|
+
if (effectiveType?.kind === "array") {
|
|
1301
|
+
return resolveTargetTypeNode(logicalName, effectiveType.items, ctx);
|
|
1302
|
+
}
|
|
1303
|
+
if (effectiveType?.kind !== "object") {
|
|
1304
|
+
return void 0;
|
|
1305
|
+
}
|
|
1306
|
+
return effectiveType.properties.find((candidate) => candidate.name === logicalName)?.type;
|
|
1307
|
+
}
|
|
1308
|
+
function buildPropertyOverrides(pathConstraints, typeNode, ctx) {
|
|
1309
|
+
const byTarget = /* @__PURE__ */ new Map();
|
|
1310
|
+
for (const constraint of pathConstraints) {
|
|
1311
|
+
const target = constraint.path?.segments[0];
|
|
1312
|
+
if (!target) {
|
|
1313
|
+
continue;
|
|
1314
|
+
}
|
|
1315
|
+
const grouped = byTarget.get(target) ?? [];
|
|
1316
|
+
grouped.push(constraint);
|
|
1317
|
+
byTarget.set(target, grouped);
|
|
1318
|
+
}
|
|
1319
|
+
const overrides = {};
|
|
1320
|
+
for (const [target, constraints] of byTarget) {
|
|
1321
|
+
overrides[resolveSerializedPropertyName(target, typeNode, ctx)] = buildPathOverrideSchema(
|
|
1322
|
+
constraints.map(stripLeadingPathSegment),
|
|
1323
|
+
resolveTargetTypeNode(target, typeNode, ctx),
|
|
1324
|
+
ctx
|
|
1325
|
+
);
|
|
1326
|
+
}
|
|
1327
|
+
return overrides;
|
|
1328
|
+
}
|
|
1329
|
+
function buildPathOverrideSchema(constraints, typeNode, ctx) {
|
|
1330
|
+
const schema = {};
|
|
1331
|
+
const directConstraints = [];
|
|
1332
|
+
const nestedConstraints = [];
|
|
1333
|
+
for (const constraint of constraints) {
|
|
1334
|
+
if (constraint.path === void 0 || constraint.path.segments.length === 0) {
|
|
1335
|
+
directConstraints.push(constraint);
|
|
1336
|
+
} else {
|
|
1337
|
+
nestedConstraints.push(constraint);
|
|
1338
|
+
}
|
|
1339
|
+
}
|
|
1340
|
+
applyConstraints(schema, directConstraints, ctx);
|
|
1341
|
+
if (nestedConstraints.length === 0) {
|
|
1342
|
+
return schema;
|
|
1343
|
+
}
|
|
1344
|
+
const effectiveType = resolveTraversableTypeNode(typeNode, ctx);
|
|
1345
|
+
if (effectiveType?.kind === "array") {
|
|
1346
|
+
schema.items = buildPathOverrideSchema(nestedConstraints, effectiveType.items, ctx);
|
|
1347
|
+
return schema;
|
|
1348
|
+
}
|
|
1349
|
+
schema.properties = buildPropertyOverrides(nestedConstraints, effectiveType, ctx);
|
|
1350
|
+
return schema;
|
|
1351
|
+
}
|
|
1352
|
+
function mergeSchemaOverride(target, override) {
|
|
1353
|
+
const nullableValueBranch = getNullableUnionValueSchema(target);
|
|
1354
|
+
if (nullableValueBranch !== void 0) {
|
|
1355
|
+
mergeSchemaOverride(nullableValueBranch, override);
|
|
1356
|
+
return;
|
|
1357
|
+
}
|
|
1358
|
+
if (override.properties !== void 0) {
|
|
1359
|
+
const mergedProperties = target.properties ?? {};
|
|
1360
|
+
for (const [name, propertyOverride] of Object.entries(override.properties)) {
|
|
1361
|
+
const existing = mergedProperties[name];
|
|
1362
|
+
if (existing === void 0) {
|
|
1363
|
+
mergedProperties[name] = propertyOverride;
|
|
1364
|
+
} else {
|
|
1365
|
+
mergeSchemaOverride(existing, propertyOverride);
|
|
1366
|
+
}
|
|
1367
|
+
}
|
|
1368
|
+
target.properties = mergedProperties;
|
|
1369
|
+
}
|
|
1370
|
+
if (override.items !== void 0) {
|
|
1371
|
+
if (target.items === void 0) {
|
|
1372
|
+
target.items = override.items;
|
|
1373
|
+
} else {
|
|
1374
|
+
mergeSchemaOverride(target.items, override.items);
|
|
1375
|
+
}
|
|
1376
|
+
}
|
|
1377
|
+
for (const [key, value] of Object.entries(override)) {
|
|
1378
|
+
if (key === "properties" || key === "items") {
|
|
1379
|
+
continue;
|
|
1380
|
+
}
|
|
1381
|
+
target[key] = value;
|
|
1382
|
+
}
|
|
1383
|
+
}
|
|
1384
|
+
function stripLeadingPathSegment(constraint) {
|
|
1385
|
+
const segments = constraint.path?.segments;
|
|
1386
|
+
if (segments === void 0 || segments.length === 0) {
|
|
1387
|
+
return constraint;
|
|
1388
|
+
}
|
|
1389
|
+
const [, ...rest] = segments;
|
|
1390
|
+
if (rest.length === 0) {
|
|
1391
|
+
const { path: _path, ...stripped } = constraint;
|
|
1392
|
+
return stripped;
|
|
1393
|
+
}
|
|
1394
|
+
return {
|
|
1395
|
+
...constraint,
|
|
1396
|
+
path: { segments: rest }
|
|
1397
|
+
};
|
|
1398
|
+
}
|
|
1399
|
+
function getNullableUnionValueSchema(schema) {
|
|
1400
|
+
if (schema.oneOf?.length !== 2) {
|
|
1401
|
+
return void 0;
|
|
1402
|
+
}
|
|
1403
|
+
const valueSchema = schema.oneOf.find((branch) => branch.type !== "null");
|
|
1404
|
+
const nullSchema = schema.oneOf.find((branch) => branch.type === "null");
|
|
1405
|
+
return valueSchema !== void 0 && nullSchema !== void 0 ? valueSchema : void 0;
|
|
1406
|
+
}
|
|
1265
1407
|
function generateDynamicType(type) {
|
|
1266
1408
|
if (type.dynamicKind === "enum") {
|
|
1267
1409
|
const schema = {
|