@formspec/build 0.1.0-alpha.54 → 0.1.0-alpha.57

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
@@ -1018,20 +1018,29 @@ var init_collision_guards = __esm({
1018
1018
  });
1019
1019
 
1020
1020
  // src/json-schema/ir-generator.ts
1021
+ function parseEnumSerialization(value) {
1022
+ switch (value) {
1023
+ case void 0:
1024
+ case "enum":
1025
+ return "enum";
1026
+ case "oneOf":
1027
+ return "oneOf";
1028
+ case "smart-size":
1029
+ return "smart-size";
1030
+ default:
1031
+ throw new Error(
1032
+ `Invalid enumSerialization "${String(value)}". Expected "enum", "oneOf", or "smart-size".`
1033
+ );
1034
+ }
1035
+ }
1021
1036
  function makeContext(options) {
1022
1037
  const vendorPrefix = options?.vendorPrefix ?? "x-formspec";
1023
- const rawEnumSerialization = options?.enumSerialization;
1038
+ const enumSerialization = parseEnumSerialization(options?.enumSerialization);
1024
1039
  if (!vendorPrefix.startsWith("x-")) {
1025
1040
  throw new Error(
1026
1041
  `Invalid vendorPrefix "${vendorPrefix}". Extension JSON Schema keywords must start with "x-".`
1027
1042
  );
1028
1043
  }
1029
- if (rawEnumSerialization !== void 0 && rawEnumSerialization !== "enum" && rawEnumSerialization !== "oneOf") {
1030
- throw new Error(
1031
- `Invalid enumSerialization "${rawEnumSerialization}". Expected "enum" or "oneOf".`
1032
- );
1033
- }
1034
- const enumSerialization = rawEnumSerialization ?? "enum";
1035
1044
  return {
1036
1045
  defs: {},
1037
1046
  typeNameMap: {},
@@ -1239,21 +1248,31 @@ function generatePrimitiveType(type) {
1239
1248
  };
1240
1249
  }
1241
1250
  function generateEnumType(type, ctx) {
1242
- if (ctx.enumSerialization === "oneOf") {
1251
+ if (ctx.enumSerialization === "oneOf" || ctx.enumSerialization === "smart-size" && shouldSerializeEnumAsOneOf(type)) {
1243
1252
  return {
1244
- oneOf: type.members.map((m) => ({
1245
- const: m.value,
1246
- title: m.displayName ?? String(m.value)
1247
- }))
1253
+ oneOf: type.members.map((m) => {
1254
+ const stringValue = String(m.value);
1255
+ const title = m.displayName !== void 0 && m.displayName !== stringValue ? m.displayName : void 0;
1256
+ return title !== void 0 ? { const: m.value, title } : { const: m.value };
1257
+ })
1248
1258
  };
1249
1259
  }
1250
1260
  const schema = { enum: type.members.map((m) => m.value) };
1261
+ if (ctx.enumSerialization === "smart-size") {
1262
+ return schema;
1263
+ }
1251
1264
  const displayNames = buildEnumDisplayNameExtension(type);
1252
1265
  if (displayNames !== void 0) {
1253
1266
  schema[`${ctx.vendorPrefix}-display-names`] = displayNames;
1254
1267
  }
1255
1268
  return schema;
1256
1269
  }
1270
+ function shouldSerializeEnumAsOneOf(type) {
1271
+ return type.members.some((member) => {
1272
+ const title = member.displayName ?? String(member.value);
1273
+ return title !== String(member.value);
1274
+ });
1275
+ }
1257
1276
  function buildEnumDisplayNameExtension(type) {
1258
1277
  if (!type.members.some((member) => member.displayName !== void 0)) {
1259
1278
  return void 0;
@@ -2072,6 +2091,11 @@ function buildConstraintTagSources(extensions) {
2072
2091
  }));
2073
2092
  }
2074
2093
  function createExtensionRegistry(extensions) {
2094
+ const registryLog = (0, import_internal.getSyntheticLogger)();
2095
+ registryLog.debug("createExtensionRegistry: constructing", {
2096
+ extensionCount: extensions.length,
2097
+ extensionIds: extensions.map((e) => e.extensionId)
2098
+ });
2075
2099
  const reservedTagSources = buildConstraintTagSources(extensions);
2076
2100
  let symbolMap = /* @__PURE__ */ new Map();
2077
2101
  const typeMap = /* @__PURE__ */ new Map();
@@ -2203,6 +2227,14 @@ function createExtensionRegistry(extensions) {
2203
2227
  }
2204
2228
  }
2205
2229
  }
2230
+ registryLog.debug("createExtensionRegistry: complete", {
2231
+ typeCount: typeMap.size,
2232
+ constraintCount: constraintMap.size,
2233
+ constraintTagCount: constraintTagMap.size,
2234
+ broadeningCount: builtinBroadeningMap.size,
2235
+ annotationCount: annotationMap.size,
2236
+ metadataSlotCount: metadataSlotMap.size
2237
+ });
2206
2238
  return {
2207
2239
  extensions,
2208
2240
  findType: (typeId) => typeMap.get(typeId),
@@ -2851,56 +2883,82 @@ function buildCompilerBackedConstraintDiagnostics(node, sourceFile, tagName, par
2851
2883
  if (definition === null) {
2852
2884
  return [];
2853
2885
  }
2886
+ const nonNullPlacement = placement;
2887
+ const log2 = (0, import_internal4.getBuildLogger)();
2888
+ const broadeningLog = (0, import_internal4.getBroadeningLogger)();
2889
+ const syntheticLog = (0, import_internal4.getSyntheticLogger)();
2890
+ const logsEnabled = log2 !== import_core4.noopLogger || broadeningLog !== import_core4.noopLogger;
2891
+ const syntheticTraceEnabled = syntheticLog !== import_core4.noopLogger;
2892
+ const logStart = logsEnabled ? (0, import_internal4.nowMicros)() : 0;
2893
+ const subjectTypeKind = logsEnabled ? (0, import_internal4.describeTypeKind)(subjectType, checker) : "";
2894
+ function emit(outcome, result2) {
2895
+ if (!logsEnabled) {
2896
+ return result2;
2897
+ }
2898
+ const entry = {
2899
+ consumer: "build",
2900
+ tag: tagName,
2901
+ placement: nonNullPlacement,
2902
+ subjectTypeKind,
2903
+ roleOutcome: outcome,
2904
+ elapsedMicros: (0, import_internal4.elapsedMicros)(logStart)
2905
+ };
2906
+ (0, import_internal4.logTagApplication)(log2, entry);
2907
+ if (outcome === "bypass" || outcome === "D1" || outcome === "D2") {
2908
+ (0, import_internal4.logTagApplication)(broadeningLog, entry);
2909
+ }
2910
+ return result2;
2911
+ }
2854
2912
  if (!definition.placements.includes(placement)) {
2855
- return [
2913
+ return emit("A-reject", [
2856
2914
  makeDiagnostic(
2857
2915
  "INVALID_TAG_PLACEMENT",
2858
2916
  `Tag "@${tagName}" is not allowed on ${placementLabel(placement)}.`,
2859
2917
  provenance
2860
2918
  )
2861
- ];
2919
+ ]);
2862
2920
  }
2863
2921
  const target = parsedTag?.target ?? null;
2864
2922
  let evaluatedType = subjectType;
2865
2923
  let targetLabel = node.getText(sourceFile);
2866
2924
  if (target !== null) {
2867
2925
  if (target.kind !== "path") {
2868
- return [
2926
+ return emit("B-reject", [
2869
2927
  makeDiagnostic(
2870
2928
  "UNSUPPORTED_TARGETING_SYNTAX",
2871
2929
  `Tag "@${tagName}" does not support ${target.kind} targeting syntax.`,
2872
2930
  provenance
2873
2931
  )
2874
- ];
2932
+ ]);
2875
2933
  }
2876
2934
  if (!target.valid || target.path === null) {
2877
- return [
2935
+ return emit("B-reject", [
2878
2936
  makeDiagnostic(
2879
2937
  "UNSUPPORTED_TARGETING_SYNTAX",
2880
2938
  `Tag "@${tagName}" has invalid path targeting syntax.`,
2881
2939
  provenance
2882
2940
  )
2883
- ];
2941
+ ]);
2884
2942
  }
2885
2943
  const resolution = (0, import_internal3.resolvePathTargetType)(subjectType, checker, target.path.segments);
2886
2944
  if (resolution.kind === "missing-property") {
2887
- return [
2945
+ return emit("B-reject", [
2888
2946
  makeDiagnostic(
2889
2947
  "UNKNOWN_PATH_TARGET",
2890
2948
  `Target "${target.rawText}": path-targeted constraint "${tagName}" references unknown path segment "${resolution.segment}"`,
2891
2949
  provenance
2892
2950
  )
2893
- ];
2951
+ ]);
2894
2952
  }
2895
2953
  if (resolution.kind === "unresolvable") {
2896
2954
  const actualType = checker.typeToString(resolution.type, node, SYNTHETIC_TYPE_FORMAT_FLAGS);
2897
- return [
2955
+ return emit("B-reject", [
2898
2956
  makeDiagnostic(
2899
2957
  "TYPE_MISMATCH",
2900
2958
  `Target "${target.rawText}": path-targeted constraint "${tagName}" is invalid because type "${actualType}" cannot be traversed`,
2901
2959
  provenance
2902
2960
  )
2903
- ];
2961
+ ]);
2904
2962
  }
2905
2963
  evaluatedType = resolution.type;
2906
2964
  targetLabel = target.rawText;
@@ -2929,13 +2987,13 @@ function buildCompilerBackedConstraintDiagnostics(node, sourceFile, tagName, par
2929
2987
  tagName,
2930
2988
  parsedTag?.argumentText
2931
2989
  ) : null;
2932
- return [
2990
+ return emit("B-reject", [
2933
2991
  makeDiagnostic(
2934
2992
  "TYPE_MISMATCH",
2935
2993
  hint === null ? baseMessage : `${baseMessage}. ${hint}`,
2936
2994
  provenance
2937
2995
  )
2938
- ];
2996
+ ]);
2939
2997
  }
2940
2998
  }
2941
2999
  const argumentExpression = renderSyntheticArgumentExpression(
@@ -2943,14 +3001,23 @@ function buildCompilerBackedConstraintDiagnostics(node, sourceFile, tagName, par
2943
3001
  parsedTag?.argumentText ?? ""
2944
3002
  );
2945
3003
  if (definition.requiresArgument && argumentExpression === null) {
2946
- return [];
3004
+ return emit("A-pass", []);
2947
3005
  }
2948
3006
  if (hasBroadening) {
2949
- return [];
3007
+ return emit("bypass", []);
2950
3008
  }
2951
3009
  const subjectTypeText = checker.typeToString(subjectType, node, SYNTHETIC_TYPE_FORMAT_FLAGS);
2952
3010
  const hostType = options?.hostType ?? subjectType;
2953
3011
  const hostTypeText = checker.typeToString(hostType, node, SYNTHETIC_TYPE_FORMAT_FLAGS);
3012
+ if (syntheticTraceEnabled) {
3013
+ syntheticLog.trace("invoking synthetic checker", {
3014
+ consumer: "build",
3015
+ tag: tagName,
3016
+ placement,
3017
+ subjectTypeKind,
3018
+ subjectTypeText
3019
+ });
3020
+ }
2954
3021
  const result = (0, import_internal3.checkSyntheticTagApplication)({
2955
3022
  tagName,
2956
3023
  placement,
@@ -2977,26 +3044,26 @@ function buildCompilerBackedConstraintDiagnostics(node, sourceFile, tagName, par
2977
3044
  } : {}
2978
3045
  });
2979
3046
  if (result.diagnostics.length === 0) {
2980
- return [];
3047
+ return emit("C-pass", []);
2981
3048
  }
2982
3049
  const setupDiagnostic = result.diagnostics.find((diagnostic) => diagnostic.kind !== "typescript");
2983
3050
  if (setupDiagnostic !== void 0) {
2984
- return [
3051
+ return emit("C-reject", [
2985
3052
  makeDiagnostic(
2986
3053
  setupDiagnostic.kind === "unsupported-custom-type-override" ? "UNSUPPORTED_CUSTOM_TYPE_OVERRIDE" : "SYNTHETIC_SETUP_FAILURE",
2987
3054
  setupDiagnostic.message,
2988
3055
  provenance
2989
3056
  )
2990
- ];
3057
+ ]);
2991
3058
  }
2992
3059
  const expectedLabel = definition.valueKind === null ? "compatible argument" : capabilityLabel(definition.valueKind);
2993
- return [
3060
+ return emit("C-reject", [
2994
3061
  makeDiagnostic(
2995
3062
  "TYPE_MISMATCH",
2996
3063
  `Tag "@${tagName}" received an invalid argument for ${expectedLabel}.`,
2997
3064
  provenance
2998
3065
  )
2999
- ];
3066
+ ]);
3000
3067
  }
3001
3068
  function getExtensionTagNames(options) {
3002
3069
  return [
@@ -3308,7 +3375,7 @@ function getTagCommentText(tag) {
3308
3375
  }
3309
3376
  return ts4.getTextOfJSDocComment(tag.comment);
3310
3377
  }
3311
- var ts4, import_internal3, import_internals4, import_internals5, SYNTHETIC_TYPE_FORMAT_FLAGS, MAX_HINT_CANDIDATES, MAX_HINT_DEPTH, parseResultCache;
3378
+ var ts4, import_internal3, import_internals4, import_internals5, import_core4, import_internal4, SYNTHETIC_TYPE_FORMAT_FLAGS, MAX_HINT_CANDIDATES, MAX_HINT_DEPTH, parseResultCache;
3312
3379
  var init_tsdoc_parser = __esm({
3313
3380
  "src/analyzer/tsdoc-parser.ts"() {
3314
3381
  "use strict";
@@ -3316,8 +3383,10 @@ var init_tsdoc_parser = __esm({
3316
3383
  import_internal3 = require("@formspec/analysis/internal");
3317
3384
  import_internals4 = require("@formspec/core/internals");
3318
3385
  import_internals5 = require("@formspec/core/internals");
3386
+ import_core4 = require("@formspec/core");
3319
3387
  init_resolve_custom_type();
3320
3388
  init_builtin_brands();
3389
+ import_internal4 = require("@formspec/analysis/internal");
3321
3390
  SYNTHETIC_TYPE_FORMAT_FLAGS = ts4.TypeFormatFlags.NoTruncation | ts4.TypeFormatFlags.UseAliasDefinedOutsideCurrentScope;
3322
3391
  MAX_HINT_CANDIDATES = 5;
3323
3392
  MAX_HINT_DEPTH = 3;
@@ -3424,7 +3493,7 @@ function createAnalyzerMetadataPolicy(input, discriminator) {
3424
3493
  };
3425
3494
  }
3426
3495
  function resolveNodeMetadata(metadataPolicy, declarationKind, logicalName, node, checker, extensionRegistry, buildContext) {
3427
- const analysis = (0, import_internal4.analyzeMetadataForNodeWithChecker)({
3496
+ const analysis = (0, import_internal5.analyzeMetadataForNodeWithChecker)({
3428
3497
  checker,
3429
3498
  node,
3430
3499
  logicalName,
@@ -3765,7 +3834,7 @@ function getLeadingParsedTags(node) {
3765
3834
  if (!commentText.startsWith("/**")) {
3766
3835
  continue;
3767
3836
  }
3768
- parsedTags.push(...(0, import_internal4.parseCommentBlock)(commentText, { offset: range.pos }).tags);
3837
+ parsedTags.push(...(0, import_internal5.parseCommentBlock)(commentText, { offset: range.pos }).tags);
3769
3838
  }
3770
3839
  return parsedTags;
3771
3840
  }
@@ -4174,6 +4243,22 @@ function extractReferenceTypeArguments(type, checker, file, typeRegistry, visiti
4174
4243
  }
4175
4244
  return referenceTypeNode.typeArguments.map((argumentNode) => {
4176
4245
  const argumentType = checker.getTypeFromTypeNode(argumentNode);
4246
+ const baseSymbol = argumentType.aliasSymbol ?? argumentType.getSymbol();
4247
+ const argumentSymbol = baseSymbol !== void 0 && baseSymbol.flags & ts6.SymbolFlags.Alias ? checker.getAliasedSymbol(baseSymbol) : baseSymbol;
4248
+ const argumentDecl = argumentSymbol?.declarations?.[0];
4249
+ if (argumentDecl !== void 0 && argumentDecl.getSourceFile().fileName !== file) {
4250
+ const argumentName = argumentSymbol?.getName() ?? baseSymbol?.getName();
4251
+ if (argumentName !== void 0) {
4252
+ return {
4253
+ tsType: argumentType,
4254
+ typeNode: {
4255
+ kind: "reference",
4256
+ name: argumentName,
4257
+ typeArguments: []
4258
+ }
4259
+ };
4260
+ }
4261
+ }
4177
4262
  return {
4178
4263
  tsType: argumentType,
4179
4264
  typeNode: resolveTypeNode(
@@ -4440,22 +4525,10 @@ function resolveTypeNode(type, checker, file, typeRegistry, visiting, sourceNode
4440
4525
  sourceNode
4441
4526
  );
4442
4527
  if (customTypeLookup !== null) {
4443
- const typeId = customTypeIdFromLookup(customTypeLookup);
4444
- let payload = null;
4445
- if (customTypeLookup.registration.extractPayload !== void 0) {
4446
- try {
4447
- payload = customTypeLookup.registration.extractPayload(type, checker) ?? null;
4448
- } catch (cause) {
4449
- throw new Error(
4450
- `extractPayload for custom type "${customTypeLookup.registration.typeName}" in extension "${customTypeLookup.extensionId}" threw`,
4451
- { cause }
4452
- );
4453
- }
4454
- }
4455
4528
  return {
4456
4529
  kind: "custom",
4457
- typeId,
4458
- payload
4530
+ typeId: customTypeIdFromLookup(customTypeLookup),
4531
+ payload: null
4459
4532
  };
4460
4533
  }
4461
4534
  const primitiveAlias = tryResolveNamedPrimitiveAlias(
@@ -4639,6 +4712,21 @@ function getReferencedTypeAliasDeclaration(sourceNode, checker) {
4639
4712
  }
4640
4713
  return getTypeAliasDeclarationFromTypeReference(typeNode, checker);
4641
4714
  }
4715
+ function resolveNamedTypeWithSourceRecovery(type, sourceNode, checker) {
4716
+ const typeName = getNamedTypeName(type);
4717
+ const namedDecl = getNamedTypeDeclaration(type);
4718
+ if (typeName !== null && namedDecl !== void 0) {
4719
+ return { typeName, namedDecl };
4720
+ }
4721
+ if (sourceNode === void 0) {
4722
+ return null;
4723
+ }
4724
+ const refAliasDecl = getReferencedTypeAliasDeclaration(sourceNode, checker);
4725
+ if (refAliasDecl === void 0) {
4726
+ return null;
4727
+ }
4728
+ return { typeName: refAliasDecl.name.text, namedDecl: refAliasDecl };
4729
+ }
4642
4730
  function shouldEmitPrimitiveAliasDefinition(typeNode, checker) {
4643
4731
  if (!ts6.isTypeReferenceNode(typeNode)) {
4644
4732
  return false;
@@ -4697,8 +4785,23 @@ function resolveAliasedPrimitiveTarget(type, checker, file, typeRegistry, visiti
4697
4785
  );
4698
4786
  }
4699
4787
  function resolveUnionType(type, checker, file, typeRegistry, visiting, sourceNode, metadataPolicy = createAnalyzerMetadataPolicy(void 0), extensionRegistry, diagnostics) {
4700
- const typeName = getNamedTypeName(type);
4701
- const namedDecl = getNamedTypeDeclaration(type);
4788
+ const recovered = resolveNamedTypeWithSourceRecovery(type, sourceNode, checker);
4789
+ let typeName = null;
4790
+ let namedDecl;
4791
+ if (recovered !== null) {
4792
+ const recoveredAliasDecl = ts6.isTypeAliasDeclaration(recovered.namedDecl) ? recovered.namedDecl : void 0;
4793
+ if (recoveredAliasDecl !== void 0) {
4794
+ const aliasUnderlyingType = checker.getTypeFromTypeNode(recoveredAliasDecl.type);
4795
+ const isNonGeneric = recoveredAliasDecl.typeParameters === void 0 || recoveredAliasDecl.typeParameters.length === 0;
4796
+ if (isNonGeneric && (aliasUnderlyingType.isUnion() || isObjectType(aliasUnderlyingType))) {
4797
+ typeName = recovered.typeName;
4798
+ namedDecl = recovered.namedDecl;
4799
+ }
4800
+ } else {
4801
+ typeName = recovered.typeName;
4802
+ namedDecl = recovered.namedDecl;
4803
+ }
4804
+ }
4702
4805
  if (typeName && typeName in typeRegistry) {
4703
4806
  return { kind: "reference", name: typeName, typeArguments: [] };
4704
4807
  }
@@ -4730,6 +4833,10 @@ function resolveUnionType(type, checker, file, typeRegistry, visiting, sourceNod
4730
4833
  if (!typeName) {
4731
4834
  return result;
4732
4835
  }
4836
+ const existing = typeRegistry[typeName];
4837
+ if (existing !== void 0 && existing.type !== RESOLVING_TYPE_PLACEHOLDER) {
4838
+ return { kind: "reference", name: typeName, typeArguments: [] };
4839
+ }
4733
4840
  const annotations = namedDecl ? extractJSDocAnnotationNodes(namedDecl, file, makeParseOptions(extensionRegistry)) : void 0;
4734
4841
  const metadata = namedDecl !== void 0 ? resolveNodeMetadata(
4735
4842
  metadataPolicy,
@@ -5377,12 +5484,12 @@ function detectFormSpecReference(typeNode) {
5377
5484
  }
5378
5485
  return null;
5379
5486
  }
5380
- var ts6, import_internal4, RESOLVING_TYPE_PLACEHOLDER, MAX_ALIAS_CHAIN_DEPTH;
5487
+ var ts6, import_internal5, RESOLVING_TYPE_PLACEHOLDER, MAX_ALIAS_CHAIN_DEPTH;
5381
5488
  var init_class_analyzer = __esm({
5382
5489
  "src/analyzer/class-analyzer.ts"() {
5383
5490
  "use strict";
5384
5491
  ts6 = __toESM(require("typescript"), 1);
5385
- import_internal4 = require("@formspec/analysis/internal");
5492
+ import_internal5 = require("@formspec/analysis/internal");
5386
5493
  init_jsdoc_constraints();
5387
5494
  init_tsdoc_parser();
5388
5495
  init_resolve_custom_type();
@@ -5889,7 +5996,7 @@ var init_symbol_registry = __esm({
5889
5996
 
5890
5997
  // src/validate/constraint-validator.ts
5891
5998
  function validateFieldNode(ctx, field) {
5892
- const analysis = (0, import_internal5.analyzeConstraintTargets)(
5999
+ const analysis = (0, import_internal6.analyzeConstraintTargets)(
5893
6000
  field.name,
5894
6001
  field.type,
5895
6002
  field.constraints,
@@ -5907,7 +6014,7 @@ function validateFieldNode(ctx, field) {
5907
6014
  }
5908
6015
  function validateObjectProperty(ctx, parentName, property) {
5909
6016
  const qualifiedName = `${parentName}.${property.name}`;
5910
- const analysis = (0, import_internal5.analyzeConstraintTargets)(
6017
+ const analysis = (0, import_internal6.analyzeConstraintTargets)(
5911
6018
  qualifiedName,
5912
6019
  property.type,
5913
6020
  property.constraints,
@@ -5958,11 +6065,11 @@ function validateIR(ir, options) {
5958
6065
  valid: ctx.diagnostics.every((diagnostic) => diagnostic.severity !== "error")
5959
6066
  };
5960
6067
  }
5961
- var import_internal5;
6068
+ var import_internal6;
5962
6069
  var init_constraint_validator = __esm({
5963
6070
  "src/validate/constraint-validator.ts"() {
5964
6071
  "use strict";
5965
- import_internal5 = require("@formspec/analysis/internal");
6072
+ import_internal6 = require("@formspec/analysis/internal");
5966
6073
  }
5967
6074
  });
5968
6075
 
@@ -6710,7 +6817,7 @@ function generateSchemasFromReturnType(options) {
6710
6817
  }
6711
6818
  function resolveDeclarationMetadata(options) {
6712
6819
  const resolved = resolveStaticOptions(options);
6713
- const analysis = (0, import_internal6.analyzeMetadataForNodeWithChecker)({
6820
+ const analysis = (0, import_internal7.analyzeMetadataForNodeWithChecker)({
6714
6821
  checker: options.context.checker,
6715
6822
  node: options.declaration,
6716
6823
  metadata: resolved.metadata,
@@ -6756,12 +6863,12 @@ function unwrapPromiseTypeNode(typeNode) {
6756
6863
  function isPromiseTypeReferenceNode(typeNode) {
6757
6864
  return ts11.isTypeReferenceNode(typeNode) && ts11.isIdentifier(typeNode.typeName) && typeNode.typeName.text === "Promise" && typeNode.typeArguments !== void 0 && typeNode.typeArguments.length > 0;
6758
6865
  }
6759
- var ts11, import_internal6, import_internals6;
6866
+ var ts11, import_internal7, import_internals6;
6760
6867
  var init_discovered_schema = __esm({
6761
6868
  "src/generators/discovered-schema.ts"() {
6762
6869
  "use strict";
6763
6870
  ts11 = __toESM(require("typescript"), 1);
6764
- import_internal6 = require("@formspec/analysis/internal");
6871
+ import_internal7 = require("@formspec/analysis/internal");
6765
6872
  init_class_analyzer();
6766
6873
  init_class_schema();
6767
6874
  init_ir_generator();
@@ -7003,7 +7110,7 @@ __export(index_exports, {
7003
7110
  writeSchemas: () => writeSchemas
7004
7111
  });
7005
7112
  function buildFormSchemas(form, options) {
7006
- const logger = options?.logger ?? import_core4.noopLogger;
7113
+ const logger = options?.logger ?? import_core5.noopLogger;
7007
7114
  logger.debug("buildFormSchemas: starting schema generation");
7008
7115
  return {
7009
7116
  jsonSchema: generateJsonSchema(form, options),
@@ -7020,7 +7127,7 @@ function writeSchemas(form, options) {
7020
7127
  metadata,
7021
7128
  logger: rawLogger
7022
7129
  } = options;
7023
- const logger = (rawLogger ?? import_core4.noopLogger).child({ stage: "write" });
7130
+ const logger = (rawLogger ?? import_core5.noopLogger).child({ stage: "write" });
7024
7131
  const buildOptions = vendorPrefix === void 0 && enumSerialization === void 0 && metadata === void 0 ? { logger: rawLogger } : {
7025
7132
  ...vendorPrefix !== void 0 && { vendorPrefix },
7026
7133
  ...enumSerialization !== void 0 && { enumSerialization },
@@ -7039,11 +7146,11 @@ function writeSchemas(form, options) {
7039
7146
  fs.writeFileSync(uiSchemaPath, JSON.stringify(uiSchema2, null, indent));
7040
7147
  return { jsonSchemaPath, uiSchemaPath };
7041
7148
  }
7042
- var import_core4, fs, path3;
7149
+ var import_core5, fs, path3;
7043
7150
  var init_index = __esm({
7044
7151
  "src/index.ts"() {
7045
7152
  "use strict";
7046
- import_core4 = require("@formspec/core");
7153
+ import_core5 = require("@formspec/core");
7047
7154
  init_generator();
7048
7155
  init_generator2();
7049
7156
  init_ir_generator();
@@ -7105,7 +7212,7 @@ Usage:
7105
7212
  Options:
7106
7213
  -o, --out-dir <dir> Output directory (default: ./generated)
7107
7214
  -n, --name <name> Base name for output files (default: derived from input)
7108
- --enum-serialization <enum|oneOf>
7215
+ --enum-serialization <enum|oneOf|smart-size>
7109
7216
  Enum JSON Schema representation (default: enum)
7110
7217
  -h, --help Show this help message
7111
7218
 
@@ -7157,8 +7264,10 @@ function parseArgs(args) {
7157
7264
  console.error("Error: --enum-serialization requires a value");
7158
7265
  return null;
7159
7266
  }
7160
- if (nextArg !== "enum" && nextArg !== "oneOf") {
7161
- console.error('Error: --enum-serialization must be "enum" or "oneOf"');
7267
+ if (nextArg !== "enum" && nextArg !== "oneOf" && nextArg !== "smart-size") {
7268
+ console.error(
7269
+ 'Error: --enum-serialization must be "enum", "oneOf", or "smart-size"'
7270
+ );
7162
7271
  return null;
7163
7272
  }
7164
7273
  enumSerialization = nextArg;