zod 4.2.0-canary.20251202T062120 → 4.2.0-canary.20251213T203150
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/package.json +1 -1
- package/src/v4/classic/schemas.ts +97 -5
- package/src/v4/classic/tests/fix-json-issue.test.ts +26 -0
- package/src/v4/classic/tests/json.test.ts +4 -3
- package/src/v4/classic/tests/standard-schema.test.ts +77 -0
- package/src/v4/classic/tests/to-json-schema-methods.test.ts +438 -0
- package/src/v4/classic/tests/to-json-schema.test.ts +66 -30
- package/src/v4/core/index.ts +2 -0
- package/src/v4/core/json-schema-generator.ts +124 -0
- package/src/v4/core/json-schema-processors.ts +630 -0
- package/src/v4/core/schemas.ts +8 -13
- package/src/v4/core/standard-schema.ts +114 -19
- package/src/v4/core/to-json-schema.ts +373 -827
- package/src/v4/mini/schemas.ts +2 -2
- package/src/v4/mini/tests/standard-schema.test.ts +17 -0
- package/v4/classic/schemas.cjs +48 -0
- package/v4/classic/schemas.d.cts +35 -0
- package/v4/classic/schemas.d.ts +35 -0
- package/v4/classic/schemas.js +48 -0
- package/v4/core/index.cjs +5 -1
- package/v4/core/index.d.cts +2 -0
- package/v4/core/index.d.ts +2 -0
- package/v4/core/index.js +2 -0
- package/v4/core/json-schema-generator.cjs +99 -0
- package/v4/core/json-schema-generator.d.cts +64 -0
- package/v4/core/json-schema-generator.d.ts +64 -0
- package/v4/core/json-schema-generator.js +95 -0
- package/v4/core/json-schema-processors.cjs +617 -0
- package/v4/core/json-schema-processors.d.cts +49 -0
- package/v4/core/json-schema-processors.d.ts +49 -0
- package/v4/core/json-schema-processors.js +574 -0
- package/v4/core/schemas.cjs +0 -10
- package/v4/core/schemas.d.cts +4 -1
- package/v4/core/schemas.d.ts +4 -1
- package/v4/core/schemas.js +0 -10
- package/v4/core/standard-schema.d.cts +90 -19
- package/v4/core/standard-schema.d.ts +90 -19
- package/v4/core/to-json-schema.cjs +302 -793
- package/v4/core/to-json-schema.d.cts +56 -33
- package/v4/core/to-json-schema.d.ts +56 -33
- package/v4/core/to-json-schema.js +296 -791
- package/v4/mini/schemas.d.cts +2 -2
- package/v4/mini/schemas.d.ts +2 -2
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Validator } from "@seriousme/openapi-schema-validator";
|
|
2
2
|
import { describe, expect, test } from "vitest";
|
|
3
|
-
import * as z from "zod
|
|
3
|
+
import * as z from "zod";
|
|
4
4
|
// import * as zCore from "zod/v4/core";
|
|
5
5
|
|
|
6
6
|
const openAPI30Validator = new Validator();
|
|
@@ -628,6 +628,42 @@ describe("toJSONSchema", () => {
|
|
|
628
628
|
`);
|
|
629
629
|
});
|
|
630
630
|
|
|
631
|
+
test("target normalization draft-04 and draft-07", () => {
|
|
632
|
+
// Test that both old (draft-4, draft-7) and new (draft-04, draft-07) target formats work
|
|
633
|
+
// Test draft-04 / draft-4
|
|
634
|
+
expect(z.toJSONSchema(z.number().gt(5), { target: "draft-04" })).toMatchInlineSnapshot(`
|
|
635
|
+
{
|
|
636
|
+
"$schema": "http://json-schema.org/draft-04/schema#",
|
|
637
|
+
"exclusiveMinimum": true,
|
|
638
|
+
"minimum": 5,
|
|
639
|
+
"type": "number",
|
|
640
|
+
}
|
|
641
|
+
`);
|
|
642
|
+
expect(z.toJSONSchema(z.number().gt(5), { target: "draft-4" })).toMatchInlineSnapshot(`
|
|
643
|
+
{
|
|
644
|
+
"$schema": "http://json-schema.org/draft-04/schema#",
|
|
645
|
+
"exclusiveMinimum": true,
|
|
646
|
+
"minimum": 5,
|
|
647
|
+
"type": "number",
|
|
648
|
+
}
|
|
649
|
+
`);
|
|
650
|
+
// Test draft-07 / draft-7
|
|
651
|
+
expect(z.toJSONSchema(z.number().gt(5), { target: "draft-07" })).toMatchInlineSnapshot(`
|
|
652
|
+
{
|
|
653
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
654
|
+
"exclusiveMinimum": 5,
|
|
655
|
+
"type": "number",
|
|
656
|
+
}
|
|
657
|
+
`);
|
|
658
|
+
expect(z.toJSONSchema(z.number().gt(5), { target: "draft-7" })).toMatchInlineSnapshot(`
|
|
659
|
+
{
|
|
660
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
661
|
+
"exclusiveMinimum": 5,
|
|
662
|
+
"type": "number",
|
|
663
|
+
}
|
|
664
|
+
`);
|
|
665
|
+
});
|
|
666
|
+
|
|
631
667
|
test("nullable openapi-3.0", () => {
|
|
632
668
|
const schema = z.string().nullable();
|
|
633
669
|
const jsonSchema = z.toJSONSchema(schema, { target: "openapi-3.0" });
|
|
@@ -1577,7 +1613,7 @@ describe("toJSONSchema", () => {
|
|
|
1577
1613
|
});
|
|
1578
1614
|
|
|
1579
1615
|
test("override", () => {
|
|
1580
|
-
const schema = z.
|
|
1616
|
+
const schema = z.toJSONSchema(z.string(), {
|
|
1581
1617
|
override: (ctx) => {
|
|
1582
1618
|
ctx.zodSchema;
|
|
1583
1619
|
ctx.jsonSchema;
|
|
@@ -1603,7 +1639,7 @@ test("override: do not run on references", () => {
|
|
|
1603
1639
|
.pipe(z.date())
|
|
1604
1640
|
.meta({ c: true })
|
|
1605
1641
|
.brand("dateIn");
|
|
1606
|
-
z.
|
|
1642
|
+
z.toJSONSchema(schema, {
|
|
1607
1643
|
unrepresentable: "any",
|
|
1608
1644
|
io: "input",
|
|
1609
1645
|
override(_) {
|
|
@@ -1616,7 +1652,7 @@ test("override: do not run on references", () => {
|
|
|
1616
1652
|
|
|
1617
1653
|
test("override with refs", () => {
|
|
1618
1654
|
const a = z.string().optional();
|
|
1619
|
-
const result = z.
|
|
1655
|
+
const result = z.toJSONSchema(a, {
|
|
1620
1656
|
override(ctx) {
|
|
1621
1657
|
if (ctx.zodSchema._zod.def.type === "string") {
|
|
1622
1658
|
ctx.jsonSchema.type = "STRING" as "string";
|
|
@@ -1635,7 +1671,7 @@ test("override with refs", () => {
|
|
|
1635
1671
|
test("override execution order", () => {
|
|
1636
1672
|
const schema = z.union([z.string(), z.number()]);
|
|
1637
1673
|
let unionSchema!: any;
|
|
1638
|
-
z.
|
|
1674
|
+
z.toJSONSchema(schema, {
|
|
1639
1675
|
override(ctx) {
|
|
1640
1676
|
if (ctx.zodSchema._zod.def.type === "union") {
|
|
1641
1677
|
unionSchema = ctx.jsonSchema;
|
|
@@ -1693,7 +1729,7 @@ test("pipe", () => {
|
|
|
1693
1729
|
.pipe(z.number());
|
|
1694
1730
|
// ZodPipe
|
|
1695
1731
|
|
|
1696
|
-
const a = z.
|
|
1732
|
+
const a = z.toJSONSchema(mySchema);
|
|
1697
1733
|
expect(a).toMatchInlineSnapshot(`
|
|
1698
1734
|
{
|
|
1699
1735
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
@@ -1702,7 +1738,7 @@ test("pipe", () => {
|
|
|
1702
1738
|
`);
|
|
1703
1739
|
// => { type: "number" }
|
|
1704
1740
|
|
|
1705
|
-
const b = z.
|
|
1741
|
+
const b = z.toJSONSchema(mySchema, { io: "input" });
|
|
1706
1742
|
expect(b).toMatchInlineSnapshot(`
|
|
1707
1743
|
{
|
|
1708
1744
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
@@ -1727,7 +1763,7 @@ test("passthrough schemas", () => {
|
|
|
1727
1763
|
e: z.pipe(Internal, Internal),
|
|
1728
1764
|
});
|
|
1729
1765
|
|
|
1730
|
-
const result = z.
|
|
1766
|
+
const result = z.toJSONSchema(External, {
|
|
1731
1767
|
reused: "ref",
|
|
1732
1768
|
});
|
|
1733
1769
|
expect(result).toMatchInlineSnapshot(`
|
|
@@ -1782,7 +1818,7 @@ test("passthrough schemas", () => {
|
|
|
1782
1818
|
|
|
1783
1819
|
test("extract schemas with id", () => {
|
|
1784
1820
|
const name = z.string().meta({ id: "name" });
|
|
1785
|
-
const result = z.
|
|
1821
|
+
const result = z.toJSONSchema(
|
|
1786
1822
|
z.object({
|
|
1787
1823
|
first_name: name,
|
|
1788
1824
|
last_name: name.nullable(),
|
|
@@ -1836,7 +1872,7 @@ test("extract schemas with id", () => {
|
|
|
1836
1872
|
});
|
|
1837
1873
|
|
|
1838
1874
|
test("unrepresentable literal values are ignored", () => {
|
|
1839
|
-
const a = z.
|
|
1875
|
+
const a = z.toJSONSchema(z.literal(["hello", null, 5, BigInt(1324), undefined]), { unrepresentable: "any" });
|
|
1840
1876
|
expect(a).toMatchInlineSnapshot(`
|
|
1841
1877
|
{
|
|
1842
1878
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
@@ -1849,7 +1885,7 @@ test("unrepresentable literal values are ignored", () => {
|
|
|
1849
1885
|
}
|
|
1850
1886
|
`);
|
|
1851
1887
|
|
|
1852
|
-
const b = z.
|
|
1888
|
+
const b = z.toJSONSchema(z.literal([undefined, null, 5, BigInt(1324)]), {
|
|
1853
1889
|
unrepresentable: "any",
|
|
1854
1890
|
});
|
|
1855
1891
|
expect(b).toMatchInlineSnapshot(`
|
|
@@ -1863,7 +1899,7 @@ test("unrepresentable literal values are ignored", () => {
|
|
|
1863
1899
|
}
|
|
1864
1900
|
`);
|
|
1865
1901
|
|
|
1866
|
-
const c = z.
|
|
1902
|
+
const c = z.toJSONSchema(z.literal([undefined]), {
|
|
1867
1903
|
unrepresentable: "any",
|
|
1868
1904
|
});
|
|
1869
1905
|
expect(c).toMatchInlineSnapshot(`
|
|
@@ -1876,7 +1912,7 @@ test("unrepresentable literal values are ignored", () => {
|
|
|
1876
1912
|
test("describe with id", () => {
|
|
1877
1913
|
const jobId = z.string().meta({ id: "jobId" });
|
|
1878
1914
|
|
|
1879
|
-
const a = z.
|
|
1915
|
+
const a = z.toJSONSchema(
|
|
1880
1916
|
z.object({
|
|
1881
1917
|
current: jobId.describe("Current job"),
|
|
1882
1918
|
previous: jobId.describe("Previous job"),
|
|
@@ -1914,7 +1950,7 @@ test("describe with id", () => {
|
|
|
1914
1950
|
test("overwrite id", () => {
|
|
1915
1951
|
const jobId = z.string().meta({ id: "aaa" });
|
|
1916
1952
|
|
|
1917
|
-
const a = z.
|
|
1953
|
+
const a = z.toJSONSchema(
|
|
1918
1954
|
z.object({
|
|
1919
1955
|
current: jobId,
|
|
1920
1956
|
previous: jobId.meta({ id: "bbb" }),
|
|
@@ -1950,7 +1986,7 @@ test("overwrite id", () => {
|
|
|
1950
1986
|
}
|
|
1951
1987
|
`);
|
|
1952
1988
|
|
|
1953
|
-
const b = z.
|
|
1989
|
+
const b = z.toJSONSchema(
|
|
1954
1990
|
z.object({
|
|
1955
1991
|
current: jobId,
|
|
1956
1992
|
previous: jobId.meta({ id: "ccc" }),
|
|
@@ -1993,7 +2029,7 @@ test("overwrite id", () => {
|
|
|
1993
2029
|
test("overwrite descriptions", () => {
|
|
1994
2030
|
const field = z.string().describe("a").describe("b").describe("c");
|
|
1995
2031
|
|
|
1996
|
-
const a = z.
|
|
2032
|
+
const a = z.toJSONSchema(
|
|
1997
2033
|
z.object({
|
|
1998
2034
|
d: field.describe("d"),
|
|
1999
2035
|
e: field.describe("e"),
|
|
@@ -2021,7 +2057,7 @@ test("overwrite descriptions", () => {
|
|
|
2021
2057
|
}
|
|
2022
2058
|
`);
|
|
2023
2059
|
|
|
2024
|
-
const b = z.
|
|
2060
|
+
const b = z.toJSONSchema(
|
|
2025
2061
|
z.object({
|
|
2026
2062
|
d: field.describe("d"),
|
|
2027
2063
|
e: field.describe("e"),
|
|
@@ -2084,7 +2120,7 @@ test("top-level readonly", () => {
|
|
|
2084
2120
|
// z.globalRegistry.add(B, { id: "B" });
|
|
2085
2121
|
// .meta({ id: "B" });
|
|
2086
2122
|
|
|
2087
|
-
const result = z.
|
|
2123
|
+
const result = z.toJSONSchema(A);
|
|
2088
2124
|
expect(result).toMatchInlineSnapshot(`
|
|
2089
2125
|
{
|
|
2090
2126
|
"$defs": {
|
|
@@ -2148,7 +2184,7 @@ test("basic registry", () => {
|
|
|
2148
2184
|
myRegistry.add(User, { id: "User" });
|
|
2149
2185
|
myRegistry.add(Post, { id: "Post" });
|
|
2150
2186
|
|
|
2151
|
-
const result = z.
|
|
2187
|
+
const result = z.toJSONSchema(myRegistry, {
|
|
2152
2188
|
uri: (id) => `https://example.com/${id}.json`,
|
|
2153
2189
|
});
|
|
2154
2190
|
expect(result).toMatchInlineSnapshot(`
|
|
@@ -2204,7 +2240,7 @@ test("basic registry", () => {
|
|
|
2204
2240
|
|
|
2205
2241
|
test("_ref", () => {
|
|
2206
2242
|
// const a = z.promise(z.string().describe("a"));
|
|
2207
|
-
const a = z.
|
|
2243
|
+
const a = z.toJSONSchema(z.promise(z.string().describe("a")));
|
|
2208
2244
|
expect(a).toMatchInlineSnapshot(`
|
|
2209
2245
|
{
|
|
2210
2246
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
@@ -2213,7 +2249,7 @@ test("_ref", () => {
|
|
|
2213
2249
|
}
|
|
2214
2250
|
`);
|
|
2215
2251
|
|
|
2216
|
-
const b = z.
|
|
2252
|
+
const b = z.toJSONSchema(z.lazy(() => z.string().describe("a")));
|
|
2217
2253
|
expect(b).toMatchInlineSnapshot(`
|
|
2218
2254
|
{
|
|
2219
2255
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
@@ -2222,7 +2258,7 @@ test("_ref", () => {
|
|
|
2222
2258
|
}
|
|
2223
2259
|
`);
|
|
2224
2260
|
|
|
2225
|
-
const c = z.
|
|
2261
|
+
const c = z.toJSONSchema(z.optional(z.string().describe("a")));
|
|
2226
2262
|
expect(c).toMatchInlineSnapshot(`
|
|
2227
2263
|
{
|
|
2228
2264
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
@@ -2441,7 +2477,7 @@ test("examples on pipe", () => {
|
|
|
2441
2477
|
// .pipe(z.transform(Number).meta({ examples: [4] }))
|
|
2442
2478
|
.meta({ examples: [4] });
|
|
2443
2479
|
|
|
2444
|
-
const i = z.
|
|
2480
|
+
const i = z.toJSONSchema(schema, { io: "input", unrepresentable: "any" });
|
|
2445
2481
|
expect(i).toMatchInlineSnapshot(`
|
|
2446
2482
|
{
|
|
2447
2483
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
@@ -2451,7 +2487,7 @@ test("examples on pipe", () => {
|
|
|
2451
2487
|
"type": "string",
|
|
2452
2488
|
}
|
|
2453
2489
|
`);
|
|
2454
|
-
const o = z.
|
|
2490
|
+
const o = z.toJSONSchema(schema, { io: "output", unrepresentable: "any" });
|
|
2455
2491
|
expect(o).toMatchInlineSnapshot(`
|
|
2456
2492
|
{
|
|
2457
2493
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
@@ -2463,21 +2499,21 @@ test("examples on pipe", () => {
|
|
|
2463
2499
|
});
|
|
2464
2500
|
|
|
2465
2501
|
// test("number checks", () => {
|
|
2466
|
-
// expect(z.
|
|
2502
|
+
// expect(z.toJSONSchema(z.number().int())).toMatchInlineSnapshot(`
|
|
2467
2503
|
// {
|
|
2468
2504
|
// "maximum": 9007199254740991,
|
|
2469
2505
|
// "minimum": -9007199254740991,
|
|
2470
2506
|
// "type": "integer",
|
|
2471
2507
|
// }
|
|
2472
2508
|
// `);
|
|
2473
|
-
// expect(z.
|
|
2509
|
+
// expect(z.toJSONSchema(z.int())).toMatchInlineSnapshot(`
|
|
2474
2510
|
// {
|
|
2475
2511
|
// "maximum": 9007199254740991,
|
|
2476
2512
|
// "minimum": -9007199254740991,
|
|
2477
2513
|
// "type": "integer",
|
|
2478
2514
|
// }
|
|
2479
2515
|
// `);
|
|
2480
|
-
// expect(z.
|
|
2516
|
+
// expect(z.toJSONSchema(z.int().positive())).toMatchInlineSnapshot(`
|
|
2481
2517
|
// {
|
|
2482
2518
|
// "exclusiveMinimum": 0,
|
|
2483
2519
|
// "maximum": 9007199254740991,
|
|
@@ -2485,14 +2521,14 @@ test("examples on pipe", () => {
|
|
|
2485
2521
|
// "type": "integer",
|
|
2486
2522
|
// }
|
|
2487
2523
|
// `);
|
|
2488
|
-
// expect(z.
|
|
2524
|
+
// expect(z.toJSONSchema(z.int().nonnegative())).toMatchInlineSnapshot(`
|
|
2489
2525
|
// {
|
|
2490
2526
|
// "maximum": 9007199254740991,
|
|
2491
2527
|
// "minimum": 0,
|
|
2492
2528
|
// "type": "integer",
|
|
2493
2529
|
// }
|
|
2494
2530
|
// `);
|
|
2495
|
-
// expect(z.
|
|
2531
|
+
// expect(z.toJSONSchema(z.int().gt(0))).toMatchInlineSnapshot(`
|
|
2496
2532
|
// {
|
|
2497
2533
|
// "exclusiveMinimum": 0,
|
|
2498
2534
|
// "maximum": 9007199254740991,
|
|
@@ -2500,7 +2536,7 @@ test("examples on pipe", () => {
|
|
|
2500
2536
|
// "type": "integer",
|
|
2501
2537
|
// }
|
|
2502
2538
|
// `);
|
|
2503
|
-
// expect(z.
|
|
2539
|
+
// expect(z.toJSONSchema(z.int().gte(0))).toMatchInlineSnapshot(`
|
|
2504
2540
|
// {
|
|
2505
2541
|
// "maximum": 9007199254740991,
|
|
2506
2542
|
// "minimum": 0,
|
package/src/v4/core/index.ts
CHANGED
|
@@ -11,4 +11,6 @@ export * from "./registries.js";
|
|
|
11
11
|
export * from "./doc.js";
|
|
12
12
|
export * from "./api.js";
|
|
13
13
|
export * from "./to-json-schema.js";
|
|
14
|
+
export { toJSONSchema } from "./json-schema-processors.js";
|
|
15
|
+
export { JSONSchemaGenerator } from "./json-schema-generator.js";
|
|
14
16
|
export * as JSONSchema from "./json-schema.js";
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import { allProcessors } from "./json-schema-processors.js";
|
|
2
|
+
import type * as JSONSchema from "./json-schema.js";
|
|
3
|
+
import type * as schemas from "./schemas.js";
|
|
4
|
+
import {
|
|
5
|
+
type JSONSchemaGeneratorParams,
|
|
6
|
+
type ProcessParams,
|
|
7
|
+
type ToJSONSchemaContext,
|
|
8
|
+
extractDefs,
|
|
9
|
+
finalize,
|
|
10
|
+
initializeContext,
|
|
11
|
+
process,
|
|
12
|
+
} from "./to-json-schema.js";
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Parameters for the emit method of JSONSchemaGenerator.
|
|
16
|
+
* @deprecated Use toJSONSchema function instead
|
|
17
|
+
*/
|
|
18
|
+
export type EmitParams = Pick<JSONSchemaGeneratorParams, "cycles" | "reused" | "external">;
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Parameters for JSONSchemaGenerator constructor.
|
|
22
|
+
* @deprecated Use toJSONSchema function instead
|
|
23
|
+
*/
|
|
24
|
+
type JSONSchemaGeneratorConstructorParams = Pick<
|
|
25
|
+
JSONSchemaGeneratorParams,
|
|
26
|
+
"metadata" | "target" | "unrepresentable" | "override" | "io"
|
|
27
|
+
>;
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Legacy class-based interface for JSON Schema generation.
|
|
31
|
+
* This class wraps the new functional implementation to provide backward compatibility.
|
|
32
|
+
*
|
|
33
|
+
* @deprecated Use the `toJSONSchema` function instead for new code.
|
|
34
|
+
*
|
|
35
|
+
* @example
|
|
36
|
+
* ```typescript
|
|
37
|
+
* // Legacy usage (still supported)
|
|
38
|
+
* const gen = new JSONSchemaGenerator({ target: "draft-07" });
|
|
39
|
+
* gen.process(schema);
|
|
40
|
+
* const result = gen.emit(schema);
|
|
41
|
+
*
|
|
42
|
+
* // Preferred modern usage
|
|
43
|
+
* const result = toJSONSchema(schema, { target: "draft-07" });
|
|
44
|
+
* ```
|
|
45
|
+
*/
|
|
46
|
+
export class JSONSchemaGenerator {
|
|
47
|
+
private ctx: ToJSONSchemaContext;
|
|
48
|
+
|
|
49
|
+
/** @deprecated Access via ctx instead */
|
|
50
|
+
get metadataRegistry() {
|
|
51
|
+
return this.ctx.metadataRegistry;
|
|
52
|
+
}
|
|
53
|
+
/** @deprecated Access via ctx instead */
|
|
54
|
+
get target() {
|
|
55
|
+
return this.ctx.target;
|
|
56
|
+
}
|
|
57
|
+
/** @deprecated Access via ctx instead */
|
|
58
|
+
get unrepresentable() {
|
|
59
|
+
return this.ctx.unrepresentable;
|
|
60
|
+
}
|
|
61
|
+
/** @deprecated Access via ctx instead */
|
|
62
|
+
get override() {
|
|
63
|
+
return this.ctx.override;
|
|
64
|
+
}
|
|
65
|
+
/** @deprecated Access via ctx instead */
|
|
66
|
+
get io() {
|
|
67
|
+
return this.ctx.io;
|
|
68
|
+
}
|
|
69
|
+
/** @deprecated Access via ctx instead */
|
|
70
|
+
get counter() {
|
|
71
|
+
return this.ctx.counter;
|
|
72
|
+
}
|
|
73
|
+
set counter(value: number) {
|
|
74
|
+
this.ctx.counter = value;
|
|
75
|
+
}
|
|
76
|
+
/** @deprecated Access via ctx instead */
|
|
77
|
+
get seen() {
|
|
78
|
+
return this.ctx.seen;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
constructor(params?: JSONSchemaGeneratorConstructorParams) {
|
|
82
|
+
// Normalize target for internal context
|
|
83
|
+
let normalizedTarget: ToJSONSchemaContext["target"] = params?.target ?? "draft-2020-12";
|
|
84
|
+
if (normalizedTarget === "draft-4") normalizedTarget = "draft-04";
|
|
85
|
+
if (normalizedTarget === "draft-7") normalizedTarget = "draft-07";
|
|
86
|
+
|
|
87
|
+
this.ctx = initializeContext({
|
|
88
|
+
processors: allProcessors,
|
|
89
|
+
target: normalizedTarget,
|
|
90
|
+
...(params?.metadata && { metadata: params.metadata }),
|
|
91
|
+
...(params?.unrepresentable && { unrepresentable: params.unrepresentable }),
|
|
92
|
+
...(params?.override && { override: params.override as any }),
|
|
93
|
+
...(params?.io && { io: params.io }),
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Process a schema to prepare it for JSON Schema generation.
|
|
99
|
+
* This must be called before emit().
|
|
100
|
+
*/
|
|
101
|
+
process(schema: schemas.$ZodType, _params: ProcessParams = { path: [], schemaPath: [] }): JSONSchema.BaseSchema {
|
|
102
|
+
return process(schema, this.ctx, _params);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Emit the final JSON Schema after processing.
|
|
107
|
+
* Must call process() first.
|
|
108
|
+
*/
|
|
109
|
+
emit(schema: schemas.$ZodType, _params?: EmitParams): JSONSchema.BaseSchema {
|
|
110
|
+
// Apply emit params to the context
|
|
111
|
+
if (_params) {
|
|
112
|
+
if (_params.cycles) this.ctx.cycles = _params.cycles;
|
|
113
|
+
if (_params.reused) this.ctx.reused = _params.reused;
|
|
114
|
+
if (_params.external) this.ctx.external = _params.external;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
extractDefs(this.ctx, schema);
|
|
118
|
+
const result = finalize(this.ctx, schema);
|
|
119
|
+
|
|
120
|
+
// Strip ~standard property to match old implementation's return type
|
|
121
|
+
const { "~standard": _, ...plainResult } = result as any;
|
|
122
|
+
return plainResult as JSONSchema.BaseSchema;
|
|
123
|
+
}
|
|
124
|
+
}
|