|
1 | | -import * as R from "ramda"; |
2 | | -import { globalRegistry, z } from "zod"; |
3 | | -import { name } from "./package.json"; |
4 | | -import { Intact, Remap } from "./remap"; |
| 1 | +import type { z } from "zod"; |
| 2 | +import type { Intact, Remap } from "./remap"; |
5 | 3 |
|
6 | 4 | declare module "zod/v4/core" { |
7 | 5 | interface GlobalMeta { |
@@ -55,107 +53,3 @@ declare module "zod" { |
55 | 53 | ): z.ZodPipe<z.ZodPipe<this, z.ZodTransform>, z.ZodObject<U>>; // internal type simplified |
56 | 54 | } |
57 | 55 | } |
58 | | - |
59 | | -interface $EZBrandCheckDef extends z.core.$ZodCheckDef { |
60 | | - check: "$EZBrandCheck"; |
61 | | - brand?: string | number | symbol; |
62 | | -} |
63 | | - |
64 | | -interface $EZBrandCheckInternals extends z.core.$ZodCheckInternals<unknown> { |
65 | | - def: $EZBrandCheckDef; |
66 | | -} |
67 | | - |
68 | | -interface $EZBrandCheck extends z.core.$ZodCheck { |
69 | | - _zod: $EZBrandCheckInternals; |
70 | | -} |
71 | | - |
72 | | -/** |
73 | | - * This approach was suggested to me by Colin in a PM on Twitter. |
74 | | - * Refrained from storing the brand in Metadata because it should withstand refinements. |
75 | | - * */ |
76 | | -const $EZBrandCheck = z.core.$constructor<$EZBrandCheck>( |
77 | | - "$EZBrandCheck", |
78 | | - (inst, def) => { |
79 | | - z.core.$ZodCheck.init(inst, def); |
80 | | - inst._zod.onattach.push((schema) => (schema._zod.bag.brand = def.brand)); |
81 | | - inst._zod.check = () => {}; |
82 | | - }, |
83 | | -); |
84 | | - |
85 | | -const exampleSetter = function (this: z.ZodType, value: z.output<typeof this>) { |
86 | | - const examples = globalRegistry.get(this)?.examples?.slice() || []; |
87 | | - examples.push(value); |
88 | | - return this.meta({ examples }); |
89 | | -}; |
90 | | - |
91 | | -const deprecationSetter = function (this: z.ZodType) { |
92 | | - return this.meta({ deprecated: true }); |
93 | | -}; |
94 | | - |
95 | | -const labelSetter = function (this: z.ZodDefault, defaultLabel: string) { |
96 | | - return this.meta({ default: defaultLabel }); |
97 | | -}; |
98 | | - |
99 | | -const brandSetter = function ( |
100 | | - this: z.ZodType, |
101 | | - brand?: string | number | symbol, |
102 | | -) { |
103 | | - return this.check(new $EZBrandCheck({ brand, check: "$EZBrandCheck" })); |
104 | | -}; |
105 | | - |
106 | | -type _Mapper = <T extends Record<string, unknown>>( |
107 | | - subject: T, |
108 | | -) => { [P in string | keyof T]: T[keyof T] }; |
109 | | - |
110 | | -const objectMapper = function ( |
111 | | - this: z.ZodObject, |
112 | | - tool: Record<string, string> | _Mapper, |
113 | | -) { |
114 | | - const transformer = |
115 | | - typeof tool === "function" ? tool : R.renameKeys(R.reject(R.isNil, tool)); // rejecting undefined |
116 | | - const nextShape = transformer( |
117 | | - R.map(R.invoker(0, "clone"), this._zod.def.shape), // immutable, changed from R.clone due to failure |
118 | | - ); |
119 | | - const hasPassThrough = this._zod.def.catchall instanceof z.ZodUnknown; |
120 | | - const output = (hasPassThrough ? z.looseObject : z.object)(nextShape); // proxies unknown keys when set to "passthrough" |
121 | | - return this.transform(transformer).pipe(output); |
122 | | -}; |
123 | | - |
124 | | -const pluginFlag = Symbol.for(name); |
125 | | - |
126 | | -if (!(pluginFlag in globalThis)) { |
127 | | - (globalThis as Record<symbol, unknown>)[pluginFlag] = true; |
128 | | - for (const entry of Object.keys(z)) { |
129 | | - if (!entry.startsWith("Zod")) continue; |
130 | | - if (/(Success|Error|Function)$/.test(entry)) continue; |
131 | | - const Cls = z[entry as keyof typeof z]; |
132 | | - if (typeof Cls !== "function") continue; |
133 | | - Object.defineProperties(Cls.prototype, { |
134 | | - ["example" satisfies keyof z.ZodType]: { |
135 | | - value: exampleSetter, |
136 | | - writable: false, |
137 | | - }, |
138 | | - ["deprecated" satisfies keyof z.ZodType]: { |
139 | | - value: deprecationSetter, |
140 | | - writable: false, |
141 | | - }, |
142 | | - ["brand" satisfies keyof z.ZodType]: { |
143 | | - set() {}, // this is required to override the existing method |
144 | | - get() { |
145 | | - return brandSetter.bind(this) as z.ZodType["brand"]; |
146 | | - }, |
147 | | - }, |
148 | | - }); |
149 | | - } |
150 | | - |
151 | | - Object.defineProperty( |
152 | | - z.ZodDefault.prototype, |
153 | | - "label" satisfies keyof z.ZodDefault, |
154 | | - { value: labelSetter, writable: false }, |
155 | | - ); |
156 | | - Object.defineProperty( |
157 | | - z.ZodObject.prototype, |
158 | | - "remap" satisfies keyof z.ZodObject, |
159 | | - { value: objectMapper, writable: false }, |
160 | | - ); |
161 | | -} |
0 commit comments