@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/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[getSerializedName(element.name, element.metadata)] = generateFieldSchema(element, ctx);
989
+ properties[getSerializedFieldName(element)] = generateFieldSchema(element, ctx);
982
990
  if (element.required) {
983
- required.push(getSerializedName(element.name, element.metadata));
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 byTarget = /* @__PURE__ */ new Map();
1055
- for (const c of pathConstraints) {
1056
- const target = c.path?.segments[0];
1057
- if (!target) continue;
1058
- const group = byTarget.get(target) ?? [];
1059
- group.push(c);
1060
- byTarget.set(target, group);
1061
- }
1062
- const propertyOverrides = {};
1063
- for (const [target, constraints] of byTarget) {
1064
- const subSchema = {};
1065
- applyConstraints(subSchema, constraints, ctx);
1066
- propertyOverrides[resolveSerializedPropertyName(target, typeNode, ctx)] = subSchema;
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
- Object.assign(schema.properties[target], overrideSchema);
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 = getSerializedName(prop.name, prop.metadata);
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/${ctx.typeNameMap[type.name] ?? type.name}` };
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
- if (typeNode?.kind === "object") {
1222
- const property = typeNode.properties.find((candidate) => candidate.name === logicalName);
1223
- return property === void 0 ? logicalName : getSerializedName(property.name, property.metadata);
1262
+ const effectiveType = resolveTraversableTypeNode(typeNode, ctx);
1263
+ if (effectiveType?.kind === "array") {
1264
+ return resolveSerializedPropertyName(logicalName, effectiveType.items, ctx);
1224
1265
  }
1225
- if (typeNode?.kind === "reference") {
1226
- const referencedType = resolveReferencedType(typeNode, ctx);
1227
- return referencedType === void 0 ? logicalName : resolveSerializedPropertyName(logicalName, referencedType, ctx);
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
- ...fieldNodeInfo?.metadata !== void 0 && { metadata: fieldNodeInfo.metadata },
4147
- type: propTypeNode,
4337
+ ...resolvedFieldNodeInfo?.metadata !== void 0 && {
4338
+ metadata: resolvedFieldNodeInfo.metadata
4339
+ },
4340
+ type: resolvedPropertyType,
4148
4341
  optional,
4149
- constraints: fieldNodeInfo?.constraints ?? [],
4150
- annotations: fieldNodeInfo?.annotations ?? [],
4151
- provenance: fieldNodeInfo?.provenance ?? provenanceForFile(file)
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
  });