Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

zod-to-json-schema

Package Overview
Dependencies
Maintainers
1
Versions
81
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

zod-to-json-schema - npm Package Compare versions

Comparing version 3.21.1 to 3.21.2

2

changelog.md

@@ -5,2 +5,4 @@ # Changelog

| --------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 3.21.2 | Adds "integer" type Date output to support min/max checks, markdownDescription option, fixes "none" refStrategy by adding "seen" and adds an option to use "pattern" with Zods' email enum instead of "format". |
| 3.21.1 | New target (2019-09) along with improved intersection schemas, improved mutual recursion references in definitions, descriptions respected in union parser and not removed in collapsed |
| 3.21.0 | Added new string validations (ip, emoji, etc) and BigInt checks to support Zod 3.21 |

@@ -7,0 +9,0 @@ | 3.20.5 | Added uniqueItems to Set and an option to disregard pipe schemas |

import { zodToJsonSchema } from "./src/zodToJsonSchema";
export default zodToJsonSchema;
export { zodToJsonSchema };

@@ -0,0 +0,0 @@ "use strict";

13

package.json
{
"name": "zod-to-json-schema",
"version": "3.21.1",
"version": "3.21.2",
"description": "Converts Zod schemas to Json Schemas",

@@ -30,3 +30,4 @@ "main": "index.js",

"Andreas Berger (https://github.com/Andy2003)",
"Jan Potoms (https://github.com/Janpot)"
"Jan Potoms (https://github.com/Janpot)",
"Santiago Cammi (https://github.com/scammi)"
],

@@ -46,10 +47,10 @@ "repository": {

"ajv-formats": "^2.1.1",
"jest": "^26.6.3",
"jest": "^29.5.0",
"json-schema-deref-sync": "^0.14.0",
"rimraf": "^3.0.2",
"ts-jest": "^26.5.2",
"typescript": "^4.9.4",
"ts-jest": "^29.1.0",
"typescript": "^5.1.3",
"zod": "^3.21.4"
},
"types": "index.d.ts"
}
}

@@ -69,13 +69,16 @@ # Zod to Json Schema

| Option | Effect |
|-----------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| **name**?: _string_ | As described above. |
| **basePath**?: string[] | The base path of the root reference builder. Defaults to ["#"]. |
| **$refStrategy**?: "root" \| "relative" \| "none" | The reference builder strategy; <ul><li>**"root"** resolves $refs from the root up, ie: "#/definitions/mySchema".</li><li>**"relative"** uses [relative JSON pointers](https://tools.ietf.org/id/draft-handrews-relative-json-pointer-00.html). _See known issues!_</li><li>**"none"** ignores referencing all together, creating a new schema branch even on "seen" schemas. Recursive references defaults to "any", ie `{}`.</li></ul> Defaults to "root". |
| **effectStrategy**?: "input" \| "any" | The effects output strategy. Defaults to "input". _See known issues!_ |
| **definitionPath**?: "definitions" \| "$defs" | The name of the definitions property when name is passed. Defaults to "definitions". |
| **target**?: "jsonSchema7" \| "jsonSchema2019-09" \| "openApi3" | Which spec to target. Defaults to "jsonSchema7" |
| **strictUnions**?: boolean | Scrubs unions of any-like json schemas, like `{}` or `true`. Multiple zod types may result in these out of necessity, such as z.instanceof() |
| **definitions**?: Record<string, ZodSchema> | See separate section below |
| **errorMessages**?: boolean | Include custom error messages created via chained function checks for supported zod types. See section below |
| Option | Effect |
| ------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **name**?: _string_ | As described above. |
| **basePath**?: string[] | The base path of the root reference builder. Defaults to ["#"]. |
| **$refStrategy**?: "root" \| "relative" \| "seen" \| "none" | The reference builder strategy; <ul><li>**"root"** resolves $refs from the root up, ie: "#/definitions/mySchema".</li><li>**"relative"** uses [relative JSON pointers](https://tools.ietf.org/id/draft-handrews-relative-json-pointer-00.html). _See known issues!_</li><li>**"seen"** reuses the output of any "seen" Zod schema. In theory it's a more performant version of "none", but in practice this behaviour can cause issues with nested schemas and has now gotten its own option.</li> <li>**"none"** ignores referencing all together, creating a new schema branch even on "seen" schemas. Recursive references defaults to "any", ie `{}`.</li></ul> Defaults to "root". |
| **effectStrategy**?: "input" \| "any" | The effects output strategy. Defaults to "input". _See known issues!_ |
| **dateStrategy**?: "string" \| "integer" | Date strategy, integer allow to specify in unix-time min and max values. Defaults to "string". |
| **emailStrategy**?: "format:email" \| "format:idn-email" \| "pattern:zod" | Choose how to handle the email string check. Defaults to "format:email". |
| **definitionPath**?: "definitions" \| "$defs" | The name of the definitions property when name is passed. Defaults to "definitions". |
| **target**?: "jsonSchema7" \| "jsonSchema2019-09" \| "openApi3" | Which spec to target. Defaults to "jsonSchema7" |
| **strictUnions**?: boolean | Scrubs unions of any-like json schemas, like `{}` or `true`. Multiple zod types may result in these out of necessity, such as z.instanceof() |
| **definitions**?: Record<string, ZodSchema> | See separate section below |
| **errorMessages**?: boolean | Include custom error messages created via chained function checks for supported zod types. See section below |
| **markdownDescription**?: boolean | Copies the `description` meta to `markdownDescription` |

@@ -82,0 +85,0 @@ ### Definitions

@@ -0,0 +0,0 @@ import { JsonSchema7TypeUnion } from "./parseDef";

@@ -0,0 +0,0 @@ "use strict";

@@ -5,6 +5,7 @@ import { ZodSchema } from "zod";

name: string | undefined;
$refStrategy: "root" | "relative" | "none";
$refStrategy: "root" | "relative" | "none" | "seen";
basePath: string[];
effectStrategy: "input" | "any";
pipeStrategy: "input" | "all";
dateStrategy: "string" | "integer";
target: Target;

@@ -15,4 +16,6 @@ strictUnions: boolean;

errorMessages: boolean;
markdownDescription: boolean;
emailStrategy: "format:email" | "format:idn-email" | "pattern:zod";
};
export declare const defaultOptions: Options;
export declare const getDefaultOptions: <Target extends Targets>(options: string | Partial<Options<Target>> | undefined) => Options<Target>;

@@ -10,2 +10,3 @@ "use strict";

pipeStrategy: "all",
dateStrategy: "string",
definitionPath: "definitions",

@@ -16,2 +17,4 @@ target: "jsonSchema7",

errorMessages: false,
markdownDescription: false,
emailStrategy: "format:email",
};

@@ -18,0 +21,0 @@ const getDefaultOptions = (options) => (typeof options === "string"

@@ -31,2 +31,3 @@ import { ZodTypeDef } from "zod";

description?: string;
markdownDescription?: string;
};

@@ -33,0 +34,0 @@ export type JsonSchema7TypeUnion = JsonSchema7StringType | JsonSchema7ArrayType | JsonSchema7NumberType | JsonSchema7BigintType | JsonSchema7BooleanType | JsonSchema7DateType | JsonSchema7EnumType | JsonSchema7LiteralType | JsonSchema7NativeEnumType | JsonSchema7NullType | JsonSchema7NumberType | JsonSchema7ObjectType | JsonSchema7RecordType | JsonSchema7TupleType | JsonSchema7UnionType | JsonSchema7UndefinedType | JsonSchema7RefType | JsonSchema7NeverType | JsonSchema7MapType | JsonSchema7AnyType | JsonSchema7NullableType | JsonSchema7AllOfType | JsonSchema7UnknownType | JsonSchema7SetType;

@@ -38,3 +38,6 @@ "use strict";

if (seenItem && !forceResolution) {
return get$ref(seenItem, refs);
const seenSchema = get$ref(seenItem, refs);
if (seenSchema !== undefined) {
return seenSchema;
}
}

@@ -45,3 +48,3 @@ const newItem = { def, path: refs.currentPath, jsonSchema: undefined };

if (jsonSchema) {
addMeta(def, jsonSchema);
addMeta(def, refs, jsonSchema);
}

@@ -70,2 +73,10 @@ newItem.jsonSchema = jsonSchema;

}
return undefined;
}
case "seen": {
if (item.path.length < refs.currentPath.length &&
item.path.every((value, index) => refs.currentPath[index] === value)) {
console.warn(`Recursive reference detected at ${refs.currentPath.join("/")}! Defaulting to any`);
return {};
}
else {

@@ -98,3 +109,3 @@ return item.jsonSchema;

case zod_1.ZodFirstPartyTypeKind.ZodDate:
return (0, date_1.parseDateDef)();
return (0, date_1.parseDateDef)(def, refs);
case zod_1.ZodFirstPartyTypeKind.ZodUndefined:

@@ -158,6 +169,10 @@ return (0, undefined_1.parseUndefinedDef)();

};
const addMeta = (def, jsonSchema) => {
if (def.description)
const addMeta = (def, refs, jsonSchema) => {
if (def.description) {
jsonSchema.description = def.description;
if (refs.markdownDescription) {
jsonSchema.markdownDescription = def.description;
}
}
return jsonSchema;
};
export type JsonSchema7AnyType = {};
export declare function parseAnyDef(): JsonSchema7AnyType;

@@ -0,0 +0,0 @@ "use strict";

@@ -0,0 +0,0 @@ import { ZodArrayDef } from "zod";

@@ -0,0 +0,0 @@ "use strict";

@@ -0,0 +0,0 @@ import { ZodBigIntDef } from "zod";

@@ -0,0 +0,0 @@ "use strict";

@@ -0,0 +0,0 @@ export type JsonSchema7BooleanType = {

@@ -0,0 +0,0 @@ "use strict";

import { ZodBrandedDef } from "zod";
import { Refs } from "../Refs";
export declare function parseBrandedDef(_def: ZodBrandedDef<any>, refs: Refs): import("../parseDef").JsonSchema7Type | undefined;

@@ -0,0 +0,0 @@ "use strict";

import { ZodCatchDef } from "zod";
import { Refs } from "../Refs";
export declare const parseCatchDef: (def: ZodCatchDef<any>, refs: Refs) => import("../parseDef").JsonSchema7Type | undefined;

@@ -0,0 +0,0 @@ "use strict";

@@ -0,5 +1,12 @@

import { ZodDateDef } from "zod";
import { Refs } from "../Refs";
import { ErrorMessages } from "../errorMessages";
import { JsonSchema7NumberType } from "./number";
export type JsonSchema7DateType = {
type: "string";
format: "date-time";
type: "integer" | "string";
format: "unix-time" | "date-time";
minimum?: number;
maximum?: number;
errorMessage?: ErrorMessages<JsonSchema7NumberType>;
};
export declare function parseDateDef(): JsonSchema7DateType;
export declare function parseDateDef(def: ZodDateDef, refs: Refs): JsonSchema7DateType;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.parseDateDef = void 0;
function parseDateDef() {
return {
type: "string",
format: "date-time",
};
const errorMessages_1 = require("../errorMessages");
function parseDateDef(def, refs) {
if (refs.dateStrategy == "integer") {
return integerDateParser(def, refs);
}
else {
return {
type: "string",
format: "date-time",
};
}
}
exports.parseDateDef = parseDateDef;
const integerDateParser = (def, refs) => {
const res = {
type: "integer",
format: "unix-time",
};
for (const check of def.checks) {
switch (check.kind) {
case "min":
if (refs.target === "jsonSchema7") {
(0, errorMessages_1.setResponseValueAndErrors)(res, "minimum", check.value, // This is in milliseconds
check.message, refs);
}
break;
case "max":
if (refs.target === "jsonSchema7") {
(0, errorMessages_1.setResponseValueAndErrors)(res, "maximum", check.value, // This is in milliseconds
check.message, refs);
}
break;
}
}
return res;
};

@@ -0,0 +0,0 @@ import { ZodDefaultDef } from "zod";

@@ -0,0 +0,0 @@ "use strict";

@@ -0,0 +0,0 @@ import { ZodEffectsDef } from "zod";

@@ -0,0 +0,0 @@ "use strict";

@@ -0,0 +0,0 @@ import { ZodEnumDef } from "zod";

@@ -0,0 +0,0 @@ "use strict";

@@ -0,0 +0,0 @@ import { ZodIntersectionDef } from "zod";

@@ -0,0 +0,0 @@ "use strict";

@@ -0,0 +0,0 @@ import { ZodLiteralDef } from "zod";

@@ -0,0 +0,0 @@ "use strict";

@@ -0,0 +0,0 @@ import { ZodMapDef } from "zod";

@@ -0,0 +0,0 @@ "use strict";

@@ -0,0 +0,0 @@ import { ZodNativeEnumDef } from "zod";

@@ -0,0 +0,0 @@ "use strict";

@@ -0,0 +0,0 @@ export type JsonSchema7NeverType = {

@@ -0,0 +0,0 @@ "use strict";

@@ -0,0 +0,0 @@ import { Refs } from "../Refs";

@@ -0,0 +0,0 @@ "use strict";

@@ -0,0 +0,0 @@ import { ZodNullableDef } from "zod";

@@ -0,0 +0,0 @@ "use strict";

@@ -0,0 +0,0 @@ import { ZodNumberDef } from "zod";

@@ -0,0 +0,0 @@ "use strict";

@@ -10,2 +10,3 @@ import { ZodObjectDef } from "zod";

};
export declare function parseObjectDefX(def: ZodObjectDef, refs: Refs): JsonSchema7ObjectType;
export declare function parseObjectDef(def: ZodObjectDef, refs: Refs): JsonSchema7ObjectType;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.parseObjectDef = void 0;
exports.parseObjectDef = exports.parseObjectDefX = void 0;
const parseDef_1 = require("../parseDef");
function parseObjectDefX(def, refs) {
var _a, _b;
Object.keys(def.shape()).reduce((schema, key) => {
let prop = def.shape()[key];
const isOptional = prop.isOptional();
if (!isOptional) {
prop = Object.assign({}, prop._def.innerSchema);
}
const propSchema = (0, parseDef_1.parseDef)(prop._def, Object.assign(Object.assign({}, refs), { currentPath: [...refs.currentPath, "properties", key], propertyPath: [...refs.currentPath, "properties", key] }));
if (propSchema !== undefined) {
schema.properties[key] = propSchema;
if (!isOptional) {
if (!schema.required) {
schema.required = [];
}
schema.required.push(key);
}
}
return schema;
}, {
type: "object",
properties: {},
additionalProperties: def.catchall._def.typeName === "ZodNever"
? def.unknownKeys === "passthrough"
: (_a = (0, parseDef_1.parseDef)(def.catchall._def, Object.assign(Object.assign({}, refs), { currentPath: [...refs.currentPath, "additionalProperties"] }))) !== null && _a !== void 0 ? _a : true,
});
const result = Object.assign(Object.assign({ type: "object" }, Object.entries(def.shape()).reduce((acc, [propName, propDef]) => {
if (propDef === undefined || propDef._def === undefined)
return acc;
const parsedDef = (0, parseDef_1.parseDef)(propDef._def, Object.assign(Object.assign({}, refs), { currentPath: [...refs.currentPath, "properties", propName], propertyPath: [...refs.currentPath, "properties", propName] }));
if (parsedDef === undefined)
return acc;
return {
properties: Object.assign(Object.assign({}, acc.properties), { [propName]: parsedDef }),
required: propDef.isOptional()
? acc.required
: [...acc.required, propName],
};
}, { properties: {}, required: [] })), { additionalProperties: def.catchall._def.typeName === "ZodNever"
? def.unknownKeys === "passthrough"
: (_b = (0, parseDef_1.parseDef)(def.catchall._def, Object.assign(Object.assign({}, refs), { currentPath: [...refs.currentPath, "additionalProperties"] }))) !== null && _b !== void 0 ? _b : true });
if (!result.required.length)
delete result.required;
return result;
}
exports.parseObjectDefX = parseObjectDefX;
function parseObjectDef(def, refs) {

@@ -6,0 +52,0 @@ var _a;

@@ -0,0 +0,0 @@ import { ZodOptionalDef } from "zod";

@@ -0,0 +0,0 @@ "use strict";

@@ -0,0 +0,0 @@ import { ZodPipelineDef } from "zod";

@@ -0,0 +0,0 @@ "use strict";

@@ -0,0 +0,0 @@ import { ZodPromiseDef } from "zod";

@@ -0,0 +0,0 @@ "use strict";

@@ -0,0 +0,0 @@ import { ZodRecordDef, ZodTypeAny } from "zod";

@@ -0,0 +0,0 @@ "use strict";

@@ -0,0 +0,0 @@ import { ZodSetDef } from "zod";

@@ -0,0 +0,0 @@ "use strict";

import { ZodStringDef } from "zod";
import { ErrorMessages } from "../errorMessages";
import { Refs } from "../Refs";
export declare const emailPattern = "^(([^<>()[\\]\\\\.,;:\\s@\\\"]+(\\.[^<>()[\\]\\\\.,;:\\s@\\\"]+)*)|(\\\".+\\\"))@((\\[(((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2}))\\.){3}((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2}))\\])|(\\[IPv6:(([a-f0-9]{1,4}:){7}|::([a-f0-9]{1,4}:){0,6}|([a-f0-9]{1,4}:){1}:([a-f0-9]{1,4}:){0,5}|([a-f0-9]{1,4}:){2}:([a-f0-9]{1,4}:){0,4}|([a-f0-9]{1,4}:){3}:([a-f0-9]{1,4}:){0,3}|([a-f0-9]{1,4}:){4}:([a-f0-9]{1,4}:){0,2}|([a-f0-9]{1,4}:){5}:([a-f0-9]{1,4}:){0,1})([a-f0-9]{1,4}|(((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2}))\\.){3}((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2})))\\])|([A-Za-z0-9]([A-Za-z0-9-]*[A-Za-z0-9])*(\\.[A-Za-z]{2,})+))$";
export declare const cuidPattern = "^c[^\\s-]{8,}$";
export declare const cuid2Pattern = "^[a-z][a-z0-9]*$";
export declare const ulidPattern = "/[0-9A-HJKMNP-TV-Z]{26}/";
export declare const emojiPattern = "/^(p{Extended_Pictographic}|p{Emoji_Component})+$/u";
export type JsonSchema7StringType = {

@@ -8,3 +13,3 @@ type: "string";

maxLength?: number;
format?: "email" | "uri" | "uuid" | "date-time" | "ipv4" | "ipv6";
format?: "email" | "idn-email" | "uri" | "uuid" | "date-time" | "ipv4" | "ipv6";
pattern?: string;

@@ -11,0 +16,0 @@ allOf?: {

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.parseStringDef = void 0;
exports.parseStringDef = exports.emojiPattern = exports.ulidPattern = exports.cuid2Pattern = exports.cuidPattern = exports.emailPattern = void 0;
const errorMessages_1 = require("../errorMessages");
exports.emailPattern = '^(([^<>()[\\]\\\\.,;:\\s@\\"]+(\\.[^<>()[\\]\\\\.,;:\\s@\\"]+)*)|(\\".+\\"))@((\\[(((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2}))\\.){3}((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2}))\\])|(\\[IPv6:(([a-f0-9]{1,4}:){7}|::([a-f0-9]{1,4}:){0,6}|([a-f0-9]{1,4}:){1}:([a-f0-9]{1,4}:){0,5}|([a-f0-9]{1,4}:){2}:([a-f0-9]{1,4}:){0,4}|([a-f0-9]{1,4}:){3}:([a-f0-9]{1,4}:){0,3}|([a-f0-9]{1,4}:){4}:([a-f0-9]{1,4}:){0,2}|([a-f0-9]{1,4}:){5}:([a-f0-9]{1,4}:){0,1})([a-f0-9]{1,4}|(((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2}))\\.){3}((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2})))\\])|([A-Za-z0-9]([A-Za-z0-9-]*[A-Za-z0-9])*(\\.[A-Za-z]{2,})+))$';
exports.cuidPattern = "^c[^\\s-]{8,}$";
exports.cuid2Pattern = "^[a-z][a-z0-9]*$";
exports.ulidPattern = "/[0-9A-HJKMNP-TV-Z]{26}/";
exports.emojiPattern = "/^(p{Extended_Pictographic}|p{Emoji_Component})+$/u";
function parseStringDef(def, refs) {

@@ -23,3 +28,13 @@ const res = {

case "email":
addFormat(res, "email", check.message, refs);
switch (refs.emailStrategy) {
case "format:email":
addFormat(res, "email", check.message, refs);
break;
case "format:idn-email":
addFormat(res, "idn-email", check.message, refs);
break;
case "pattern:zod":
addPattern(res, exports.emailPattern, check.message, refs);
break;
}
break;

@@ -36,6 +51,6 @@ case "url":

case "cuid":
addPattern(res, "^c[^\\s-]{8,}$", check.message, refs);
addPattern(res, exports.cuidPattern, check.message, refs);
break;
case "cuid2":
addPattern(res, "^[a-z][a-z0-9]*$", check.message, refs);
addPattern(res, exports.cuid2Pattern, check.message, refs);
break;

@@ -73,6 +88,6 @@ case "startsWith":

case "emoji":
addPattern(res, "/^(p{Extended_Pictographic}|p{Emoji_Component})+$/u", check.message, refs);
addPattern(res, exports.emojiPattern, check.message, refs);
break;
case "ulid": {
addPattern(res, "/[0-9A-HJKMNP-TV-Z]{26}/", check.message, refs);
addPattern(res, exports.ulidPattern, check.message, refs);
break;

@@ -79,0 +94,0 @@ }

@@ -0,0 +0,0 @@ import { ZodTupleDef, ZodTupleItems, ZodTypeAny } from "zod";

@@ -0,0 +0,0 @@ "use strict";

@@ -0,0 +0,0 @@ export type JsonSchema7UndefinedType = {

@@ -0,0 +0,0 @@ "use strict";

@@ -0,0 +0,0 @@ import { ZodDiscriminatedUnionDef, ZodUnionDef } from "zod";

@@ -0,0 +0,0 @@ "use strict";

export type JsonSchema7UnknownType = {};
export declare function parseUnknownDef(): JsonSchema7UnknownType;

@@ -0,0 +0,0 @@ "use strict";

@@ -0,0 +0,0 @@ import { ZodTypeDef } from "zod";

@@ -0,0 +0,0 @@ "use strict";

@@ -0,0 +0,0 @@ import { ZodSchema } from "zod";

@@ -0,0 +0,0 @@ "use strict";

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc