@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/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[getSerializedName(element.name, element.metadata)] = generateFieldSchema(element, ctx);
1015
+ properties[getSerializedFieldName(element)] = generateFieldSchema(element, ctx);
1016
1016
  if (element.required) {
1017
- required.push(getSerializedName(element.name, element.metadata));
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 byTarget = /* @__PURE__ */ new Map();
1089
- for (const c of pathConstraints) {
1090
- const target = c.path?.segments[0];
1091
- if (!target) continue;
1092
- const group = byTarget.get(target) ?? [];
1093
- group.push(c);
1094
- byTarget.set(target, group);
1095
- }
1096
- const propertyOverrides = {};
1097
- for (const [target, constraints] of byTarget) {
1098
- const subSchema = {};
1099
- applyConstraints(subSchema, constraints, ctx);
1100
- propertyOverrides[resolveSerializedPropertyName(target, typeNode, ctx)] = subSchema;
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
- Object.assign(schema.properties[target], overrideSchema);
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 = getSerializedName(prop.name, prop.metadata);
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/${ctx.typeNameMap[type.name] ?? type.name}` };
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
- if (typeNode?.kind === "object") {
1256
- const property = typeNode.properties.find((candidate) => candidate.name === logicalName);
1257
- return property === void 0 ? logicalName : getSerializedName(property.name, property.metadata);
1288
+ const effectiveType = resolveTraversableTypeNode(typeNode, ctx);
1289
+ if (effectiveType?.kind === "array") {
1290
+ return resolveSerializedPropertyName(logicalName, effectiveType.items, ctx);
1258
1291
  }
1259
- if (typeNode?.kind === "reference") {
1260
- const referencedType = resolveReferencedType(typeNode, ctx);
1261
- return referencedType === void 0 ? logicalName : resolveSerializedPropertyName(logicalName, referencedType, ctx);
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
- ...fieldNodeInfo?.metadata !== void 0 && { metadata: fieldNodeInfo.metadata },
4227
- type: propTypeNode,
4409
+ ...resolvedFieldNodeInfo?.metadata !== void 0 && {
4410
+ metadata: resolvedFieldNodeInfo.metadata
4411
+ },
4412
+ type: resolvedPropertyType,
4228
4413
  optional,
4229
- constraints: fieldNodeInfo?.constraints ?? [],
4230
- annotations: fieldNodeInfo?.annotations ?? [],
4231
- provenance: fieldNodeInfo?.provenance ?? provenanceForFile(file)
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
  });