@formspec/build 0.1.0-alpha.40 → 0.1.0-alpha.42

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.
@@ -467,6 +467,11 @@ export declare interface GenerateJsonSchemaOptions {
467
467
  * @defaultValue "x-formspec"
468
468
  */
469
469
  readonly vendorPrefix?: string | undefined;
470
+ /**
471
+ * JSON Schema representation to use for static enums.
472
+ * @defaultValue "enum"
473
+ */
474
+ readonly enumSerialization?: "enum" | "oneOf";
470
475
  /** Metadata resolution policy for chain DSL generation. */
471
476
  readonly metadata?: MetadataPolicyInput | undefined;
472
477
  }
@@ -1284,6 +1289,11 @@ export declare interface StaticSchemaGenerationOptions {
1284
1289
  * @defaultValue "x-formspec"
1285
1290
  */
1286
1291
  readonly vendorPrefix?: string | undefined;
1292
+ /**
1293
+ * JSON Schema representation to use for static enums.
1294
+ * @defaultValue "enum"
1295
+ */
1296
+ readonly enumSerialization?: "enum" | "oneOf";
1287
1297
  /** Metadata resolution policy for static schema generation. */
1288
1298
  readonly metadata?: MetadataPolicyInput | undefined;
1289
1299
  /** Discriminator-specific schema generation behavior. */
@@ -467,6 +467,11 @@ export declare interface GenerateJsonSchemaOptions {
467
467
  * @defaultValue "x-formspec"
468
468
  */
469
469
  readonly vendorPrefix?: string | undefined;
470
+ /**
471
+ * JSON Schema representation to use for static enums.
472
+ * @defaultValue "enum"
473
+ */
474
+ readonly enumSerialization?: "enum" | "oneOf";
470
475
  /** Metadata resolution policy for chain DSL generation. */
471
476
  readonly metadata?: MetadataPolicyInput | undefined;
472
477
  }
@@ -1284,6 +1289,11 @@ export declare interface StaticSchemaGenerationOptions {
1284
1289
  * @defaultValue "x-formspec"
1285
1290
  */
1286
1291
  readonly vendorPrefix?: string | undefined;
1292
+ /**
1293
+ * JSON Schema representation to use for static enums.
1294
+ * @defaultValue "enum"
1295
+ */
1296
+ readonly enumSerialization?: "enum" | "oneOf";
1287
1297
  /** Metadata resolution policy for static schema generation. */
1288
1298
  readonly metadata?: MetadataPolicyInput | undefined;
1289
1299
  /** Discriminator-specific schema generation behavior. */
@@ -467,6 +467,11 @@ export declare interface GenerateJsonSchemaOptions {
467
467
  * @defaultValue "x-formspec"
468
468
  */
469
469
  readonly vendorPrefix?: string | undefined;
470
+ /**
471
+ * JSON Schema representation to use for static enums.
472
+ * @defaultValue "enum"
473
+ */
474
+ readonly enumSerialization?: "enum" | "oneOf";
470
475
  /** Metadata resolution policy for chain DSL generation. */
471
476
  readonly metadata?: MetadataPolicyInput | undefined;
472
477
  }
@@ -1284,6 +1289,11 @@ export declare interface StaticSchemaGenerationOptions {
1284
1289
  * @defaultValue "x-formspec"
1285
1290
  */
1286
1291
  readonly vendorPrefix?: string | undefined;
1292
+ /**
1293
+ * JSON Schema representation to use for static enums.
1294
+ * @defaultValue "enum"
1295
+ */
1296
+ readonly enumSerialization?: "enum" | "oneOf";
1287
1297
  /** Metadata resolution policy for static schema generation. */
1288
1298
  readonly metadata?: MetadataPolicyInput | undefined;
1289
1299
  /** Discriminator-specific schema generation behavior. */
package/dist/build.d.ts CHANGED
@@ -467,6 +467,11 @@ export declare interface GenerateJsonSchemaOptions {
467
467
  * @defaultValue "x-formspec"
468
468
  */
469
469
  readonly vendorPrefix?: string | undefined;
470
+ /**
471
+ * JSON Schema representation to use for static enums.
472
+ * @defaultValue "enum"
473
+ */
474
+ readonly enumSerialization?: "enum" | "oneOf";
470
475
  /** Metadata resolution policy for chain DSL generation. */
471
476
  readonly metadata?: MetadataPolicyInput | undefined;
472
477
  }
@@ -1284,6 +1289,11 @@ export declare interface StaticSchemaGenerationOptions {
1284
1289
  * @defaultValue "x-formspec"
1285
1290
  */
1286
1291
  readonly vendorPrefix?: string | undefined;
1292
+ /**
1293
+ * JSON Schema representation to use for static enums.
1294
+ * @defaultValue "enum"
1295
+ */
1296
+ readonly enumSerialization?: "enum" | "oneOf";
1287
1297
  /** Metadata resolution policy for static schema generation. */
1288
1298
  readonly metadata?: MetadataPolicyInput | undefined;
1289
1299
  /** Discriminator-specific schema generation behavior. */
@@ -1 +1 @@
1
- {"version":3,"file":"chain-dsl-canonicalizer.d.ts","sourceRoot":"","sources":["../../src/canonicalize/chain-dsl-canonicalizer.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EASV,WAAW,EACX,QAAQ,EAMR,mBAAmB,EACpB,MAAM,gBAAgB,CAAC;AACxB,OAAO,KAAK,EAYV,MAAM,EAaP,MAAM,0BAA0B,CAAC;AA2ClC;;;;;GAKG;AACH,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,CAAC,QAAQ,CAAC,EAAE,mBAAmB,CAAC;CACzC;AAED,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,QAAQ,CAAC,SAAS,WAAW,EAAE,CAAC,EACtC,OAAO,CAAC,EAAE,2BAA2B,GACpC,MAAM,CAYR"}
1
+ {"version":3,"file":"chain-dsl-canonicalizer.d.ts","sourceRoot":"","sources":["../../src/canonicalize/chain-dsl-canonicalizer.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EASV,WAAW,EACX,QAAQ,EAMR,mBAAmB,EACpB,MAAM,gBAAgB,CAAC;AACxB,OAAO,KAAK,EAYV,MAAM,EAaP,MAAM,0BAA0B,CAAC;AA4ClC;;;;;GAKG;AACH,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,CAAC,QAAQ,CAAC,EAAE,mBAAmB,CAAC;CACzC;AAED,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,QAAQ,CAAC,SAAS,WAAW,EAAE,CAAC,EACtC,OAAO,CAAC,EAAE,2BAA2B,GACpC,MAAM,CAoBR"}
package/dist/cli.cjs CHANGED
@@ -79,11 +79,35 @@ function normalizeDeclarationPolicy(input) {
79
79
  displayName: normalizeScalarPolicy(input?.displayName)
80
80
  };
81
81
  }
82
+ function normalizeEnumMemberDisplayNamePolicy(input) {
83
+ if (input?.mode === "infer-if-missing") {
84
+ return {
85
+ mode: "infer-if-missing",
86
+ infer: input.infer
87
+ };
88
+ }
89
+ if (input?.mode === "require-explicit") {
90
+ return {
91
+ mode: "require-explicit",
92
+ infer: () => ""
93
+ };
94
+ }
95
+ return {
96
+ mode: "disabled",
97
+ infer: () => ""
98
+ };
99
+ }
100
+ function normalizeEnumMemberPolicy(input) {
101
+ return {
102
+ displayName: normalizeEnumMemberDisplayNamePolicy(input?.displayName)
103
+ };
104
+ }
82
105
  function normalizeMetadataPolicy(input) {
83
106
  return {
84
107
  type: normalizeDeclarationPolicy(input?.type),
85
108
  field: normalizeDeclarationPolicy(input?.field),
86
- method: normalizeDeclarationPolicy(input?.method)
109
+ method: normalizeDeclarationPolicy(input?.method),
110
+ enumMember: normalizeEnumMemberPolicy(input?.enumMember)
87
111
  };
88
112
  }
89
113
  function getDeclarationMetadataPolicy(policy, declarationKind) {
@@ -196,6 +220,40 @@ function pickResolvedMetadataValue(baseValue, overlayValue) {
196
220
  }
197
221
  return baseValue ?? overlayValue;
198
222
  }
223
+ function resolveEnumMemberDisplayName(current, policy, context) {
224
+ if (current !== void 0) {
225
+ return current;
226
+ }
227
+ if (policy.mode === "require-explicit") {
228
+ throw new Error(
229
+ `Metadata policy requires explicit displayName for enum member "${context.logicalName}" on the ${context.surface} surface.`
230
+ );
231
+ }
232
+ if (policy.mode !== "infer-if-missing") {
233
+ return void 0;
234
+ }
235
+ const inferredValue = policy.infer(context).trim();
236
+ return inferredValue !== "" ? inferredValue : void 0;
237
+ }
238
+ function resolveEnumTypeMetadata(type, options) {
239
+ const members = type.members.map((member) => {
240
+ const displayName = resolveEnumMemberDisplayName(
241
+ member.displayName,
242
+ options.policy.enumMember.displayName,
243
+ {
244
+ surface: options.surface,
245
+ logicalName: String(member.value),
246
+ memberValue: member.value,
247
+ ...options.buildContext !== void 0 && { buildContext: options.buildContext }
248
+ }
249
+ );
250
+ if (displayName === member.displayName) {
251
+ return member;
252
+ }
253
+ return displayName === void 0 ? { value: member.value } : { value: member.value, displayName };
254
+ });
255
+ return members.some((member, index) => member !== type.members[index]) ? { ...type, members } : type;
256
+ }
199
257
  function resolveTypeNodeMetadata(type, options) {
200
258
  switch (type.kind) {
201
259
  case "array":
@@ -218,9 +276,10 @@ function resolveTypeNodeMetadata(type, options) {
218
276
  ...type,
219
277
  members: type.members.map((member) => resolveTypeNodeMetadata(member, options))
220
278
  };
279
+ case "enum":
280
+ return resolveEnumTypeMetadata(type, options);
221
281
  case "reference":
222
282
  case "primitive":
223
- case "enum":
224
283
  case "dynamic":
225
284
  case "custom":
226
285
  return type;
@@ -323,11 +382,10 @@ function getDisplayName(metadata) {
323
382
  return metadata?.displayName?.value;
324
383
  }
325
384
  function resolveFormIRMetadata(ir, options) {
326
- const rootLogicalName = options.rootLogicalName ?? ir.name ?? "FormSpec";
327
- const metadata = resolveResolvedMetadata(ir.metadata, options.policy.type, {
385
+ const metadata = options.resolveRootTypeMetadata === false ? ir.metadata : resolveResolvedMetadata(ir.metadata, options.policy.type, {
328
386
  surface: options.surface,
329
387
  declarationKind: "type",
330
- logicalName: rootLogicalName,
388
+ logicalName: options.rootLogicalName ?? ir.name ?? "FormSpec",
331
389
  ...options.buildContext !== void 0 && { buildContext: options.buildContext }
332
390
  });
333
391
  return {
@@ -372,7 +430,7 @@ function canonicalizeChainDSL(form, options) {
372
430
  const metadataPolicy = normalizeMetadataPolicy(
373
431
  options?.metadata ?? (0, import_internals._getFormSpecMetadataPolicy)(form)
374
432
  );
375
- return {
433
+ const ir = {
376
434
  kind: "form-ir",
377
435
  irVersion: import_internals.IR_VERSION,
378
436
  elements: canonicalizeElements(form.elements, metadataPolicy),
@@ -380,6 +438,13 @@ function canonicalizeChainDSL(form, options) {
380
438
  typeRegistry: {},
381
439
  provenance: CHAIN_DSL_PROVENANCE
382
440
  };
441
+ return resolveFormIRMetadata(ir, {
442
+ policy: metadataPolicy,
443
+ surface: "chain-dsl",
444
+ // Chain DSL has no root/type-metadata authoring surface, so only resolve
445
+ // field/type-registry metadata and enum-member labels here.
446
+ resolveRootTypeMetadata: false
447
+ });
383
448
  }
384
449
  function canonicalizeElements(elements, metadataPolicy) {
385
450
  return elements.map((element) => canonicalizeElement(element, metadataPolicy));
@@ -953,17 +1018,25 @@ var init_collision_guards = __esm({
953
1018
  // src/json-schema/ir-generator.ts
954
1019
  function makeContext(options) {
955
1020
  const vendorPrefix = options?.vendorPrefix ?? "x-formspec";
1021
+ const rawEnumSerialization = options?.enumSerialization;
956
1022
  if (!vendorPrefix.startsWith("x-")) {
957
1023
  throw new Error(
958
1024
  `Invalid vendorPrefix "${vendorPrefix}". Extension JSON Schema keywords must start with "x-".`
959
1025
  );
960
1026
  }
1027
+ if (rawEnumSerialization !== void 0 && rawEnumSerialization !== "enum" && rawEnumSerialization !== "oneOf") {
1028
+ throw new Error(
1029
+ `Invalid enumSerialization "${rawEnumSerialization}". Expected "enum" or "oneOf".`
1030
+ );
1031
+ }
1032
+ const enumSerialization = rawEnumSerialization ?? "enum";
961
1033
  return {
962
1034
  defs: {},
963
1035
  typeNameMap: {},
964
1036
  typeRegistry: {},
965
1037
  extensionRegistry: options?.extensionRegistry,
966
- vendorPrefix
1038
+ vendorPrefix,
1039
+ enumSerialization
967
1040
  };
968
1041
  }
969
1042
  function generateJsonSchemaFromIR(ir, options) {
@@ -1137,7 +1210,7 @@ function generateTypeNode(type, ctx) {
1137
1210
  case "primitive":
1138
1211
  return generatePrimitiveType(type);
1139
1212
  case "enum":
1140
- return generateEnumType(type);
1213
+ return generateEnumType(type, ctx);
1141
1214
  case "array":
1142
1215
  return generateArrayType(type, ctx);
1143
1216
  case "object":
@@ -1163,20 +1236,37 @@ function generatePrimitiveType(type) {
1163
1236
  type: type.primitiveKind === "integer" || type.primitiveKind === "bigint" ? "integer" : type.primitiveKind
1164
1237
  };
1165
1238
  }
1166
- function generateEnumType(type) {
1167
- const hasDisplayNames = type.members.some((m) => m.displayName !== void 0);
1168
- if (hasDisplayNames) {
1239
+ function generateEnumType(type, ctx) {
1240
+ if (ctx.enumSerialization === "oneOf") {
1169
1241
  return {
1170
- oneOf: type.members.map((m) => {
1171
- const entry = { const: m.value };
1172
- if (m.displayName !== void 0) {
1173
- entry.title = m.displayName;
1174
- }
1175
- return entry;
1176
- })
1242
+ oneOf: type.members.map((m) => ({
1243
+ const: m.value,
1244
+ title: m.displayName ?? String(m.value)
1245
+ }))
1177
1246
  };
1178
1247
  }
1179
- return { enum: type.members.map((m) => m.value) };
1248
+ const schema = { enum: type.members.map((m) => m.value) };
1249
+ const displayNames = buildEnumDisplayNameExtension(type);
1250
+ if (displayNames !== void 0) {
1251
+ schema[`${ctx.vendorPrefix}-display-names`] = displayNames;
1252
+ }
1253
+ return schema;
1254
+ }
1255
+ function buildEnumDisplayNameExtension(type) {
1256
+ if (!type.members.some((member) => member.displayName !== void 0)) {
1257
+ return void 0;
1258
+ }
1259
+ const displayNames = /* @__PURE__ */ Object.create(null);
1260
+ for (const member of type.members) {
1261
+ const key = String(member.value);
1262
+ if (Object.hasOwn(displayNames, key)) {
1263
+ throw new Error(
1264
+ `Enum display-name key "${key}" is ambiguous after stringification. Use oneOf serialization for mixed string/number enum values that collide.`
1265
+ );
1266
+ }
1267
+ displayNames[key] = member.displayName ?? key;
1268
+ }
1269
+ return displayNames;
1180
1270
  }
1181
1271
  function generateArrayType(type, ctx) {
1182
1272
  return {
@@ -1532,12 +1622,25 @@ function applyCustomConstraint(schema, constraint, ctx) {
1532
1622
  `Cannot generate JSON Schema for custom constraint "${constraint.constraintId}" without a matching extension registration`
1533
1623
  );
1534
1624
  }
1535
- assignVendorPrefixedExtensionKeywords(
1536
- schema,
1537
- registration.toJsonSchema(constraint.payload, ctx.vendorPrefix),
1538
- ctx.vendorPrefix,
1539
- `custom constraint "${constraint.constraintId}"`
1540
- );
1625
+ const extensionSchema = registration.toJsonSchema(constraint.payload, ctx.vendorPrefix);
1626
+ if (registration.emitsVocabularyKeywords) {
1627
+ const target = schema;
1628
+ for (const [key, value] of Object.entries(extensionSchema)) {
1629
+ if (JSON_SCHEMA_STRUCTURAL_KEYWORDS.has(key)) {
1630
+ throw new Error(
1631
+ `Custom constraint "${constraint.constraintId}" with emitsVocabularyKeywords must not overwrite standard JSON Schema keyword "${key}"`
1632
+ );
1633
+ }
1634
+ target[key] = value;
1635
+ }
1636
+ } else {
1637
+ assignVendorPrefixedExtensionKeywords(
1638
+ schema,
1639
+ extensionSchema,
1640
+ ctx.vendorPrefix,
1641
+ `custom constraint "${constraint.constraintId}"`
1642
+ );
1643
+ }
1541
1644
  }
1542
1645
  function applyCustomAnnotation(schema, annotation, ctx) {
1543
1646
  const registration = ctx.extensionRegistry?.findAnnotation(annotation.annotationId);
@@ -1566,21 +1669,88 @@ function assignVendorPrefixedExtensionKeywords(schema, extensionSchema, vendorPr
1566
1669
  schema[key] = value;
1567
1670
  }
1568
1671
  }
1672
+ var JSON_SCHEMA_STRUCTURAL_KEYWORDS;
1569
1673
  var init_ir_generator = __esm({
1570
1674
  "src/json-schema/ir-generator.ts"() {
1571
1675
  "use strict";
1572
1676
  init_metadata();
1573
1677
  init_collision_guards();
1678
+ JSON_SCHEMA_STRUCTURAL_KEYWORDS = /* @__PURE__ */ new Set([
1679
+ "$schema",
1680
+ "$ref",
1681
+ "$defs",
1682
+ "$id",
1683
+ "$anchor",
1684
+ "$dynamicRef",
1685
+ "$dynamicAnchor",
1686
+ "$vocabulary",
1687
+ "$comment",
1688
+ "type",
1689
+ "enum",
1690
+ "const",
1691
+ "properties",
1692
+ "patternProperties",
1693
+ "additionalProperties",
1694
+ "required",
1695
+ "items",
1696
+ "prefixItems",
1697
+ "additionalItems",
1698
+ "contains",
1699
+ "allOf",
1700
+ "oneOf",
1701
+ "anyOf",
1702
+ "not",
1703
+ "if",
1704
+ "then",
1705
+ "else",
1706
+ "minimum",
1707
+ "maximum",
1708
+ "exclusiveMinimum",
1709
+ "exclusiveMaximum",
1710
+ "multipleOf",
1711
+ "minLength",
1712
+ "maxLength",
1713
+ "pattern",
1714
+ "minItems",
1715
+ "maxItems",
1716
+ "uniqueItems",
1717
+ "minProperties",
1718
+ "maxProperties",
1719
+ "minContains",
1720
+ "maxContains",
1721
+ "format",
1722
+ "title",
1723
+ "description",
1724
+ "default",
1725
+ "deprecated",
1726
+ "readOnly",
1727
+ "writeOnly",
1728
+ "examples",
1729
+ "dependentRequired",
1730
+ "dependentSchemas",
1731
+ "propertyNames",
1732
+ "unevaluatedItems",
1733
+ "unevaluatedProperties",
1734
+ "contentEncoding",
1735
+ "contentMediaType",
1736
+ "contentSchema"
1737
+ ]);
1574
1738
  }
1575
1739
  });
1576
1740
 
1577
1741
  // src/json-schema/generator.ts
1578
1742
  function generateJsonSchema(form, options) {
1743
+ const metadata = options?.metadata;
1744
+ const vendorPrefix = options?.vendorPrefix;
1745
+ const enumSerialization = options?.enumSerialization;
1579
1746
  const ir = canonicalizeChainDSL(
1580
1747
  form,
1581
- options?.metadata !== void 0 ? { metadata: options.metadata } : void 0
1748
+ metadata !== void 0 ? { metadata } : void 0
1582
1749
  );
1583
- const internalOptions = options?.vendorPrefix === void 0 ? void 0 : { vendorPrefix: options.vendorPrefix };
1750
+ const internalOptions = vendorPrefix === void 0 && enumSerialization === void 0 ? void 0 : {
1751
+ ...vendorPrefix !== void 0 && { vendorPrefix },
1752
+ ...enumSerialization !== void 0 && { enumSerialization }
1753
+ };
1584
1754
  return generateJsonSchemaFromIR(ir, internalOptions);
1585
1755
  }
1586
1756
  var init_generator = __esm({
@@ -5594,6 +5764,7 @@ function generateSchemasFromClass(options) {
5594
5764
  {
5595
5765
  extensionRegistry: options.extensionRegistry,
5596
5766
  metadata: options.metadata,
5767
+ enumSerialization: options.enumSerialization,
5597
5768
  vendorPrefix: options.vendorPrefix
5598
5769
  }
5599
5770
  );
@@ -5723,6 +5894,7 @@ function generateSchemasFromDetailedProgramContext(ctx, filePath, typeName, opti
5723
5894
  {
5724
5895
  extensionRegistry: options.extensionRegistry,
5725
5896
  metadata: options.metadata,
5897
+ enumSerialization: options.enumSerialization,
5726
5898
  vendorPrefix: options.vendorPrefix
5727
5899
  }
5728
5900
  );
@@ -5939,7 +6111,7 @@ function toStandaloneJsonSchema(root, typeRegistry, options) {
5939
6111
  column: 0
5940
6112
  }
5941
6113
  };
5942
- const schema = generateJsonSchemaFromIR(
6114
+ const ir = resolveFormIRMetadata(
5943
6115
  {
5944
6116
  kind: "form-ir",
5945
6117
  name: root.name,
@@ -5950,8 +6122,17 @@ function toStandaloneJsonSchema(root, typeRegistry, options) {
5950
6122
  typeRegistry,
5951
6123
  provenance: syntheticField.provenance
5952
6124
  },
6125
+ {
6126
+ policy: normalizeMetadataPolicy(options?.metadata),
6127
+ surface: "tsdoc",
6128
+ rootLogicalName: root.name
6129
+ }
6130
+ );
6131
+ const schema = generateJsonSchemaFromIR(
6132
+ ir,
5953
6133
  {
5954
6134
  extensionRegistry: options?.extensionRegistry,
6135
+ enumSerialization: options?.enumSerialization,
5955
6136
  vendorPrefix: options?.vendorPrefix
5956
6137
  }
5957
6138
  );
@@ -5978,6 +6159,7 @@ function generateSchemasFromAnalysis(analysis, filePath, options) {
5978
6159
  { file: filePath },
5979
6160
  {
5980
6161
  extensionRegistry: options?.extensionRegistry,
6162
+ enumSerialization: options?.enumSerialization,
5981
6163
  metadata: options?.metadata,
5982
6164
  vendorPrefix: options?.vendorPrefix
5983
6165
  }
@@ -6425,8 +6607,19 @@ function buildFormSchemas(form, options) {
6425
6607
  };
6426
6608
  }
6427
6609
  function writeSchemas(form, options) {
6428
- const { outDir, name = "schema", indent = 2, vendorPrefix, metadata } = options;
6429
- const buildOptions = vendorPrefix === void 0 && metadata === void 0 ? void 0 : { vendorPrefix, metadata };
6610
+ const {
6611
+ outDir,
6612
+ name = "schema",
6613
+ indent = 2,
6614
+ vendorPrefix,
6615
+ enumSerialization,
6616
+ metadata
6617
+ } = options;
6618
+ const buildOptions = vendorPrefix === void 0 && enumSerialization === void 0 && metadata === void 0 ? void 0 : {
6619
+ ...vendorPrefix !== void 0 && { vendorPrefix },
6620
+ ...enumSerialization !== void 0 && { enumSerialization },
6621
+ ...metadata !== void 0 && { metadata }
6622
+ };
6430
6623
  const { jsonSchema, uiSchema: uiSchema2 } = buildFormSchemas(form, buildOptions);
6431
6624
  if (!fs.existsSync(outDir)) {
6432
6625
  fs.mkdirSync(outDir, { recursive: true });
@@ -6474,6 +6667,8 @@ Usage:
6474
6667
  Options:
6475
6668
  -o, --out-dir <dir> Output directory (default: ./generated)
6476
6669
  -n, --name <name> Base name for output files (default: derived from input)
6670
+ --enum-serialization <enum|oneOf>
6671
+ Enum JSON Schema representation (default: enum)
6477
6672
  -h, --help Show this help message
6478
6673
 
6479
6674
  Example:
@@ -6490,6 +6685,7 @@ function parseArgs(args) {
6490
6685
  const positional = [];
6491
6686
  let outDir = "./generated";
6492
6687
  let name = "";
6688
+ let enumSerialization = "enum";
6493
6689
  for (let i = 0; i < args.length; i++) {
6494
6690
  const arg = args[i];
6495
6691
  if (arg === void 0) continue;
@@ -6517,6 +6713,20 @@ function parseArgs(args) {
6517
6713
  i++;
6518
6714
  continue;
6519
6715
  }
6716
+ if (arg === "--enum-serialization") {
6717
+ const nextArg = args[i + 1];
6718
+ if (!nextArg) {
6719
+ console.error("Error: --enum-serialization requires a value");
6720
+ return null;
6721
+ }
6722
+ if (nextArg !== "enum" && nextArg !== "oneOf") {
6723
+ console.error('Error: --enum-serialization must be "enum" or "oneOf"');
6724
+ return null;
6725
+ }
6726
+ enumSerialization = nextArg;
6727
+ i++;
6728
+ continue;
6729
+ }
6520
6730
  if (arg.startsWith("-")) {
6521
6731
  console.error(`Error: Unknown option: ${arg}`);
6522
6732
  return null;
@@ -6536,7 +6746,7 @@ function parseArgs(args) {
6536
6746
  if (!name) {
6537
6747
  name = path3.basename(inputFile, path3.extname(inputFile));
6538
6748
  }
6539
- return { inputFile, outDir, name };
6749
+ return { inputFile, outDir, name, enumSerialization };
6540
6750
  }
6541
6751
  async function main() {
6542
6752
  const args = process.argv.slice(2);
@@ -6544,7 +6754,7 @@ async function main() {
6544
6754
  if (!options) {
6545
6755
  process.exit(1);
6546
6756
  }
6547
- const { inputFile, outDir, name } = options;
6757
+ const { inputFile, outDir, name, enumSerialization } = options;
6548
6758
  const absoluteInput = path3.resolve(process.cwd(), inputFile);
6549
6759
  try {
6550
6760
  const fileUrl = (0, import_node_url.pathToFileURL)(absoluteInput).href;
@@ -6561,7 +6771,7 @@ async function main() {
6561
6771
  const { writeSchemas: writeSchemas2 } = await Promise.resolve().then(() => (init_index(), index_exports));
6562
6772
  const { jsonSchemaPath, uiSchemaPath } = writeSchemas2(
6563
6773
  form,
6564
- { outDir, name }
6774
+ { outDir, name, enumSerialization }
6565
6775
  );
6566
6776
  console.log("Generated:");
6567
6777
  console.log(` ${jsonSchemaPath}`);