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

json-schema-to-zod

Package Overview
Dependencies
Maintainers
1
Versions
46
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

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

Comparing version 2.0.4 to 2.0.5

dist/cjs/utils/pick.js

73

dist/cjs/args.js

@@ -8,56 +8,52 @@ "use strict";

if (help) {
const defaults = {
name: "help",
short: "h",
description: "Display this message :)",
};
const param = help === true
? defaults
: {
...defaults,
...help,
};
let index = args.indexOf("--" + param.name);
let index = args.indexOf("--help");
if (index === -1) {
index = args.indexOf("-" + param.short);
index = args.indexOf("-h");
}
if (index !== -1) {
printParams([...params, param]);
printParams({
...params,
help: {
shorthand: "h",
description: typeof help === "string" ? help : "Display this message :)",
},
});
process.exit(0);
}
}
for (const param of params) {
let index = args.indexOf("--" + param.name);
if (index === -1) {
index = args.indexOf("-" + param.short);
for (const name in params) {
const { shorthand, required, value } = params[name];
let index = args.indexOf("--" + name);
if (index === -1 && shorthand) {
index = args.indexOf("-" + shorthand);
}
if (index === -1) {
if (param.required) {
throw new Error(typeof param.required === "string"
? param.required
: `Missing required argument ${param.name}`);
if (required !== false) {
throw new Error(typeof required === "string" && required !== ""
? required
: `Missing required argument ${name}`);
}
result[param.name] = false;
result[name] = false;
continue;
}
if (param.value) {
if (value) {
const value = args[index + 1];
if (value === undefined) {
throw new Error(`Expected a value for argument ${param.name}`);
throw new Error(`Expected a value for argument ${name}`);
}
if (param.value === "number") {
if (value === "number") {
const asNumber = Number(value);
if (isNaN(asNumber)) {
throw new Error(`Value of argument ${param.name} must be a valid number`);
throw new Error(`Value of argument ${name} must be a valid number`);
}
result[param.name] = asNumber;
result[name] = asNumber;
continue;
}
if (Array.isArray(param.value) && !param.value.includes(value)) {
throw new Error(`Value of argument ${param.name} must be one of ${param.value}`);
if (Array.isArray(value) && !value.includes(value)) {
throw new Error(`Value of argument ${name} must be one of ${value}`);
}
result[param.name] = value;
result[name] = value;
}
else {
result[param.name] = true;
result[name] = true;
}

@@ -93,15 +89,16 @@ }

function printParams(params) {
const longest = params.reduce((n, p) => (p.name.length > n ? p.name.length : n), 5);
const longest = Object.keys(params).reduce((l, c) => (c.length > l ? c.length : l), 5);
const header = "Name " + " ".repeat(longest - 2) + "Short Description";
console.log(header);
for (const param of params) {
for (const name in params) {
const { shorthand, description } = params[name];
console.log("--" +
param.name +
" ".repeat(longest - param.name.length) +
name +
" ".repeat(longest - name.length) +
" -" +
param.short +
shorthand +
" " +
param.description ?? "");
description ?? "");
}
}
exports.printParams = printParams;

@@ -8,45 +8,37 @@ #!/usr/bin/env node

const args_js_1 = require("./args.js");
const params = [
{
name: "input",
short: "i",
const pick_js_1 = require("./utils/pick.js");
const params = {
input: {
shorthand: "i",
value: "string",
required: process.stdin.isTTY &&
"input is required when no JSON or file path is piped",
description: "JSON or a source file path",
description: "JSON or a source file path. Required if no data is piped.",
},
{
name: "output",
short: "o",
output: {
shorthand: "o",
value: "string",
description: "A file path to write to. If not supplied output will be stdout",
description: "A file path to write to. If not supplied stdout will be used.",
},
{
name: "name",
short: "n",
name: {
shorthand: "n",
value: "string",
description: "The name of the schema in the output",
description: "The name of the schema in the output.",
},
{
name: "depth",
short: "d",
depth: {
shorthand: "d",
value: "number",
description: "Maximum depth of recursion before falling back to z.any() - defaults to 0",
description: "Maximum depth of recursion before falling back to z.any(). Defaults to 0.",
},
{
name: "module",
short: "m",
value: ["esm", "cjs"],
description: "Force module syntax ('esm' or 'cjs')",
module: {
shorthand: "m",
value: ["esm", "cjs", "none"],
description: "Module syntax; 'esm', 'cjs' or 'none'. Defaults to 'esm'.",
},
];
};
async function main() {
const args = (0, args_js_1.parseArgs)(params, process.argv, {});
const args = (0, args_js_1.parseArgs)(params, process.argv, true);
const input = args.input || (await (0, args_js_1.readPipe)());
const jsonSchema = (0, args_js_1.parseOrReadJSON)(input);
const zodSchema = (0, jsonSchemaToZod_js_1.jsonSchemaToZod)(jsonSchema, {
module: args.module,
name: args.name,
recursionDepth: args["recursion-depth"],
});
const zodSchema = (0, jsonSchemaToZod_js_1.jsonSchemaToZod)(jsonSchema, (0, pick_js_1.pick)(args, "name", "depth", "module"));
if (args.output) {

@@ -53,0 +45,0 @@ (0, fs_1.mkdirSync)((0, path_1.dirname)(args.output), { recursive: true });

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.parseSchema = exports.jsonSchemaToZod = void 0;
const jsonSchemaToZod_js_1 = require("./jsonSchemaToZod.js");
Object.defineProperty(exports, "jsonSchemaToZod", { enumerable: true, get: function () { return jsonSchemaToZod_js_1.jsonSchemaToZod; } });
const parseSchema_js_1 = require("./parsers/parseSchema.js");
Object.defineProperty(exports, "parseSchema", { enumerable: true, get: function () { return parseSchema_js_1.parseSchema; } });
exports.default = jsonSchemaToZod_js_1.jsonSchemaToZod;

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

const parseSchema_js_1 = require("./parsers/parseSchema.js");
const jsonSchemaToZod = (schema, { module = true, name, ...rest } = {}) => {
const jsonSchemaToZod = (schema, { module, name, ...rest } = {}) => {
let result = (0, parseSchema_js_1.parseSchema)(schema, {

@@ -14,18 +14,16 @@ module,

});
if (module) {
if (module === "cjs") {
result = `const { z } = require("zod")
if (module === "cjs") {
result = `const { z } = require("zod")
module.exports = ${name ? `{ ${JSON.stringify(name)}: ${result} }` : result}
`;
}
else {
result = `import { z } from "zod"
}
else if (module === "esm") {
result = `import { z } from "zod"
export ${name ? `const ${name} =` : `default`} ${result}
`;
}
}
else {
result = `const ${name || "schema"} = ${result}`;
else if (name) {
result = `const ${name} = ${result}`;
}

@@ -32,0 +30,0 @@ return result;

@@ -23,4 +23,4 @@ "use strict";

return schema ? "z.any()" : "z.never()";
if (refs.overrideParser) {
const custom = refs.overrideParser(schema, refs);
if (refs.parserOverride) {
const custom = refs.parserOverride(schema, refs);
if (typeof custom === "string") {

@@ -35,3 +35,3 @@ return custom;

}
if (refs.recursionDepth === undefined || seen.n >= refs.recursionDepth) {
if (refs.depth === undefined || seen.n >= refs.depth) {
return "z.any()";

@@ -38,0 +38,0 @@ }

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.omit = void 0;
const omit = (obj, ...keys) => Object.fromEntries(Object.entries(obj).filter(([key]) => !keys.includes(key)));
const omit = (obj, ...keys) => Object.keys(obj).reduce((acc, key) => {
if (!keys.includes(key)) {
acc[key] = obj[key];
}
return acc;
}, {});
exports.omit = omit;

@@ -5,56 +5,52 @@ import { statSync, readFileSync } from "fs";

if (help) {
const defaults = {
name: "help",
short: "h",
description: "Display this message :)",
};
const param = help === true
? defaults
: {
...defaults,
...help,
};
let index = args.indexOf("--" + param.name);
let index = args.indexOf("--help");
if (index === -1) {
index = args.indexOf("-" + param.short);
index = args.indexOf("-h");
}
if (index !== -1) {
printParams([...params, param]);
printParams({
...params,
help: {
shorthand: "h",
description: typeof help === "string" ? help : "Display this message :)",
},
});
process.exit(0);
}
}
for (const param of params) {
let index = args.indexOf("--" + param.name);
if (index === -1) {
index = args.indexOf("-" + param.short);
for (const name in params) {
const { shorthand, required, value } = params[name];
let index = args.indexOf("--" + name);
if (index === -1 && shorthand) {
index = args.indexOf("-" + shorthand);
}
if (index === -1) {
if (param.required) {
throw new Error(typeof param.required === "string"
? param.required
: `Missing required argument ${param.name}`);
if (required !== false) {
throw new Error(typeof required === "string" && required !== ""
? required
: `Missing required argument ${name}`);
}
result[param.name] = false;
result[name] = false;
continue;
}
if (param.value) {
if (value) {
const value = args[index + 1];
if (value === undefined) {
throw new Error(`Expected a value for argument ${param.name}`);
throw new Error(`Expected a value for argument ${name}`);
}
if (param.value === "number") {
if (value === "number") {
const asNumber = Number(value);
if (isNaN(asNumber)) {
throw new Error(`Value of argument ${param.name} must be a valid number`);
throw new Error(`Value of argument ${name} must be a valid number`);
}
result[param.name] = asNumber;
result[name] = asNumber;
continue;
}
if (Array.isArray(param.value) && !param.value.includes(value)) {
throw new Error(`Value of argument ${param.name} must be one of ${param.value}`);
if (Array.isArray(value) && !value.includes(value)) {
throw new Error(`Value of argument ${name} must be one of ${value}`);
}
result[param.name] = value;
result[name] = value;
}
else {
result[param.name] = true;
result[name] = true;
}

@@ -87,14 +83,15 @@ }

export function printParams(params) {
const longest = params.reduce((n, p) => (p.name.length > n ? p.name.length : n), 5);
const longest = Object.keys(params).reduce((l, c) => (c.length > l ? c.length : l), 5);
const header = "Name " + " ".repeat(longest - 2) + "Short Description";
console.log(header);
for (const param of params) {
for (const name in params) {
const { shorthand, description } = params[name];
console.log("--" +
param.name +
" ".repeat(longest - param.name.length) +
name +
" ".repeat(longest - name.length) +
" -" +
param.short +
shorthand +
" " +
param.description ?? "");
description ?? "");
}
}

@@ -6,45 +6,37 @@ #!/usr/bin/env node

import { parseArgs, parseOrReadJSON, readPipe } from "./args.js";
const params = [
{
name: "input",
short: "i",
import { pick } from "./utils/pick.js";
const params = {
input: {
shorthand: "i",
value: "string",
required: process.stdin.isTTY &&
"input is required when no JSON or file path is piped",
description: "JSON or a source file path",
description: "JSON or a source file path. Required if no data is piped.",
},
{
name: "output",
short: "o",
output: {
shorthand: "o",
value: "string",
description: "A file path to write to. If not supplied output will be stdout",
description: "A file path to write to. If not supplied stdout will be used.",
},
{
name: "name",
short: "n",
name: {
shorthand: "n",
value: "string",
description: "The name of the schema in the output",
description: "The name of the schema in the output.",
},
{
name: "depth",
short: "d",
depth: {
shorthand: "d",
value: "number",
description: "Maximum depth of recursion before falling back to z.any() - defaults to 0",
description: "Maximum depth of recursion before falling back to z.any(). Defaults to 0.",
},
{
name: "module",
short: "m",
value: ["esm", "cjs"],
description: "Force module syntax ('esm' or 'cjs')",
module: {
shorthand: "m",
value: ["esm", "cjs", "none"],
description: "Module syntax; 'esm', 'cjs' or 'none'. Defaults to 'esm'.",
},
];
};
async function main() {
const args = parseArgs(params, process.argv, {});
const args = parseArgs(params, process.argv, true);
const input = args.input || (await readPipe());
const jsonSchema = parseOrReadJSON(input);
const zodSchema = jsonSchemaToZod(jsonSchema, {
module: args.module,
name: args.name,
recursionDepth: args["recursion-depth"],
});
const zodSchema = jsonSchemaToZod(jsonSchema, pick(args, "name", "depth", "module"));
if (args.output) {

@@ -51,0 +43,0 @@ mkdirSync(dirname(args.output), { recursive: true });

import { jsonSchemaToZod } from "./jsonSchemaToZod.js";
export { jsonSchemaToZod };
import { parseSchema } from "./parsers/parseSchema.js";
export { parseSchema };
export default jsonSchemaToZod;
import { parseSchema } from "./parsers/parseSchema.js";
export const jsonSchemaToZod = (schema, { module = true, name, ...rest } = {}) => {
export const jsonSchemaToZod = (schema, { module, name, ...rest } = {}) => {
let result = parseSchema(schema, {

@@ -10,20 +10,18 @@ module,

});
if (module) {
if (module === "cjs") {
result = `const { z } = require("zod")
if (module === "cjs") {
result = `const { z } = require("zod")
module.exports = ${name ? `{ ${JSON.stringify(name)}: ${result} }` : result}
`;
}
else {
result = `import { z } from "zod"
}
else if (module === "esm") {
result = `import { z } from "zod"
export ${name ? `const ${name} =` : `default`} ${result}
`;
}
}
else {
result = `const ${name || "schema"} = ${result}`;
else if (name) {
result = `const ${name} = ${result}`;
}
return result;
};

@@ -20,4 +20,4 @@ import { parseAnyOf } from "./parseAnyOf.js";

return schema ? "z.any()" : "z.never()";
if (refs.overrideParser) {
const custom = refs.overrideParser(schema, refs);
if (refs.parserOverride) {
const custom = refs.parserOverride(schema, refs);
if (typeof custom === "string") {

@@ -32,3 +32,3 @@ return custom;

}
if (refs.recursionDepth === undefined || seen.n >= refs.recursionDepth) {
if (refs.depth === undefined || seen.n >= refs.depth) {
return "z.any()";

@@ -35,0 +35,0 @@ }

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

export const omit = (obj, ...keys) => Object.fromEntries(Object.entries(obj).filter(([key]) => !keys.includes(key)));
export const omit = (obj, ...keys) => Object.keys(obj).reduce((acc, key) => {
if (!keys.includes(key)) {
acc[key] = obj[key];
}
return acc;
}, {});
export type Param = {
name: string;
short: string;
shorthand?: string;
description?: string;
value?: "string" | "number" | string[];
required?: boolean | string;
required?: boolean | string | undefined;
} & ({
value?: "boolean";
} | {
value: "number";
} | {
value: "string";
} | {
value: {
[key: number]: string;
};
});
export type Params = {
[name: string]: Param;
};
type Help = Partial<Pick<Param, "name" | "short" | "description">>;
export declare function parseArgs(params: Param[], args: string[], help?: boolean | Help): Record<string, string | number | boolean | undefined>;
type InferReturnType<T extends Params> = {
[name in keyof T]: (T[name]["value"] extends "number" ? number : T[name]["value"] extends "string" ? string : T[name]["value"] extends {
[key: number]: string;
} ? T[name]["value"][number] : boolean) | (T[name]["required"] extends string | true ? never : undefined);
};
export declare function parseArgs<T extends Params>(params: T, args: string[], help?: boolean | string): InferReturnType<T>;
export declare function parseOrReadJSON(jsonOrPath: string): unknown;
export declare function readPipe(): Promise<string>;
export declare function printParams(params: Param[]): void;
export declare function printParams(params: Record<string, Param>): void;
export {};
import { jsonSchemaToZod } from "./jsonSchemaToZod.js";
export { jsonSchemaToZod };
import { parseSchema } from "./parsers/parseSchema.js";
export { parseSchema };
export default jsonSchemaToZod;

@@ -51,6 +51,6 @@ export type Serializable = {

name?: string;
module?: boolean | "cjs" | "esm";
module?: "cjs" | "esm" | "none";
withoutDefaults?: boolean;
overrideParser?: ParserOverride;
recursionDepth?: number;
parserOverride?: ParserOverride;
depth?: number;
};

@@ -57,0 +57,0 @@ export type Refs = Options & {

{
"name": "json-schema-to-zod",
"version": "2.0.4",
"version": "2.0.5",
"description": "Converts JSON schema objects or files into Zod schemas",

@@ -47,2 +47,3 @@ "types": "dist/types/index.d.ts",

"@types/node": "^20.9.0",
"fast-diff": "^1.3.0",
"rimraf": "^5.0.5",

@@ -49,0 +50,0 @@ "tsx": "^4.1.1",

@@ -38,9 +38,9 @@ # Json-Schema-to-Zod

| Flag | Shorthand | Function |
| ---------- | --------- | --------------------------------------------------------------------------------------- |
| `--input` | `-i` | JSON or a source file path (required if no data is piped) |
| `--output` | `-t` | Target file name |
| `--name` | `-n` | The name of the schema in the output |
| `--depth` | `-d` | Maximum depth of recursion in schema before falling back to `z.any()`. Defaults to 0. ` |
| `--module` | `-m` | Force module syntax (`"esm"` or `"cjs"`) |
| Flag | Shorthand | Function |
| ---------- | --------- | -------------------------------------------------------------------------------------------- |
| `--input` | `-i` | JSON or a source file path. Required if no data is piped. |
| `--output` | `-t` | A file path to write to. If not supplied stdout will be used. |
| `--name` | `-n` | The name of the schema in the output |
| `--depth` | `-d` | Maximum depth of recursion in schema before falling back to `z.any()`. Defaults to 0. |
| `--module` | `-m` | Module syntax; `esm`, `cjs` or none. Defaults to `esm` in the CLI and `none` programmaticly. |

@@ -52,3 +52,3 @@ ### Programmatic

```typescript
import { jsonSchemaToZod, parseSchema } from "json-schema-to-zod";
import { jsonSchemaToZod } from "json-schema-to-zod";

@@ -62,7 +62,9 @@ const myObject = {

},
} as const;
};
const module = jsonSchemaToZod(myObject);
const module = jsonSchemaToZod(myObject, { module: "esm" });
const schema = parseSchema(myObject);
const cjs = jsonSchemaToZod(myObject, { module: "cjs", name: "mySchema" });
const schema = jsonSchemaToZod(myObject);
```

@@ -78,2 +80,10 @@

#### `cjs`
```typescript
const { z } = require("zod");
module.exports = { mySchema: z.object({ hello: z.string().optional() }) };
```
#### `schema`

@@ -87,3 +97,3 @@

You can pass a `ParserOverride` to the `overrideParser` option, which is a function that receives the current schema node and the reference object, and should return a string when it wants to replace a default output. If the default output should be used for the node, just return nothing.
You can pass a function to the `overrideParser` option, which represents a function that receives the current schema node and the reference object, and should return a string when it wants to replace a default output. If the default output should be used for the node just return void.

@@ -90,0 +100,0 @@ ### Use at Runtime

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