@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.js
CHANGED
|
@@ -990,9 +990,9 @@ function collectFields(elements, properties, required, ctx) {
|
|
|
990
990
|
for (const element of elements) {
|
|
991
991
|
switch (element.kind) {
|
|
992
992
|
case "field":
|
|
993
|
-
properties[
|
|
993
|
+
properties[getSerializedFieldName(element)] = generateFieldSchema(element, ctx);
|
|
994
994
|
if (element.required) {
|
|
995
|
-
required.push(
|
|
995
|
+
required.push(getSerializedFieldName(element));
|
|
996
996
|
}
|
|
997
997
|
break;
|
|
998
998
|
case "group":
|
|
@@ -1063,19 +1063,21 @@ function applyPathTargetedConstraints(schema, pathConstraints, ctx, typeNode) {
|
|
|
1063
1063
|
schema.items = applyPathTargetedConstraints(schema.items, pathConstraints, ctx, nestedType);
|
|
1064
1064
|
return schema;
|
|
1065
1065
|
}
|
|
1066
|
-
const
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1066
|
+
const propertyOverrides = buildPropertyOverrides(pathConstraints, typeNode, ctx);
|
|
1067
|
+
const nullableValueBranch = getNullableUnionValueSchema(schema);
|
|
1068
|
+
if (nullableValueBranch !== void 0) {
|
|
1069
|
+
const updatedNullableValueBranch = applyPathTargetedConstraints(
|
|
1070
|
+
nullableValueBranch,
|
|
1071
|
+
pathConstraints,
|
|
1072
|
+
ctx,
|
|
1073
|
+
resolveTraversableTypeNode(typeNode, ctx)
|
|
1074
|
+
);
|
|
1075
|
+
if (schema.oneOf !== void 0) {
|
|
1076
|
+
schema.oneOf = schema.oneOf.map(
|
|
1077
|
+
(branch) => branch === nullableValueBranch ? updatedNullableValueBranch : branch
|
|
1078
|
+
);
|
|
1079
|
+
}
|
|
1080
|
+
return schema;
|
|
1079
1081
|
}
|
|
1080
1082
|
if (schema.$ref) {
|
|
1081
1083
|
const { $ref, ...rest } = schema;
|
|
@@ -1090,7 +1092,7 @@ function applyPathTargetedConstraints(schema, pathConstraints, ctx, typeNode) {
|
|
|
1090
1092
|
const missingOverrides = {};
|
|
1091
1093
|
for (const [target, overrideSchema] of Object.entries(propertyOverrides)) {
|
|
1092
1094
|
if (schema.properties[target]) {
|
|
1093
|
-
|
|
1095
|
+
mergeSchemaOverride(schema.properties[target], overrideSchema);
|
|
1094
1096
|
} else {
|
|
1095
1097
|
missingOverrides[target] = overrideSchema;
|
|
1096
1098
|
}
|
|
@@ -1164,7 +1166,7 @@ function generateObjectType(type, ctx) {
|
|
|
1164
1166
|
const properties = {};
|
|
1165
1167
|
const required = [];
|
|
1166
1168
|
for (const prop of type.properties) {
|
|
1167
|
-
const propertyName =
|
|
1169
|
+
const propertyName = getSerializedObjectPropertyName(prop);
|
|
1168
1170
|
properties[propertyName] = generatePropertySchema(prop, ctx);
|
|
1169
1171
|
if (!prop.optional) {
|
|
1170
1172
|
required.push(propertyName);
|
|
@@ -1218,7 +1220,16 @@ function isNullableUnion(type) {
|
|
|
1218
1220
|
return nullCount === 1;
|
|
1219
1221
|
}
|
|
1220
1222
|
function generateReferenceType(type, ctx) {
|
|
1221
|
-
return { $ref: `#/$defs/${
|
|
1223
|
+
return { $ref: `#/$defs/${getSerializedTypeName(type.name, ctx)}` };
|
|
1224
|
+
}
|
|
1225
|
+
function getSerializedFieldName(field) {
|
|
1226
|
+
return getSerializedName(field.name, field.metadata);
|
|
1227
|
+
}
|
|
1228
|
+
function getSerializedObjectPropertyName(property) {
|
|
1229
|
+
return getSerializedName(property.name, property.metadata);
|
|
1230
|
+
}
|
|
1231
|
+
function getSerializedTypeName(logicalName, ctx) {
|
|
1232
|
+
return ctx.typeNameMap[logicalName] ?? logicalName;
|
|
1222
1233
|
}
|
|
1223
1234
|
function applyResolvedMetadata(schema, metadata) {
|
|
1224
1235
|
const displayName = getDisplayName(metadata);
|
|
@@ -1229,17 +1240,148 @@ function applyResolvedMetadata(schema, metadata) {
|
|
|
1229
1240
|
function resolveReferencedType(type, ctx) {
|
|
1230
1241
|
return ctx.typeRegistry[type.name]?.type;
|
|
1231
1242
|
}
|
|
1243
|
+
function dereferenceTypeNode(typeNode, ctx) {
|
|
1244
|
+
if (typeNode?.kind !== "reference") {
|
|
1245
|
+
return typeNode;
|
|
1246
|
+
}
|
|
1247
|
+
return resolveReferencedType(typeNode, ctx);
|
|
1248
|
+
}
|
|
1249
|
+
function unwrapNullableTypeNode(typeNode) {
|
|
1250
|
+
if (typeNode?.kind !== "union" || !isNullableUnion(typeNode)) {
|
|
1251
|
+
return typeNode;
|
|
1252
|
+
}
|
|
1253
|
+
return typeNode.members.find(
|
|
1254
|
+
(member) => !(member.kind === "primitive" && member.primitiveKind === "null")
|
|
1255
|
+
);
|
|
1256
|
+
}
|
|
1257
|
+
function resolveTraversableTypeNode(typeNode, ctx) {
|
|
1258
|
+
const dereferenced = dereferenceTypeNode(typeNode, ctx);
|
|
1259
|
+
const unwrapped = unwrapNullableTypeNode(dereferenced);
|
|
1260
|
+
if (unwrapped !== dereferenced) {
|
|
1261
|
+
return resolveTraversableTypeNode(unwrapped, ctx);
|
|
1262
|
+
}
|
|
1263
|
+
return dereferenced;
|
|
1264
|
+
}
|
|
1232
1265
|
function resolveSerializedPropertyName(logicalName, typeNode, ctx) {
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
return
|
|
1266
|
+
const effectiveType = resolveTraversableTypeNode(typeNode, ctx);
|
|
1267
|
+
if (effectiveType?.kind === "array") {
|
|
1268
|
+
return resolveSerializedPropertyName(logicalName, effectiveType.items, ctx);
|
|
1236
1269
|
}
|
|
1237
|
-
if (
|
|
1238
|
-
const
|
|
1239
|
-
return
|
|
1270
|
+
if (effectiveType?.kind === "object") {
|
|
1271
|
+
const property = effectiveType.properties.find((candidate) => candidate.name === logicalName);
|
|
1272
|
+
return property === void 0 ? logicalName : getSerializedObjectPropertyName(property);
|
|
1240
1273
|
}
|
|
1241
1274
|
return logicalName;
|
|
1242
1275
|
}
|
|
1276
|
+
function resolveTargetTypeNode(logicalName, typeNode, ctx) {
|
|
1277
|
+
const effectiveType = resolveTraversableTypeNode(typeNode, ctx);
|
|
1278
|
+
if (effectiveType?.kind === "array") {
|
|
1279
|
+
return resolveTargetTypeNode(logicalName, effectiveType.items, ctx);
|
|
1280
|
+
}
|
|
1281
|
+
if (effectiveType?.kind !== "object") {
|
|
1282
|
+
return void 0;
|
|
1283
|
+
}
|
|
1284
|
+
return effectiveType.properties.find((candidate) => candidate.name === logicalName)?.type;
|
|
1285
|
+
}
|
|
1286
|
+
function buildPropertyOverrides(pathConstraints, typeNode, ctx) {
|
|
1287
|
+
const byTarget = /* @__PURE__ */ new Map();
|
|
1288
|
+
for (const constraint of pathConstraints) {
|
|
1289
|
+
const target = constraint.path?.segments[0];
|
|
1290
|
+
if (!target) {
|
|
1291
|
+
continue;
|
|
1292
|
+
}
|
|
1293
|
+
const grouped = byTarget.get(target) ?? [];
|
|
1294
|
+
grouped.push(constraint);
|
|
1295
|
+
byTarget.set(target, grouped);
|
|
1296
|
+
}
|
|
1297
|
+
const overrides = {};
|
|
1298
|
+
for (const [target, constraints] of byTarget) {
|
|
1299
|
+
overrides[resolveSerializedPropertyName(target, typeNode, ctx)] = buildPathOverrideSchema(
|
|
1300
|
+
constraints.map(stripLeadingPathSegment),
|
|
1301
|
+
resolveTargetTypeNode(target, typeNode, ctx),
|
|
1302
|
+
ctx
|
|
1303
|
+
);
|
|
1304
|
+
}
|
|
1305
|
+
return overrides;
|
|
1306
|
+
}
|
|
1307
|
+
function buildPathOverrideSchema(constraints, typeNode, ctx) {
|
|
1308
|
+
const schema = {};
|
|
1309
|
+
const directConstraints = [];
|
|
1310
|
+
const nestedConstraints = [];
|
|
1311
|
+
for (const constraint of constraints) {
|
|
1312
|
+
if (constraint.path === void 0 || constraint.path.segments.length === 0) {
|
|
1313
|
+
directConstraints.push(constraint);
|
|
1314
|
+
} else {
|
|
1315
|
+
nestedConstraints.push(constraint);
|
|
1316
|
+
}
|
|
1317
|
+
}
|
|
1318
|
+
applyConstraints(schema, directConstraints, ctx);
|
|
1319
|
+
if (nestedConstraints.length === 0) {
|
|
1320
|
+
return schema;
|
|
1321
|
+
}
|
|
1322
|
+
const effectiveType = resolveTraversableTypeNode(typeNode, ctx);
|
|
1323
|
+
if (effectiveType?.kind === "array") {
|
|
1324
|
+
schema.items = buildPathOverrideSchema(nestedConstraints, effectiveType.items, ctx);
|
|
1325
|
+
return schema;
|
|
1326
|
+
}
|
|
1327
|
+
schema.properties = buildPropertyOverrides(nestedConstraints, effectiveType, ctx);
|
|
1328
|
+
return schema;
|
|
1329
|
+
}
|
|
1330
|
+
function mergeSchemaOverride(target, override) {
|
|
1331
|
+
const nullableValueBranch = getNullableUnionValueSchema(target);
|
|
1332
|
+
if (nullableValueBranch !== void 0) {
|
|
1333
|
+
mergeSchemaOverride(nullableValueBranch, override);
|
|
1334
|
+
return;
|
|
1335
|
+
}
|
|
1336
|
+
if (override.properties !== void 0) {
|
|
1337
|
+
const mergedProperties = target.properties ?? {};
|
|
1338
|
+
for (const [name, propertyOverride] of Object.entries(override.properties)) {
|
|
1339
|
+
const existing = mergedProperties[name];
|
|
1340
|
+
if (existing === void 0) {
|
|
1341
|
+
mergedProperties[name] = propertyOverride;
|
|
1342
|
+
} else {
|
|
1343
|
+
mergeSchemaOverride(existing, propertyOverride);
|
|
1344
|
+
}
|
|
1345
|
+
}
|
|
1346
|
+
target.properties = mergedProperties;
|
|
1347
|
+
}
|
|
1348
|
+
if (override.items !== void 0) {
|
|
1349
|
+
if (target.items === void 0) {
|
|
1350
|
+
target.items = override.items;
|
|
1351
|
+
} else {
|
|
1352
|
+
mergeSchemaOverride(target.items, override.items);
|
|
1353
|
+
}
|
|
1354
|
+
}
|
|
1355
|
+
for (const [key, value] of Object.entries(override)) {
|
|
1356
|
+
if (key === "properties" || key === "items") {
|
|
1357
|
+
continue;
|
|
1358
|
+
}
|
|
1359
|
+
target[key] = value;
|
|
1360
|
+
}
|
|
1361
|
+
}
|
|
1362
|
+
function stripLeadingPathSegment(constraint) {
|
|
1363
|
+
const segments = constraint.path?.segments;
|
|
1364
|
+
if (segments === void 0 || segments.length === 0) {
|
|
1365
|
+
return constraint;
|
|
1366
|
+
}
|
|
1367
|
+
const [, ...rest] = segments;
|
|
1368
|
+
if (rest.length === 0) {
|
|
1369
|
+
const { path: _path, ...stripped } = constraint;
|
|
1370
|
+
return stripped;
|
|
1371
|
+
}
|
|
1372
|
+
return {
|
|
1373
|
+
...constraint,
|
|
1374
|
+
path: { segments: rest }
|
|
1375
|
+
};
|
|
1376
|
+
}
|
|
1377
|
+
function getNullableUnionValueSchema(schema) {
|
|
1378
|
+
if (schema.oneOf?.length !== 2) {
|
|
1379
|
+
return void 0;
|
|
1380
|
+
}
|
|
1381
|
+
const valueSchema = schema.oneOf.find((branch) => branch.type !== "null");
|
|
1382
|
+
const nullSchema = schema.oneOf.find((branch) => branch.type === "null");
|
|
1383
|
+
return valueSchema !== void 0 && nullSchema !== void 0 ? valueSchema : void 0;
|
|
1384
|
+
}
|
|
1243
1385
|
function generateDynamicType(type) {
|
|
1244
1386
|
if (type.dynamicKind === "enum") {
|
|
1245
1387
|
const schema = {
|