@formspec/build 0.1.0-alpha.31 → 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
@@ -2987,6 +2987,27 @@ function resolveNodeMetadata(metadataPolicy, declarationKind, logicalName, node,
2987
2987
  makeMetadataContext("tsdoc", declarationKind, logicalName, buildContext)
2988
2988
  );
2989
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
+ }
2990
3011
  function analyzeClassToIR(classDecl, checker, file = "", extensionRegistry, metadataPolicy) {
2991
3012
  const normalizedMetadataPolicy = normalizeMetadataPolicy(metadataPolicy);
2992
3013
  const name = classDecl.name?.text ?? "AnonymousClass";
@@ -3401,10 +3422,7 @@ function resolveLiteralDiscriminatorPropertyValue(boundType, fieldName, checker,
3401
3422
  if (resolvedAnchorNode === null) {
3402
3423
  return void 0;
3403
3424
  }
3404
- const propertyType = checker.getTypeOfSymbolAtLocation(
3405
- propertySymbol,
3406
- resolvedAnchorNode
3407
- );
3425
+ const propertyType = checker.getTypeOfSymbolAtLocation(propertySymbol, resolvedAnchorNode);
3408
3426
  if (propertyType.isStringLiteral()) {
3409
3427
  return propertyType.value;
3410
3428
  }
@@ -4363,14 +4381,39 @@ function resolveObjectType(type, checker, file, typeRegistry, visiting, sourceNo
4363
4381
  collectedDiagnostics
4364
4382
  );
4365
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;
4366
4407
  properties.push({
4367
4408
  name: prop.name,
4368
- ...fieldNodeInfo?.metadata !== void 0 && { metadata: fieldNodeInfo.metadata },
4369
- type: propTypeNode,
4409
+ ...resolvedFieldNodeInfo?.metadata !== void 0 && {
4410
+ metadata: resolvedFieldNodeInfo.metadata
4411
+ },
4412
+ type: resolvedPropertyType,
4370
4413
  optional,
4371
- constraints: fieldNodeInfo?.constraints ?? [],
4372
- annotations: fieldNodeInfo?.annotations ?? [],
4373
- provenance: fieldNodeInfo?.provenance ?? provenanceForFile(file)
4414
+ constraints: resolvedFieldNodeInfo?.constraints ?? [],
4415
+ annotations: resolvedFieldNodeInfo?.annotations ?? [],
4416
+ provenance: resolvedFieldNodeInfo?.provenance ?? provenanceForFile(file)
4374
4417
  });
4375
4418
  }
4376
4419
  visiting.delete(type);
@@ -5018,6 +5061,362 @@ var init_class_schema = __esm({
5018
5061
  }
5019
5062
  });
5020
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
+
5021
5420
  // src/generators/mixed-authoring.ts
5022
5421
  function buildMixedAuthoringSchemas(options) {
5023
5422
  const { filePath, typeName, overlays, ...schemaOptions } = options;
@@ -5224,12 +5623,20 @@ __export(index_exports, {
5224
5623
  buildFormSchemas: () => buildFormSchemas,
5225
5624
  buildMixedAuthoringSchemas: () => buildMixedAuthoringSchemas,
5226
5625
  createExtensionRegistry: () => createExtensionRegistry,
5626
+ createStaticBuildContext: () => createStaticBuildContext,
5627
+ createStaticBuildContextFromProgram: () => createStaticBuildContextFromProgram,
5227
5628
  generateJsonSchema: () => generateJsonSchema,
5228
5629
  generateSchemas: () => generateSchemas,
5229
5630
  generateSchemasFromClass: () => generateSchemasFromClass,
5631
+ generateSchemasFromDeclaration: () => generateSchemasFromDeclaration,
5632
+ generateSchemasFromParameter: () => generateSchemasFromParameter,
5230
5633
  generateSchemasFromProgram: () => generateSchemasFromProgram,
5634
+ generateSchemasFromReturnType: () => generateSchemasFromReturnType,
5635
+ generateSchemasFromType: () => generateSchemasFromType,
5231
5636
  generateUiSchema: () => generateUiSchema,
5232
5637
  jsonSchema7Schema: () => jsonSchema7Schema,
5638
+ resolveModuleExport: () => resolveModuleExport,
5639
+ resolveModuleExportDeclaration: () => resolveModuleExportDeclaration,
5233
5640
  uiSchemaSchema: () => uiSchema,
5234
5641
  writeSchemas: () => writeSchemas
5235
5642
  });
@@ -5267,6 +5674,8 @@ var init_index = __esm({
5267
5674
  init_generator();
5268
5675
  init_generator2();
5269
5676
  init_class_schema();
5677
+ init_static_build();
5678
+ init_discovered_schema();
5270
5679
  init_mixed_authoring();
5271
5680
  }
5272
5681
  });