@gabrielbryk/json-schema-to-zod 2.7.2
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.
- package/.prettierrc.json +3 -0
- package/CONTRIBUTING.md +9 -0
- package/LICENSE +15 -0
- package/README.md +157 -0
- package/createIndex.ts +32 -0
- package/dist/cjs/Types.js +2 -0
- package/dist/cjs/cli.js +70 -0
- package/dist/cjs/index.js +44 -0
- package/dist/cjs/jsonSchemaToZod.js +78 -0
- package/dist/cjs/package.json +1 -0
- package/dist/cjs/parsers/parseAllOf.js +40 -0
- package/dist/cjs/parsers/parseAnyOf.js +18 -0
- package/dist/cjs/parsers/parseArray.js +71 -0
- package/dist/cjs/parsers/parseBoolean.js +7 -0
- package/dist/cjs/parsers/parseConst.js +7 -0
- package/dist/cjs/parsers/parseDefault.js +8 -0
- package/dist/cjs/parsers/parseEnum.js +21 -0
- package/dist/cjs/parsers/parseIfThenElse.js +34 -0
- package/dist/cjs/parsers/parseMultipleType.js +10 -0
- package/dist/cjs/parsers/parseNot.js +12 -0
- package/dist/cjs/parsers/parseNull.js +7 -0
- package/dist/cjs/parsers/parseNullable.js +12 -0
- package/dist/cjs/parsers/parseNumber.js +74 -0
- package/dist/cjs/parsers/parseObject.js +286 -0
- package/dist/cjs/parsers/parseOneOf.js +53 -0
- package/dist/cjs/parsers/parseSchema.js +285 -0
- package/dist/cjs/parsers/parseSimpleDiscriminatedOneOf.js +29 -0
- package/dist/cjs/parsers/parseString.js +77 -0
- package/dist/cjs/utils/anyOrUnknown.js +14 -0
- package/dist/cjs/utils/cliTools.js +108 -0
- package/dist/cjs/utils/half.js +7 -0
- package/dist/cjs/utils/jsdocs.js +20 -0
- package/dist/cjs/utils/omit.js +10 -0
- package/dist/cjs/utils/withMessage.js +22 -0
- package/dist/cjs/zodToJsonSchema.js +89 -0
- package/dist/esm/Types.js +1 -0
- package/dist/esm/cli.js +68 -0
- package/dist/esm/index.js +28 -0
- package/dist/esm/jsonSchemaToZod.js +74 -0
- package/dist/esm/package.json +1 -0
- package/dist/esm/parsers/parseAllOf.js +37 -0
- package/dist/esm/parsers/parseAnyOf.js +14 -0
- package/dist/esm/parsers/parseArray.js +67 -0
- package/dist/esm/parsers/parseBoolean.js +3 -0
- package/dist/esm/parsers/parseConst.js +3 -0
- package/dist/esm/parsers/parseDefault.js +4 -0
- package/dist/esm/parsers/parseEnum.js +17 -0
- package/dist/esm/parsers/parseIfThenElse.js +30 -0
- package/dist/esm/parsers/parseMultipleType.js +6 -0
- package/dist/esm/parsers/parseNot.js +8 -0
- package/dist/esm/parsers/parseNull.js +3 -0
- package/dist/esm/parsers/parseNullable.js +8 -0
- package/dist/esm/parsers/parseNumber.js +70 -0
- package/dist/esm/parsers/parseObject.js +283 -0
- package/dist/esm/parsers/parseOneOf.js +49 -0
- package/dist/esm/parsers/parseSchema.js +281 -0
- package/dist/esm/parsers/parseSimpleDiscriminatedOneOf.js +25 -0
- package/dist/esm/parsers/parseString.js +73 -0
- package/dist/esm/utils/anyOrUnknown.js +10 -0
- package/dist/esm/utils/cliTools.js +102 -0
- package/dist/esm/utils/half.js +3 -0
- package/dist/esm/utils/jsdocs.js +15 -0
- package/dist/esm/utils/omit.js +6 -0
- package/dist/esm/utils/withMessage.js +19 -0
- package/dist/esm/zodToJsonSchema.js +86 -0
- package/dist/types/Types.d.ts +125 -0
- package/dist/types/cli.d.ts +2 -0
- package/dist/types/index.d.ts +28 -0
- package/dist/types/jsonSchemaToZod.d.ts +2 -0
- package/dist/types/parsers/parseAllOf.d.ts +4 -0
- package/dist/types/parsers/parseAnyOf.d.ts +4 -0
- package/dist/types/parsers/parseArray.d.ts +4 -0
- package/dist/types/parsers/parseBoolean.d.ts +4 -0
- package/dist/types/parsers/parseConst.d.ts +4 -0
- package/dist/types/parsers/parseDefault.d.ts +2 -0
- package/dist/types/parsers/parseEnum.d.ts +4 -0
- package/dist/types/parsers/parseIfThenElse.d.ts +6 -0
- package/dist/types/parsers/parseMultipleType.d.ts +4 -0
- package/dist/types/parsers/parseNot.d.ts +4 -0
- package/dist/types/parsers/parseNull.d.ts +4 -0
- package/dist/types/parsers/parseNullable.d.ts +7 -0
- package/dist/types/parsers/parseNumber.d.ts +4 -0
- package/dist/types/parsers/parseObject.d.ts +4 -0
- package/dist/types/parsers/parseOneOf.d.ts +4 -0
- package/dist/types/parsers/parseSchema.d.ts +50 -0
- package/dist/types/parsers/parseSimpleDiscriminatedOneOf.d.ts +2 -0
- package/dist/types/parsers/parseString.d.ts +4 -0
- package/dist/types/utils/anyOrUnknown.d.ts +9 -0
- package/dist/types/utils/cliTools.d.ts +28 -0
- package/dist/types/utils/half.d.ts +1 -0
- package/dist/types/utils/jsdocs.d.ts +3 -0
- package/dist/types/utils/omit.d.ts +1 -0
- package/dist/types/utils/withMessage.d.ts +10 -0
- package/dist/types/zodToJsonSchema.d.ts +26 -0
- package/jest.config.js +4 -0
- package/package.json +83 -0
- package/postcjs.js +1 -0
- package/postesm.js +1 -0
- package/scripts/generateWorkflowSchema.ts +82 -0
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { withMessage } from "../utils/withMessage.js";
|
|
2
|
+
import { parseSchema } from "./parseSchema.js";
|
|
3
|
+
export const parseString = (schema) => {
|
|
4
|
+
let r = "z.string()";
|
|
5
|
+
r += withMessage(schema, "format", ({ value }) => {
|
|
6
|
+
switch (value) {
|
|
7
|
+
case "email":
|
|
8
|
+
return [".email(", ")"];
|
|
9
|
+
case "ip":
|
|
10
|
+
return [".ip(", ")"];
|
|
11
|
+
case "ipv4":
|
|
12
|
+
return ['.ip({ version: "v4"', ", message: ", " })"];
|
|
13
|
+
case "ipv6":
|
|
14
|
+
return ['.ip({ version: "v6"', ", message: ", " })"];
|
|
15
|
+
case "uri":
|
|
16
|
+
return [".url(", ")"];
|
|
17
|
+
case "uuid":
|
|
18
|
+
return [".uuid(", ")"];
|
|
19
|
+
case "date-time":
|
|
20
|
+
return [".datetime({ offset: true", ", message: ", " })"];
|
|
21
|
+
case "time":
|
|
22
|
+
return [".time(", ")"];
|
|
23
|
+
case "date":
|
|
24
|
+
return [".date(", ")"];
|
|
25
|
+
case "binary":
|
|
26
|
+
return [".base64(", ")"];
|
|
27
|
+
case "duration":
|
|
28
|
+
return [".duration(", ")"];
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
r += withMessage(schema, "pattern", ({ json }) => [
|
|
32
|
+
`.regex(new RegExp(${json})`,
|
|
33
|
+
", ",
|
|
34
|
+
")",
|
|
35
|
+
]);
|
|
36
|
+
r += withMessage(schema, "minLength", ({ json }) => [
|
|
37
|
+
`.min(${json}`,
|
|
38
|
+
", ",
|
|
39
|
+
")",
|
|
40
|
+
]);
|
|
41
|
+
r += withMessage(schema, "maxLength", ({ json }) => [
|
|
42
|
+
`.max(${json}`,
|
|
43
|
+
", ",
|
|
44
|
+
")",
|
|
45
|
+
]);
|
|
46
|
+
r += withMessage(schema, "contentEncoding", ({ value }) => {
|
|
47
|
+
if (value === "base64") {
|
|
48
|
+
return [".base64(", ")"];
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
const contentMediaType = withMessage(schema, "contentMediaType", ({ value }) => {
|
|
52
|
+
if (value === "application/json") {
|
|
53
|
+
return [
|
|
54
|
+
".transform((str, ctx) => { try { return JSON.parse(str); } catch (err) { ctx.addIssue({ code: \"custom\", message: \"Invalid JSON\" }); }}",
|
|
55
|
+
", ",
|
|
56
|
+
")"
|
|
57
|
+
];
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
if (contentMediaType != "") {
|
|
61
|
+
r += contentMediaType;
|
|
62
|
+
r += withMessage(schema, "contentSchema", ({ value }) => {
|
|
63
|
+
if (value && value instanceof Object) {
|
|
64
|
+
return [
|
|
65
|
+
`.pipe(${parseSchema(value)}`,
|
|
66
|
+
", ",
|
|
67
|
+
")"
|
|
68
|
+
];
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
return r;
|
|
73
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Returns "z.unknown()" if the useUnknown option is enabled, otherwise "z.any()".
|
|
3
|
+
* This helper is used throughout the library for fallback cases.
|
|
4
|
+
*
|
|
5
|
+
* @param refs - The refs object containing options
|
|
6
|
+
* @returns The appropriate Zod schema string
|
|
7
|
+
*/
|
|
8
|
+
export const anyOrUnknown = (refs) => {
|
|
9
|
+
return refs?.useUnknown ? "z.unknown()" : "z.any()";
|
|
10
|
+
};
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { statSync, readFileSync } from "fs";
|
|
2
|
+
export function parseArgs(params, args, help) {
|
|
3
|
+
const result = {};
|
|
4
|
+
if (help) {
|
|
5
|
+
let index = args.indexOf("--help");
|
|
6
|
+
if (index === -1) {
|
|
7
|
+
index = args.indexOf("-h");
|
|
8
|
+
}
|
|
9
|
+
if (index !== -1) {
|
|
10
|
+
printParams({
|
|
11
|
+
...params,
|
|
12
|
+
help: {
|
|
13
|
+
shorthand: "h",
|
|
14
|
+
description: typeof help === "string" ? help : "Display this message :)",
|
|
15
|
+
},
|
|
16
|
+
});
|
|
17
|
+
process.exit(0);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
for (const name in params) {
|
|
21
|
+
const { shorthand, required, value } = params[name];
|
|
22
|
+
let index = args.indexOf("--" + name);
|
|
23
|
+
if (index === -1 && shorthand) {
|
|
24
|
+
index = args.indexOf("-" + shorthand);
|
|
25
|
+
}
|
|
26
|
+
if (index === -1) {
|
|
27
|
+
if (required || required === "") {
|
|
28
|
+
throw new Error(typeof required === "string" && required !== ""
|
|
29
|
+
? required
|
|
30
|
+
: `Missing required argument ${name}`);
|
|
31
|
+
}
|
|
32
|
+
result[name] = false;
|
|
33
|
+
continue;
|
|
34
|
+
}
|
|
35
|
+
if (value) {
|
|
36
|
+
const val = args[index + 1];
|
|
37
|
+
if (val === undefined) {
|
|
38
|
+
throw new Error(`Expected a value for argument ${name}`);
|
|
39
|
+
}
|
|
40
|
+
if (value === "number") {
|
|
41
|
+
const asNumber = Number(val);
|
|
42
|
+
if (isNaN(asNumber)) {
|
|
43
|
+
throw new Error(`Value of argument ${name} must be a valid number`);
|
|
44
|
+
}
|
|
45
|
+
result[name] = asNumber;
|
|
46
|
+
continue;
|
|
47
|
+
}
|
|
48
|
+
if (Array.isArray(value) && !value.includes(val)) {
|
|
49
|
+
throw new Error(`Value of argument ${name} must be one of ${value}`);
|
|
50
|
+
}
|
|
51
|
+
result[name] = val;
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
result[name] = true;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
return result;
|
|
58
|
+
}
|
|
59
|
+
export function parseOrReadJSON(jsonOrPath) {
|
|
60
|
+
jsonOrPath = jsonOrPath.trim();
|
|
61
|
+
if (jsonOrPath.length < 255 &&
|
|
62
|
+
statSync(jsonOrPath, { throwIfNoEntry: false })?.isFile()) {
|
|
63
|
+
jsonOrPath = readFileSync(jsonOrPath, "utf-8");
|
|
64
|
+
}
|
|
65
|
+
return JSON.parse(jsonOrPath);
|
|
66
|
+
}
|
|
67
|
+
export function readPipe() {
|
|
68
|
+
return new Promise((resolve, reject) => {
|
|
69
|
+
let buf = "";
|
|
70
|
+
process.stdin
|
|
71
|
+
.setEncoding("utf-8")
|
|
72
|
+
.on("end", () => resolve(buf))
|
|
73
|
+
.on("error", reject)
|
|
74
|
+
.on("readable", () => {
|
|
75
|
+
let chunk;
|
|
76
|
+
while ((chunk = process.stdin.read()) != null) {
|
|
77
|
+
buf += chunk;
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
export function printParams(params) {
|
|
83
|
+
const longest = Object.keys(params).reduce((l, c) => (c.length > l ? c.length : l), 5);
|
|
84
|
+
const header = "Name " + " ".repeat(longest - 2) + "Short Description";
|
|
85
|
+
console.log(header);
|
|
86
|
+
for (const name in params) {
|
|
87
|
+
let { shorthand, description } = params[name];
|
|
88
|
+
if (shorthand) {
|
|
89
|
+
shorthand = " -" + shorthand;
|
|
90
|
+
}
|
|
91
|
+
else {
|
|
92
|
+
shorthand = " ";
|
|
93
|
+
}
|
|
94
|
+
if (description) {
|
|
95
|
+
description = " " + description;
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
description = "";
|
|
99
|
+
}
|
|
100
|
+
console.log("--" + name + " ".repeat(longest - name.length) + shorthand + description);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export const expandJsdocs = (jsdocs) => {
|
|
2
|
+
const lines = jsdocs.split("\n");
|
|
3
|
+
const result = lines.length === 1
|
|
4
|
+
? lines[0]
|
|
5
|
+
: `\n${lines.map(x => `* ${x}`)
|
|
6
|
+
.join("\n")}\n`;
|
|
7
|
+
return `/**${result}*/\n`;
|
|
8
|
+
};
|
|
9
|
+
export const addJsdocs = (schema, parsed) => {
|
|
10
|
+
const description = schema.description;
|
|
11
|
+
if (!description) {
|
|
12
|
+
return parsed;
|
|
13
|
+
}
|
|
14
|
+
return `\n${expandJsdocs(description)}${parsed}`;
|
|
15
|
+
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export function withMessage(schema, key, get) {
|
|
2
|
+
const value = schema[key];
|
|
3
|
+
let r = "";
|
|
4
|
+
if (value !== undefined) {
|
|
5
|
+
const got = get({ value, json: JSON.stringify(value) });
|
|
6
|
+
if (got) {
|
|
7
|
+
const opener = got[0];
|
|
8
|
+
const prefix = got.length === 3 ? got[1] : "";
|
|
9
|
+
const closer = got.length === 3 ? got[2] : got[1];
|
|
10
|
+
r += opener;
|
|
11
|
+
if (schema.errorMessage?.[key] !== undefined) {
|
|
12
|
+
r += prefix + JSON.stringify(schema.errorMessage[key]);
|
|
13
|
+
}
|
|
14
|
+
r;
|
|
15
|
+
r += closer;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
return r;
|
|
19
|
+
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Post-processor for Zod's z.toJSONSchema() output.
|
|
3
|
+
*
|
|
4
|
+
* When `preserveJsonSchemaForRoundTrip` was used during JSON Schema → Zod conversion,
|
|
5
|
+
* this function reconstructs the original JSON Schema features from the stored __jsonSchema meta.
|
|
6
|
+
*
|
|
7
|
+
* Usage:
|
|
8
|
+
* 1. Convert JSON Schema to Zod code with `preserveJsonSchemaForRoundTrip: true`
|
|
9
|
+
* 2. Evaluate the Zod code to get a schema instance
|
|
10
|
+
* 3. Call Zod's `z.toJSONSchema(schema)` to get JSON Schema output
|
|
11
|
+
* 4. Pass that output to `reconstructJsonSchema()` to restore preserved features
|
|
12
|
+
*
|
|
13
|
+
* Handles:
|
|
14
|
+
* - patternProperties (stored in __jsonSchema.patternProperties)
|
|
15
|
+
* - if/then/else conditionals (stored in __jsonSchema.conditional)
|
|
16
|
+
*/
|
|
17
|
+
/**
|
|
18
|
+
* Recursively process a JSON Schema to reconstruct original features from __jsonSchema meta.
|
|
19
|
+
*
|
|
20
|
+
* Handles special cases:
|
|
21
|
+
* - allOf[object, {__jsonSchema: {conditional: ...}}] -> object with if/then/else at top level
|
|
22
|
+
* - patternProperties meta -> patternProperties at current level
|
|
23
|
+
*/
|
|
24
|
+
export function reconstructJsonSchema(schema) {
|
|
25
|
+
if (typeof schema !== "object" || schema === null) {
|
|
26
|
+
return schema;
|
|
27
|
+
}
|
|
28
|
+
const result = { ...schema };
|
|
29
|
+
// Handle allOf structures created by .and() with conditionals
|
|
30
|
+
// Pattern: allOf: [mainSchema, {__jsonSchema: {conditional: ...}, anyOf: [...]}]
|
|
31
|
+
if (Array.isArray(result.allOf) &&
|
|
32
|
+
result.allOf.length === 2 &&
|
|
33
|
+
typeof result.allOf[1] === "object" &&
|
|
34
|
+
result.allOf[1] !== null) {
|
|
35
|
+
const secondElement = result.allOf[1];
|
|
36
|
+
// Check if second element has conditional meta
|
|
37
|
+
if (secondElement.__jsonSchema &&
|
|
38
|
+
typeof secondElement.__jsonSchema === "object" &&
|
|
39
|
+
secondElement.__jsonSchema.conditional) {
|
|
40
|
+
// Extract the main schema and conditional
|
|
41
|
+
const mainSchema = reconstructJsonSchema(result.allOf[0]);
|
|
42
|
+
const conditionalMeta = secondElement.__jsonSchema
|
|
43
|
+
.conditional;
|
|
44
|
+
// Merge: main schema + if/then/else at top level
|
|
45
|
+
const merged = {
|
|
46
|
+
...mainSchema,
|
|
47
|
+
if: conditionalMeta.if,
|
|
48
|
+
then: conditionalMeta.then,
|
|
49
|
+
else: conditionalMeta.else,
|
|
50
|
+
};
|
|
51
|
+
// Recursively process the merged result
|
|
52
|
+
return reconstructJsonSchema(merged);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
// Check for __jsonSchema meta at this level
|
|
56
|
+
if (result.__jsonSchema && typeof result.__jsonSchema === "object") {
|
|
57
|
+
const preserved = result.__jsonSchema;
|
|
58
|
+
// Reconstruct patternProperties
|
|
59
|
+
if (preserved.patternProperties) {
|
|
60
|
+
result.patternProperties = preserved.patternProperties;
|
|
61
|
+
}
|
|
62
|
+
// Reconstruct if/then/else conditional (for non-allOf cases)
|
|
63
|
+
if (preserved.conditional) {
|
|
64
|
+
const conditional = preserved.conditional;
|
|
65
|
+
result.if = conditional.if;
|
|
66
|
+
result.then = conditional.then;
|
|
67
|
+
result.else = conditional.else;
|
|
68
|
+
}
|
|
69
|
+
// Remove the __jsonSchema meta from the output
|
|
70
|
+
delete result.__jsonSchema;
|
|
71
|
+
}
|
|
72
|
+
// Recursively process nested schemas
|
|
73
|
+
for (const [key, value] of Object.entries(result)) {
|
|
74
|
+
if (typeof value === "object" && value !== null) {
|
|
75
|
+
if (Array.isArray(value)) {
|
|
76
|
+
result[key] = value.map((item) => typeof item === "object" && item !== null
|
|
77
|
+
? reconstructJsonSchema(item)
|
|
78
|
+
: item);
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
result[key] = reconstructJsonSchema(value);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
return result;
|
|
86
|
+
}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
export type Serializable = {
|
|
2
|
+
[key: string]: Serializable;
|
|
3
|
+
} | Serializable[] | string | number | boolean | null;
|
|
4
|
+
export type JsonSchema = JsonSchemaObject | boolean;
|
|
5
|
+
export type JsonSchemaObject = {
|
|
6
|
+
type?: string | string[];
|
|
7
|
+
$id?: string;
|
|
8
|
+
$ref?: string;
|
|
9
|
+
$defs?: Record<string, JsonSchema>;
|
|
10
|
+
definitions?: Record<string, JsonSchema>;
|
|
11
|
+
title?: string;
|
|
12
|
+
description?: string;
|
|
13
|
+
examples?: Serializable[];
|
|
14
|
+
deprecated?: boolean;
|
|
15
|
+
dependentSchemas?: Record<string, JsonSchema>;
|
|
16
|
+
contains?: JsonSchema;
|
|
17
|
+
minContains?: number;
|
|
18
|
+
maxContains?: number;
|
|
19
|
+
properties?: {
|
|
20
|
+
[key: string]: JsonSchema;
|
|
21
|
+
};
|
|
22
|
+
additionalProperties?: JsonSchema;
|
|
23
|
+
unevaluatedProperties?: boolean | JsonSchema;
|
|
24
|
+
patternProperties?: {
|
|
25
|
+
[key: string]: JsonSchema;
|
|
26
|
+
};
|
|
27
|
+
minProperties?: number;
|
|
28
|
+
maxProperties?: number;
|
|
29
|
+
required?: string[] | boolean;
|
|
30
|
+
propertyNames?: JsonSchema;
|
|
31
|
+
items?: JsonSchema | JsonSchema[];
|
|
32
|
+
additionalItems?: JsonSchema;
|
|
33
|
+
minItems?: number;
|
|
34
|
+
maxItems?: number;
|
|
35
|
+
uniqueItems?: boolean;
|
|
36
|
+
minLength?: number;
|
|
37
|
+
maxLength?: number;
|
|
38
|
+
pattern?: string;
|
|
39
|
+
format?: string;
|
|
40
|
+
minimum?: number;
|
|
41
|
+
maximum?: number;
|
|
42
|
+
exclusiveMinimum?: number | boolean;
|
|
43
|
+
exclusiveMaximum?: number | boolean;
|
|
44
|
+
multipleOf?: number;
|
|
45
|
+
anyOf?: JsonSchema[];
|
|
46
|
+
allOf?: JsonSchema[];
|
|
47
|
+
oneOf?: JsonSchema[];
|
|
48
|
+
if?: JsonSchema;
|
|
49
|
+
then?: JsonSchema;
|
|
50
|
+
else?: JsonSchema;
|
|
51
|
+
const?: Serializable;
|
|
52
|
+
enum?: Serializable[];
|
|
53
|
+
errorMessage?: {
|
|
54
|
+
[key: string]: string | undefined;
|
|
55
|
+
};
|
|
56
|
+
} & {
|
|
57
|
+
[key: string]: any;
|
|
58
|
+
};
|
|
59
|
+
export type ParserSelector = (schema: JsonSchemaObject, refs: Refs) => string;
|
|
60
|
+
export type ParserOverride = (schema: JsonSchemaObject, refs: Refs) => string | void;
|
|
61
|
+
export type Options = {
|
|
62
|
+
name?: string;
|
|
63
|
+
module?: "cjs" | "esm" | "none";
|
|
64
|
+
withoutDefaults?: boolean;
|
|
65
|
+
withoutDescribes?: boolean;
|
|
66
|
+
withJsdocs?: boolean;
|
|
67
|
+
/** Use .meta() instead of .describe() - includes id, title, description */
|
|
68
|
+
withMeta?: boolean;
|
|
69
|
+
parserOverride?: ParserOverride;
|
|
70
|
+
depth?: number;
|
|
71
|
+
type?: boolean | string;
|
|
72
|
+
noImport?: boolean;
|
|
73
|
+
/** Export all generated reference schemas (for $refs) when using ESM */
|
|
74
|
+
exportRefs?: boolean;
|
|
75
|
+
/**
|
|
76
|
+
* Store original JSON Schema constructs in .meta({ __jsonSchema: {...} })
|
|
77
|
+
* for features that can't be natively represented in Zod (patternProperties,
|
|
78
|
+
* if/then/else, etc.). This enables round-trip conversion back to JSON Schema.
|
|
79
|
+
*/
|
|
80
|
+
preserveJsonSchemaForRoundTrip?: boolean;
|
|
81
|
+
/**
|
|
82
|
+
* Use z.unknown() instead of z.any() for fallback cases.
|
|
83
|
+
* This provides better type safety as z.unknown() requires type checking
|
|
84
|
+
* before using the value, while z.any() bypasses TypeScript checks entirely.
|
|
85
|
+
* @default false
|
|
86
|
+
*/
|
|
87
|
+
useUnknown?: boolean;
|
|
88
|
+
/**
|
|
89
|
+
* Enforce strict oneOf semantics where exactly one schema must match.
|
|
90
|
+
* When false (default), oneOf behaves like "at least one must match" (same as Zod union).
|
|
91
|
+
* When true, adds superRefine to enforce "exactly one must match".
|
|
92
|
+
*
|
|
93
|
+
* Note: Strict enforcement often fails with schemas that have overlapping base types.
|
|
94
|
+
* @default false
|
|
95
|
+
*/
|
|
96
|
+
strictOneOf?: boolean;
|
|
97
|
+
};
|
|
98
|
+
export type Refs = Options & {
|
|
99
|
+
path: (string | number)[];
|
|
100
|
+
seen: Map<object | boolean, {
|
|
101
|
+
n: number;
|
|
102
|
+
r: string | undefined;
|
|
103
|
+
}>;
|
|
104
|
+
root?: JsonSchema;
|
|
105
|
+
declarations?: Map<string, string>;
|
|
106
|
+
inProgress?: Set<string>;
|
|
107
|
+
refNameByPointer?: Map<string, string>;
|
|
108
|
+
usedNames?: Set<string>;
|
|
109
|
+
currentSchemaName?: string;
|
|
110
|
+
};
|
|
111
|
+
export type SimpleDiscriminatedOneOfSchema<D extends string = string> = JsonSchemaObject & {
|
|
112
|
+
oneOf: (JsonSchemaObject & {
|
|
113
|
+
type: "object";
|
|
114
|
+
properties: {
|
|
115
|
+
[K in D]: JsonSchemaObject & {
|
|
116
|
+
type: "string";
|
|
117
|
+
};
|
|
118
|
+
} & {
|
|
119
|
+
[key: string]: JsonSchemaObject;
|
|
120
|
+
};
|
|
121
|
+
})[];
|
|
122
|
+
discriminator: {
|
|
123
|
+
propertyName: D;
|
|
124
|
+
};
|
|
125
|
+
};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export * from "./Types.js";
|
|
2
|
+
export * from "./jsonSchemaToZod.js";
|
|
3
|
+
export * from "./parsers/parseAllOf.js";
|
|
4
|
+
export * from "./parsers/parseAnyOf.js";
|
|
5
|
+
export * from "./parsers/parseArray.js";
|
|
6
|
+
export * from "./parsers/parseBoolean.js";
|
|
7
|
+
export * from "./parsers/parseConst.js";
|
|
8
|
+
export * from "./parsers/parseDefault.js";
|
|
9
|
+
export * from "./parsers/parseEnum.js";
|
|
10
|
+
export * from "./parsers/parseIfThenElse.js";
|
|
11
|
+
export * from "./parsers/parseMultipleType.js";
|
|
12
|
+
export * from "./parsers/parseNot.js";
|
|
13
|
+
export * from "./parsers/parseNull.js";
|
|
14
|
+
export * from "./parsers/parseNullable.js";
|
|
15
|
+
export * from "./parsers/parseNumber.js";
|
|
16
|
+
export * from "./parsers/parseObject.js";
|
|
17
|
+
export * from "./parsers/parseOneOf.js";
|
|
18
|
+
export * from "./parsers/parseSchema.js";
|
|
19
|
+
export * from "./parsers/parseSimpleDiscriminatedOneOf.js";
|
|
20
|
+
export * from "./parsers/parseString.js";
|
|
21
|
+
export * from "./utils/anyOrUnknown.js";
|
|
22
|
+
export * from "./utils/half.js";
|
|
23
|
+
export * from "./utils/jsdocs.js";
|
|
24
|
+
export * from "./utils/omit.js";
|
|
25
|
+
export * from "./utils/withMessage.js";
|
|
26
|
+
export * from "./zodToJsonSchema.js";
|
|
27
|
+
import { jsonSchemaToZod } from "./jsonSchemaToZod.js";
|
|
28
|
+
export default jsonSchemaToZod;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { Refs, JsonSchemaObject, JsonSchema, Serializable, SimpleDiscriminatedOneOfSchema } from "../Types.js";
|
|
2
|
+
export declare const parseSchema: (schema: JsonSchema, refs?: Refs, blockMeta?: boolean) => string;
|
|
3
|
+
export declare const its: {
|
|
4
|
+
an: {
|
|
5
|
+
object: (x: JsonSchemaObject) => x is JsonSchemaObject & {
|
|
6
|
+
type: "object";
|
|
7
|
+
};
|
|
8
|
+
array: (x: JsonSchemaObject) => x is JsonSchemaObject & {
|
|
9
|
+
type: "array";
|
|
10
|
+
};
|
|
11
|
+
anyOf: (x: JsonSchemaObject) => x is JsonSchemaObject & {
|
|
12
|
+
anyOf: JsonSchema[];
|
|
13
|
+
};
|
|
14
|
+
allOf: (x: JsonSchemaObject) => x is JsonSchemaObject & {
|
|
15
|
+
allOf: JsonSchema[];
|
|
16
|
+
};
|
|
17
|
+
enum: (x: JsonSchemaObject) => x is JsonSchemaObject & {
|
|
18
|
+
enum: Serializable | Serializable[];
|
|
19
|
+
};
|
|
20
|
+
};
|
|
21
|
+
a: {
|
|
22
|
+
nullable: (x: JsonSchemaObject) => x is JsonSchemaObject & {
|
|
23
|
+
nullable: true;
|
|
24
|
+
};
|
|
25
|
+
multipleType: (x: JsonSchemaObject) => x is JsonSchemaObject & {
|
|
26
|
+
type: string[];
|
|
27
|
+
};
|
|
28
|
+
not: (x: JsonSchemaObject) => x is JsonSchemaObject & {
|
|
29
|
+
not: JsonSchema;
|
|
30
|
+
};
|
|
31
|
+
ref: (x: JsonSchemaObject) => x is JsonSchemaObject & {
|
|
32
|
+
$ref: string;
|
|
33
|
+
};
|
|
34
|
+
const: (x: JsonSchemaObject) => x is JsonSchemaObject & {
|
|
35
|
+
const: Serializable;
|
|
36
|
+
};
|
|
37
|
+
primitive: <T extends "string" | "number" | "integer" | "boolean" | "null">(x: JsonSchemaObject, p: T) => x is JsonSchemaObject & {
|
|
38
|
+
type: T;
|
|
39
|
+
};
|
|
40
|
+
conditional: (x: JsonSchemaObject) => x is JsonSchemaObject & {
|
|
41
|
+
if: JsonSchema;
|
|
42
|
+
then: JsonSchema;
|
|
43
|
+
else: JsonSchema;
|
|
44
|
+
};
|
|
45
|
+
simpleDiscriminatedOneOf: (x: JsonSchemaObject) => x is SimpleDiscriminatedOneOfSchema;
|
|
46
|
+
oneOf: (x: JsonSchemaObject) => x is JsonSchemaObject & {
|
|
47
|
+
oneOf: JsonSchema[];
|
|
48
|
+
};
|
|
49
|
+
};
|
|
50
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Refs } from "../Types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Returns "z.unknown()" if the useUnknown option is enabled, otherwise "z.any()".
|
|
4
|
+
* This helper is used throughout the library for fallback cases.
|
|
5
|
+
*
|
|
6
|
+
* @param refs - The refs object containing options
|
|
7
|
+
* @returns The appropriate Zod schema string
|
|
8
|
+
*/
|
|
9
|
+
export declare const anyOrUnknown: (refs?: Refs) => string;
|