@formspec/build 0.1.0-alpha.30 → 0.1.0-alpha.32
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/README.md +82 -5
- package/dist/analyzer/class-analyzer.d.ts +6 -0
- package/dist/analyzer/class-analyzer.d.ts.map +1 -1
- 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/build-alpha.d.ts +180 -0
- package/dist/build-beta.d.ts +180 -0
- package/dist/build-internal.d.ts +180 -0
- package/dist/build.d.ts +180 -0
- package/dist/cli.cjs +584 -33
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +582 -33
- package/dist/cli.js.map +1 -1
- package/dist/generators/discovered-schema.d.ts +112 -0
- package/dist/generators/discovered-schema.d.ts.map +1 -0
- package/dist/index.cjs +573 -33
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +565 -33
- package/dist/index.js.map +1 -1
- package/dist/internals.cjs +197 -33
- package/dist/internals.cjs.map +1 -1
- package/dist/internals.js +197 -33
- package/dist/internals.js.map +1 -1
- package/dist/static-build.d.ts +61 -0
- package/dist/static-build.d.ts.map +1 -0
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -33,12 +33,20 @@ __export(index_exports, {
|
|
|
33
33
|
buildFormSchemas: () => buildFormSchemas,
|
|
34
34
|
buildMixedAuthoringSchemas: () => buildMixedAuthoringSchemas,
|
|
35
35
|
createExtensionRegistry: () => createExtensionRegistry,
|
|
36
|
+
createStaticBuildContext: () => createStaticBuildContext,
|
|
37
|
+
createStaticBuildContextFromProgram: () => createStaticBuildContextFromProgram,
|
|
36
38
|
generateJsonSchema: () => generateJsonSchema,
|
|
37
39
|
generateSchemas: () => generateSchemas,
|
|
38
40
|
generateSchemasFromClass: () => generateSchemasFromClass,
|
|
41
|
+
generateSchemasFromDeclaration: () => generateSchemasFromDeclaration,
|
|
42
|
+
generateSchemasFromParameter: () => generateSchemasFromParameter,
|
|
39
43
|
generateSchemasFromProgram: () => generateSchemasFromProgram,
|
|
44
|
+
generateSchemasFromReturnType: () => generateSchemasFromReturnType,
|
|
45
|
+
generateSchemasFromType: () => generateSchemasFromType,
|
|
40
46
|
generateUiSchema: () => generateUiSchema,
|
|
41
47
|
jsonSchema7Schema: () => jsonSchema7Schema,
|
|
48
|
+
resolveModuleExport: () => resolveModuleExport,
|
|
49
|
+
resolveModuleExportDeclaration: () => resolveModuleExportDeclaration,
|
|
42
50
|
uiSchemaSchema: () => uiSchema,
|
|
43
51
|
writeSchemas: () => writeSchemas
|
|
44
52
|
});
|
|
@@ -978,9 +986,9 @@ function collectFields(elements, properties, required, ctx) {
|
|
|
978
986
|
for (const element of elements) {
|
|
979
987
|
switch (element.kind) {
|
|
980
988
|
case "field":
|
|
981
|
-
properties[
|
|
989
|
+
properties[getSerializedFieldName(element)] = generateFieldSchema(element, ctx);
|
|
982
990
|
if (element.required) {
|
|
983
|
-
required.push(
|
|
991
|
+
required.push(getSerializedFieldName(element));
|
|
984
992
|
}
|
|
985
993
|
break;
|
|
986
994
|
case "group":
|
|
@@ -1051,19 +1059,21 @@ function applyPathTargetedConstraints(schema, pathConstraints, ctx, typeNode) {
|
|
|
1051
1059
|
schema.items = applyPathTargetedConstraints(schema.items, pathConstraints, ctx, nestedType);
|
|
1052
1060
|
return schema;
|
|
1053
1061
|
}
|
|
1054
|
-
const
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1062
|
+
const propertyOverrides = buildPropertyOverrides(pathConstraints, typeNode, ctx);
|
|
1063
|
+
const nullableValueBranch = getNullableUnionValueSchema(schema);
|
|
1064
|
+
if (nullableValueBranch !== void 0) {
|
|
1065
|
+
const updatedNullableValueBranch = applyPathTargetedConstraints(
|
|
1066
|
+
nullableValueBranch,
|
|
1067
|
+
pathConstraints,
|
|
1068
|
+
ctx,
|
|
1069
|
+
resolveTraversableTypeNode(typeNode, ctx)
|
|
1070
|
+
);
|
|
1071
|
+
if (schema.oneOf !== void 0) {
|
|
1072
|
+
schema.oneOf = schema.oneOf.map(
|
|
1073
|
+
(branch) => branch === nullableValueBranch ? updatedNullableValueBranch : branch
|
|
1074
|
+
);
|
|
1075
|
+
}
|
|
1076
|
+
return schema;
|
|
1067
1077
|
}
|
|
1068
1078
|
if (schema.$ref) {
|
|
1069
1079
|
const { $ref, ...rest } = schema;
|
|
@@ -1078,7 +1088,7 @@ function applyPathTargetedConstraints(schema, pathConstraints, ctx, typeNode) {
|
|
|
1078
1088
|
const missingOverrides = {};
|
|
1079
1089
|
for (const [target, overrideSchema] of Object.entries(propertyOverrides)) {
|
|
1080
1090
|
if (schema.properties[target]) {
|
|
1081
|
-
|
|
1091
|
+
mergeSchemaOverride(schema.properties[target], overrideSchema);
|
|
1082
1092
|
} else {
|
|
1083
1093
|
missingOverrides[target] = overrideSchema;
|
|
1084
1094
|
}
|
|
@@ -1152,7 +1162,7 @@ function generateObjectType(type, ctx) {
|
|
|
1152
1162
|
const properties = {};
|
|
1153
1163
|
const required = [];
|
|
1154
1164
|
for (const prop of type.properties) {
|
|
1155
|
-
const propertyName =
|
|
1165
|
+
const propertyName = getSerializedObjectPropertyName(prop);
|
|
1156
1166
|
properties[propertyName] = generatePropertySchema(prop, ctx);
|
|
1157
1167
|
if (!prop.optional) {
|
|
1158
1168
|
required.push(propertyName);
|
|
@@ -1206,7 +1216,16 @@ function isNullableUnion(type) {
|
|
|
1206
1216
|
return nullCount === 1;
|
|
1207
1217
|
}
|
|
1208
1218
|
function generateReferenceType(type, ctx) {
|
|
1209
|
-
return { $ref: `#/$defs/${
|
|
1219
|
+
return { $ref: `#/$defs/${getSerializedTypeName(type.name, ctx)}` };
|
|
1220
|
+
}
|
|
1221
|
+
function getSerializedFieldName(field) {
|
|
1222
|
+
return getSerializedName(field.name, field.metadata);
|
|
1223
|
+
}
|
|
1224
|
+
function getSerializedObjectPropertyName(property) {
|
|
1225
|
+
return getSerializedName(property.name, property.metadata);
|
|
1226
|
+
}
|
|
1227
|
+
function getSerializedTypeName(logicalName, ctx) {
|
|
1228
|
+
return ctx.typeNameMap[logicalName] ?? logicalName;
|
|
1210
1229
|
}
|
|
1211
1230
|
function applyResolvedMetadata(schema, metadata) {
|
|
1212
1231
|
const displayName = getDisplayName(metadata);
|
|
@@ -1217,17 +1236,148 @@ function applyResolvedMetadata(schema, metadata) {
|
|
|
1217
1236
|
function resolveReferencedType(type, ctx) {
|
|
1218
1237
|
return ctx.typeRegistry[type.name]?.type;
|
|
1219
1238
|
}
|
|
1239
|
+
function dereferenceTypeNode(typeNode, ctx) {
|
|
1240
|
+
if (typeNode?.kind !== "reference") {
|
|
1241
|
+
return typeNode;
|
|
1242
|
+
}
|
|
1243
|
+
return resolveReferencedType(typeNode, ctx);
|
|
1244
|
+
}
|
|
1245
|
+
function unwrapNullableTypeNode(typeNode) {
|
|
1246
|
+
if (typeNode?.kind !== "union" || !isNullableUnion(typeNode)) {
|
|
1247
|
+
return typeNode;
|
|
1248
|
+
}
|
|
1249
|
+
return typeNode.members.find(
|
|
1250
|
+
(member) => !(member.kind === "primitive" && member.primitiveKind === "null")
|
|
1251
|
+
);
|
|
1252
|
+
}
|
|
1253
|
+
function resolveTraversableTypeNode(typeNode, ctx) {
|
|
1254
|
+
const dereferenced = dereferenceTypeNode(typeNode, ctx);
|
|
1255
|
+
const unwrapped = unwrapNullableTypeNode(dereferenced);
|
|
1256
|
+
if (unwrapped !== dereferenced) {
|
|
1257
|
+
return resolveTraversableTypeNode(unwrapped, ctx);
|
|
1258
|
+
}
|
|
1259
|
+
return dereferenced;
|
|
1260
|
+
}
|
|
1220
1261
|
function resolveSerializedPropertyName(logicalName, typeNode, ctx) {
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
return
|
|
1262
|
+
const effectiveType = resolveTraversableTypeNode(typeNode, ctx);
|
|
1263
|
+
if (effectiveType?.kind === "array") {
|
|
1264
|
+
return resolveSerializedPropertyName(logicalName, effectiveType.items, ctx);
|
|
1224
1265
|
}
|
|
1225
|
-
if (
|
|
1226
|
-
const
|
|
1227
|
-
return
|
|
1266
|
+
if (effectiveType?.kind === "object") {
|
|
1267
|
+
const property = effectiveType.properties.find((candidate) => candidate.name === logicalName);
|
|
1268
|
+
return property === void 0 ? logicalName : getSerializedObjectPropertyName(property);
|
|
1228
1269
|
}
|
|
1229
1270
|
return logicalName;
|
|
1230
1271
|
}
|
|
1272
|
+
function resolveTargetTypeNode(logicalName, typeNode, ctx) {
|
|
1273
|
+
const effectiveType = resolveTraversableTypeNode(typeNode, ctx);
|
|
1274
|
+
if (effectiveType?.kind === "array") {
|
|
1275
|
+
return resolveTargetTypeNode(logicalName, effectiveType.items, ctx);
|
|
1276
|
+
}
|
|
1277
|
+
if (effectiveType?.kind !== "object") {
|
|
1278
|
+
return void 0;
|
|
1279
|
+
}
|
|
1280
|
+
return effectiveType.properties.find((candidate) => candidate.name === logicalName)?.type;
|
|
1281
|
+
}
|
|
1282
|
+
function buildPropertyOverrides(pathConstraints, typeNode, ctx) {
|
|
1283
|
+
const byTarget = /* @__PURE__ */ new Map();
|
|
1284
|
+
for (const constraint of pathConstraints) {
|
|
1285
|
+
const target = constraint.path?.segments[0];
|
|
1286
|
+
if (!target) {
|
|
1287
|
+
continue;
|
|
1288
|
+
}
|
|
1289
|
+
const grouped = byTarget.get(target) ?? [];
|
|
1290
|
+
grouped.push(constraint);
|
|
1291
|
+
byTarget.set(target, grouped);
|
|
1292
|
+
}
|
|
1293
|
+
const overrides = {};
|
|
1294
|
+
for (const [target, constraints] of byTarget) {
|
|
1295
|
+
overrides[resolveSerializedPropertyName(target, typeNode, ctx)] = buildPathOverrideSchema(
|
|
1296
|
+
constraints.map(stripLeadingPathSegment),
|
|
1297
|
+
resolveTargetTypeNode(target, typeNode, ctx),
|
|
1298
|
+
ctx
|
|
1299
|
+
);
|
|
1300
|
+
}
|
|
1301
|
+
return overrides;
|
|
1302
|
+
}
|
|
1303
|
+
function buildPathOverrideSchema(constraints, typeNode, ctx) {
|
|
1304
|
+
const schema = {};
|
|
1305
|
+
const directConstraints = [];
|
|
1306
|
+
const nestedConstraints = [];
|
|
1307
|
+
for (const constraint of constraints) {
|
|
1308
|
+
if (constraint.path === void 0 || constraint.path.segments.length === 0) {
|
|
1309
|
+
directConstraints.push(constraint);
|
|
1310
|
+
} else {
|
|
1311
|
+
nestedConstraints.push(constraint);
|
|
1312
|
+
}
|
|
1313
|
+
}
|
|
1314
|
+
applyConstraints(schema, directConstraints, ctx);
|
|
1315
|
+
if (nestedConstraints.length === 0) {
|
|
1316
|
+
return schema;
|
|
1317
|
+
}
|
|
1318
|
+
const effectiveType = resolveTraversableTypeNode(typeNode, ctx);
|
|
1319
|
+
if (effectiveType?.kind === "array") {
|
|
1320
|
+
schema.items = buildPathOverrideSchema(nestedConstraints, effectiveType.items, ctx);
|
|
1321
|
+
return schema;
|
|
1322
|
+
}
|
|
1323
|
+
schema.properties = buildPropertyOverrides(nestedConstraints, effectiveType, ctx);
|
|
1324
|
+
return schema;
|
|
1325
|
+
}
|
|
1326
|
+
function mergeSchemaOverride(target, override) {
|
|
1327
|
+
const nullableValueBranch = getNullableUnionValueSchema(target);
|
|
1328
|
+
if (nullableValueBranch !== void 0) {
|
|
1329
|
+
mergeSchemaOverride(nullableValueBranch, override);
|
|
1330
|
+
return;
|
|
1331
|
+
}
|
|
1332
|
+
if (override.properties !== void 0) {
|
|
1333
|
+
const mergedProperties = target.properties ?? {};
|
|
1334
|
+
for (const [name, propertyOverride] of Object.entries(override.properties)) {
|
|
1335
|
+
const existing = mergedProperties[name];
|
|
1336
|
+
if (existing === void 0) {
|
|
1337
|
+
mergedProperties[name] = propertyOverride;
|
|
1338
|
+
} else {
|
|
1339
|
+
mergeSchemaOverride(existing, propertyOverride);
|
|
1340
|
+
}
|
|
1341
|
+
}
|
|
1342
|
+
target.properties = mergedProperties;
|
|
1343
|
+
}
|
|
1344
|
+
if (override.items !== void 0) {
|
|
1345
|
+
if (target.items === void 0) {
|
|
1346
|
+
target.items = override.items;
|
|
1347
|
+
} else {
|
|
1348
|
+
mergeSchemaOverride(target.items, override.items);
|
|
1349
|
+
}
|
|
1350
|
+
}
|
|
1351
|
+
for (const [key, value] of Object.entries(override)) {
|
|
1352
|
+
if (key === "properties" || key === "items") {
|
|
1353
|
+
continue;
|
|
1354
|
+
}
|
|
1355
|
+
target[key] = value;
|
|
1356
|
+
}
|
|
1357
|
+
}
|
|
1358
|
+
function stripLeadingPathSegment(constraint) {
|
|
1359
|
+
const segments = constraint.path?.segments;
|
|
1360
|
+
if (segments === void 0 || segments.length === 0) {
|
|
1361
|
+
return constraint;
|
|
1362
|
+
}
|
|
1363
|
+
const [, ...rest] = segments;
|
|
1364
|
+
if (rest.length === 0) {
|
|
1365
|
+
const { path: _path, ...stripped } = constraint;
|
|
1366
|
+
return stripped;
|
|
1367
|
+
}
|
|
1368
|
+
return {
|
|
1369
|
+
...constraint,
|
|
1370
|
+
path: { segments: rest }
|
|
1371
|
+
};
|
|
1372
|
+
}
|
|
1373
|
+
function getNullableUnionValueSchema(schema) {
|
|
1374
|
+
if (schema.oneOf?.length !== 2) {
|
|
1375
|
+
return void 0;
|
|
1376
|
+
}
|
|
1377
|
+
const valueSchema = schema.oneOf.find((branch) => branch.type !== "null");
|
|
1378
|
+
const nullSchema = schema.oneOf.find((branch) => branch.type === "null");
|
|
1379
|
+
return valueSchema !== void 0 && nullSchema !== void 0 ? valueSchema : void 0;
|
|
1380
|
+
}
|
|
1231
1381
|
function generateDynamicType(type) {
|
|
1232
1382
|
if (type.dynamicKind === "enum") {
|
|
1233
1383
|
const schema = {
|
|
@@ -2765,6 +2915,27 @@ function resolveNodeMetadata(metadataPolicy, declarationKind, logicalName, node,
|
|
|
2765
2915
|
makeMetadataContext("tsdoc", declarationKind, logicalName, buildContext)
|
|
2766
2916
|
);
|
|
2767
2917
|
}
|
|
2918
|
+
function analyzeDeclarationRootInfo(declaration, checker, file = "", extensionRegistry, metadataPolicy) {
|
|
2919
|
+
const normalizedMetadataPolicy = normalizeMetadataPolicy(metadataPolicy);
|
|
2920
|
+
const declarationType = checker.getTypeAtLocation(declaration);
|
|
2921
|
+
const logicalName = ts3.isClassDeclaration(declaration) ? declaration.name?.text ?? "AnonymousClass" : declaration.name.text;
|
|
2922
|
+
const docResult = extractJSDocParseResult(
|
|
2923
|
+
declaration,
|
|
2924
|
+
file,
|
|
2925
|
+
makeParseOptions(extensionRegistry, void 0, checker, declarationType, declarationType)
|
|
2926
|
+
);
|
|
2927
|
+
const metadata = resolveNodeMetadata(normalizedMetadataPolicy, "type", logicalName, declaration, {
|
|
2928
|
+
checker,
|
|
2929
|
+
declaration,
|
|
2930
|
+
subjectType: declarationType,
|
|
2931
|
+
hostType: declarationType
|
|
2932
|
+
});
|
|
2933
|
+
return {
|
|
2934
|
+
...metadata !== void 0 && { metadata },
|
|
2935
|
+
annotations: docResult.annotations,
|
|
2936
|
+
diagnostics: docResult.diagnostics
|
|
2937
|
+
};
|
|
2938
|
+
}
|
|
2768
2939
|
function analyzeClassToIR(classDecl, checker, file = "", extensionRegistry, metadataPolicy) {
|
|
2769
2940
|
const normalizedMetadataPolicy = normalizeMetadataPolicy(metadataPolicy);
|
|
2770
2941
|
const name = classDecl.name?.text ?? "AnonymousClass";
|
|
@@ -3179,10 +3350,7 @@ function resolveLiteralDiscriminatorPropertyValue(boundType, fieldName, checker,
|
|
|
3179
3350
|
if (resolvedAnchorNode === null) {
|
|
3180
3351
|
return void 0;
|
|
3181
3352
|
}
|
|
3182
|
-
const propertyType = checker.getTypeOfSymbolAtLocation(
|
|
3183
|
-
propertySymbol,
|
|
3184
|
-
resolvedAnchorNode
|
|
3185
|
-
);
|
|
3353
|
+
const propertyType = checker.getTypeOfSymbolAtLocation(propertySymbol, resolvedAnchorNode);
|
|
3186
3354
|
if (propertyType.isStringLiteral()) {
|
|
3187
3355
|
return propertyType.value;
|
|
3188
3356
|
}
|
|
@@ -4141,14 +4309,39 @@ function resolveObjectType(type, checker, file, typeRegistry, visiting, sourceNo
|
|
|
4141
4309
|
collectedDiagnostics
|
|
4142
4310
|
);
|
|
4143
4311
|
const fieldNodeInfo = fieldInfoMap?.get(prop.name);
|
|
4312
|
+
const inlineFieldNodeInfo = fieldNodeInfo === void 0 ? ts3.isPropertySignature(declaration) ? analyzeInterfacePropertyToIR(
|
|
4313
|
+
declaration,
|
|
4314
|
+
checker,
|
|
4315
|
+
file,
|
|
4316
|
+
typeRegistry,
|
|
4317
|
+
visiting,
|
|
4318
|
+
collectedDiagnostics,
|
|
4319
|
+
type,
|
|
4320
|
+
metadataPolicy,
|
|
4321
|
+
extensionRegistry
|
|
4322
|
+
) : ts3.isPropertyDeclaration(declaration) ? analyzeFieldToIR(
|
|
4323
|
+
declaration,
|
|
4324
|
+
checker,
|
|
4325
|
+
file,
|
|
4326
|
+
typeRegistry,
|
|
4327
|
+
visiting,
|
|
4328
|
+
collectedDiagnostics,
|
|
4329
|
+
type,
|
|
4330
|
+
metadataPolicy,
|
|
4331
|
+
extensionRegistry
|
|
4332
|
+
) : null : null;
|
|
4333
|
+
const resolvedFieldNodeInfo = fieldNodeInfo ?? inlineFieldNodeInfo;
|
|
4334
|
+
const resolvedPropertyType = inlineFieldNodeInfo?.type ?? propTypeNode;
|
|
4144
4335
|
properties.push({
|
|
4145
4336
|
name: prop.name,
|
|
4146
|
-
...
|
|
4147
|
-
|
|
4337
|
+
...resolvedFieldNodeInfo?.metadata !== void 0 && {
|
|
4338
|
+
metadata: resolvedFieldNodeInfo.metadata
|
|
4339
|
+
},
|
|
4340
|
+
type: resolvedPropertyType,
|
|
4148
4341
|
optional,
|
|
4149
|
-
constraints:
|
|
4150
|
-
annotations:
|
|
4151
|
-
provenance:
|
|
4342
|
+
constraints: resolvedFieldNodeInfo?.constraints ?? [],
|
|
4343
|
+
annotations: resolvedFieldNodeInfo?.annotations ?? [],
|
|
4344
|
+
provenance: resolvedFieldNodeInfo?.provenance ?? provenanceForFile(file)
|
|
4152
4345
|
});
|
|
4153
4346
|
}
|
|
4154
4347
|
visiting.delete(type);
|
|
@@ -4744,6 +4937,345 @@ function generateSchemasFromProgram(options) {
|
|
|
4744
4937
|
);
|
|
4745
4938
|
}
|
|
4746
4939
|
|
|
4940
|
+
// src/static-build.ts
|
|
4941
|
+
var ts6 = __toESM(require("typescript"), 1);
|
|
4942
|
+
function toStaticBuildContext(context) {
|
|
4943
|
+
return context;
|
|
4944
|
+
}
|
|
4945
|
+
function createStaticBuildContext(filePath) {
|
|
4946
|
+
return toStaticBuildContext(createProgramContext(filePath));
|
|
4947
|
+
}
|
|
4948
|
+
function createStaticBuildContextFromProgram(program, filePath) {
|
|
4949
|
+
return toStaticBuildContext(createProgramContextFromProgram(program, filePath));
|
|
4950
|
+
}
|
|
4951
|
+
function getModuleSymbol(context) {
|
|
4952
|
+
const sourceFileWithSymbol = context.sourceFile;
|
|
4953
|
+
return context.checker.getSymbolAtLocation(context.sourceFile) ?? sourceFileWithSymbol.symbol;
|
|
4954
|
+
}
|
|
4955
|
+
function isSchemaSourceDeclaration(declaration) {
|
|
4956
|
+
return ts6.isClassDeclaration(declaration) || ts6.isInterfaceDeclaration(declaration) || ts6.isTypeAliasDeclaration(declaration);
|
|
4957
|
+
}
|
|
4958
|
+
function resolveModuleExport(context, exportName = "default") {
|
|
4959
|
+
const moduleSymbol = getModuleSymbol(context);
|
|
4960
|
+
if (moduleSymbol === void 0) {
|
|
4961
|
+
return null;
|
|
4962
|
+
}
|
|
4963
|
+
const exportSymbol = context.checker.getExportsOfModule(moduleSymbol).find((candidate) => candidate.name === exportName) ?? null;
|
|
4964
|
+
if (exportSymbol === null) {
|
|
4965
|
+
return null;
|
|
4966
|
+
}
|
|
4967
|
+
return exportSymbol.flags & ts6.SymbolFlags.Alias ? context.checker.getAliasedSymbol(exportSymbol) : exportSymbol;
|
|
4968
|
+
}
|
|
4969
|
+
function resolveModuleExportDeclaration(context, exportName = "default") {
|
|
4970
|
+
return resolveModuleExport(context, exportName)?.declarations?.find(isSchemaSourceDeclaration) ?? null;
|
|
4971
|
+
}
|
|
4972
|
+
|
|
4973
|
+
// src/generators/discovered-schema.ts
|
|
4974
|
+
var ts7 = __toESM(require("typescript"), 1);
|
|
4975
|
+
var import_internals5 = require("@formspec/core/internals");
|
|
4976
|
+
function toDiscoveredTypeSchemas(result) {
|
|
4977
|
+
return result;
|
|
4978
|
+
}
|
|
4979
|
+
function isNamedTypeDeclaration(declaration) {
|
|
4980
|
+
return ts7.isClassDeclaration(declaration) || ts7.isInterfaceDeclaration(declaration) || ts7.isTypeAliasDeclaration(declaration);
|
|
4981
|
+
}
|
|
4982
|
+
function hasConcreteTypeArguments(type, checker) {
|
|
4983
|
+
if ("aliasTypeArguments" in type && Array.isArray(type.aliasTypeArguments) && type.aliasTypeArguments.length > 0) {
|
|
4984
|
+
return true;
|
|
4985
|
+
}
|
|
4986
|
+
if ((type.flags & ts7.TypeFlags.Object) === 0) {
|
|
4987
|
+
return false;
|
|
4988
|
+
}
|
|
4989
|
+
const objectType = type;
|
|
4990
|
+
if ((objectType.objectFlags & ts7.ObjectFlags.Reference) === 0) {
|
|
4991
|
+
return false;
|
|
4992
|
+
}
|
|
4993
|
+
return checker.getTypeArguments(objectType).length > 0;
|
|
4994
|
+
}
|
|
4995
|
+
function getNamedTypeDeclaration2(type) {
|
|
4996
|
+
const symbol = type.getSymbol();
|
|
4997
|
+
if (symbol?.declarations !== void 0) {
|
|
4998
|
+
const declaration = symbol.declarations[0];
|
|
4999
|
+
if (declaration !== void 0 && isNamedTypeDeclaration(declaration)) {
|
|
5000
|
+
return declaration;
|
|
5001
|
+
}
|
|
5002
|
+
}
|
|
5003
|
+
const aliasDeclaration = type.aliasSymbol?.declarations?.find(ts7.isTypeAliasDeclaration);
|
|
5004
|
+
return aliasDeclaration;
|
|
5005
|
+
}
|
|
5006
|
+
function getFallbackName(sourceNode, fallback = "AnonymousType") {
|
|
5007
|
+
if (sourceNode !== void 0 && "name" in sourceNode) {
|
|
5008
|
+
const namedNode = sourceNode;
|
|
5009
|
+
if (namedNode.name !== void 0 && ts7.isIdentifier(namedNode.name)) {
|
|
5010
|
+
return namedNode.name.text;
|
|
5011
|
+
}
|
|
5012
|
+
}
|
|
5013
|
+
return fallback;
|
|
5014
|
+
}
|
|
5015
|
+
function createObjectRootAnalysis(name, properties, typeRegistry, metadata, annotations) {
|
|
5016
|
+
const fields = properties.map((property) => ({
|
|
5017
|
+
kind: "field",
|
|
5018
|
+
name: property.name,
|
|
5019
|
+
...property.metadata !== void 0 && { metadata: property.metadata },
|
|
5020
|
+
type: property.type,
|
|
5021
|
+
required: !property.optional,
|
|
5022
|
+
constraints: property.constraints,
|
|
5023
|
+
annotations: property.annotations,
|
|
5024
|
+
provenance: property.provenance
|
|
5025
|
+
}));
|
|
5026
|
+
return {
|
|
5027
|
+
name,
|
|
5028
|
+
...metadata !== void 0 && { metadata },
|
|
5029
|
+
fields,
|
|
5030
|
+
fieldLayouts: fields.map(() => ({})),
|
|
5031
|
+
typeRegistry,
|
|
5032
|
+
...annotations !== void 0 && annotations.length > 0 && { annotations },
|
|
5033
|
+
instanceMethods: [],
|
|
5034
|
+
staticMethods: [],
|
|
5035
|
+
diagnostics: []
|
|
5036
|
+
};
|
|
5037
|
+
}
|
|
5038
|
+
function omitApiName(metadata) {
|
|
5039
|
+
if (metadata?.apiName === void 0) {
|
|
5040
|
+
return metadata;
|
|
5041
|
+
}
|
|
5042
|
+
const { apiName: _apiName, ...rest } = metadata;
|
|
5043
|
+
return Object.keys(rest).length > 0 ? rest : void 0;
|
|
5044
|
+
}
|
|
5045
|
+
function describeRootType(rootType, typeRegistry, fallbackName) {
|
|
5046
|
+
if (rootType.kind !== "reference") {
|
|
5047
|
+
return {
|
|
5048
|
+
name: fallbackName,
|
|
5049
|
+
type: rootType
|
|
5050
|
+
};
|
|
5051
|
+
}
|
|
5052
|
+
const definition = typeRegistry[rootType.name];
|
|
5053
|
+
if (definition === void 0) {
|
|
5054
|
+
return {
|
|
5055
|
+
name: rootType.name,
|
|
5056
|
+
type: rootType
|
|
5057
|
+
};
|
|
5058
|
+
}
|
|
5059
|
+
return {
|
|
5060
|
+
name: definition.name,
|
|
5061
|
+
...definition.metadata !== void 0 && { metadata: definition.metadata },
|
|
5062
|
+
...definition.annotations !== void 0 && definition.annotations.length > 0 && { annotations: definition.annotations },
|
|
5063
|
+
type: definition.type
|
|
5064
|
+
};
|
|
5065
|
+
}
|
|
5066
|
+
function toStandaloneJsonSchema(root, typeRegistry, options) {
|
|
5067
|
+
const syntheticFieldMetadata = omitApiName(root.metadata);
|
|
5068
|
+
const syntheticField = {
|
|
5069
|
+
kind: "field",
|
|
5070
|
+
name: "__result",
|
|
5071
|
+
...syntheticFieldMetadata !== void 0 && { metadata: syntheticFieldMetadata },
|
|
5072
|
+
type: root.type,
|
|
5073
|
+
required: true,
|
|
5074
|
+
constraints: [],
|
|
5075
|
+
annotations: [...root.annotations ?? []],
|
|
5076
|
+
provenance: {
|
|
5077
|
+
surface: "tsdoc",
|
|
5078
|
+
file: "",
|
|
5079
|
+
line: 1,
|
|
5080
|
+
column: 0
|
|
5081
|
+
}
|
|
5082
|
+
};
|
|
5083
|
+
const schema = generateJsonSchemaFromIR(
|
|
5084
|
+
{
|
|
5085
|
+
kind: "form-ir",
|
|
5086
|
+
name: root.name,
|
|
5087
|
+
irVersion: import_internals5.IR_VERSION,
|
|
5088
|
+
elements: [syntheticField],
|
|
5089
|
+
...root.metadata !== void 0 && { metadata: root.metadata },
|
|
5090
|
+
...root.annotations !== void 0 && root.annotations.length > 0 && { rootAnnotations: root.annotations },
|
|
5091
|
+
typeRegistry,
|
|
5092
|
+
provenance: syntheticField.provenance
|
|
5093
|
+
},
|
|
5094
|
+
{
|
|
5095
|
+
extensionRegistry: options?.extensionRegistry,
|
|
5096
|
+
vendorPrefix: options?.vendorPrefix
|
|
5097
|
+
}
|
|
5098
|
+
);
|
|
5099
|
+
const result = schema.properties?.["__result"];
|
|
5100
|
+
if (result === void 0) {
|
|
5101
|
+
throw new Error("FormSpec failed to extract the standalone schema root from the synthetic IR.");
|
|
5102
|
+
}
|
|
5103
|
+
if (schema.$defs === void 0 || Object.keys(schema.$defs).length === 0) {
|
|
5104
|
+
return {
|
|
5105
|
+
...schema.$schema !== void 0 && { $schema: schema.$schema },
|
|
5106
|
+
...result
|
|
5107
|
+
};
|
|
5108
|
+
}
|
|
5109
|
+
return {
|
|
5110
|
+
...schema.$schema !== void 0 && { $schema: schema.$schema },
|
|
5111
|
+
...result,
|
|
5112
|
+
$defs: schema.$defs
|
|
5113
|
+
};
|
|
5114
|
+
}
|
|
5115
|
+
function generateSchemasFromAnalysis(analysis, filePath, options) {
|
|
5116
|
+
return toDiscoveredTypeSchemas(
|
|
5117
|
+
generateClassSchemas(
|
|
5118
|
+
analysis,
|
|
5119
|
+
{ file: filePath },
|
|
5120
|
+
{
|
|
5121
|
+
extensionRegistry: options?.extensionRegistry,
|
|
5122
|
+
metadata: options?.metadata,
|
|
5123
|
+
vendorPrefix: options?.vendorPrefix
|
|
5124
|
+
}
|
|
5125
|
+
)
|
|
5126
|
+
);
|
|
5127
|
+
}
|
|
5128
|
+
function generateSchemasFromResolvedType(options, skipNamedDeclaration = false, rootOverride) {
|
|
5129
|
+
const namedDeclaration = skipNamedDeclaration || hasConcreteTypeArguments(options.type, options.context.checker) ? void 0 : getNamedTypeDeclaration2(options.type);
|
|
5130
|
+
if (namedDeclaration !== void 0) {
|
|
5131
|
+
return generateSchemasFromDeclaration({
|
|
5132
|
+
...options,
|
|
5133
|
+
declaration: namedDeclaration
|
|
5134
|
+
});
|
|
5135
|
+
}
|
|
5136
|
+
const filePath = options.sourceNode?.getSourceFile().fileName ?? options.context.sourceFile.fileName;
|
|
5137
|
+
const typeRegistry = {};
|
|
5138
|
+
const diagnostics = [];
|
|
5139
|
+
const rootType = resolveTypeNode(
|
|
5140
|
+
options.type,
|
|
5141
|
+
options.context.checker,
|
|
5142
|
+
filePath,
|
|
5143
|
+
typeRegistry,
|
|
5144
|
+
/* @__PURE__ */ new Set(),
|
|
5145
|
+
options.sourceNode,
|
|
5146
|
+
normalizeMetadataPolicy(options.metadata),
|
|
5147
|
+
options.extensionRegistry,
|
|
5148
|
+
diagnostics
|
|
5149
|
+
);
|
|
5150
|
+
if (diagnostics.length > 0) {
|
|
5151
|
+
const diagnosticDetails = diagnostics.map((diagnostic) => `${diagnostic.code}: ${diagnostic.message}`).join("; ");
|
|
5152
|
+
throw new Error(
|
|
5153
|
+
`FormSpec validation failed while generating discovered type schemas. ${diagnosticDetails}`
|
|
5154
|
+
);
|
|
5155
|
+
}
|
|
5156
|
+
const describedRoot = describeRootType(
|
|
5157
|
+
rootType,
|
|
5158
|
+
typeRegistry,
|
|
5159
|
+
options.name ?? getFallbackName(options.sourceNode)
|
|
5160
|
+
);
|
|
5161
|
+
const mergedMetadata = mergeResolvedMetadata(describedRoot.metadata, rootOverride?.metadata);
|
|
5162
|
+
const root = {
|
|
5163
|
+
...describedRoot,
|
|
5164
|
+
...rootOverride?.name !== void 0 && { name: rootOverride.name },
|
|
5165
|
+
...mergedMetadata !== void 0 && { metadata: mergedMetadata },
|
|
5166
|
+
...rootOverride?.annotations !== void 0 && { annotations: rootOverride.annotations }
|
|
5167
|
+
};
|
|
5168
|
+
if (root.type.kind === "object") {
|
|
5169
|
+
return generateSchemasFromAnalysis(
|
|
5170
|
+
createObjectRootAnalysis(
|
|
5171
|
+
options.name ?? root.name,
|
|
5172
|
+
root.type.properties,
|
|
5173
|
+
typeRegistry,
|
|
5174
|
+
root.metadata,
|
|
5175
|
+
root.annotations
|
|
5176
|
+
),
|
|
5177
|
+
filePath,
|
|
5178
|
+
options
|
|
5179
|
+
);
|
|
5180
|
+
}
|
|
5181
|
+
return {
|
|
5182
|
+
jsonSchema: toStandaloneJsonSchema(root, typeRegistry, options),
|
|
5183
|
+
uiSchema: null
|
|
5184
|
+
};
|
|
5185
|
+
}
|
|
5186
|
+
function generateSchemasFromDeclaration(options) {
|
|
5187
|
+
const filePath = options.declaration.getSourceFile().fileName;
|
|
5188
|
+
if (ts7.isClassDeclaration(options.declaration)) {
|
|
5189
|
+
return generateSchemasFromAnalysis(
|
|
5190
|
+
analyzeClassToIR(
|
|
5191
|
+
options.declaration,
|
|
5192
|
+
options.context.checker,
|
|
5193
|
+
filePath,
|
|
5194
|
+
options.extensionRegistry,
|
|
5195
|
+
options.metadata
|
|
5196
|
+
),
|
|
5197
|
+
filePath,
|
|
5198
|
+
options
|
|
5199
|
+
);
|
|
5200
|
+
}
|
|
5201
|
+
if (ts7.isInterfaceDeclaration(options.declaration)) {
|
|
5202
|
+
return generateSchemasFromAnalysis(
|
|
5203
|
+
analyzeInterfaceToIR(
|
|
5204
|
+
options.declaration,
|
|
5205
|
+
options.context.checker,
|
|
5206
|
+
filePath,
|
|
5207
|
+
options.extensionRegistry,
|
|
5208
|
+
options.metadata
|
|
5209
|
+
),
|
|
5210
|
+
filePath,
|
|
5211
|
+
options
|
|
5212
|
+
);
|
|
5213
|
+
}
|
|
5214
|
+
if (ts7.isTypeAliasDeclaration(options.declaration)) {
|
|
5215
|
+
const analyzedAlias = analyzeTypeAliasToIR(
|
|
5216
|
+
options.declaration,
|
|
5217
|
+
options.context.checker,
|
|
5218
|
+
filePath,
|
|
5219
|
+
options.extensionRegistry,
|
|
5220
|
+
options.metadata
|
|
5221
|
+
);
|
|
5222
|
+
if (analyzedAlias.ok) {
|
|
5223
|
+
return generateSchemasFromAnalysis(analyzedAlias.analysis, filePath, options);
|
|
5224
|
+
}
|
|
5225
|
+
const aliasRootInfo = analyzeDeclarationRootInfo(
|
|
5226
|
+
options.declaration,
|
|
5227
|
+
options.context.checker,
|
|
5228
|
+
filePath,
|
|
5229
|
+
options.extensionRegistry,
|
|
5230
|
+
options.metadata
|
|
5231
|
+
);
|
|
5232
|
+
if (aliasRootInfo.diagnostics.length > 0) {
|
|
5233
|
+
const diagnosticDetails = aliasRootInfo.diagnostics.map((diagnostic) => `${diagnostic.code}: ${diagnostic.message}`).join("; ");
|
|
5234
|
+
throw new Error(
|
|
5235
|
+
`FormSpec validation failed while generating discovered type schemas. ${diagnosticDetails}`
|
|
5236
|
+
);
|
|
5237
|
+
}
|
|
5238
|
+
return generateSchemasFromResolvedType(
|
|
5239
|
+
{
|
|
5240
|
+
...options,
|
|
5241
|
+
type: options.context.checker.getTypeAtLocation(options.declaration),
|
|
5242
|
+
sourceNode: options.declaration,
|
|
5243
|
+
name: options.declaration.name.text
|
|
5244
|
+
},
|
|
5245
|
+
true,
|
|
5246
|
+
{
|
|
5247
|
+
name: options.declaration.name.text,
|
|
5248
|
+
...aliasRootInfo.metadata !== void 0 && { metadata: aliasRootInfo.metadata },
|
|
5249
|
+
...aliasRootInfo.annotations.length > 0 && { annotations: aliasRootInfo.annotations }
|
|
5250
|
+
}
|
|
5251
|
+
);
|
|
5252
|
+
}
|
|
5253
|
+
const _exhaustive = options.declaration;
|
|
5254
|
+
return _exhaustive;
|
|
5255
|
+
}
|
|
5256
|
+
function generateSchemasFromType(options) {
|
|
5257
|
+
return generateSchemasFromResolvedType(options);
|
|
5258
|
+
}
|
|
5259
|
+
function generateSchemasFromParameter(options) {
|
|
5260
|
+
return generateSchemasFromResolvedType({
|
|
5261
|
+
...options,
|
|
5262
|
+
type: options.context.checker.getTypeAtLocation(options.parameter),
|
|
5263
|
+
sourceNode: options.parameter,
|
|
5264
|
+
name: getFallbackName(options.parameter, "Parameter")
|
|
5265
|
+
});
|
|
5266
|
+
}
|
|
5267
|
+
function generateSchemasFromReturnType(options) {
|
|
5268
|
+
const signature = options.context.checker.getSignatureFromDeclaration(options.declaration);
|
|
5269
|
+
const type = signature !== void 0 ? options.context.checker.getReturnTypeOfSignature(signature) : options.context.checker.getTypeAtLocation(options.declaration);
|
|
5270
|
+
const fallbackName = options.declaration.name !== void 0 && ts7.isIdentifier(options.declaration.name) ? `${options.declaration.name.text}ReturnType` : "ReturnType";
|
|
5271
|
+
return generateSchemasFromResolvedType({
|
|
5272
|
+
...options,
|
|
5273
|
+
type,
|
|
5274
|
+
sourceNode: options.declaration.type ?? options.declaration,
|
|
5275
|
+
name: fallbackName
|
|
5276
|
+
});
|
|
5277
|
+
}
|
|
5278
|
+
|
|
4747
5279
|
// src/generators/mixed-authoring.ts
|
|
4748
5280
|
function buildMixedAuthoringSchemas(options) {
|
|
4749
5281
|
const { filePath, typeName, overlays, ...schemaOptions } = options;
|
|
@@ -4959,12 +5491,20 @@ function writeSchemas(form, options) {
|
|
|
4959
5491
|
buildFormSchemas,
|
|
4960
5492
|
buildMixedAuthoringSchemas,
|
|
4961
5493
|
createExtensionRegistry,
|
|
5494
|
+
createStaticBuildContext,
|
|
5495
|
+
createStaticBuildContextFromProgram,
|
|
4962
5496
|
generateJsonSchema,
|
|
4963
5497
|
generateSchemas,
|
|
4964
5498
|
generateSchemasFromClass,
|
|
5499
|
+
generateSchemasFromDeclaration,
|
|
5500
|
+
generateSchemasFromParameter,
|
|
4965
5501
|
generateSchemasFromProgram,
|
|
5502
|
+
generateSchemasFromReturnType,
|
|
5503
|
+
generateSchemasFromType,
|
|
4966
5504
|
generateUiSchema,
|
|
4967
5505
|
jsonSchema7Schema,
|
|
5506
|
+
resolveModuleExport,
|
|
5507
|
+
resolveModuleExportDeclaration,
|
|
4968
5508
|
uiSchemaSchema,
|
|
4969
5509
|
writeSchemas
|
|
4970
5510
|
});
|