@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/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 = {
|
|
@@ -2845,6 +2987,27 @@ function resolveNodeMetadata(metadataPolicy, declarationKind, logicalName, node,
|
|
|
2845
2987
|
makeMetadataContext("tsdoc", declarationKind, logicalName, buildContext)
|
|
2846
2988
|
);
|
|
2847
2989
|
}
|
|
2990
|
+
function analyzeDeclarationRootInfo(declaration, checker, file = "", extensionRegistry, metadataPolicy) {
|
|
2991
|
+
const normalizedMetadataPolicy = normalizeMetadataPolicy(metadataPolicy);
|
|
2992
|
+
const declarationType = checker.getTypeAtLocation(declaration);
|
|
2993
|
+
const logicalName = ts3.isClassDeclaration(declaration) ? declaration.name?.text ?? "AnonymousClass" : declaration.name.text;
|
|
2994
|
+
const docResult = extractJSDocParseResult(
|
|
2995
|
+
declaration,
|
|
2996
|
+
file,
|
|
2997
|
+
makeParseOptions(extensionRegistry, void 0, checker, declarationType, declarationType)
|
|
2998
|
+
);
|
|
2999
|
+
const metadata = resolveNodeMetadata(normalizedMetadataPolicy, "type", logicalName, declaration, {
|
|
3000
|
+
checker,
|
|
3001
|
+
declaration,
|
|
3002
|
+
subjectType: declarationType,
|
|
3003
|
+
hostType: declarationType
|
|
3004
|
+
});
|
|
3005
|
+
return {
|
|
3006
|
+
...metadata !== void 0 && { metadata },
|
|
3007
|
+
annotations: docResult.annotations,
|
|
3008
|
+
diagnostics: docResult.diagnostics
|
|
3009
|
+
};
|
|
3010
|
+
}
|
|
2848
3011
|
function analyzeClassToIR(classDecl, checker, file = "", extensionRegistry, metadataPolicy) {
|
|
2849
3012
|
const normalizedMetadataPolicy = normalizeMetadataPolicy(metadataPolicy);
|
|
2850
3013
|
const name = classDecl.name?.text ?? "AnonymousClass";
|
|
@@ -3259,10 +3422,7 @@ function resolveLiteralDiscriminatorPropertyValue(boundType, fieldName, checker,
|
|
|
3259
3422
|
if (resolvedAnchorNode === null) {
|
|
3260
3423
|
return void 0;
|
|
3261
3424
|
}
|
|
3262
|
-
const propertyType = checker.getTypeOfSymbolAtLocation(
|
|
3263
|
-
propertySymbol,
|
|
3264
|
-
resolvedAnchorNode
|
|
3265
|
-
);
|
|
3425
|
+
const propertyType = checker.getTypeOfSymbolAtLocation(propertySymbol, resolvedAnchorNode);
|
|
3266
3426
|
if (propertyType.isStringLiteral()) {
|
|
3267
3427
|
return propertyType.value;
|
|
3268
3428
|
}
|
|
@@ -4221,14 +4381,39 @@ function resolveObjectType(type, checker, file, typeRegistry, visiting, sourceNo
|
|
|
4221
4381
|
collectedDiagnostics
|
|
4222
4382
|
);
|
|
4223
4383
|
const fieldNodeInfo = fieldInfoMap?.get(prop.name);
|
|
4384
|
+
const inlineFieldNodeInfo = fieldNodeInfo === void 0 ? ts3.isPropertySignature(declaration) ? analyzeInterfacePropertyToIR(
|
|
4385
|
+
declaration,
|
|
4386
|
+
checker,
|
|
4387
|
+
file,
|
|
4388
|
+
typeRegistry,
|
|
4389
|
+
visiting,
|
|
4390
|
+
collectedDiagnostics,
|
|
4391
|
+
type,
|
|
4392
|
+
metadataPolicy,
|
|
4393
|
+
extensionRegistry
|
|
4394
|
+
) : ts3.isPropertyDeclaration(declaration) ? analyzeFieldToIR(
|
|
4395
|
+
declaration,
|
|
4396
|
+
checker,
|
|
4397
|
+
file,
|
|
4398
|
+
typeRegistry,
|
|
4399
|
+
visiting,
|
|
4400
|
+
collectedDiagnostics,
|
|
4401
|
+
type,
|
|
4402
|
+
metadataPolicy,
|
|
4403
|
+
extensionRegistry
|
|
4404
|
+
) : null : null;
|
|
4405
|
+
const resolvedFieldNodeInfo = fieldNodeInfo ?? inlineFieldNodeInfo;
|
|
4406
|
+
const resolvedPropertyType = inlineFieldNodeInfo?.type ?? propTypeNode;
|
|
4224
4407
|
properties.push({
|
|
4225
4408
|
name: prop.name,
|
|
4226
|
-
...
|
|
4227
|
-
|
|
4409
|
+
...resolvedFieldNodeInfo?.metadata !== void 0 && {
|
|
4410
|
+
metadata: resolvedFieldNodeInfo.metadata
|
|
4411
|
+
},
|
|
4412
|
+
type: resolvedPropertyType,
|
|
4228
4413
|
optional,
|
|
4229
|
-
constraints:
|
|
4230
|
-
annotations:
|
|
4231
|
-
provenance:
|
|
4414
|
+
constraints: resolvedFieldNodeInfo?.constraints ?? [],
|
|
4415
|
+
annotations: resolvedFieldNodeInfo?.annotations ?? [],
|
|
4416
|
+
provenance: resolvedFieldNodeInfo?.provenance ?? provenanceForFile(file)
|
|
4232
4417
|
});
|
|
4233
4418
|
}
|
|
4234
4419
|
visiting.delete(type);
|
|
@@ -4876,6 +5061,362 @@ var init_class_schema = __esm({
|
|
|
4876
5061
|
}
|
|
4877
5062
|
});
|
|
4878
5063
|
|
|
5064
|
+
// src/static-build.ts
|
|
5065
|
+
function toStaticBuildContext(context) {
|
|
5066
|
+
return context;
|
|
5067
|
+
}
|
|
5068
|
+
function createStaticBuildContext(filePath) {
|
|
5069
|
+
return toStaticBuildContext(createProgramContext(filePath));
|
|
5070
|
+
}
|
|
5071
|
+
function createStaticBuildContextFromProgram(program, filePath) {
|
|
5072
|
+
return toStaticBuildContext(createProgramContextFromProgram(program, filePath));
|
|
5073
|
+
}
|
|
5074
|
+
function getModuleSymbol(context) {
|
|
5075
|
+
const sourceFileWithSymbol = context.sourceFile;
|
|
5076
|
+
return context.checker.getSymbolAtLocation(context.sourceFile) ?? sourceFileWithSymbol.symbol;
|
|
5077
|
+
}
|
|
5078
|
+
function isSchemaSourceDeclaration(declaration) {
|
|
5079
|
+
return ts6.isClassDeclaration(declaration) || ts6.isInterfaceDeclaration(declaration) || ts6.isTypeAliasDeclaration(declaration);
|
|
5080
|
+
}
|
|
5081
|
+
function resolveModuleExport(context, exportName = "default") {
|
|
5082
|
+
const moduleSymbol = getModuleSymbol(context);
|
|
5083
|
+
if (moduleSymbol === void 0) {
|
|
5084
|
+
return null;
|
|
5085
|
+
}
|
|
5086
|
+
const exportSymbol = context.checker.getExportsOfModule(moduleSymbol).find((candidate) => candidate.name === exportName) ?? null;
|
|
5087
|
+
if (exportSymbol === null) {
|
|
5088
|
+
return null;
|
|
5089
|
+
}
|
|
5090
|
+
return exportSymbol.flags & ts6.SymbolFlags.Alias ? context.checker.getAliasedSymbol(exportSymbol) : exportSymbol;
|
|
5091
|
+
}
|
|
5092
|
+
function resolveModuleExportDeclaration(context, exportName = "default") {
|
|
5093
|
+
return resolveModuleExport(context, exportName)?.declarations?.find(isSchemaSourceDeclaration) ?? null;
|
|
5094
|
+
}
|
|
5095
|
+
var ts6;
|
|
5096
|
+
var init_static_build = __esm({
|
|
5097
|
+
"src/static-build.ts"() {
|
|
5098
|
+
"use strict";
|
|
5099
|
+
ts6 = __toESM(require("typescript"), 1);
|
|
5100
|
+
init_program();
|
|
5101
|
+
}
|
|
5102
|
+
});
|
|
5103
|
+
|
|
5104
|
+
// src/generators/discovered-schema.ts
|
|
5105
|
+
function toDiscoveredTypeSchemas(result) {
|
|
5106
|
+
return result;
|
|
5107
|
+
}
|
|
5108
|
+
function isNamedTypeDeclaration(declaration) {
|
|
5109
|
+
return ts7.isClassDeclaration(declaration) || ts7.isInterfaceDeclaration(declaration) || ts7.isTypeAliasDeclaration(declaration);
|
|
5110
|
+
}
|
|
5111
|
+
function hasConcreteTypeArguments(type, checker) {
|
|
5112
|
+
if ("aliasTypeArguments" in type && Array.isArray(type.aliasTypeArguments) && type.aliasTypeArguments.length > 0) {
|
|
5113
|
+
return true;
|
|
5114
|
+
}
|
|
5115
|
+
if ((type.flags & ts7.TypeFlags.Object) === 0) {
|
|
5116
|
+
return false;
|
|
5117
|
+
}
|
|
5118
|
+
const objectType = type;
|
|
5119
|
+
if ((objectType.objectFlags & ts7.ObjectFlags.Reference) === 0) {
|
|
5120
|
+
return false;
|
|
5121
|
+
}
|
|
5122
|
+
return checker.getTypeArguments(objectType).length > 0;
|
|
5123
|
+
}
|
|
5124
|
+
function getNamedTypeDeclaration2(type) {
|
|
5125
|
+
const symbol = type.getSymbol();
|
|
5126
|
+
if (symbol?.declarations !== void 0) {
|
|
5127
|
+
const declaration = symbol.declarations[0];
|
|
5128
|
+
if (declaration !== void 0 && isNamedTypeDeclaration(declaration)) {
|
|
5129
|
+
return declaration;
|
|
5130
|
+
}
|
|
5131
|
+
}
|
|
5132
|
+
const aliasDeclaration = type.aliasSymbol?.declarations?.find(ts7.isTypeAliasDeclaration);
|
|
5133
|
+
return aliasDeclaration;
|
|
5134
|
+
}
|
|
5135
|
+
function getFallbackName(sourceNode, fallback = "AnonymousType") {
|
|
5136
|
+
if (sourceNode !== void 0 && "name" in sourceNode) {
|
|
5137
|
+
const namedNode = sourceNode;
|
|
5138
|
+
if (namedNode.name !== void 0 && ts7.isIdentifier(namedNode.name)) {
|
|
5139
|
+
return namedNode.name.text;
|
|
5140
|
+
}
|
|
5141
|
+
}
|
|
5142
|
+
return fallback;
|
|
5143
|
+
}
|
|
5144
|
+
function createObjectRootAnalysis(name, properties, typeRegistry, metadata, annotations) {
|
|
5145
|
+
const fields = properties.map((property) => ({
|
|
5146
|
+
kind: "field",
|
|
5147
|
+
name: property.name,
|
|
5148
|
+
...property.metadata !== void 0 && { metadata: property.metadata },
|
|
5149
|
+
type: property.type,
|
|
5150
|
+
required: !property.optional,
|
|
5151
|
+
constraints: property.constraints,
|
|
5152
|
+
annotations: property.annotations,
|
|
5153
|
+
provenance: property.provenance
|
|
5154
|
+
}));
|
|
5155
|
+
return {
|
|
5156
|
+
name,
|
|
5157
|
+
...metadata !== void 0 && { metadata },
|
|
5158
|
+
fields,
|
|
5159
|
+
fieldLayouts: fields.map(() => ({})),
|
|
5160
|
+
typeRegistry,
|
|
5161
|
+
...annotations !== void 0 && annotations.length > 0 && { annotations },
|
|
5162
|
+
instanceMethods: [],
|
|
5163
|
+
staticMethods: [],
|
|
5164
|
+
diagnostics: []
|
|
5165
|
+
};
|
|
5166
|
+
}
|
|
5167
|
+
function omitApiName(metadata) {
|
|
5168
|
+
if (metadata?.apiName === void 0) {
|
|
5169
|
+
return metadata;
|
|
5170
|
+
}
|
|
5171
|
+
const { apiName: _apiName, ...rest } = metadata;
|
|
5172
|
+
return Object.keys(rest).length > 0 ? rest : void 0;
|
|
5173
|
+
}
|
|
5174
|
+
function describeRootType(rootType, typeRegistry, fallbackName) {
|
|
5175
|
+
if (rootType.kind !== "reference") {
|
|
5176
|
+
return {
|
|
5177
|
+
name: fallbackName,
|
|
5178
|
+
type: rootType
|
|
5179
|
+
};
|
|
5180
|
+
}
|
|
5181
|
+
const definition = typeRegistry[rootType.name];
|
|
5182
|
+
if (definition === void 0) {
|
|
5183
|
+
return {
|
|
5184
|
+
name: rootType.name,
|
|
5185
|
+
type: rootType
|
|
5186
|
+
};
|
|
5187
|
+
}
|
|
5188
|
+
return {
|
|
5189
|
+
name: definition.name,
|
|
5190
|
+
...definition.metadata !== void 0 && { metadata: definition.metadata },
|
|
5191
|
+
...definition.annotations !== void 0 && definition.annotations.length > 0 && { annotations: definition.annotations },
|
|
5192
|
+
type: definition.type
|
|
5193
|
+
};
|
|
5194
|
+
}
|
|
5195
|
+
function toStandaloneJsonSchema(root, typeRegistry, options) {
|
|
5196
|
+
const syntheticFieldMetadata = omitApiName(root.metadata);
|
|
5197
|
+
const syntheticField = {
|
|
5198
|
+
kind: "field",
|
|
5199
|
+
name: "__result",
|
|
5200
|
+
...syntheticFieldMetadata !== void 0 && { metadata: syntheticFieldMetadata },
|
|
5201
|
+
type: root.type,
|
|
5202
|
+
required: true,
|
|
5203
|
+
constraints: [],
|
|
5204
|
+
annotations: [...root.annotations ?? []],
|
|
5205
|
+
provenance: {
|
|
5206
|
+
surface: "tsdoc",
|
|
5207
|
+
file: "",
|
|
5208
|
+
line: 1,
|
|
5209
|
+
column: 0
|
|
5210
|
+
}
|
|
5211
|
+
};
|
|
5212
|
+
const schema = generateJsonSchemaFromIR(
|
|
5213
|
+
{
|
|
5214
|
+
kind: "form-ir",
|
|
5215
|
+
name: root.name,
|
|
5216
|
+
irVersion: import_internals5.IR_VERSION,
|
|
5217
|
+
elements: [syntheticField],
|
|
5218
|
+
...root.metadata !== void 0 && { metadata: root.metadata },
|
|
5219
|
+
...root.annotations !== void 0 && root.annotations.length > 0 && { rootAnnotations: root.annotations },
|
|
5220
|
+
typeRegistry,
|
|
5221
|
+
provenance: syntheticField.provenance
|
|
5222
|
+
},
|
|
5223
|
+
{
|
|
5224
|
+
extensionRegistry: options?.extensionRegistry,
|
|
5225
|
+
vendorPrefix: options?.vendorPrefix
|
|
5226
|
+
}
|
|
5227
|
+
);
|
|
5228
|
+
const result = schema.properties?.["__result"];
|
|
5229
|
+
if (result === void 0) {
|
|
5230
|
+
throw new Error("FormSpec failed to extract the standalone schema root from the synthetic IR.");
|
|
5231
|
+
}
|
|
5232
|
+
if (schema.$defs === void 0 || Object.keys(schema.$defs).length === 0) {
|
|
5233
|
+
return {
|
|
5234
|
+
...schema.$schema !== void 0 && { $schema: schema.$schema },
|
|
5235
|
+
...result
|
|
5236
|
+
};
|
|
5237
|
+
}
|
|
5238
|
+
return {
|
|
5239
|
+
...schema.$schema !== void 0 && { $schema: schema.$schema },
|
|
5240
|
+
...result,
|
|
5241
|
+
$defs: schema.$defs
|
|
5242
|
+
};
|
|
5243
|
+
}
|
|
5244
|
+
function generateSchemasFromAnalysis(analysis, filePath, options) {
|
|
5245
|
+
return toDiscoveredTypeSchemas(
|
|
5246
|
+
generateClassSchemas(
|
|
5247
|
+
analysis,
|
|
5248
|
+
{ file: filePath },
|
|
5249
|
+
{
|
|
5250
|
+
extensionRegistry: options?.extensionRegistry,
|
|
5251
|
+
metadata: options?.metadata,
|
|
5252
|
+
vendorPrefix: options?.vendorPrefix
|
|
5253
|
+
}
|
|
5254
|
+
)
|
|
5255
|
+
);
|
|
5256
|
+
}
|
|
5257
|
+
function generateSchemasFromResolvedType(options, skipNamedDeclaration = false, rootOverride) {
|
|
5258
|
+
const namedDeclaration = skipNamedDeclaration || hasConcreteTypeArguments(options.type, options.context.checker) ? void 0 : getNamedTypeDeclaration2(options.type);
|
|
5259
|
+
if (namedDeclaration !== void 0) {
|
|
5260
|
+
return generateSchemasFromDeclaration({
|
|
5261
|
+
...options,
|
|
5262
|
+
declaration: namedDeclaration
|
|
5263
|
+
});
|
|
5264
|
+
}
|
|
5265
|
+
const filePath = options.sourceNode?.getSourceFile().fileName ?? options.context.sourceFile.fileName;
|
|
5266
|
+
const typeRegistry = {};
|
|
5267
|
+
const diagnostics = [];
|
|
5268
|
+
const rootType = resolveTypeNode(
|
|
5269
|
+
options.type,
|
|
5270
|
+
options.context.checker,
|
|
5271
|
+
filePath,
|
|
5272
|
+
typeRegistry,
|
|
5273
|
+
/* @__PURE__ */ new Set(),
|
|
5274
|
+
options.sourceNode,
|
|
5275
|
+
normalizeMetadataPolicy(options.metadata),
|
|
5276
|
+
options.extensionRegistry,
|
|
5277
|
+
diagnostics
|
|
5278
|
+
);
|
|
5279
|
+
if (diagnostics.length > 0) {
|
|
5280
|
+
const diagnosticDetails = diagnostics.map((diagnostic) => `${diagnostic.code}: ${diagnostic.message}`).join("; ");
|
|
5281
|
+
throw new Error(
|
|
5282
|
+
`FormSpec validation failed while generating discovered type schemas. ${diagnosticDetails}`
|
|
5283
|
+
);
|
|
5284
|
+
}
|
|
5285
|
+
const describedRoot = describeRootType(
|
|
5286
|
+
rootType,
|
|
5287
|
+
typeRegistry,
|
|
5288
|
+
options.name ?? getFallbackName(options.sourceNode)
|
|
5289
|
+
);
|
|
5290
|
+
const mergedMetadata = mergeResolvedMetadata(describedRoot.metadata, rootOverride?.metadata);
|
|
5291
|
+
const root = {
|
|
5292
|
+
...describedRoot,
|
|
5293
|
+
...rootOverride?.name !== void 0 && { name: rootOverride.name },
|
|
5294
|
+
...mergedMetadata !== void 0 && { metadata: mergedMetadata },
|
|
5295
|
+
...rootOverride?.annotations !== void 0 && { annotations: rootOverride.annotations }
|
|
5296
|
+
};
|
|
5297
|
+
if (root.type.kind === "object") {
|
|
5298
|
+
return generateSchemasFromAnalysis(
|
|
5299
|
+
createObjectRootAnalysis(
|
|
5300
|
+
options.name ?? root.name,
|
|
5301
|
+
root.type.properties,
|
|
5302
|
+
typeRegistry,
|
|
5303
|
+
root.metadata,
|
|
5304
|
+
root.annotations
|
|
5305
|
+
),
|
|
5306
|
+
filePath,
|
|
5307
|
+
options
|
|
5308
|
+
);
|
|
5309
|
+
}
|
|
5310
|
+
return {
|
|
5311
|
+
jsonSchema: toStandaloneJsonSchema(root, typeRegistry, options),
|
|
5312
|
+
uiSchema: null
|
|
5313
|
+
};
|
|
5314
|
+
}
|
|
5315
|
+
function generateSchemasFromDeclaration(options) {
|
|
5316
|
+
const filePath = options.declaration.getSourceFile().fileName;
|
|
5317
|
+
if (ts7.isClassDeclaration(options.declaration)) {
|
|
5318
|
+
return generateSchemasFromAnalysis(
|
|
5319
|
+
analyzeClassToIR(
|
|
5320
|
+
options.declaration,
|
|
5321
|
+
options.context.checker,
|
|
5322
|
+
filePath,
|
|
5323
|
+
options.extensionRegistry,
|
|
5324
|
+
options.metadata
|
|
5325
|
+
),
|
|
5326
|
+
filePath,
|
|
5327
|
+
options
|
|
5328
|
+
);
|
|
5329
|
+
}
|
|
5330
|
+
if (ts7.isInterfaceDeclaration(options.declaration)) {
|
|
5331
|
+
return generateSchemasFromAnalysis(
|
|
5332
|
+
analyzeInterfaceToIR(
|
|
5333
|
+
options.declaration,
|
|
5334
|
+
options.context.checker,
|
|
5335
|
+
filePath,
|
|
5336
|
+
options.extensionRegistry,
|
|
5337
|
+
options.metadata
|
|
5338
|
+
),
|
|
5339
|
+
filePath,
|
|
5340
|
+
options
|
|
5341
|
+
);
|
|
5342
|
+
}
|
|
5343
|
+
if (ts7.isTypeAliasDeclaration(options.declaration)) {
|
|
5344
|
+
const analyzedAlias = analyzeTypeAliasToIR(
|
|
5345
|
+
options.declaration,
|
|
5346
|
+
options.context.checker,
|
|
5347
|
+
filePath,
|
|
5348
|
+
options.extensionRegistry,
|
|
5349
|
+
options.metadata
|
|
5350
|
+
);
|
|
5351
|
+
if (analyzedAlias.ok) {
|
|
5352
|
+
return generateSchemasFromAnalysis(analyzedAlias.analysis, filePath, options);
|
|
5353
|
+
}
|
|
5354
|
+
const aliasRootInfo = analyzeDeclarationRootInfo(
|
|
5355
|
+
options.declaration,
|
|
5356
|
+
options.context.checker,
|
|
5357
|
+
filePath,
|
|
5358
|
+
options.extensionRegistry,
|
|
5359
|
+
options.metadata
|
|
5360
|
+
);
|
|
5361
|
+
if (aliasRootInfo.diagnostics.length > 0) {
|
|
5362
|
+
const diagnosticDetails = aliasRootInfo.diagnostics.map((diagnostic) => `${diagnostic.code}: ${diagnostic.message}`).join("; ");
|
|
5363
|
+
throw new Error(
|
|
5364
|
+
`FormSpec validation failed while generating discovered type schemas. ${diagnosticDetails}`
|
|
5365
|
+
);
|
|
5366
|
+
}
|
|
5367
|
+
return generateSchemasFromResolvedType(
|
|
5368
|
+
{
|
|
5369
|
+
...options,
|
|
5370
|
+
type: options.context.checker.getTypeAtLocation(options.declaration),
|
|
5371
|
+
sourceNode: options.declaration,
|
|
5372
|
+
name: options.declaration.name.text
|
|
5373
|
+
},
|
|
5374
|
+
true,
|
|
5375
|
+
{
|
|
5376
|
+
name: options.declaration.name.text,
|
|
5377
|
+
...aliasRootInfo.metadata !== void 0 && { metadata: aliasRootInfo.metadata },
|
|
5378
|
+
...aliasRootInfo.annotations.length > 0 && { annotations: aliasRootInfo.annotations }
|
|
5379
|
+
}
|
|
5380
|
+
);
|
|
5381
|
+
}
|
|
5382
|
+
const _exhaustive = options.declaration;
|
|
5383
|
+
return _exhaustive;
|
|
5384
|
+
}
|
|
5385
|
+
function generateSchemasFromType(options) {
|
|
5386
|
+
return generateSchemasFromResolvedType(options);
|
|
5387
|
+
}
|
|
5388
|
+
function generateSchemasFromParameter(options) {
|
|
5389
|
+
return generateSchemasFromResolvedType({
|
|
5390
|
+
...options,
|
|
5391
|
+
type: options.context.checker.getTypeAtLocation(options.parameter),
|
|
5392
|
+
sourceNode: options.parameter,
|
|
5393
|
+
name: getFallbackName(options.parameter, "Parameter")
|
|
5394
|
+
});
|
|
5395
|
+
}
|
|
5396
|
+
function generateSchemasFromReturnType(options) {
|
|
5397
|
+
const signature = options.context.checker.getSignatureFromDeclaration(options.declaration);
|
|
5398
|
+
const type = signature !== void 0 ? options.context.checker.getReturnTypeOfSignature(signature) : options.context.checker.getTypeAtLocation(options.declaration);
|
|
5399
|
+
const fallbackName = options.declaration.name !== void 0 && ts7.isIdentifier(options.declaration.name) ? `${options.declaration.name.text}ReturnType` : "ReturnType";
|
|
5400
|
+
return generateSchemasFromResolvedType({
|
|
5401
|
+
...options,
|
|
5402
|
+
type,
|
|
5403
|
+
sourceNode: options.declaration.type ?? options.declaration,
|
|
5404
|
+
name: fallbackName
|
|
5405
|
+
});
|
|
5406
|
+
}
|
|
5407
|
+
var ts7, import_internals5;
|
|
5408
|
+
var init_discovered_schema = __esm({
|
|
5409
|
+
"src/generators/discovered-schema.ts"() {
|
|
5410
|
+
"use strict";
|
|
5411
|
+
ts7 = __toESM(require("typescript"), 1);
|
|
5412
|
+
init_class_analyzer();
|
|
5413
|
+
init_class_schema();
|
|
5414
|
+
init_ir_generator();
|
|
5415
|
+
import_internals5 = require("@formspec/core/internals");
|
|
5416
|
+
init_metadata();
|
|
5417
|
+
}
|
|
5418
|
+
});
|
|
5419
|
+
|
|
4879
5420
|
// src/generators/mixed-authoring.ts
|
|
4880
5421
|
function buildMixedAuthoringSchemas(options) {
|
|
4881
5422
|
const { filePath, typeName, overlays, ...schemaOptions } = options;
|
|
@@ -5082,12 +5623,20 @@ __export(index_exports, {
|
|
|
5082
5623
|
buildFormSchemas: () => buildFormSchemas,
|
|
5083
5624
|
buildMixedAuthoringSchemas: () => buildMixedAuthoringSchemas,
|
|
5084
5625
|
createExtensionRegistry: () => createExtensionRegistry,
|
|
5626
|
+
createStaticBuildContext: () => createStaticBuildContext,
|
|
5627
|
+
createStaticBuildContextFromProgram: () => createStaticBuildContextFromProgram,
|
|
5085
5628
|
generateJsonSchema: () => generateJsonSchema,
|
|
5086
5629
|
generateSchemas: () => generateSchemas,
|
|
5087
5630
|
generateSchemasFromClass: () => generateSchemasFromClass,
|
|
5631
|
+
generateSchemasFromDeclaration: () => generateSchemasFromDeclaration,
|
|
5632
|
+
generateSchemasFromParameter: () => generateSchemasFromParameter,
|
|
5088
5633
|
generateSchemasFromProgram: () => generateSchemasFromProgram,
|
|
5634
|
+
generateSchemasFromReturnType: () => generateSchemasFromReturnType,
|
|
5635
|
+
generateSchemasFromType: () => generateSchemasFromType,
|
|
5089
5636
|
generateUiSchema: () => generateUiSchema,
|
|
5090
5637
|
jsonSchema7Schema: () => jsonSchema7Schema,
|
|
5638
|
+
resolveModuleExport: () => resolveModuleExport,
|
|
5639
|
+
resolveModuleExportDeclaration: () => resolveModuleExportDeclaration,
|
|
5091
5640
|
uiSchemaSchema: () => uiSchema,
|
|
5092
5641
|
writeSchemas: () => writeSchemas
|
|
5093
5642
|
});
|
|
@@ -5125,6 +5674,8 @@ var init_index = __esm({
|
|
|
5125
5674
|
init_generator();
|
|
5126
5675
|
init_generator2();
|
|
5127
5676
|
init_class_schema();
|
|
5677
|
+
init_static_build();
|
|
5678
|
+
init_discovered_schema();
|
|
5128
5679
|
init_mixed_authoring();
|
|
5129
5680
|
}
|
|
5130
5681
|
});
|