@formspec/build 0.1.0-alpha.37 → 0.1.0-alpha.39

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
@@ -2223,6 +2223,16 @@ function buildSupportingDeclarations(sourceFile, extensionTypeNames) {
2223
2223
  return true;
2224
2224
  }).map((statement) => statement.getText(sourceFile));
2225
2225
  }
2226
+ function pushUniqueCompilerDiagnostics(target, additions) {
2227
+ for (const diagnostic of additions) {
2228
+ if ((diagnostic.code === "UNSUPPORTED_CUSTOM_TYPE_OVERRIDE" || diagnostic.code === "SYNTHETIC_SETUP_FAILURE") && target.some(
2229
+ (existing) => existing.code === diagnostic.code && existing.message === diagnostic.message
2230
+ )) {
2231
+ continue;
2232
+ }
2233
+ target.push(diagnostic);
2234
+ }
2235
+ }
2226
2236
  function renderSyntheticArgumentExpression(valueKind, argumentText) {
2227
2237
  const trimmed = argumentText.trim();
2228
2238
  if (trimmed === "") {
@@ -2489,6 +2499,16 @@ function buildCompilerBackedConstraintDiagnostics(node, sourceFile, tagName, par
2489
2499
  if (result.diagnostics.length === 0) {
2490
2500
  return [];
2491
2501
  }
2502
+ const setupDiagnostic = result.diagnostics.find((diagnostic) => diagnostic.kind !== "typescript");
2503
+ if (setupDiagnostic !== void 0) {
2504
+ return [
2505
+ makeDiagnostic(
2506
+ setupDiagnostic.kind === "unsupported-custom-type-override" ? "UNSUPPORTED_CUSTOM_TYPE_OVERRIDE" : "SYNTHETIC_SETUP_FAILURE",
2507
+ setupDiagnostic.message,
2508
+ provenance
2509
+ )
2510
+ ];
2511
+ }
2492
2512
  const expectedLabel = definition.valueKind === null ? "compatible argument" : capabilityLabel(definition.valueKind);
2493
2513
  return [
2494
2514
  makeDiagnostic(
@@ -2652,7 +2672,7 @@ function parseTSDocTags(node, file = "", options) {
2652
2672
  options
2653
2673
  );
2654
2674
  if (compilerDiagnostics.length > 0) {
2655
- diagnostics.push(...compilerDiagnostics);
2675
+ pushUniqueCompilerDiagnostics(diagnostics, compilerDiagnostics);
2656
2676
  continue;
2657
2677
  }
2658
2678
  const constraintNode = (0, import_internal2.parseConstraintTagValue)(
@@ -2739,7 +2759,7 @@ function parseTSDocTags(node, file = "", options) {
2739
2759
  options
2740
2760
  );
2741
2761
  if (compilerDiagnostics.length > 0) {
2742
- diagnostics.push(...compilerDiagnostics);
2762
+ pushUniqueCompilerDiagnostics(diagnostics, compilerDiagnostics);
2743
2763
  continue;
2744
2764
  }
2745
2765
  const constraintNode = (0, import_internal2.parseConstraintTagValue)(
@@ -2773,7 +2793,7 @@ function parseTSDocTags(node, file = "", options) {
2773
2793
  options
2774
2794
  );
2775
2795
  if (compilerDiagnostics.length > 0) {
2776
- diagnostics.push(...compilerDiagnostics);
2796
+ pushUniqueCompilerDiagnostics(diagnostics, compilerDiagnostics);
2777
2797
  continue;
2778
2798
  }
2779
2799
  const constraintNode = (0, import_internal2.parseConstraintTagValue)(
@@ -5231,29 +5251,35 @@ function analyzeNamedTypeToIR(filePath, typeName, extensionRegistry, metadataPol
5231
5251
  discriminatorOptions
5232
5252
  );
5233
5253
  }
5234
- function analyzeNamedTypeToIRFromProgramContext(ctx, filePath, typeName, extensionRegistry, metadataPolicy, discriminatorOptions) {
5254
+ function analyzeNamedTypeToIRFromProgramContextDetailed(ctx, filePath, typeName, extensionRegistry, metadataPolicy, discriminatorOptions) {
5235
5255
  const analysisFilePath = path.resolve(filePath);
5236
5256
  const classDecl = findClassByName(ctx.sourceFile, typeName);
5237
5257
  if (classDecl !== null) {
5238
- return analyzeClassToIR(
5239
- classDecl,
5240
- ctx.checker,
5241
- analysisFilePath,
5242
- extensionRegistry,
5243
- metadataPolicy,
5244
- discriminatorOptions
5245
- );
5258
+ return {
5259
+ ok: true,
5260
+ analysis: analyzeClassToIR(
5261
+ classDecl,
5262
+ ctx.checker,
5263
+ analysisFilePath,
5264
+ extensionRegistry,
5265
+ metadataPolicy,
5266
+ discriminatorOptions
5267
+ )
5268
+ };
5246
5269
  }
5247
5270
  const interfaceDecl = findInterfaceByName(ctx.sourceFile, typeName);
5248
5271
  if (interfaceDecl !== null) {
5249
- return analyzeInterfaceToIR(
5250
- interfaceDecl,
5251
- ctx.checker,
5252
- analysisFilePath,
5253
- extensionRegistry,
5254
- metadataPolicy,
5255
- discriminatorOptions
5256
- );
5272
+ return {
5273
+ ok: true,
5274
+ analysis: analyzeInterfaceToIR(
5275
+ interfaceDecl,
5276
+ ctx.checker,
5277
+ analysisFilePath,
5278
+ extensionRegistry,
5279
+ metadataPolicy,
5280
+ discriminatorOptions
5281
+ )
5282
+ };
5257
5283
  }
5258
5284
  const typeAlias = findTypeAliasByName(ctx.sourceFile, typeName);
5259
5285
  if (typeAlias !== null) {
@@ -5266,11 +5292,20 @@ function analyzeNamedTypeToIRFromProgramContext(ctx, filePath, typeName, extensi
5266
5292
  discriminatorOptions
5267
5293
  );
5268
5294
  if (result.ok) {
5269
- return result.analysis;
5295
+ return { ok: true, analysis: result.analysis };
5270
5296
  }
5271
5297
  const fallbackEligible = result.kind === "not-object-like" && isResolvableObjectLikeAliasTypeNode(typeAlias.type) && containsTypeReferenceInObjectLikeAlias(typeAlias.type);
5272
5298
  if (!fallbackEligible) {
5273
- throw new Error(result.error);
5299
+ return {
5300
+ ok: false,
5301
+ diagnostics: [
5302
+ makeProgramDiagnostic(
5303
+ result.kind === "duplicate-properties" ? "DUPLICATE_ROOT_PROPERTIES" : "UNSUPPORTED_ROOT_TYPE",
5304
+ result.error,
5305
+ makeNodeProvenance(typeAlias, analysisFilePath)
5306
+ )
5307
+ ]
5308
+ };
5274
5309
  }
5275
5310
  const duplicatePropertyNames = findFallbackAliasDuplicatePropertyNames(
5276
5311
  typeAlias.type,
@@ -5279,9 +5314,16 @@ function analyzeNamedTypeToIRFromProgramContext(ctx, filePath, typeName, extensi
5279
5314
  if (duplicatePropertyNames.length > 0) {
5280
5315
  const sourceFile = typeAlias.getSourceFile();
5281
5316
  const { line } = sourceFile.getLineAndCharacterOfPosition(typeAlias.getStart());
5282
- throw new Error(
5283
- `Type alias "${typeAlias.name.text}" at line ${String(line + 1)} contains duplicate property names across object-like members: ${duplicatePropertyNames.join(", ")}`
5284
- );
5317
+ return {
5318
+ ok: false,
5319
+ diagnostics: [
5320
+ makeProgramDiagnostic(
5321
+ "DUPLICATE_ROOT_PROPERTIES",
5322
+ `Type alias "${typeAlias.name.text}" at line ${String(line + 1)} contains duplicate property names across object-like members: ${duplicatePropertyNames.join(", ")}`,
5323
+ makeNodeProvenance(typeAlias, analysisFilePath)
5324
+ )
5325
+ ]
5326
+ };
5285
5327
  }
5286
5328
  const rootInfo = analyzeDeclarationRootInfo(
5287
5329
  typeAlias,
@@ -5311,13 +5353,71 @@ function analyzeNamedTypeToIRFromProgramContext(ctx, filePath, typeName, extensi
5311
5353
  diagnostics
5312
5354
  );
5313
5355
  if (fallbackAnalysis !== null) {
5314
- return fallbackAnalysis;
5356
+ return { ok: true, analysis: fallbackAnalysis };
5315
5357
  }
5316
- throw new Error(result.error);
5358
+ return {
5359
+ ok: false,
5360
+ diagnostics: [
5361
+ makeProgramDiagnostic(
5362
+ "UNSUPPORTED_ROOT_TYPE",
5363
+ result.error,
5364
+ makeNodeProvenance(typeAlias, analysisFilePath)
5365
+ )
5366
+ ]
5367
+ };
5317
5368
  }
5318
- throw new Error(
5319
- `Type "${typeName}" not found as a class, interface, or type alias in ${analysisFilePath}`
5369
+ return {
5370
+ ok: false,
5371
+ diagnostics: [
5372
+ makeProgramDiagnostic(
5373
+ "TYPE_NOT_FOUND",
5374
+ `Type "${typeName}" not found as a class, interface, or type alias in ${analysisFilePath}`,
5375
+ makeFileProvenance(analysisFilePath)
5376
+ )
5377
+ ]
5378
+ };
5379
+ }
5380
+ function analyzeNamedTypeToIRFromProgramContext(ctx, filePath, typeName, extensionRegistry, metadataPolicy, discriminatorOptions) {
5381
+ const result = analyzeNamedTypeToIRFromProgramContextDetailed(
5382
+ ctx,
5383
+ filePath,
5384
+ typeName,
5385
+ extensionRegistry,
5386
+ metadataPolicy,
5387
+ discriminatorOptions
5320
5388
  );
5389
+ if (result.ok) {
5390
+ return result.analysis;
5391
+ }
5392
+ throw new Error(result.diagnostics.map((diagnostic) => diagnostic.message).join("\n"));
5393
+ }
5394
+ function makeProgramDiagnostic(code, message, primaryLocation) {
5395
+ return {
5396
+ code,
5397
+ message,
5398
+ severity: "error",
5399
+ primaryLocation,
5400
+ relatedLocations: []
5401
+ };
5402
+ }
5403
+ function makeNodeProvenance(node, filePath) {
5404
+ const sourceFile = node.getSourceFile();
5405
+ const position = sourceFile.getLineAndCharacterOfPosition(node.getStart());
5406
+ return {
5407
+ surface: "tsdoc",
5408
+ file: filePath,
5409
+ line: position.line + 1,
5410
+ column: position.character,
5411
+ length: node.getWidth()
5412
+ };
5413
+ }
5414
+ function makeFileProvenance(filePath) {
5415
+ return {
5416
+ surface: "tsdoc",
5417
+ file: filePath,
5418
+ line: 1,
5419
+ column: 0
5420
+ };
5321
5421
  }
5322
5422
  var ts4, path;
5323
5423
  var init_program = __esm({
@@ -5418,11 +5518,25 @@ var init_validate = __esm({
5418
5518
 
5419
5519
  // src/generators/class-schema.ts
5420
5520
  function generateClassSchemas(analysis, source, options) {
5421
- const errorDiagnostics = analysis.diagnostics?.filter(
5521
+ const result = generateClassSchemasDetailed(analysis, source, options);
5522
+ if (!result.ok || result.jsonSchema === void 0 || result.uiSchema === void 0) {
5523
+ throw new Error(formatValidationError(result.diagnostics));
5524
+ }
5525
+ return {
5526
+ jsonSchema: result.jsonSchema,
5527
+ uiSchema: result.uiSchema
5528
+ };
5529
+ }
5530
+ function generateClassSchemasDetailed(analysis, source, options) {
5531
+ const analysisDiagnostics = analysis.diagnostics ?? [];
5532
+ const errorDiagnostics = analysisDiagnostics.filter(
5422
5533
  (diagnostic) => diagnostic.severity === "error"
5423
5534
  );
5424
- if (errorDiagnostics !== void 0 && errorDiagnostics.length > 0) {
5425
- throw new Error(formatValidationError(errorDiagnostics));
5535
+ if (errorDiagnostics.length > 0) {
5536
+ return {
5537
+ ok: false,
5538
+ diagnostics: analysisDiagnostics
5539
+ };
5426
5540
  }
5427
5541
  const ir = canonicalizeTSDoc(
5428
5542
  analysis,
@@ -5436,9 +5550,14 @@ function generateClassSchemas(analysis, source, options) {
5436
5550
  ...options?.vendorPrefix !== void 0 && { vendorPrefix: options.vendorPrefix }
5437
5551
  });
5438
5552
  if (!validationResult.valid) {
5439
- throw new Error(formatValidationError(validationResult.diagnostics));
5553
+ return {
5554
+ ok: false,
5555
+ diagnostics: [...analysisDiagnostics, ...validationResult.diagnostics]
5556
+ };
5440
5557
  }
5441
5558
  return {
5559
+ ok: true,
5560
+ diagnostics: [...analysisDiagnostics, ...validationResult.diagnostics],
5442
5561
  jsonSchema: generateJsonSchemaFromIR(ir, options),
5443
5562
  uiSchema: generateUiSchemaFromIR(ir)
5444
5563
  };
@@ -5480,25 +5599,127 @@ function generateSchemasFromClass(options) {
5480
5599
  );
5481
5600
  }
5482
5601
  function generateSchemas(options) {
5483
- const ctx = createProgramContext(options.filePath);
5602
+ const result = generateSchemasDetailedInternal(options);
5603
+ if (options.errorReporting === "diagnostics") {
5604
+ return result;
5605
+ }
5606
+ if (!result.ok || result.jsonSchema === void 0 || result.uiSchema === void 0) {
5607
+ throw new Error(formatValidationError(result.diagnostics));
5608
+ }
5609
+ return {
5610
+ jsonSchema: result.jsonSchema,
5611
+ uiSchema: result.uiSchema
5612
+ };
5613
+ }
5614
+ function generateSchemasFromProgram(options) {
5615
+ const result = generateSchemasFromProgramDetailedInternal(options);
5616
+ if (options.errorReporting === "diagnostics") {
5617
+ return result;
5618
+ }
5619
+ if (!result.ok || result.jsonSchema === void 0 || result.uiSchema === void 0) {
5620
+ throw new Error(formatValidationError(result.diagnostics));
5621
+ }
5622
+ return {
5623
+ jsonSchema: result.jsonSchema,
5624
+ uiSchema: result.uiSchema
5625
+ };
5626
+ }
5627
+ function generateSchemasDetailed(options) {
5628
+ return generateSchemas({
5629
+ ...options,
5630
+ errorReporting: "diagnostics"
5631
+ });
5632
+ }
5633
+ function generateSchemasDetailedInternal(options) {
5634
+ let ctx;
5635
+ try {
5636
+ ctx = createProgramContext(options.filePath);
5637
+ } catch (error) {
5638
+ return {
5639
+ ok: false,
5640
+ diagnostics: [createProgramContextFailureDiagnostic(options.filePath, error)]
5641
+ };
5642
+ }
5643
+ return generateSchemasFromDetailedProgramContext(ctx, options.filePath, options.typeName, options);
5644
+ }
5645
+ function generateSchemasFromProgramDetailed(options) {
5484
5646
  return generateSchemasFromProgram({
5485
5647
  ...options,
5486
- program: ctx.program
5648
+ errorReporting: "diagnostics"
5487
5649
  });
5488
5650
  }
5489
- function generateSchemasFromProgram(options) {
5490
- const ctx = createProgramContextFromProgram(options.program, options.filePath);
5491
- const analysis = analyzeNamedTypeToIRFromProgramContext(
5651
+ function generateSchemasFromProgramDetailedInternal(options) {
5652
+ let ctx;
5653
+ try {
5654
+ ctx = createProgramContextFromProgram(options.program, options.filePath);
5655
+ } catch (error) {
5656
+ return {
5657
+ ok: false,
5658
+ diagnostics: [createProgramContextFailureDiagnostic(options.filePath, error)]
5659
+ };
5660
+ }
5661
+ return generateSchemasFromDetailedProgramContext(ctx, options.filePath, options.typeName, options);
5662
+ }
5663
+ function generateSchemasBatch(options) {
5664
+ const contextCache = /* @__PURE__ */ new Map();
5665
+ return options.targets.map((target) => {
5666
+ let ctx;
5667
+ try {
5668
+ const cacheKey = ts5.sys.useCaseSensitiveFileNames ? target.filePath : target.filePath.toLowerCase();
5669
+ const cachedContext = contextCache.get(cacheKey);
5670
+ if (cachedContext === void 0) {
5671
+ ctx = createProgramContext(target.filePath);
5672
+ contextCache.set(cacheKey, ctx);
5673
+ } else {
5674
+ ctx = cachedContext;
5675
+ }
5676
+ } catch (error) {
5677
+ return withTarget(target, {
5678
+ ok: false,
5679
+ diagnostics: [createProgramContextFailureDiagnostic(target.filePath, error)]
5680
+ });
5681
+ }
5682
+ return withTarget(
5683
+ target,
5684
+ generateSchemasFromDetailedProgramContext(ctx, target.filePath, target.typeName, options)
5685
+ );
5686
+ });
5687
+ }
5688
+ function generateSchemasBatchFromProgram(options) {
5689
+ return options.targets.map((target) => {
5690
+ let ctx;
5691
+ try {
5692
+ ctx = createProgramContextFromProgram(options.program, target.filePath);
5693
+ } catch (error) {
5694
+ return withTarget(target, {
5695
+ ok: false,
5696
+ diagnostics: [createProgramContextFailureDiagnostic(target.filePath, error)]
5697
+ });
5698
+ }
5699
+ return withTarget(
5700
+ target,
5701
+ generateSchemasFromDetailedProgramContext(ctx, target.filePath, target.typeName, options)
5702
+ );
5703
+ });
5704
+ }
5705
+ function generateSchemasFromDetailedProgramContext(ctx, filePath, typeName, options) {
5706
+ const analysisResult = analyzeNamedTypeToIRFromProgramContextDetailed(
5492
5707
  ctx,
5493
- options.filePath,
5494
- options.typeName,
5708
+ filePath,
5709
+ typeName,
5495
5710
  options.extensionRegistry,
5496
5711
  options.metadata,
5497
5712
  options.discriminator
5498
5713
  );
5499
- return generateClassSchemas(
5500
- analysis,
5501
- { file: options.filePath },
5714
+ if (!analysisResult.ok) {
5715
+ return {
5716
+ ok: false,
5717
+ diagnostics: analysisResult.diagnostics
5718
+ };
5719
+ }
5720
+ return generateClassSchemasDetailed(
5721
+ analysisResult.analysis,
5722
+ { file: filePath },
5502
5723
  {
5503
5724
  extensionRegistry: options.extensionRegistry,
5504
5725
  metadata: options.metadata,
@@ -5506,11 +5727,32 @@ function generateSchemasFromProgram(options) {
5506
5727
  }
5507
5728
  );
5508
5729
  }
5730
+ function withTarget(target, result) {
5731
+ return {
5732
+ filePath: target.filePath,
5733
+ typeName: target.typeName,
5734
+ ...result
5735
+ };
5736
+ }
5737
+ function createProgramContextFailureDiagnostic(filePath, error) {
5738
+ return {
5739
+ code: "PROGRAM_CONTEXT_FAILURE",
5740
+ message: error instanceof Error ? error.message : String(error),
5741
+ severity: "error",
5742
+ primaryLocation: {
5743
+ surface: "tsdoc",
5744
+ file: filePath,
5745
+ line: 1,
5746
+ column: 0
5747
+ },
5748
+ relatedLocations: []
5749
+ };
5750
+ }
5509
5751
  var ts5;
5510
5752
  var init_class_schema = __esm({
5511
5753
  "src/generators/class-schema.ts"() {
5512
5754
  "use strict";
5513
- ts5 = require("typescript");
5755
+ ts5 = __toESM(require("typescript"), 1);
5514
5756
  init_program();
5515
5757
  init_class_analyzer();
5516
5758
  init_canonicalize();
@@ -5561,8 +5803,11 @@ var init_static_build = __esm({
5561
5803
  });
5562
5804
 
5563
5805
  // src/generators/discovered-schema.ts
5564
- function toDiscoveredTypeSchemas(result) {
5565
- return result;
5806
+ function toDiscoveredTypeSchemas(result, resolvedMetadata) {
5807
+ return {
5808
+ ...result,
5809
+ ...resolvedMetadata !== void 0 && { resolvedMetadata }
5810
+ };
5566
5811
  }
5567
5812
  function isNamedTypeDeclaration(declaration) {
5568
5813
  return ts7.isClassDeclaration(declaration) || ts7.isInterfaceDeclaration(declaration) || ts7.isTypeAliasDeclaration(declaration);
@@ -5710,7 +5955,8 @@ function generateSchemasFromAnalysis(analysis, filePath, options) {
5710
5955
  metadata: options?.metadata,
5711
5956
  vendorPrefix: options?.vendorPrefix
5712
5957
  }
5713
- )
5958
+ ),
5959
+ analysis.metadata
5714
5960
  );
5715
5961
  }
5716
5962
  function generateSchemasFromResolvedType(options, skipNamedDeclaration = false, rootOverride) {
@@ -5768,7 +6014,8 @@ function generateSchemasFromResolvedType(options, skipNamedDeclaration = false,
5768
6014
  }
5769
6015
  return {
5770
6016
  jsonSchema: toStandaloneJsonSchema(root, typeRegistry, options),
5771
- uiSchema: null
6017
+ uiSchema: null,
6018
+ ...root.metadata !== void 0 && { resolvedMetadata: root.metadata }
5772
6019
  };
5773
6020
  }
5774
6021
  function generateSchemasFromDeclaration(options) {
@@ -6111,10 +6358,14 @@ __export(index_exports, {
6111
6358
  createStaticBuildContextFromProgram: () => createStaticBuildContextFromProgram,
6112
6359
  generateJsonSchema: () => generateJsonSchema,
6113
6360
  generateSchemas: () => generateSchemas,
6361
+ generateSchemasBatch: () => generateSchemasBatch,
6362
+ generateSchemasBatchFromProgram: () => generateSchemasBatchFromProgram,
6363
+ generateSchemasDetailed: () => generateSchemasDetailed,
6114
6364
  generateSchemasFromClass: () => generateSchemasFromClass,
6115
6365
  generateSchemasFromDeclaration: () => generateSchemasFromDeclaration,
6116
6366
  generateSchemasFromParameter: () => generateSchemasFromParameter,
6117
6367
  generateSchemasFromProgram: () => generateSchemasFromProgram,
6368
+ generateSchemasFromProgramDetailed: () => generateSchemasFromProgramDetailed,
6118
6369
  generateSchemasFromReturnType: () => generateSchemasFromReturnType,
6119
6370
  generateSchemasFromType: () => generateSchemasFromType,
6120
6371
  generateUiSchema: () => generateUiSchema,
@@ -6158,6 +6409,9 @@ var init_index = __esm({
6158
6409
  init_generator();
6159
6410
  init_generator2();
6160
6411
  init_class_schema();
6412
+ init_class_schema();
6413
+ init_class_schema();
6414
+ init_class_schema();
6161
6415
  init_static_build();
6162
6416
  init_discovered_schema();
6163
6417
  init_mixed_authoring();