You're Invited:Meet the Socket Team at BlackHat and DEF CON in Las Vegas, Aug 4-6.RSVP
Socket
Book a DemoInstallSign in
Socket

zod-to-json-schema

Package Overview
Dependencies
Maintainers
1
Versions
88
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

to
3.24.6

dist/cjs/getRelativePath.js

1

changelog.md

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

| --------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 3.24.6 | Removed use of instanceOf to check for optional properties as differing package versions could produce intermittent bugs. Added OpenAiAnyType to work around their schema restrictions. |
| 3.24.5 | Update .npmignore to drop 2 mb of test files. Thanks [Misha Kaletsky](https://github.com/mmkal)! |

@@ -7,0 +8,0 @@ | 3.24.4 | Added options to set the value of additionalProperties in objects and record |

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

__exportStar(require("./errorMessages.js"), exports);
__exportStar(require("./getRelativePath.js"), exports);
__exportStar(require("./parseDef.js"), exports);

@@ -22,0 +23,0 @@ __exportStar(require("./parseTypes.js"), exports);

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

nameStrategy: "ref",
openAiAnyTypeName: "OpenAiAnyType"
};

@@ -42,0 +43,0 @@ const getDefaultOptions = (options) => (typeof options === "string"

16

dist/cjs/parseDef.js

@@ -6,2 +6,4 @@ "use strict";

const selectParser_js_1 = require("./selectParser.js");
const getRelativePath_js_1 = require("./getRelativePath.js");
const any_js_1 = require("./parsers/any.js");
function parseDef(def, refs, forceResolution = false) {

@@ -45,3 +47,3 @@ const seenItem = refs.seen.get(def);

case "relative":
return { $ref: getRelativePath(refs.currentPath, item.path) };
return { $ref: (0, getRelativePath_js_1.getRelativePath)(refs.currentPath, item.path) };
case "none":

@@ -52,16 +54,8 @@ case "seen": {

console.warn(`Recursive reference detected at ${refs.currentPath.join("/")}! Defaulting to any`);
return {};
return (0, any_js_1.parseAnyDef)(refs);
}
return refs.$refStrategy === "seen" ? {} : undefined;
return refs.$refStrategy === "seen" ? (0, any_js_1.parseAnyDef)(refs) : undefined;
}
}
};
const getRelativePath = (pathA, pathB) => {
let i = 0;
for (; i < pathA.length && i < pathB.length; i++) {
if (pathA[i] !== pathB[i])
break;
}
return [(pathA.length - i).toString(), ...pathB.slice(i)].join("/");
};
const addMeta = (def, refs, jsonSchema) => {

@@ -68,0 +62,0 @@ if (def.description) {

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.parseAnyDef = void 0;
function parseAnyDef() {
return {};
const getRelativePath_js_1 = require("../getRelativePath.js");
function parseAnyDef(refs) {
if (refs.target !== "openAi") {
return {};
}
const anyDefinitionPath = [
...refs.basePath,
refs.definitionPath,
refs.openAiAnyTypeName,
];
refs.flags.hasReferencedOpenAiAnyType = true;
return {
$ref: refs.$refStrategy === "relative"
? (0, getRelativePath_js_1.getRelativePath)(anyDefinitionPath, refs.currentPath)
: anyDefinitionPath.join("/"),
};
}
exports.parseAnyDef = parseAnyDef;

@@ -5,7 +5,8 @@ "use strict";

const parseDef_js_1 = require("../parseDef.js");
const any_js_1 = require("./any.js");
function parseEffectsDef(_def, refs) {
return refs.effectStrategy === "input"
? (0, parseDef_js_1.parseDef)(_def.schema._def, refs)
: {};
: (0, any_js_1.parseAnyDef)(refs);
}
exports.parseEffectsDef = parseEffectsDef;

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

const record_js_1 = require("./record.js");
const any_js_1 = require("./any.js");
function parseMapDef(def, refs) {

@@ -14,7 +15,7 @@ if (refs.mapStrategy === "record") {

currentPath: [...refs.currentPath, "items", "items", "0"],
}) || {};
}) || (0, any_js_1.parseAnyDef)(refs);
const values = (0, parseDef_js_1.parseDef)(def.valueType._def, {
...refs,
currentPath: [...refs.currentPath, "items", "items", "1"],
}) || {};
}) || (0, any_js_1.parseAnyDef)(refs);
return {

@@ -21,0 +22,0 @@ type: "array",

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.parseNeverDef = void 0;
function parseNeverDef() {
return {
not: {},
};
const any_js_1 = require("./any.js");
function parseNeverDef(refs) {
return refs.target === "openAi"
? undefined
: {
not: (0, any_js_1.parseAnyDef)({
...refs,
currentPath: [...refs.currentPath, "not"],
}),
};
}
exports.parseNeverDef = parseNeverDef;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.parseObjectDef = void 0;
const zod_1 = require("zod");
const parseDef_js_1 = require("../parseDef.js");

@@ -21,3 +20,3 @@ function parseObjectDef(def, refs) {

if (propOptional && forceOptionalIntoNullable) {
if (propDef instanceof zod_1.ZodOptional) {
if (propDef._def.typeName === "ZodOptional") {
propDef = propDef._def.innerType;

@@ -24,0 +23,0 @@ }

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

const parseDef_js_1 = require("../parseDef.js");
const any_js_1 = require("./any.js");
const parseOptionalDef = (def, refs) => {

@@ -18,3 +19,3 @@ if (refs.currentPath.toString() === refs.propertyPath?.toString()) {

{
not: {},
not: (0, any_js_1.parseAnyDef)(refs),
},

@@ -24,4 +25,4 @@ innerSchema,

}
: {};
: (0, any_js_1.parseAnyDef)(refs);
};
exports.parseOptionalDef = parseOptionalDef;

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

const branded_js_1 = require("./branded.js");
const any_js_1 = require("./any.js");
function parseRecordDef(def, refs) {

@@ -23,3 +24,3 @@ if (refs.target === "openAi") {

currentPath: [...refs.currentPath, "properties", key],
}) ?? {},
}) ?? (0, any_js_1.parseAnyDef)(refs),
}), {}),

@@ -26,0 +27,0 @@ additionalProperties: refs.rejectedAdditionalProperties,

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.parseUndefinedDef = void 0;
function parseUndefinedDef() {
const any_js_1 = require("./any.js");
function parseUndefinedDef(refs) {
return {
not: {},
not: (0, any_js_1.parseAnyDef)(refs),
};
}
exports.parseUndefinedDef = parseUndefinedDef;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.parseUnknownDef = void 0;
function parseUnknownDef() {
return {};
const any_js_1 = require("./any.js");
function parseUnknownDef(refs) {
return (0, any_js_1.parseAnyDef)(refs);
}
exports.parseUnknownDef = parseUnknownDef;

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

..._options,
flags: { hasReferencedOpenAiAnyType: false },
currentPath: currentPath,

@@ -14,0 +15,0 @@ propertyPath: undefined,

@@ -50,3 +50,3 @@ "use strict";

case zod_1.ZodFirstPartyTypeKind.ZodUndefined:
return (0, undefined_js_1.parseUndefinedDef)();
return (0, undefined_js_1.parseUndefinedDef)(refs);
case zod_1.ZodFirstPartyTypeKind.ZodNull:

@@ -85,9 +85,9 @@ return (0, null_js_1.parseNullDef)(refs);

case zod_1.ZodFirstPartyTypeKind.ZodNever:
return (0, never_js_1.parseNeverDef)();
return (0, never_js_1.parseNeverDef)(refs);
case zod_1.ZodFirstPartyTypeKind.ZodEffects:
return (0, effects_js_1.parseEffectsDef)(def, refs);
case zod_1.ZodFirstPartyTypeKind.ZodAny:
return (0, any_js_1.parseAnyDef)();
return (0, any_js_1.parseAnyDef)(refs);
case zod_1.ZodFirstPartyTypeKind.ZodUnknown:
return (0, unknown_js_1.parseUnknownDef)();
return (0, unknown_js_1.parseUnknownDef)(refs);
case zod_1.ZodFirstPartyTypeKind.ZodDefault:

@@ -94,0 +94,0 @@ return (0, default_js_1.parseDefaultDef)(def, refs);

@@ -6,5 +6,6 @@ "use strict";

const Refs_js_1 = require("./Refs.js");
const any_js_1 = require("./parsers/any.js");
const zodToJsonSchema = (schema, options) => {
const refs = (0, Refs_js_1.getRefs)(options);
const definitions = typeof options === "object" && options.definitions
let definitions = typeof options === "object" && options.definitions
? Object.entries(options.definitions).reduce((acc, [name, schema]) => ({

@@ -15,3 +16,3 @@ ...acc,

currentPath: [...refs.basePath, refs.definitionPath, name],
}, true) ?? {},
}, true) ?? (0, any_js_1.parseAnyDef)(refs),
}), {})

@@ -29,3 +30,3 @@ : undefined;

currentPath: [...refs.basePath, refs.definitionPath, name],
}, false) ?? {};
}, false) ?? (0, any_js_1.parseAnyDef)(refs);
const title = typeof options === "object" &&

@@ -39,2 +40,22 @@ options.name !== undefined &&

}
if (refs.flags.hasReferencedOpenAiAnyType) {
if (!definitions) {
definitions = {};
}
if (!definitions[refs.openAiAnyTypeName]) {
definitions[refs.openAiAnyTypeName] = {
// Skipping "object" as no properties can be defined and additionalProperties must be "false"
type: ["string", "number", "integer", "boolean", "array", "null"],
items: {
$ref: refs.$refStrategy === "relative"
? "1"
: [
...refs.basePath,
refs.definitionPath,
refs.openAiAnyTypeName,
].join("/"),
},
};
}
}
const combined = name === undefined

@@ -41,0 +62,0 @@ ? definitions

export * from "./Options.js";
export * from "./Refs.js";
export * from "./errorMessages.js";
export * from "./getRelativePath.js";
export * from "./parseDef.js";

@@ -5,0 +6,0 @@ export * from "./parseTypes.js";

@@ -36,2 +36,3 @@ export const ignoreOverride = Symbol("Let zodToJsonSchema decide on which parser to use");

nameStrategy: "ref",
openAiAnyTypeName: "OpenAiAnyType"
};

@@ -38,0 +39,0 @@ export const getDefaultOptions = (options) => (typeof options === "string"

import { ignoreOverride } from "./Options.js";
import { selectParser } from "./selectParser.js";
import { getRelativePath } from "./getRelativePath.js";
import { parseAnyDef } from "./parsers/any.js";
export function parseDef(def, refs, forceResolution = false) {

@@ -46,16 +48,8 @@ const seenItem = refs.seen.get(def);

console.warn(`Recursive reference detected at ${refs.currentPath.join("/")}! Defaulting to any`);
return {};
return parseAnyDef(refs);
}
return refs.$refStrategy === "seen" ? {} : undefined;
return refs.$refStrategy === "seen" ? parseAnyDef(refs) : undefined;
}
}
};
const getRelativePath = (pathA, pathB) => {
let i = 0;
for (; i < pathA.length && i < pathB.length; i++) {
if (pathA[i] !== pathB[i])
break;
}
return [(pathA.length - i).toString(), ...pathB.slice(i)].join("/");
};
const addMeta = (def, refs, jsonSchema) => {

@@ -62,0 +56,0 @@ if (def.description) {

@@ -1,3 +0,17 @@

export function parseAnyDef() {
return {};
import { getRelativePath } from "../getRelativePath.js";
export function parseAnyDef(refs) {
if (refs.target !== "openAi") {
return {};
}
const anyDefinitionPath = [
...refs.basePath,
refs.definitionPath,
refs.openAiAnyTypeName,
];
refs.flags.hasReferencedOpenAiAnyType = true;
return {
$ref: refs.$refStrategy === "relative"
? getRelativePath(anyDefinitionPath, refs.currentPath)
: anyDefinitionPath.join("/"),
};
}
import { parseDef } from "../parseDef.js";
import { parseAnyDef } from "./any.js";
export function parseEffectsDef(_def, refs) {
return refs.effectStrategy === "input"
? parseDef(_def.schema._def, refs)
: {};
: parseAnyDef(refs);
}
import { parseDef } from "../parseDef.js";
import { parseRecordDef } from "./record.js";
import { parseAnyDef } from "./any.js";
export function parseMapDef(def, refs) {

@@ -10,7 +11,7 @@ if (refs.mapStrategy === "record") {

currentPath: [...refs.currentPath, "items", "items", "0"],
}) || {};
}) || parseAnyDef(refs);
const values = parseDef(def.valueType._def, {
...refs,
currentPath: [...refs.currentPath, "items", "items", "1"],
}) || {};
}) || parseAnyDef(refs);
return {

@@ -17,0 +18,0 @@ type: "array",

@@ -1,5 +0,11 @@

export function parseNeverDef() {
return {
not: {},
};
import { parseAnyDef } from "./any.js";
export function parseNeverDef(refs) {
return refs.target === "openAi"
? undefined
: {
not: parseAnyDef({
...refs,
currentPath: [...refs.currentPath, "not"],
}),
};
}

@@ -1,2 +0,1 @@

import { ZodOptional } from "zod";
import { parseDef } from "../parseDef.js";

@@ -18,3 +17,3 @@ export function parseObjectDef(def, refs) {

if (propOptional && forceOptionalIntoNullable) {
if (propDef instanceof ZodOptional) {
if (propDef._def.typeName === "ZodOptional") {
propDef = propDef._def.innerType;

@@ -21,0 +20,0 @@ }

import { parseDef } from "../parseDef.js";
import { parseAnyDef } from "./any.js";
export const parseOptionalDef = (def, refs) => {

@@ -14,3 +15,3 @@ if (refs.currentPath.toString() === refs.propertyPath?.toString()) {

{
not: {},
not: parseAnyDef(refs),
},

@@ -20,3 +21,3 @@ innerSchema,

}
: {};
: parseAnyDef(refs);
};

@@ -5,2 +5,3 @@ import { ZodFirstPartyTypeKind, } from "zod";

import { parseBrandedDef } from "./branded.js";
import { parseAnyDef } from "./any.js";
export function parseRecordDef(def, refs) {

@@ -20,3 +21,3 @@ if (refs.target === "openAi") {

currentPath: [...refs.currentPath, "properties", key],
}) ?? {},
}) ?? parseAnyDef(refs),
}), {}),

@@ -23,0 +24,0 @@ additionalProperties: refs.rejectedAdditionalProperties,

@@ -1,5 +0,6 @@

export function parseUndefinedDef() {
import { parseAnyDef } from "./any.js";
export function parseUndefinedDef(refs) {
return {
not: {},
not: parseAnyDef(refs),
};
}

@@ -1,3 +0,4 @@

export function parseUnknownDef() {
return {};
import { parseAnyDef } from "./any.js";
export function parseUnknownDef(refs) {
return parseAnyDef(refs);
}

@@ -9,2 +9,3 @@ import { getDefaultOptions } from "./Options.js";

..._options,
flags: { hasReferencedOpenAiAnyType: false },
currentPath: currentPath,

@@ -11,0 +12,0 @@ propertyPath: undefined,

@@ -47,3 +47,3 @@ import { ZodFirstPartyTypeKind } from "zod";

case ZodFirstPartyTypeKind.ZodUndefined:
return parseUndefinedDef();
return parseUndefinedDef(refs);
case ZodFirstPartyTypeKind.ZodNull:

@@ -82,9 +82,9 @@ return parseNullDef(refs);

case ZodFirstPartyTypeKind.ZodNever:
return parseNeverDef();
return parseNeverDef(refs);
case ZodFirstPartyTypeKind.ZodEffects:
return parseEffectsDef(def, refs);
case ZodFirstPartyTypeKind.ZodAny:
return parseAnyDef();
return parseAnyDef(refs);
case ZodFirstPartyTypeKind.ZodUnknown:
return parseUnknownDef();
return parseUnknownDef(refs);
case ZodFirstPartyTypeKind.ZodDefault:

@@ -91,0 +91,0 @@ return parseDefaultDef(def, refs);

import { parseDef } from "./parseDef.js";
import { getRefs } from "./Refs.js";
import { parseAnyDef } from "./parsers/any.js";
const zodToJsonSchema = (schema, options) => {
const refs = getRefs(options);
const definitions = typeof options === "object" && options.definitions
let definitions = typeof options === "object" && options.definitions
? Object.entries(options.definitions).reduce((acc, [name, schema]) => ({

@@ -11,3 +12,3 @@ ...acc,

currentPath: [...refs.basePath, refs.definitionPath, name],
}, true) ?? {},
}, true) ?? parseAnyDef(refs),
}), {})

@@ -25,3 +26,3 @@ : undefined;

currentPath: [...refs.basePath, refs.definitionPath, name],
}, false) ?? {};
}, false) ?? parseAnyDef(refs);
const title = typeof options === "object" &&

@@ -35,2 +36,22 @@ options.name !== undefined &&

}
if (refs.flags.hasReferencedOpenAiAnyType) {
if (!definitions) {
definitions = {};
}
if (!definitions[refs.openAiAnyTypeName]) {
definitions[refs.openAiAnyTypeName] = {
// Skipping "object" as no properties can be defined and additionalProperties must be "false"
type: ["string", "number", "integer", "boolean", "array", "null"],
items: {
$ref: refs.$refStrategy === "relative"
? "1"
: [
...refs.basePath,
refs.definitionPath,
refs.openAiAnyTypeName,
].join("/"),
},
};
}
}
const combined = name === undefined

@@ -37,0 +58,0 @@ ? definitions

import { JsonSchema7TypeUnion } from "./parseTypes.js";
import { Refs } from "./Refs.js";
export type ErrorMessages<T extends JsonSchema7TypeUnion, OmitProperties extends string = ""> = Partial<Omit<{
export type ErrorMessages<T extends JsonSchema7TypeUnion | {
format: string;
} | {
pattern: string;
}, OmitProperties extends string = ""> = Partial<Omit<{
[key in keyof T]: string;

@@ -5,0 +9,0 @@ }, OmitProperties | "type" | "errorMessages">>;

export * from "./Options.js";
export * from "./Refs.js";
export * from "./errorMessages.js";
export * from "./getRelativePath.js";
export * from "./parseDef.js";

@@ -5,0 +6,0 @@ export * from "./parseTypes.js";

@@ -34,4 +34,5 @@ import { ZodSchema, ZodTypeDef } from "zod";

postProcess?: PostProcessCallback;
openAiAnyTypeName: string;
};
export declare const defaultOptions: Options;
export declare const getDefaultOptions: <Target extends Targets>(options: string | Partial<Options<Target>> | undefined) => Options<Target>;

@@ -1,2 +0,5 @@

export type JsonSchema7AnyType = {};
export declare function parseAnyDef(): JsonSchema7AnyType;
import { Refs } from "../Refs.js";
export type JsonSchema7AnyType = {
$ref?: string;
};
export declare function parseAnyDef(refs: Refs): JsonSchema7AnyType;

@@ -0,4 +1,6 @@

import { Refs } from "../Refs.js";
import { JsonSchema7AnyType } from "./any.js";
export type JsonSchema7NeverType = {
not: {};
not: JsonSchema7AnyType;
};
export declare function parseNeverDef(): JsonSchema7NeverType;
export declare function parseNeverDef(refs: Refs): JsonSchema7NeverType | undefined;

@@ -0,4 +1,6 @@

import { Refs } from "../Refs.js";
import { JsonSchema7AnyType } from "./any.js";
export type JsonSchema7UndefinedType = {
not: {};
not: JsonSchema7AnyType;
};
export declare function parseUndefinedDef(): JsonSchema7UndefinedType;
export declare function parseUndefinedDef(refs: Refs): JsonSchema7UndefinedType;

@@ -1,2 +0,4 @@

export type JsonSchema7UnknownType = {};
export declare function parseUnknownDef(): JsonSchema7UnknownType;
import { Refs } from "../Refs";
import { JsonSchema7AnyType } from "./any.js";
export type JsonSchema7UnknownType = JsonSchema7AnyType;
export declare function parseUnknownDef(refs: Refs): JsonSchema7UnknownType;

@@ -8,2 +8,5 @@ import { ZodTypeDef } from "zod";

propertyPath: string[] | undefined;
flags: {
hasReferencedOpenAiAnyType: boolean;
};
} & Options<Targets>;

@@ -10,0 +13,0 @@ export type Seen = {

{
"name": "zod-to-json-schema",
"version": "3.24.5",
"version": "3.24.6",
"description": "Converts Zod schemas to Json Schemas",

@@ -5,0 +5,0 @@ "types": "./dist/types/index.d.ts",

@@ -26,20 +26,2 @@ # Zod to Json Schema

<p>
<a href="https://retool.com/?ref=stefanterdell&utm_source=github&utm_medium=referral&utm_campaign=stefanterdell">
<picture height="45px">
<source media="(prefers-color-scheme: dark)" srcset="https://github.com/colinhacks/zod/assets/3084745/ac65013f-aeb4-48dd-a2ee-41040b69cbe6">
<img alt="stainless" height="45px" src="https://github.com/colinhacks/zod/assets/3084745/5ef4c11b-efeb-4495-90a8-41b83f798600">
</picture>
</a>
<br />
Build AI apps and workflows with <a href="https://retool.com/products/ai?ref=stefanterdell&utm_source=github&utm_medium=referral&utm_campaign=stefanterdell">Retool AI</a>
<br/>
<a href="https://retool.com/?ref=stefanterdell&utm_source=github&utm_medium=referral&utm_campaign=stefanterdell" style="text-decoration:none;">retool.com</a>
</p>
<p></p>
</td>
</tr>
<tr>
<td align="center">
<p></p>
<p>
<div style="background-color: white; padding: 4px; padding-bottom: 8px;" alt="stainless">

@@ -61,2 +43,20 @@ <a href="https://www.coderabbit.ai/">

</tr>
<tr>
<td align="center">
<p></p>
<p>
<a href="https://retool.com/?ref=stefanterdell&utm_source=github&utm_medium=referral&utm_campaign=stefanterdell">
<picture height="45px">
<source media="(prefers-color-scheme: dark)" srcset="https://github.com/colinhacks/zod/assets/3084745/ac65013f-aeb4-48dd-a2ee-41040b69cbe6">
<img alt="stainless" height="45px" src="https://github.com/colinhacks/zod/assets/3084745/5ef4c11b-efeb-4495-90a8-41b83f798600">
</picture>
</a>
<br />
Build AI apps and workflows with <a href="https://retool.com/products/ai?ref=stefanterdell&utm_source=github&utm_medium=referral&utm_campaign=stefanterdell">Retool AI</a>
<br/>
<a href="https://retool.com/?ref=stefanterdell&utm_source=github&utm_medium=referral&utm_campaign=stefanterdell" style="text-decoration:none;">retool.com</a>
</p>
<p></p>
</td>
</tr>
</table>

@@ -143,2 +143,3 @@

| **postProcess**?: callback | See section |
| **openAiAnyTypeName**?: string | Decides the name of a Json schema used to allow semi-arbitrary values in Open AI structured output. If any value in the Zod-schema resolves to any "any"-type schema it will reference a definition of this name. If no such definition is provided a default Json schema will be used. Defaults to "OpenAiAnyType" |

@@ -145,0 +146,0 @@ ### Definitions