@alt-stack/zod-openapi 1.2.0 → 1.3.0

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.
@@ -1,5 +1,5 @@
1
1
 
2
- > @alt-stack/zod-openapi@1.2.0 build /home/runner/work/alt-stack/alt-stack/packages/zod-openapi
2
+ > @alt-stack/zod-openapi@1.3.0 build /home/runner/work/alt-stack/alt-stack/packages/zod-openapi
3
3
  > tsup
4
4
 
5
5
  CLI Building entry: src/index.ts
@@ -10,13 +10,13 @@
10
10
  CLI Cleaning output folder
11
11
  ESM Build start
12
12
  CJS Build start
13
- ESM dist/index.js 38.35 KB
14
- ESM dist/index.js.map 84.13 KB
15
- ESM ⚡️ Build success in 32ms
16
- CJS dist/index.cjs 39.98 KB
17
- CJS dist/index.cjs.map 85.09 KB
13
+ CJS dist/index.cjs 42.75 KB
14
+ CJS dist/index.cjs.map 90.45 KB
18
15
  CJS ⚡️ Build success in 33ms
16
+ ESM dist/index.js 41.13 KB
17
+ ESM dist/index.js.map 89.49 KB
18
+ ESM ⚡️ Build success in 33ms
19
19
  DTS Build start
20
- DTS ⚡️ Build success in 1497ms
21
- DTS dist/index.d.ts 5.68 KB
22
- DTS dist/index.d.cts 5.68 KB
20
+ DTS ⚡️ Build success in 1429ms
21
+ DTS dist/index.d.ts 6.06 KB
22
+ DTS dist/index.d.cts 6.06 KB
package/dist/index.cjs CHANGED
@@ -267,6 +267,9 @@ function isStringRegistration(reg) {
267
267
  function isStringsRegistration(reg) {
268
268
  return reg.type === "string" && "formats" in reg;
269
269
  }
270
+ function isSupportedStringFormat(format) {
271
+ return Object.prototype.hasOwnProperty.call(SUPPORTED_STRING_FORMATS_MAP, format);
272
+ }
270
273
  function getTypeFormatPairs(reg) {
271
274
  if (isStringRegistration(reg)) {
272
275
  return [{ type: "string", format: reg.format }];
@@ -317,6 +320,7 @@ var ZodSchemaRegistry = class {
317
320
  * Reverse-lookup helper: given a string format, return the registered schema's exported variable name
318
321
  */
319
322
  getSchemaExportedVariableNameForStringFormat(format) {
323
+ if (!isSupportedStringFormat(format)) return void 0;
320
324
  for (const registration of this.map.values()) {
321
325
  if (registration.type !== "string") continue;
322
326
  if (isStringRegistration(registration) && registration.format === format) {
@@ -328,6 +332,17 @@ var ZodSchemaRegistry = class {
328
332
  }
329
333
  return void 0;
330
334
  }
335
+ /**
336
+ * Reverse-lookup helper: given a primitive type, return the registered schema's exported variable name
337
+ */
338
+ getSchemaExportedVariableNameForPrimitiveType(type) {
339
+ for (const registration of this.map.values()) {
340
+ if (registration.type === type) {
341
+ return registration.schemaExportedVariableName;
342
+ }
343
+ }
344
+ return void 0;
345
+ }
331
346
  };
332
347
  var schemaRegistry = new ZodSchemaRegistry();
333
348
  function registerZodSchemaToOpenApiSchema(schema, openApiSchema) {
@@ -336,6 +351,9 @@ function registerZodSchemaToOpenApiSchema(schema, openApiSchema) {
336
351
  function getSchemaExportedVariableNameForStringFormat(format) {
337
352
  return schemaRegistry.getSchemaExportedVariableNameForStringFormat(format);
338
353
  }
354
+ function getSchemaExportedVariableNameForPrimitiveType(type) {
355
+ return schemaRegistry.getSchemaExportedVariableNameForPrimitiveType(type);
356
+ }
339
357
  function clearZodSchemaToOpenApiSchemaRegistry() {
340
358
  schemaRegistry.clear();
341
359
  }
@@ -710,7 +728,37 @@ var validIdentifierRegex2 = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/;
710
728
  function quotePropertyName2(name) {
711
729
  return validIdentifierRegex2.test(name) ? name : `'${name}'`;
712
730
  }
713
- function schemaToTypeString(schema) {
731
+ function toPascalCase2(name) {
732
+ return name.replace(/([a-z0-9])([A-Z])/g, "$1 $2").replace(/[^a-zA-Z0-9]/g, " ").split(" ").filter(Boolean).map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join("");
733
+ }
734
+ function schemaExportNameToOutputAlias(name) {
735
+ return `${toPascalCase2(name)}Output`;
736
+ }
737
+ function registerOutputSchemaName(schemaName, options) {
738
+ options?.outputSchemaNames?.add(schemaName);
739
+ return schemaExportNameToOutputAlias(schemaName);
740
+ }
741
+ function getRegisteredOutputAlias(schema, options) {
742
+ if (!schema || typeof schema !== "object") return void 0;
743
+ if (schema["type"] === "string" && typeof schema["format"] === "string") {
744
+ const customSchemaName = getSchemaExportedVariableNameForStringFormat(
745
+ schema["format"]
746
+ );
747
+ if (customSchemaName) {
748
+ return registerOutputSchemaName(customSchemaName, options);
749
+ }
750
+ }
751
+ if (schema["type"] === "number" || schema["type"] === "integer" || schema["type"] === "boolean") {
752
+ const customSchemaName = getSchemaExportedVariableNameForPrimitiveType(
753
+ schema["type"]
754
+ );
755
+ if (customSchemaName) {
756
+ return registerOutputSchemaName(customSchemaName, options);
757
+ }
758
+ }
759
+ return void 0;
760
+ }
761
+ function schemaToTypeString(schema, options) {
714
762
  if (!schema || typeof schema !== "object") return "unknown";
715
763
  if (schema["$ref"] && typeof schema["$ref"] === "string") {
716
764
  const match = schema["$ref"].match(
@@ -728,56 +776,64 @@ function schemaToTypeString(schema) {
728
776
  let result = "unknown";
729
777
  if ("oneOf" in schema && Array.isArray(schema["oneOf"])) {
730
778
  const unionMembers = schema["oneOf"].map(
731
- (s) => schemaToTypeString(s)
779
+ (s) => schemaToTypeString(s, options)
732
780
  );
733
781
  result = unionMembers.length > 1 ? `(${unionMembers.join(" | ")})` : unionMembers[0] ?? "unknown";
734
782
  } else if ("allOf" in schema && Array.isArray(schema["allOf"])) {
735
783
  const intersectionMembers = schema["allOf"].map(
736
- (s) => schemaToTypeString(s)
784
+ (s) => schemaToTypeString(s, options)
737
785
  );
738
786
  result = intersectionMembers.length > 1 ? `(${intersectionMembers.join(" & ")})` : intersectionMembers[0] ?? "unknown";
739
787
  } else if ("anyOf" in schema && Array.isArray(schema["anyOf"])) {
740
788
  const unionMembers = schema["anyOf"].map(
741
- (s) => schemaToTypeString(s)
789
+ (s) => schemaToTypeString(s, options)
742
790
  );
743
791
  result = unionMembers.length > 1 ? `(${unionMembers.join(" | ")})` : unionMembers[0] ?? "unknown";
744
792
  } else {
745
793
  switch (schema["type"]) {
746
- case "string":
747
- if (schema["enum"] && Array.isArray(schema["enum"])) {
794
+ case "string": {
795
+ const registeredAlias = getRegisteredOutputAlias(schema, options);
796
+ if (registeredAlias) {
797
+ result = registeredAlias;
798
+ } else if (schema["enum"] && Array.isArray(schema["enum"])) {
748
799
  result = schema["enum"].map((v) => JSON.stringify(v)).join(" | ");
749
800
  } else {
750
801
  result = "string";
751
802
  }
752
803
  break;
804
+ }
753
805
  case "number":
754
- case "integer":
755
- if (schema["enum"] && Array.isArray(schema["enum"])) {
806
+ case "integer": {
807
+ const registeredAlias = getRegisteredOutputAlias(schema, options);
808
+ if (registeredAlias) {
809
+ result = registeredAlias;
810
+ } else if (schema["enum"] && Array.isArray(schema["enum"])) {
756
811
  result = schema["enum"].map((v) => String(v)).join(" | ");
757
812
  } else {
758
813
  result = "number";
759
814
  }
760
815
  break;
816
+ }
761
817
  case "boolean":
762
- result = "boolean";
818
+ result = getRegisteredOutputAlias(schema, options) ?? "boolean";
763
819
  break;
764
820
  case "null":
765
821
  result = "null";
766
822
  break;
767
823
  case "array":
768
824
  if (schema["items"]) {
769
- const itemType = schemaToTypeString(schema["items"]);
825
+ const itemType = schemaToTypeString(schema["items"], options);
770
826
  result = `Array<${itemType}>`;
771
827
  } else {
772
828
  result = "unknown[]";
773
829
  }
774
830
  break;
775
831
  case "object":
776
- result = objectSchemaToTypeString(schema);
832
+ result = objectSchemaToTypeString(schema, options);
777
833
  break;
778
834
  default:
779
835
  if (schema["properties"]) {
780
- result = objectSchemaToTypeString(schema);
836
+ result = objectSchemaToTypeString(schema, options);
781
837
  } else if (schema["enum"] && Array.isArray(schema["enum"])) {
782
838
  result = schema["enum"].map((v) => JSON.stringify(v)).join(" | ");
783
839
  } else {
@@ -791,7 +847,7 @@ function schemaToTypeString(schema) {
791
847
  }
792
848
  return result;
793
849
  }
794
- function objectSchemaToTypeString(schema) {
850
+ function objectSchemaToTypeString(schema, options) {
795
851
  const properties = schema["properties"];
796
852
  const required = new Set(schema["required"] ?? []);
797
853
  const additionalProperties = schema["additionalProperties"];
@@ -802,7 +858,7 @@ function objectSchemaToTypeString(schema) {
802
858
  if (properties) {
803
859
  for (const [propName, propSchema] of Object.entries(properties)) {
804
860
  const isRequired = required.has(propName);
805
- const propType = schemaToTypeString(propSchema);
861
+ const propType = schemaToTypeString(propSchema, options);
806
862
  const quotedName = quotePropertyName2(propName);
807
863
  propertyStrings.push(
808
864
  `${quotedName}${isRequired ? "" : "?"}: ${propType}`
@@ -812,23 +868,23 @@ function objectSchemaToTypeString(schema) {
812
868
  if (additionalProperties === true) {
813
869
  propertyStrings.push("[key: string]: unknown");
814
870
  } else if (typeof additionalProperties === "object" && additionalProperties !== null) {
815
- const additionalType = schemaToTypeString(additionalProperties);
871
+ const additionalType = schemaToTypeString(additionalProperties, options);
816
872
  propertyStrings.push(`[key: string]: ${additionalType}`);
817
873
  }
818
874
  return `{ ${propertyStrings.join("; ")} }`;
819
875
  }
820
- function generateInterface(name, schema) {
876
+ function generateInterface(name, schema, options) {
821
877
  const properties = schema["properties"];
822
878
  const required = new Set(schema["required"] ?? []);
823
879
  if (schema["type"] !== "object" && !properties) {
824
- return `export type ${name} = ${schemaToTypeString(schema)};`;
880
+ return `export type ${name} = ${schemaToTypeString(schema, options)};`;
825
881
  }
826
882
  const lines = [];
827
883
  lines.push(`export interface ${name} {`);
828
884
  if (properties) {
829
885
  for (const [propName, propSchema] of Object.entries(properties)) {
830
886
  const isRequired = required.has(propName);
831
- const propType = schemaToTypeString(propSchema);
887
+ const propType = schemaToTypeString(propSchema, options);
832
888
  const quotedName = quotePropertyName2(propName);
833
889
  lines.push(` ${quotedName}${isRequired ? "" : "?"}: ${propType};`);
834
890
  }
@@ -837,7 +893,7 @@ function generateInterface(name, schema) {
837
893
  if (additionalProperties === true) {
838
894
  lines.push(" [key: string]: unknown;");
839
895
  } else if (typeof additionalProperties === "object" && additionalProperties !== null) {
840
- const additionalType = schemaToTypeString(additionalProperties);
896
+ const additionalType = schemaToTypeString(additionalProperties, options);
841
897
  lines.push(` [key: string]: ${additionalType};`);
842
898
  }
843
899
  lines.push("}");
@@ -1163,20 +1219,31 @@ var openApiToZodTsCode = (openapi, customImportLines, options) => {
1163
1219
  const registry = createSchemaRegistry();
1164
1220
  const sortedSchemaNames = topologicalSortSchemas(schemas);
1165
1221
  const typeAssertions = [];
1222
+ const outputSchemaNames = /* @__PURE__ */ new Set();
1223
+ const schemaBlocks = [];
1166
1224
  for (const name of sortedSchemaNames) {
1167
1225
  const schema = schemas[name];
1168
1226
  if (schema) {
1169
1227
  const zodExpr = convertSchemaToZodString(schema);
1170
1228
  const schemaName = `${name}Schema`;
1171
1229
  const typeName = name;
1172
- lines.push(generateInterface(typeName, schema));
1173
- lines.push(`export const ${schemaName}: z.ZodType<${typeName}> = ${zodExpr};`);
1174
- lines.push("");
1230
+ schemaBlocks.push(generateInterface(typeName, schema, { outputSchemaNames }));
1231
+ schemaBlocks.push(`export const ${schemaName}: z.ZodType<${typeName}> = ${zodExpr};`);
1232
+ schemaBlocks.push("");
1175
1233
  typeAssertions.push(`type _Assert${typeName} = _AssertEqual<${typeName}, z.infer<typeof ${schemaName}>>;`);
1176
1234
  const fingerprint = getSchemaFingerprint(schema);
1177
1235
  preRegisterSchema(registry, schemaName, fingerprint);
1178
1236
  }
1179
1237
  }
1238
+ if (outputSchemaNames.size > 0) {
1239
+ lines.push("// Zod output aliases for registered schemas");
1240
+ for (const schemaName of outputSchemaNames) {
1241
+ const aliasName = schemaExportNameToOutputAlias(schemaName);
1242
+ lines.push(`type ${aliasName} = z.output<typeof ${schemaName}>;`);
1243
+ }
1244
+ lines.push("");
1245
+ }
1246
+ lines.push(...schemaBlocks);
1180
1247
  if (typeAssertions.length > 0) {
1181
1248
  lines.push("// Compile-time type assertions - ensure interfaces match schemas");
1182
1249
  lines.push(typeAssertions.join("\n"));