@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.
@@ -33,6 +33,7 @@ __export(internals_exports, {
33
33
  analyzeClassToIR: () => analyzeClassToIR,
34
34
  analyzeInterfaceToIR: () => analyzeInterfaceToIR,
35
35
  analyzeNamedTypeToIRFromProgramContext: () => analyzeNamedTypeToIRFromProgramContext,
36
+ analyzeNamedTypeToIRFromProgramContextDetailed: () => analyzeNamedTypeToIRFromProgramContextDetailed,
36
37
  analyzeTypeAliasToIR: () => analyzeTypeAliasToIR,
37
38
  canonicalizeChainDSL: () => canonicalizeChainDSL,
38
39
  canonicalizeTSDoc: () => canonicalizeTSDoc,
@@ -44,6 +45,7 @@ __export(internals_exports, {
44
45
  findInterfaceByName: () => findInterfaceByName,
45
46
  findTypeAliasByName: () => findTypeAliasByName,
46
47
  generateClassSchemas: () => generateClassSchemas,
48
+ generateClassSchemasDetailed: () => generateClassSchemasDetailed,
47
49
  generateJsonSchemaFromIR: () => generateJsonSchemaFromIR,
48
50
  generateMethodSchemas: () => generateMethodSchemas,
49
51
  generateUiSchemaFromIR: () => generateUiSchemaFromIR,
@@ -921,6 +923,16 @@ function buildSupportingDeclarations(sourceFile, extensionTypeNames) {
921
923
  return true;
922
924
  }).map((statement) => statement.getText(sourceFile));
923
925
  }
926
+ function pushUniqueCompilerDiagnostics(target, additions) {
927
+ for (const diagnostic of additions) {
928
+ if ((diagnostic.code === "UNSUPPORTED_CUSTOM_TYPE_OVERRIDE" || diagnostic.code === "SYNTHETIC_SETUP_FAILURE") && target.some(
929
+ (existing) => existing.code === diagnostic.code && existing.message === diagnostic.message
930
+ )) {
931
+ continue;
932
+ }
933
+ target.push(diagnostic);
934
+ }
935
+ }
924
936
  function renderSyntheticArgumentExpression(valueKind, argumentText) {
925
937
  const trimmed = argumentText.trim();
926
938
  if (trimmed === "") {
@@ -1187,6 +1199,16 @@ function buildCompilerBackedConstraintDiagnostics(node, sourceFile, tagName, par
1187
1199
  if (result.diagnostics.length === 0) {
1188
1200
  return [];
1189
1201
  }
1202
+ const setupDiagnostic = result.diagnostics.find((diagnostic) => diagnostic.kind !== "typescript");
1203
+ if (setupDiagnostic !== void 0) {
1204
+ return [
1205
+ makeDiagnostic(
1206
+ setupDiagnostic.kind === "unsupported-custom-type-override" ? "UNSUPPORTED_CUSTOM_TYPE_OVERRIDE" : "SYNTHETIC_SETUP_FAILURE",
1207
+ setupDiagnostic.message,
1208
+ provenance
1209
+ )
1210
+ ];
1211
+ }
1190
1212
  const expectedLabel = definition.valueKind === null ? "compatible argument" : capabilityLabel(definition.valueKind);
1191
1213
  return [
1192
1214
  makeDiagnostic(
@@ -1352,7 +1374,7 @@ function parseTSDocTags(node, file = "", options) {
1352
1374
  options
1353
1375
  );
1354
1376
  if (compilerDiagnostics.length > 0) {
1355
- diagnostics.push(...compilerDiagnostics);
1377
+ pushUniqueCompilerDiagnostics(diagnostics, compilerDiagnostics);
1356
1378
  continue;
1357
1379
  }
1358
1380
  const constraintNode = (0, import_internal.parseConstraintTagValue)(
@@ -1439,7 +1461,7 @@ function parseTSDocTags(node, file = "", options) {
1439
1461
  options
1440
1462
  );
1441
1463
  if (compilerDiagnostics.length > 0) {
1442
- diagnostics.push(...compilerDiagnostics);
1464
+ pushUniqueCompilerDiagnostics(diagnostics, compilerDiagnostics);
1443
1465
  continue;
1444
1466
  }
1445
1467
  const constraintNode = (0, import_internal.parseConstraintTagValue)(
@@ -1473,7 +1495,7 @@ function parseTSDocTags(node, file = "", options) {
1473
1495
  options
1474
1496
  );
1475
1497
  if (compilerDiagnostics.length > 0) {
1476
- diagnostics.push(...compilerDiagnostics);
1498
+ pushUniqueCompilerDiagnostics(diagnostics, compilerDiagnostics);
1477
1499
  continue;
1478
1500
  }
1479
1501
  const constraintNode = (0, import_internal.parseConstraintTagValue)(
@@ -3886,29 +3908,35 @@ function findFallbackAliasDuplicatePropertyNames(typeNode, checker) {
3886
3908
  }
3887
3909
  return [...duplicates].sort();
3888
3910
  }
3889
- function analyzeNamedTypeToIRFromProgramContext(ctx, filePath, typeName, extensionRegistry, metadataPolicy, discriminatorOptions) {
3911
+ function analyzeNamedTypeToIRFromProgramContextDetailed(ctx, filePath, typeName, extensionRegistry, metadataPolicy, discriminatorOptions) {
3890
3912
  const analysisFilePath = path.resolve(filePath);
3891
3913
  const classDecl = findClassByName(ctx.sourceFile, typeName);
3892
3914
  if (classDecl !== null) {
3893
- return analyzeClassToIR(
3894
- classDecl,
3895
- ctx.checker,
3896
- analysisFilePath,
3897
- extensionRegistry,
3898
- metadataPolicy,
3899
- discriminatorOptions
3900
- );
3915
+ return {
3916
+ ok: true,
3917
+ analysis: analyzeClassToIR(
3918
+ classDecl,
3919
+ ctx.checker,
3920
+ analysisFilePath,
3921
+ extensionRegistry,
3922
+ metadataPolicy,
3923
+ discriminatorOptions
3924
+ )
3925
+ };
3901
3926
  }
3902
3927
  const interfaceDecl = findInterfaceByName(ctx.sourceFile, typeName);
3903
3928
  if (interfaceDecl !== null) {
3904
- return analyzeInterfaceToIR(
3905
- interfaceDecl,
3906
- ctx.checker,
3907
- analysisFilePath,
3908
- extensionRegistry,
3909
- metadataPolicy,
3910
- discriminatorOptions
3911
- );
3929
+ return {
3930
+ ok: true,
3931
+ analysis: analyzeInterfaceToIR(
3932
+ interfaceDecl,
3933
+ ctx.checker,
3934
+ analysisFilePath,
3935
+ extensionRegistry,
3936
+ metadataPolicy,
3937
+ discriminatorOptions
3938
+ )
3939
+ };
3912
3940
  }
3913
3941
  const typeAlias = findTypeAliasByName(ctx.sourceFile, typeName);
3914
3942
  if (typeAlias !== null) {
@@ -3921,11 +3949,20 @@ function analyzeNamedTypeToIRFromProgramContext(ctx, filePath, typeName, extensi
3921
3949
  discriminatorOptions
3922
3950
  );
3923
3951
  if (result.ok) {
3924
- return result.analysis;
3952
+ return { ok: true, analysis: result.analysis };
3925
3953
  }
3926
3954
  const fallbackEligible = result.kind === "not-object-like" && isResolvableObjectLikeAliasTypeNode(typeAlias.type) && containsTypeReferenceInObjectLikeAlias(typeAlias.type);
3927
3955
  if (!fallbackEligible) {
3928
- throw new Error(result.error);
3956
+ return {
3957
+ ok: false,
3958
+ diagnostics: [
3959
+ makeProgramDiagnostic(
3960
+ result.kind === "duplicate-properties" ? "DUPLICATE_ROOT_PROPERTIES" : "UNSUPPORTED_ROOT_TYPE",
3961
+ result.error,
3962
+ makeNodeProvenance(typeAlias, analysisFilePath)
3963
+ )
3964
+ ]
3965
+ };
3929
3966
  }
3930
3967
  const duplicatePropertyNames = findFallbackAliasDuplicatePropertyNames(
3931
3968
  typeAlias.type,
@@ -3934,9 +3971,16 @@ function analyzeNamedTypeToIRFromProgramContext(ctx, filePath, typeName, extensi
3934
3971
  if (duplicatePropertyNames.length > 0) {
3935
3972
  const sourceFile = typeAlias.getSourceFile();
3936
3973
  const { line } = sourceFile.getLineAndCharacterOfPosition(typeAlias.getStart());
3937
- throw new Error(
3938
- `Type alias "${typeAlias.name.text}" at line ${String(line + 1)} contains duplicate property names across object-like members: ${duplicatePropertyNames.join(", ")}`
3939
- );
3974
+ return {
3975
+ ok: false,
3976
+ diagnostics: [
3977
+ makeProgramDiagnostic(
3978
+ "DUPLICATE_ROOT_PROPERTIES",
3979
+ `Type alias "${typeAlias.name.text}" at line ${String(line + 1)} contains duplicate property names across object-like members: ${duplicatePropertyNames.join(", ")}`,
3980
+ makeNodeProvenance(typeAlias, analysisFilePath)
3981
+ )
3982
+ ]
3983
+ };
3940
3984
  }
3941
3985
  const rootInfo = analyzeDeclarationRootInfo(
3942
3986
  typeAlias,
@@ -3966,17 +4010,75 @@ function analyzeNamedTypeToIRFromProgramContext(ctx, filePath, typeName, extensi
3966
4010
  diagnostics
3967
4011
  );
3968
4012
  if (fallbackAnalysis !== null) {
3969
- return fallbackAnalysis;
4013
+ return { ok: true, analysis: fallbackAnalysis };
3970
4014
  }
3971
- throw new Error(result.error);
4015
+ return {
4016
+ ok: false,
4017
+ diagnostics: [
4018
+ makeProgramDiagnostic(
4019
+ "UNSUPPORTED_ROOT_TYPE",
4020
+ result.error,
4021
+ makeNodeProvenance(typeAlias, analysisFilePath)
4022
+ )
4023
+ ]
4024
+ };
3972
4025
  }
3973
- throw new Error(
3974
- `Type "${typeName}" not found as a class, interface, or type alias in ${analysisFilePath}`
4026
+ return {
4027
+ ok: false,
4028
+ diagnostics: [
4029
+ makeProgramDiagnostic(
4030
+ "TYPE_NOT_FOUND",
4031
+ `Type "${typeName}" not found as a class, interface, or type alias in ${analysisFilePath}`,
4032
+ makeFileProvenance(analysisFilePath)
4033
+ )
4034
+ ]
4035
+ };
4036
+ }
4037
+ function analyzeNamedTypeToIRFromProgramContext(ctx, filePath, typeName, extensionRegistry, metadataPolicy, discriminatorOptions) {
4038
+ const result = analyzeNamedTypeToIRFromProgramContextDetailed(
4039
+ ctx,
4040
+ filePath,
4041
+ typeName,
4042
+ extensionRegistry,
4043
+ metadataPolicy,
4044
+ discriminatorOptions
3975
4045
  );
4046
+ if (result.ok) {
4047
+ return result.analysis;
4048
+ }
4049
+ throw new Error(result.diagnostics.map((diagnostic) => diagnostic.message).join("\n"));
4050
+ }
4051
+ function makeProgramDiagnostic(code, message, primaryLocation) {
4052
+ return {
4053
+ code,
4054
+ message,
4055
+ severity: "error",
4056
+ primaryLocation,
4057
+ relatedLocations: []
4058
+ };
4059
+ }
4060
+ function makeNodeProvenance(node, filePath) {
4061
+ const sourceFile = node.getSourceFile();
4062
+ const position = sourceFile.getLineAndCharacterOfPosition(node.getStart());
4063
+ return {
4064
+ surface: "tsdoc",
4065
+ file: filePath,
4066
+ line: position.line + 1,
4067
+ column: position.character,
4068
+ length: node.getWidth()
4069
+ };
4070
+ }
4071
+ function makeFileProvenance(filePath) {
4072
+ return {
4073
+ surface: "tsdoc",
4074
+ file: filePath,
4075
+ line: 1,
4076
+ column: 0
4077
+ };
3976
4078
  }
3977
4079
 
3978
4080
  // src/generators/class-schema.ts
3979
- var ts5 = require("typescript");
4081
+ var ts5 = __toESM(require("typescript"), 1);
3980
4082
 
3981
4083
  // src/metadata/collision-guards.ts
3982
4084
  function assertUniqueSerializedNames(entries, scope) {
@@ -5038,11 +5140,25 @@ function validateIR(ir, options) {
5038
5140
 
5039
5141
  // src/generators/class-schema.ts
5040
5142
  function generateClassSchemas(analysis, source, options) {
5041
- const errorDiagnostics = analysis.diagnostics?.filter(
5143
+ const result = generateClassSchemasDetailed(analysis, source, options);
5144
+ if (!result.ok || result.jsonSchema === void 0 || result.uiSchema === void 0) {
5145
+ throw new Error(formatValidationError(result.diagnostics));
5146
+ }
5147
+ return {
5148
+ jsonSchema: result.jsonSchema,
5149
+ uiSchema: result.uiSchema
5150
+ };
5151
+ }
5152
+ function generateClassSchemasDetailed(analysis, source, options) {
5153
+ const analysisDiagnostics = analysis.diagnostics ?? [];
5154
+ const errorDiagnostics = analysisDiagnostics.filter(
5042
5155
  (diagnostic) => diagnostic.severity === "error"
5043
5156
  );
5044
- if (errorDiagnostics !== void 0 && errorDiagnostics.length > 0) {
5045
- throw new Error(formatValidationError(errorDiagnostics));
5157
+ if (errorDiagnostics.length > 0) {
5158
+ return {
5159
+ ok: false,
5160
+ diagnostics: analysisDiagnostics
5161
+ };
5046
5162
  }
5047
5163
  const ir = canonicalizeTSDoc(
5048
5164
  analysis,
@@ -5056,9 +5172,14 @@ function generateClassSchemas(analysis, source, options) {
5056
5172
  ...options?.vendorPrefix !== void 0 && { vendorPrefix: options.vendorPrefix }
5057
5173
  });
5058
5174
  if (!validationResult.valid) {
5059
- throw new Error(formatValidationError(validationResult.diagnostics));
5175
+ return {
5176
+ ok: false,
5177
+ diagnostics: [...analysisDiagnostics, ...validationResult.diagnostics]
5178
+ };
5060
5179
  }
5061
5180
  return {
5181
+ ok: true,
5182
+ diagnostics: [...analysisDiagnostics, ...validationResult.diagnostics],
5062
5183
  jsonSchema: generateJsonSchemaFromIR(ir, options),
5063
5184
  uiSchema: generateUiSchemaFromIR(ir)
5064
5185
  };
@@ -5338,6 +5459,7 @@ function collectFormSpecReferences(methods) {
5338
5459
  analyzeClassToIR,
5339
5460
  analyzeInterfaceToIR,
5340
5461
  analyzeNamedTypeToIRFromProgramContext,
5462
+ analyzeNamedTypeToIRFromProgramContextDetailed,
5341
5463
  analyzeTypeAliasToIR,
5342
5464
  canonicalizeChainDSL,
5343
5465
  canonicalizeTSDoc,
@@ -5349,6 +5471,7 @@ function collectFormSpecReferences(methods) {
5349
5471
  findInterfaceByName,
5350
5472
  findTypeAliasByName,
5351
5473
  generateClassSchemas,
5474
+ generateClassSchemasDetailed,
5352
5475
  generateJsonSchemaFromIR,
5353
5476
  generateMethodSchemas,
5354
5477
  generateUiSchemaFromIR,