@wecode-ai/weibo-openclaw-plugin 2.2.2 → 2.2.4
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/node_modules/tar/dist/commonjs/index.min.js +3 -3
- package/node_modules/tar/dist/commonjs/index.min.js.map +3 -3
- package/node_modules/tar/dist/commonjs/pack.d.ts +3 -1
- package/node_modules/tar/dist/commonjs/pack.d.ts.map +1 -1
- package/node_modules/tar/dist/commonjs/pack.js +33 -7
- package/node_modules/tar/dist/commonjs/pack.js.map +1 -1
- package/node_modules/tar/dist/esm/index.min.js +3 -3
- package/node_modules/tar/dist/esm/index.min.js.map +3 -3
- package/node_modules/tar/dist/esm/pack.d.ts +3 -1
- package/node_modules/tar/dist/esm/pack.d.ts.map +1 -1
- package/node_modules/tar/dist/esm/pack.js +33 -7
- package/node_modules/tar/dist/esm/pack.js.map +1 -1
- package/node_modules/tar/package.json +4 -4
- package/node_modules/zod/README.md +1 -18
- package/node_modules/zod/locales/package.json +2 -1
- package/node_modules/zod/mini/package.json +2 -1
- package/node_modules/zod/package.json +1 -1
- package/node_modules/zod/src/v3/tests/all-errors.test.ts +3 -3
- package/node_modules/zod/src/v3/tests/object.test.ts +5 -5
- package/node_modules/zod/src/v3/tests/partials.test.ts +3 -3
- package/node_modules/zod/src/v4/classic/errors.ts +2 -2
- package/node_modules/zod/src/v4/classic/external.ts +1 -0
- package/node_modules/zod/src/v4/classic/from-json-schema.ts +39 -23
- package/node_modules/zod/src/v4/classic/parse.ts +6 -6
- package/node_modules/zod/src/v4/classic/schemas.ts +414 -151
- package/node_modules/zod/src/v4/classic/tests/assignability.test.ts +6 -0
- package/node_modules/zod/src/v4/classic/tests/catch.test.ts +50 -0
- package/node_modules/zod/src/v4/classic/tests/codec.test.ts +142 -1
- package/node_modules/zod/src/v4/classic/tests/continuability.test.ts +1 -1
- package/node_modules/zod/src/v4/classic/tests/datetime.test.ts +1 -1
- package/node_modules/zod/src/v4/classic/tests/default.test.ts +44 -0
- package/node_modules/zod/src/v4/classic/tests/detached-methods.test.ts +197 -0
- package/node_modules/zod/src/v4/classic/tests/discriminated-unions.test.ts +34 -1
- package/node_modules/zod/src/v4/classic/tests/error-utils.test.ts +214 -2
- package/node_modules/zod/src/v4/classic/tests/from-json-schema.test.ts +161 -0
- package/node_modules/zod/src/v4/classic/tests/function.test.ts +6 -6
- package/node_modules/zod/src/v4/classic/tests/global-config.test.ts +39 -0
- package/node_modules/zod/src/v4/classic/tests/index.test.ts +2 -2
- package/node_modules/zod/src/v4/classic/tests/jitless-allows-eval.test.ts +46 -0
- package/node_modules/zod/src/v4/classic/tests/locales_ka.test.ts +29 -0
- package/node_modules/zod/src/v4/classic/tests/locales_ro.test.ts +24 -0
- package/node_modules/zod/src/v4/classic/tests/number.test.ts +55 -0
- package/node_modules/zod/src/v4/classic/tests/object.test.ts +83 -6
- package/node_modules/zod/src/v4/classic/tests/optional.test.ts +114 -4
- package/node_modules/zod/src/v4/classic/tests/partial.test.ts +24 -1
- package/node_modules/zod/src/v4/classic/tests/prefault.test.ts +1 -1
- package/node_modules/zod/src/v4/classic/tests/preprocess-types.test.ts +26 -0
- package/node_modules/zod/src/v4/classic/tests/preprocess.test.ts +69 -0
- package/node_modules/zod/src/v4/classic/tests/record.test.ts +85 -0
- package/node_modules/zod/src/v4/classic/tests/recursive-types.test.ts +49 -0
- package/node_modules/zod/src/v4/classic/tests/refine.test.ts +63 -0
- package/node_modules/zod/src/v4/classic/tests/string.test.ts +50 -1
- package/node_modules/zod/src/v4/classic/tests/template-literal.test.ts +4 -4
- package/node_modules/zod/src/v4/classic/tests/to-json-schema.test.ts +150 -15
- package/node_modules/zod/src/v4/classic/tests/transform.test.ts +17 -0
- package/node_modules/zod/src/v4/classic/tests/tuple.test.ts +315 -2
- package/node_modules/zod/src/v4/classic/tests/union.test.ts +54 -0
- package/node_modules/zod/src/v4/core/api.ts +31 -6
- package/node_modules/zod/src/v4/core/checks.ts +1 -1
- package/node_modules/zod/src/v4/core/core.ts +17 -2
- package/node_modules/zod/src/v4/core/errors.ts +31 -24
- package/node_modules/zod/src/v4/core/json-schema-processors.ts +17 -18
- package/node_modules/zod/src/v4/core/parse.ts +7 -7
- package/node_modules/zod/src/v4/core/regexes.ts +8 -1
- package/node_modules/zod/src/v4/core/schemas.ts +263 -71
- package/node_modules/zod/src/v4/core/tests/locales/el.test.ts +215 -0
- package/node_modules/zod/src/v4/core/tests/locales/fr.test.ts +72 -0
- package/node_modules/zod/src/v4/core/tests/locales/hr.test.ts +163 -0
- package/node_modules/zod/src/v4/core/tests/locales/uz.test.ts +22 -0
- package/node_modules/zod/src/v4/core/tests/record-constructor.test.ts +58 -0
- package/node_modules/zod/src/v4/core/to-json-schema.ts +10 -1
- package/node_modules/zod/src/v4/core/util.ts +52 -35
- package/node_modules/zod/src/v4/core/versions.ts +2 -2
- package/node_modules/zod/src/v4/locales/el.ts +121 -0
- package/node_modules/zod/src/v4/locales/en.ts +4 -0
- package/node_modules/zod/src/v4/locales/fr.ts +24 -8
- package/node_modules/zod/src/v4/locales/hr.ts +131 -0
- package/node_modules/zod/src/v4/locales/index.ts +3 -0
- package/node_modules/zod/src/v4/locales/it.ts +1 -1
- package/node_modules/zod/src/v4/locales/ka.ts +8 -8
- package/node_modules/zod/src/v4/locales/ro.ts +129 -0
- package/node_modules/zod/src/v4/locales/uz.ts +1 -0
- package/node_modules/zod/src/v4/mini/external.ts +1 -0
- package/node_modules/zod/src/v4/mini/schemas.ts +56 -25
- package/node_modules/zod/src/v4/mini/tests/codec.test.ts +19 -0
- package/node_modules/zod/src/v4/mini/tests/index.test.ts +32 -2
- package/node_modules/zod/src/v4/mini/tests/object.test.ts +9 -9
- package/node_modules/zod/src/v4/mini/tests/recursive-types.test.ts +51 -1
- package/node_modules/zod/src/v4/mini/tests/string.test.ts +5 -0
- package/node_modules/zod/v3/package.json +2 -1
- package/node_modules/zod/v4/classic/errors.js +2 -2
- package/node_modules/zod/v4/classic/external.d.cts +1 -0
- package/node_modules/zod/v4/classic/external.d.ts +1 -0
- package/node_modules/zod/v4/classic/from-json-schema.cjs +31 -16
- package/node_modules/zod/v4/classic/from-json-schema.js +31 -16
- package/node_modules/zod/v4/classic/package.json +2 -1
- package/node_modules/zod/v4/classic/schemas.cjs +358 -119
- package/node_modules/zod/v4/classic/schemas.d.cts +42 -14
- package/node_modules/zod/v4/classic/schemas.d.ts +42 -14
- package/node_modules/zod/v4/classic/schemas.js +356 -118
- package/node_modules/zod/v4/core/api.cjs +7 -2
- package/node_modules/zod/v4/core/api.d.cts +26 -5
- package/node_modules/zod/v4/core/api.d.ts +26 -5
- package/node_modules/zod/v4/core/api.js +7 -2
- package/node_modules/zod/v4/core/checks.d.cts +1 -1
- package/node_modules/zod/v4/core/checks.d.ts +1 -1
- package/node_modules/zod/v4/core/core.cjs +3 -1
- package/node_modules/zod/v4/core/core.js +4 -2
- package/node_modules/zod/v4/core/errors.cjs +26 -23
- package/node_modules/zod/v4/core/errors.d.cts +1 -0
- package/node_modules/zod/v4/core/errors.d.ts +1 -0
- package/node_modules/zod/v4/core/errors.js +26 -23
- package/node_modules/zod/v4/core/json-schema-processors.cjs +16 -20
- package/node_modules/zod/v4/core/json-schema-processors.js +16 -20
- package/node_modules/zod/v4/core/package.json +2 -1
- package/node_modules/zod/v4/core/parse.cjs +7 -7
- package/node_modules/zod/v4/core/parse.js +7 -7
- package/node_modules/zod/v4/core/regexes.cjs +9 -3
- package/node_modules/zod/v4/core/regexes.d.cts +6 -0
- package/node_modules/zod/v4/core/regexes.d.ts +6 -0
- package/node_modules/zod/v4/core/regexes.js +7 -1
- package/node_modules/zod/v4/core/schemas.cjs +211 -65
- package/node_modules/zod/v4/core/schemas.d.cts +39 -1
- package/node_modules/zod/v4/core/schemas.d.ts +39 -1
- package/node_modules/zod/v4/core/schemas.js +210 -64
- package/node_modules/zod/v4/core/to-json-schema.cjs +12 -1
- package/node_modules/zod/v4/core/to-json-schema.js +12 -1
- package/node_modules/zod/v4/core/util.cjs +54 -30
- package/node_modules/zod/v4/core/util.d.cts +1 -0
- package/node_modules/zod/v4/core/util.d.ts +1 -0
- package/node_modules/zod/v4/core/util.js +55 -32
- package/node_modules/zod/v4/core/versions.cjs +2 -2
- package/node_modules/zod/v4/core/versions.d.cts +1 -1
- package/node_modules/zod/v4/core/versions.d.ts +1 -1
- package/node_modules/zod/v4/core/versions.js +2 -2
- package/node_modules/zod/v4/locales/el.cjs +136 -0
- package/node_modules/zod/v4/locales/el.d.cts +5 -0
- package/node_modules/zod/v4/locales/el.d.ts +4 -0
- package/node_modules/zod/v4/locales/el.js +109 -0
- package/node_modules/zod/v4/locales/en.cjs +4 -0
- package/node_modules/zod/v4/locales/en.js +4 -0
- package/node_modules/zod/v4/locales/fr.cjs +24 -7
- package/node_modules/zod/v4/locales/fr.js +24 -7
- package/node_modules/zod/v4/locales/hr.cjs +149 -0
- package/node_modules/zod/v4/locales/hr.d.cts +5 -0
- package/node_modules/zod/v4/locales/hr.d.ts +4 -0
- package/node_modules/zod/v4/locales/hr.js +122 -0
- package/node_modules/zod/v4/locales/index.cjs +8 -1
- package/node_modules/zod/v4/locales/index.d.cts +3 -0
- package/node_modules/zod/v4/locales/index.d.ts +3 -0
- package/node_modules/zod/v4/locales/index.js +3 -0
- package/node_modules/zod/v4/locales/it.cjs +1 -1
- package/node_modules/zod/v4/locales/it.js +1 -1
- package/node_modules/zod/v4/locales/ka.cjs +8 -8
- package/node_modules/zod/v4/locales/ka.js +8 -8
- package/node_modules/zod/v4/locales/package.json +2 -1
- package/node_modules/zod/v4/locales/ro.cjs +146 -0
- package/node_modules/zod/v4/locales/ro.d.cts +5 -0
- package/node_modules/zod/v4/locales/ro.d.ts +4 -0
- package/node_modules/zod/v4/locales/ro.js +119 -0
- package/node_modules/zod/v4/locales/uz.cjs +1 -0
- package/node_modules/zod/v4/locales/uz.js +1 -0
- package/node_modules/zod/v4/mini/external.d.cts +1 -0
- package/node_modules/zod/v4/mini/external.d.ts +1 -0
- package/node_modules/zod/v4/mini/package.json +2 -1
- package/node_modules/zod/v4/mini/schemas.cjs +41 -4
- package/node_modules/zod/v4/mini/schemas.d.cts +28 -10
- package/node_modules/zod/v4/mini/schemas.d.ts +28 -10
- package/node_modules/zod/v4/mini/schemas.js +40 -4
- package/node_modules/zod/v4/package.json +2 -1
- package/node_modules/zod/v4-mini/package.json +2 -1
- package/package.json +2 -1
- package/skills/manifest.json +1 -1
- package/skills/weibo-crowd/SKILL.md +127 -11
- package/skills/weibo-crowd/references/SILICON-TEAHOUSE-RULES.md +6 -19
- package/skills/weibo-crowd/scripts/weibo-crowd.js +90 -1
- package/src/accounts.js +1 -1
- package/src/accounts.js.map +1 -1
- package/src/channel.js +1 -1
- package/src/channel.js.map +1 -1
- package/src/outbound.d.ts.map +1 -1
- package/src/outbound.js +82 -4
- package/src/outbound.js.map +1 -1
- package/src/send.d.ts +23 -0
- package/src/send.d.ts.map +1 -1
- package/src/send.js +54 -2
- package/src/send.js.map +1 -1
- package/src/token.d.ts +8 -0
- package/src/token.d.ts.map +1 -1
- package/src/token.js +16 -1
- package/src/token.js.map +1 -1
|
@@ -107,7 +107,9 @@ test("async validation", async () => {
|
|
|
107
107
|
|
|
108
108
|
test("tuple with optional elements", () => {
|
|
109
109
|
const myTuple = z.tuple([z.string(), z.number().optional(), z.string().optional()]).rest(z.boolean());
|
|
110
|
-
expectTypeOf<typeof myTuple._output>().toEqualTypeOf<
|
|
110
|
+
expectTypeOf<typeof myTuple._output>().toEqualTypeOf<
|
|
111
|
+
[string, (number | undefined)?, (string | undefined)?, ...boolean[]]
|
|
112
|
+
>();
|
|
111
113
|
|
|
112
114
|
const goodData = [["asdf"], ["asdf", 1234], ["asdf", 1234, "asdf"], ["asdf", 1234, "asdf", true, false, true]];
|
|
113
115
|
for (const data of goodData) {
|
|
@@ -149,7 +151,9 @@ test("tuple with optional elements followed by required", () => {
|
|
|
149
151
|
|
|
150
152
|
test("tuple with all optional elements", () => {
|
|
151
153
|
const allOptionalTuple = z.tuple([z.string().optional(), z.number().optional(), z.boolean().optional()]);
|
|
152
|
-
expectTypeOf<typeof allOptionalTuple._output>().toEqualTypeOf<
|
|
154
|
+
expectTypeOf<typeof allOptionalTuple._output>().toEqualTypeOf<
|
|
155
|
+
[(string | undefined)?, (number | undefined)?, (boolean | undefined)?]
|
|
156
|
+
>();
|
|
153
157
|
|
|
154
158
|
// Empty array should be valid (all items optional)
|
|
155
159
|
expect(allOptionalTuple.parse([])).toEqual([]);
|
|
@@ -165,6 +169,227 @@ test("tuple with all optional elements", () => {
|
|
|
165
169
|
expect(() => allOptionalTuple.parse(["hello", 42, true, "extra"])).toThrow();
|
|
166
170
|
});
|
|
167
171
|
|
|
172
|
+
test("tuple fills defaults for missing trailing elements", () => {
|
|
173
|
+
// Issue #5229: trailing `.default()`/`.prefault()` elements should be
|
|
174
|
+
// filled in when the input array is shorter than the tuple.
|
|
175
|
+
const t = z.tuple([z.string(), z.string().default("bravo")]);
|
|
176
|
+
expectTypeOf<typeof t._output>().toEqualTypeOf<[string, string]>();
|
|
177
|
+
expectTypeOf<typeof t._input>().toEqualTypeOf<[string, (string | undefined)?]>();
|
|
178
|
+
|
|
179
|
+
expect(t.parse(["alpha", "charlie"])).toEqual(["alpha", "charlie"]);
|
|
180
|
+
expect(t.parse(["alpha"])).toEqual(["alpha", "bravo"]);
|
|
181
|
+
|
|
182
|
+
// Multiple trailing defaults
|
|
183
|
+
const multi = z.tuple([z.string(), z.number().default(42), z.boolean().default(true)]);
|
|
184
|
+
expect(multi.parse(["hello"])).toEqual(["hello", 42, true]);
|
|
185
|
+
expect(multi.parse(["hello", 100])).toEqual(["hello", 100, true]);
|
|
186
|
+
expect(multi.parse(["hello", 100, false])).toEqual(["hello", 100, false]);
|
|
187
|
+
|
|
188
|
+
// Prefault parity
|
|
189
|
+
expect(z.tuple([z.string(), z.string().prefault("delta")]).parse(["alpha"])).toEqual(["alpha", "delta"]);
|
|
190
|
+
|
|
191
|
+
// Defaults wrapped in modifiers: `optout` propagates through these, so the
|
|
192
|
+
// fix is not type-name specific.
|
|
193
|
+
expect(z.tuple([z.string(), z.string().default("x").nullable()]).parse(["alpha"])).toEqual(["alpha", "x"]);
|
|
194
|
+
expect(z.tuple([z.string(), z.string().default("x").readonly()]).parse(["alpha"])).toEqual(["alpha", "x"]);
|
|
195
|
+
expect(z.tuple([z.string(), z.string().default("x").catch("y")]).parse(["alpha"])).toEqual(["alpha", "x"]);
|
|
196
|
+
expect(z.tuple([z.string(), z.string().default("x").pipe(z.string())]).parse(["alpha"])).toEqual(["alpha", "x"]);
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
test("tuple fills defaults under async parse", async () => {
|
|
200
|
+
const t = z.tuple([z.string(), z.string().default("zulu")]);
|
|
201
|
+
await expect(t.parseAsync(["alpha"])).resolves.toEqual(["alpha", "zulu"]);
|
|
202
|
+
});
|
|
203
|
+
|
|
204
|
+
test("tuple keeps length-1 array for missing `.optional()` elements", () => {
|
|
205
|
+
// Backwards compat: a trailing `.optional()` element that is omitted from
|
|
206
|
+
// the input must NOT be filled with `undefined` — the result stays length-1.
|
|
207
|
+
// Only schemas that produce a defined value get materialized.
|
|
208
|
+
const t = z.tuple([z.string(), z.string().optional()]);
|
|
209
|
+
const out = t.parse(["alpha"]);
|
|
210
|
+
expect(out).toEqual(["alpha"]);
|
|
211
|
+
expect(out.length).toEqual(1);
|
|
212
|
+
|
|
213
|
+
// `z.undefined()` is NOT a synonym for `.optional()` — its value type is
|
|
214
|
+
// *must be undefined*, so the slot is required input. Omitting it triggers
|
|
215
|
+
// a single `too_small` (no element-level errors, matching v3's abort
|
|
216
|
+
// semantics); passing explicit `undefined` succeeds and is preserved.
|
|
217
|
+
expect(z.tuple([z.string(), z.undefined()]).safeParse(["alpha"]).error!.issues).toMatchInlineSnapshot(`
|
|
218
|
+
[
|
|
219
|
+
{
|
|
220
|
+
"code": "too_small",
|
|
221
|
+
"inclusive": true,
|
|
222
|
+
"message": "Too small: expected array to have >=2 items",
|
|
223
|
+
"minimum": 2,
|
|
224
|
+
"origin": "array",
|
|
225
|
+
"path": [],
|
|
226
|
+
},
|
|
227
|
+
]
|
|
228
|
+
`);
|
|
229
|
+
expect(z.tuple([z.string(), z.undefined()]).parse(["alpha", undefined])).toHaveLength(2);
|
|
230
|
+
|
|
231
|
+
// `.optional().nullable()` still trims — `.optional()` propagates the
|
|
232
|
+
// optin/optout flags through the nullable wrapper.
|
|
233
|
+
expect(z.tuple([z.string(), z.string().optional().nullable()]).parse(["alpha"])).toHaveLength(1);
|
|
234
|
+
|
|
235
|
+
// Multiple trailing optionals trim the same way — we don't fill the tail
|
|
236
|
+
// with literal `undefined`s.
|
|
237
|
+
const many = z.tuple([z.string(), z.string().optional(), z.string().optional(), z.string().optional()]);
|
|
238
|
+
expect(many.parse(["alpha"])).toEqual(["alpha"]);
|
|
239
|
+
expect(many.parse(["alpha", "beta"])).toEqual(["alpha", "beta"]);
|
|
240
|
+
|
|
241
|
+
// Explicit `undefined` inside `input.length` IS preserved — only slots
|
|
242
|
+
// past the input get trimmed.
|
|
243
|
+
const r = many.parse(["alpha", undefined]);
|
|
244
|
+
expect(r.length).toEqual(2);
|
|
245
|
+
expect(1 in r).toEqual(true);
|
|
246
|
+
|
|
247
|
+
// Trailing optionals after a default that fires are still trimmed.
|
|
248
|
+
expect(
|
|
249
|
+
z.tuple([z.string(), z.string().default("d"), z.string().optional(), z.string().optional()]).parse(["alpha"])
|
|
250
|
+
).toEqual(["alpha", "d"]);
|
|
251
|
+
});
|
|
252
|
+
|
|
253
|
+
test("tuple result is dense when optional precedes a default", () => {
|
|
254
|
+
// `.optional()` before a `.default()` must produce an explicit `undefined`
|
|
255
|
+
// (not a sparse hole), otherwise `1 in r`, `JSON.stringify`, `Object.keys`,
|
|
256
|
+
// and iteration all behave wrong.
|
|
257
|
+
const t = z.tuple([z.string(), z.string().optional(), z.string().default("z")]);
|
|
258
|
+
const r = t.parse(["alpha"]);
|
|
259
|
+
expect(r).toEqual(["alpha", undefined, "z"]);
|
|
260
|
+
expect(r.length).toEqual(3);
|
|
261
|
+
expect(1 in r).toEqual(true);
|
|
262
|
+
expect(JSON.stringify(r)).toEqual('["alpha",null,"z"]');
|
|
263
|
+
|
|
264
|
+
// Trailing optional after a default is still dropped (no later default
|
|
265
|
+
// forces it to materialize).
|
|
266
|
+
expect(z.tuple([z.string(), z.string().default("d"), z.string().optional()]).parse(["alpha"])).toEqual([
|
|
267
|
+
"alpha",
|
|
268
|
+
"d",
|
|
269
|
+
]);
|
|
270
|
+
|
|
271
|
+
// Multiple interleaved optional/default — every slot up to the last
|
|
272
|
+
// default must be present and dense.
|
|
273
|
+
const interleaved = z.tuple([
|
|
274
|
+
z.string(),
|
|
275
|
+
z.string().optional(),
|
|
276
|
+
z.string().default("d"),
|
|
277
|
+
z.string().optional(),
|
|
278
|
+
z.string().default("e"),
|
|
279
|
+
]);
|
|
280
|
+
const out = interleaved.parse(["alpha"]);
|
|
281
|
+
expect(out).toEqual(["alpha", undefined, "d", undefined, "e"]);
|
|
282
|
+
expect(1 in out && 3 in out).toEqual(true);
|
|
283
|
+
});
|
|
284
|
+
|
|
285
|
+
test("tuple truncates absent optional rejections only when the output tail is optional", () => {
|
|
286
|
+
// An absent optional-output slot can only be swallowed when every later
|
|
287
|
+
// output slot is optional too. If a later default would make the output tail
|
|
288
|
+
// required, truncating would violate the tuple's output type.
|
|
289
|
+
const refusesUndefined = z
|
|
290
|
+
.string()
|
|
291
|
+
.optional()
|
|
292
|
+
.refine((s) => s !== undefined, "must not be undefined");
|
|
293
|
+
|
|
294
|
+
const trailingDefault = z.tuple([z.string(), refusesUndefined, z.string().default("d")]);
|
|
295
|
+
const r1 = trailingDefault.safeParse(["alpha"]);
|
|
296
|
+
expect(r1.success).toBe(false);
|
|
297
|
+
expect(r1.error!.issues[0].path).toEqual([1]);
|
|
298
|
+
|
|
299
|
+
// Optional slots BEFORE the rejected one still cannot hide a later required
|
|
300
|
+
// output slot.
|
|
301
|
+
const beforeReject = z.tuple([z.string(), z.string().optional(), refusesUndefined, z.string().default("d")]);
|
|
302
|
+
const r2 = beforeReject.safeParse(["alpha"]);
|
|
303
|
+
expect(r2.success).toBe(false);
|
|
304
|
+
expect(r2.error!.issues[0].path).toEqual([2]);
|
|
305
|
+
|
|
306
|
+
// No default after — truncate still applies, no spurious issue surfaces.
|
|
307
|
+
const noTrailingDefault = z.tuple([z.string(), refusesUndefined]);
|
|
308
|
+
const r3 = noTrailingDefault.safeParse(["alpha"]);
|
|
309
|
+
expect(r3.success).toBe(true);
|
|
310
|
+
expect(r3.data).toEqual(["alpha"]);
|
|
311
|
+
});
|
|
312
|
+
|
|
313
|
+
test("tuple rejects absent optional before required output under async parse", async () => {
|
|
314
|
+
const refusesUndefined = z
|
|
315
|
+
.string()
|
|
316
|
+
.optional()
|
|
317
|
+
.refine(async (s) => s !== undefined, "must not be undefined");
|
|
318
|
+
|
|
319
|
+
const schema = z.tuple([z.string(), refusesUndefined, z.string().default("d")]);
|
|
320
|
+
const r = await schema.safeParseAsync(["alpha"]);
|
|
321
|
+
expect(r.success).toBe(false);
|
|
322
|
+
expect(r.error!.issues[0].path).toEqual([1]);
|
|
323
|
+
});
|
|
324
|
+
|
|
325
|
+
test("tuple rejects absent exact optional before defaulted output", () => {
|
|
326
|
+
const schema = z.tuple([z.string(), z.string().exactOptional(), z.string().default("fallback")]);
|
|
327
|
+
expectTypeOf<typeof schema._output>().toEqualTypeOf<[string, string, string]>();
|
|
328
|
+
|
|
329
|
+
const missingExact = schema.safeParse(["alpha"]);
|
|
330
|
+
expect(missingExact.success).toBe(false);
|
|
331
|
+
expect(missingExact.error!.issues[0].path).toEqual([1]);
|
|
332
|
+
|
|
333
|
+
expect(schema.parse(["alpha", "bravo"])).toEqual(["alpha", "bravo", "fallback"]);
|
|
334
|
+
expect(schema.safeParse(["alpha", undefined]).success).toBe(false);
|
|
335
|
+
|
|
336
|
+
// With no later required output slot, exact optional still behaves like an
|
|
337
|
+
// omitted tuple tail and truncates cleanly.
|
|
338
|
+
expect(z.tuple([z.string(), z.string().exactOptional(), z.string().optional()]).parse(["alpha"])).toEqual(["alpha"]);
|
|
339
|
+
});
|
|
340
|
+
|
|
341
|
+
test("tuple preserves explicit undefined inside input even for optional-out schemas", () => {
|
|
342
|
+
// The trim only runs for slots PAST `input.length`. An explicit `undefined`
|
|
343
|
+
// value supplied by the caller at index < input.length must survive, even
|
|
344
|
+
// when the schema produces undefined as a valid output (e.g.
|
|
345
|
+
// `z.string().or(z.undefined())`, `z.string().optional()`, `z.undefined()`).
|
|
346
|
+
const orUndefined = z.tuple([z.string(), z.string().or(z.undefined())]);
|
|
347
|
+
const r1 = orUndefined.parse(["alpha", undefined]);
|
|
348
|
+
expect(r1.length).toEqual(2);
|
|
349
|
+
expect(r1[1]).toBeUndefined();
|
|
350
|
+
expect(1 in r1).toEqual(true);
|
|
351
|
+
expect(JSON.stringify(r1)).toEqual('["alpha",null]');
|
|
352
|
+
|
|
353
|
+
// Same for `.optional()`.
|
|
354
|
+
const opt = z.tuple([z.string(), z.string().optional()]);
|
|
355
|
+
const r2 = opt.parse(["alpha", undefined]);
|
|
356
|
+
expect(r2.length).toEqual(2);
|
|
357
|
+
expect(1 in r2).toEqual(true);
|
|
358
|
+
|
|
359
|
+
// Same for `z.undefined()` literal.
|
|
360
|
+
const lit = z.tuple([z.string(), z.undefined()]);
|
|
361
|
+
const r3 = lit.parse(["alpha", undefined]);
|
|
362
|
+
expect(r3.length).toEqual(2);
|
|
363
|
+
expect(1 in r3).toEqual(true);
|
|
364
|
+
|
|
365
|
+
// Mid-tuple explicit undefined surrounded by defined values is also kept.
|
|
366
|
+
const mid = z.tuple([z.string(), z.string().or(z.undefined()), z.string()]);
|
|
367
|
+
const r4 = mid.parse(["alpha", undefined, "gamma"]);
|
|
368
|
+
expect(r4).toEqual(["alpha", undefined, "gamma"]);
|
|
369
|
+
expect(r4.length).toEqual(3);
|
|
370
|
+
expect(1 in r4).toEqual(true);
|
|
371
|
+
});
|
|
372
|
+
|
|
373
|
+
test("tuple does NOT break when a required slot fails past input length", () => {
|
|
374
|
+
// A required slot (no `.optional()` chain, so optout !== "optional") past
|
|
375
|
+
// input length must still surface an issue rather than silently swallowing
|
|
376
|
+
// it. Otherwise we'd accept arbitrarily short tuples for required-tail
|
|
377
|
+
// schemas. The precheck collapses this into a single `too_small`.
|
|
378
|
+
const schema = z.tuple([z.string(), z.string()]);
|
|
379
|
+
expect(schema.safeParse(["alpha"]).error!.issues).toMatchInlineSnapshot(`
|
|
380
|
+
[
|
|
381
|
+
{
|
|
382
|
+
"code": "too_small",
|
|
383
|
+
"inclusive": true,
|
|
384
|
+
"message": "Too small: expected array to have >=2 items",
|
|
385
|
+
"minimum": 2,
|
|
386
|
+
"origin": "array",
|
|
387
|
+
"path": [],
|
|
388
|
+
},
|
|
389
|
+
]
|
|
390
|
+
`);
|
|
391
|
+
});
|
|
392
|
+
|
|
168
393
|
test("tuple with rest schema", () => {
|
|
169
394
|
const myTuple = z.tuple([z.string(), z.number()]).rest(z.boolean());
|
|
170
395
|
expect(myTuple.parse(["asdf", 1234, true, false, true])).toEqual(["asdf", 1234, true, false, true]);
|
|
@@ -181,3 +406,91 @@ test("sparse array input", () => {
|
|
|
181
406
|
const schema = z.tuple([z.string(), z.number()]);
|
|
182
407
|
expect(() => schema.parse(new Array(2))).toThrow();
|
|
183
408
|
});
|
|
409
|
+
|
|
410
|
+
test("under-length tuple emits a single too_small with optStart minimum", () => {
|
|
411
|
+
const allRequired = z.tuple([z.string(), z.string()]);
|
|
412
|
+
expect(allRequired.safeParse(["a"]).error!.issues).toMatchInlineSnapshot(`
|
|
413
|
+
[
|
|
414
|
+
{
|
|
415
|
+
"code": "too_small",
|
|
416
|
+
"inclusive": true,
|
|
417
|
+
"message": "Too small: expected array to have >=2 items",
|
|
418
|
+
"minimum": 2,
|
|
419
|
+
"origin": "array",
|
|
420
|
+
"path": [],
|
|
421
|
+
},
|
|
422
|
+
]
|
|
423
|
+
`);
|
|
424
|
+
expect(allRequired.safeParse([]).error!.issues).toMatchInlineSnapshot(`
|
|
425
|
+
[
|
|
426
|
+
{
|
|
427
|
+
"code": "too_small",
|
|
428
|
+
"inclusive": true,
|
|
429
|
+
"message": "Too small: expected array to have >=2 items",
|
|
430
|
+
"minimum": 2,
|
|
431
|
+
"origin": "array",
|
|
432
|
+
"path": [],
|
|
433
|
+
},
|
|
434
|
+
]
|
|
435
|
+
`);
|
|
436
|
+
|
|
437
|
+
const trailingOptional = z.tuple([z.string(), z.number().optional()]);
|
|
438
|
+
expect(trailingOptional.safeParse([]).error!.issues).toMatchInlineSnapshot(`
|
|
439
|
+
[
|
|
440
|
+
{
|
|
441
|
+
"code": "too_small",
|
|
442
|
+
"inclusive": true,
|
|
443
|
+
"message": "Too small: expected array to have >=1 items",
|
|
444
|
+
"minimum": 1,
|
|
445
|
+
"origin": "array",
|
|
446
|
+
"path": [],
|
|
447
|
+
},
|
|
448
|
+
]
|
|
449
|
+
`);
|
|
450
|
+
|
|
451
|
+
const interiorOptional = z.tuple([z.string(), z.number().optional(), z.string()]);
|
|
452
|
+
expect(interiorOptional.safeParse(["a", 1]).error!.issues).toMatchInlineSnapshot(`
|
|
453
|
+
[
|
|
454
|
+
{
|
|
455
|
+
"code": "too_small",
|
|
456
|
+
"inclusive": true,
|
|
457
|
+
"message": "Too small: expected array to have >=3 items",
|
|
458
|
+
"minimum": 3,
|
|
459
|
+
"origin": "array",
|
|
460
|
+
"path": [],
|
|
461
|
+
},
|
|
462
|
+
]
|
|
463
|
+
`);
|
|
464
|
+
});
|
|
465
|
+
|
|
466
|
+
test("too_big tuple still surfaces element-wise type errors for present indices", () => {
|
|
467
|
+
const schema = z.tuple([z.string(), z.number()]);
|
|
468
|
+
expect(schema.safeParse([1, "x", "extra"]).error!.issues).toMatchInlineSnapshot(`
|
|
469
|
+
[
|
|
470
|
+
{
|
|
471
|
+
"code": "too_big",
|
|
472
|
+
"inclusive": true,
|
|
473
|
+
"maximum": 2,
|
|
474
|
+
"message": "Too big: expected array to have <=2 items",
|
|
475
|
+
"origin": "array",
|
|
476
|
+
"path": [],
|
|
477
|
+
},
|
|
478
|
+
{
|
|
479
|
+
"code": "invalid_type",
|
|
480
|
+
"expected": "string",
|
|
481
|
+
"message": "Invalid input: expected string, received number",
|
|
482
|
+
"path": [
|
|
483
|
+
0,
|
|
484
|
+
],
|
|
485
|
+
},
|
|
486
|
+
{
|
|
487
|
+
"code": "invalid_type",
|
|
488
|
+
"expected": "number",
|
|
489
|
+
"message": "Invalid input: expected number, received string",
|
|
490
|
+
"path": [
|
|
491
|
+
1,
|
|
492
|
+
],
|
|
493
|
+
},
|
|
494
|
+
]
|
|
495
|
+
`);
|
|
496
|
+
});
|
|
@@ -217,3 +217,57 @@ test("z.xor() type inference", () => {
|
|
|
217
217
|
type Result = z.infer<typeof schema>;
|
|
218
218
|
expectTypeOf<Result>().toEqualTypeOf<string | number | boolean>();
|
|
219
219
|
});
|
|
220
|
+
|
|
221
|
+
test("z.union([]) constructs and rejects all input", () => {
|
|
222
|
+
const schema = z.union([]);
|
|
223
|
+
expectTypeOf<z.infer<typeof schema>>().toEqualTypeOf<never>();
|
|
224
|
+
const result = schema.safeParse("anything");
|
|
225
|
+
expect(result.success).toEqual(false);
|
|
226
|
+
if (!result.success) {
|
|
227
|
+
expect(result.error.issues).toMatchInlineSnapshot(`
|
|
228
|
+
[
|
|
229
|
+
{
|
|
230
|
+
"code": "invalid_union",
|
|
231
|
+
"errors": [],
|
|
232
|
+
"message": "Invalid input",
|
|
233
|
+
"path": [],
|
|
234
|
+
},
|
|
235
|
+
]
|
|
236
|
+
`);
|
|
237
|
+
}
|
|
238
|
+
});
|
|
239
|
+
|
|
240
|
+
test("z.xor([]) constructs and rejects all input", () => {
|
|
241
|
+
const schema = z.xor([]);
|
|
242
|
+
expectTypeOf<z.infer<typeof schema>>().toEqualTypeOf<never>();
|
|
243
|
+
const result = schema.safeParse("anything");
|
|
244
|
+
expect(result.success).toEqual(false);
|
|
245
|
+
if (!result.success) {
|
|
246
|
+
expect(result.error.issues).toMatchInlineSnapshot(`
|
|
247
|
+
[
|
|
248
|
+
{
|
|
249
|
+
"code": "invalid_union",
|
|
250
|
+
"errors": [],
|
|
251
|
+
"message": "Invalid input",
|
|
252
|
+
"path": [],
|
|
253
|
+
},
|
|
254
|
+
]
|
|
255
|
+
`);
|
|
256
|
+
}
|
|
257
|
+
});
|
|
258
|
+
|
|
259
|
+
test("z.discriminatedUnion with empty options constructs and rejects", () => {
|
|
260
|
+
const schema = z.discriminatedUnion("type", [] as any);
|
|
261
|
+
const nonObject = schema.safeParse("nope");
|
|
262
|
+
expect(nonObject.success).toEqual(false);
|
|
263
|
+
if (!nonObject.success) {
|
|
264
|
+
expect(nonObject.error.issues[0].code).toBe("invalid_type");
|
|
265
|
+
}
|
|
266
|
+
const obj = schema.safeParse({ type: "x" });
|
|
267
|
+
expect(obj.success).toEqual(false);
|
|
268
|
+
if (!obj.success) {
|
|
269
|
+
expect(obj.error.issues[0].code).toBe("invalid_union");
|
|
270
|
+
expect((obj.error.issues[0] as any).errors).toEqual([]);
|
|
271
|
+
expect((obj.error.issues[0] as any).options).toEqual([]);
|
|
272
|
+
}
|
|
273
|
+
});
|
|
@@ -246,8 +246,23 @@ export function _nanoid<T extends schemas.$ZodNanoID>(
|
|
|
246
246
|
}
|
|
247
247
|
|
|
248
248
|
// CUID
|
|
249
|
+
/**
|
|
250
|
+
* @deprecated CUID v1 is deprecated by its authors due to information leakage
|
|
251
|
+
* (timestamps embedded in the id). Use {@link _cuid2} instead.
|
|
252
|
+
* See https://github.com/paralleldrive/cuid.
|
|
253
|
+
*/
|
|
249
254
|
export type $ZodCUIDParams = StringFormatParams<schemas.$ZodCUID, "when">;
|
|
255
|
+
/**
|
|
256
|
+
* @deprecated CUID v1 is deprecated by its authors due to information leakage
|
|
257
|
+
* (timestamps embedded in the id). Use {@link _cuid2} instead.
|
|
258
|
+
* See https://github.com/paralleldrive/cuid.
|
|
259
|
+
*/
|
|
250
260
|
export type $ZodCheckCUIDParams = CheckStringFormatParams<schemas.$ZodCUID, "when">;
|
|
261
|
+
/**
|
|
262
|
+
* @deprecated CUID v1 is deprecated by its authors due to information leakage
|
|
263
|
+
* (timestamps embedded in the id). Use {@link _cuid2} instead.
|
|
264
|
+
* See https://github.com/paralleldrive/cuid.
|
|
265
|
+
*/
|
|
251
266
|
// @__NO_SIDE_EFFECTS__
|
|
252
267
|
export function _cuid<T extends schemas.$ZodCUID>(
|
|
253
268
|
Class: util.SchemaClass<T>,
|
|
@@ -1192,17 +1207,19 @@ export function _xor<const T extends readonly schemas.$ZodObject[]>(
|
|
|
1192
1207
|
}
|
|
1193
1208
|
|
|
1194
1209
|
// ZodDiscriminatedUnion
|
|
1195
|
-
export interface $ZodTypeDiscriminableInternals extends
|
|
1210
|
+
export interface $ZodTypeDiscriminableInternals<Disc extends string = string>
|
|
1211
|
+
extends schemas.$ZodTypeInternals<unknown, { [K in Disc]?: unknown }> {
|
|
1196
1212
|
propValues: util.PropValues;
|
|
1197
1213
|
}
|
|
1198
1214
|
|
|
1199
|
-
export interface $ZodTypeDiscriminable extends schemas.$ZodType {
|
|
1200
|
-
_zod: $ZodTypeDiscriminableInternals
|
|
1215
|
+
export interface $ZodTypeDiscriminable<Disc extends string = string> extends schemas.$ZodType {
|
|
1216
|
+
_zod: $ZodTypeDiscriminableInternals<Disc>;
|
|
1201
1217
|
}
|
|
1218
|
+
|
|
1202
1219
|
export type $ZodDiscriminatedUnionParams = TypeParams<schemas.$ZodDiscriminatedUnion, "options" | "discriminator">;
|
|
1203
1220
|
// @__NO_SIDE_EFFECTS__
|
|
1204
1221
|
export function _discriminatedUnion<
|
|
1205
|
-
Types extends [$ZodTypeDiscriminable
|
|
1222
|
+
Types extends [$ZodTypeDiscriminable<Disc>, ...$ZodTypeDiscriminable<Disc>[]],
|
|
1206
1223
|
Disc extends string,
|
|
1207
1224
|
>(
|
|
1208
1225
|
Class: util.SchemaClass<schemas.$ZodDiscriminatedUnion>,
|
|
@@ -1633,8 +1650,16 @@ export interface $RefinementCtx<T = unknown> extends schemas.ParsePayload<T> {
|
|
|
1633
1650
|
addIssue(arg: string | $ZodSuperRefineIssue): void;
|
|
1634
1651
|
}
|
|
1635
1652
|
|
|
1653
|
+
export interface $ZodSuperRefineParams {
|
|
1654
|
+
/** If provided, the refinement runs only when this returns `true`. By default, it is skipped if prior parsing produced aborting issues. */
|
|
1655
|
+
when?: ((payload: schemas.ParsePayload) => boolean) | undefined;
|
|
1656
|
+
}
|
|
1657
|
+
|
|
1636
1658
|
// @__NO_SIDE_EFFECTS__
|
|
1637
|
-
export function _superRefine<T>(
|
|
1659
|
+
export function _superRefine<T>(
|
|
1660
|
+
fn: (arg: T, payload: $RefinementCtx<T>) => void | Promise<void>,
|
|
1661
|
+
params?: $ZodSuperRefineParams
|
|
1662
|
+
): checks.$ZodCheck<T> {
|
|
1638
1663
|
const ch = _check<T>((payload) => {
|
|
1639
1664
|
(payload as $RefinementCtx).addIssue = (issue) => {
|
|
1640
1665
|
if (typeof issue === "string") {
|
|
@@ -1652,7 +1677,7 @@ export function _superRefine<T>(fn: (arg: T, payload: $RefinementCtx<T>) => void
|
|
|
1652
1677
|
};
|
|
1653
1678
|
|
|
1654
1679
|
return fn(payload.value, payload as $RefinementCtx<T>);
|
|
1655
|
-
});
|
|
1680
|
+
}, params);
|
|
1656
1681
|
return ch;
|
|
1657
1682
|
}
|
|
1658
1683
|
|
|
@@ -13,7 +13,7 @@ export interface $ZodCheckDef {
|
|
|
13
13
|
error?: errors.$ZodErrorMap<never> | undefined;
|
|
14
14
|
/** If true, no later checks will be executed if this check fails. Default `false`. */
|
|
15
15
|
abort?: boolean | undefined;
|
|
16
|
-
/** If provided,
|
|
16
|
+
/** If provided, the check runs only when this returns `true`. By default, it is skipped if prior parsing produced aborting issues. */
|
|
17
17
|
when?: ((payload: schemas.ParsePayload) => boolean) | undefined;
|
|
18
18
|
}
|
|
19
19
|
|
|
@@ -10,7 +10,7 @@ export interface $constructor<T extends ZodTrait, D = T["_zod"]["def"]> {
|
|
|
10
10
|
}
|
|
11
11
|
|
|
12
12
|
/** A special constant with type `never` */
|
|
13
|
-
export const NEVER: never = Object.freeze({
|
|
13
|
+
export const NEVER: never = /*@__PURE__*/ Object.freeze({
|
|
14
14
|
status: "aborted",
|
|
15
15
|
}) as never;
|
|
16
16
|
|
|
@@ -130,7 +130,22 @@ export interface $ZodConfig {
|
|
|
130
130
|
jitless?: boolean | undefined;
|
|
131
131
|
}
|
|
132
132
|
|
|
133
|
-
|
|
133
|
+
interface GlobalThisWithConfig {
|
|
134
|
+
/**
|
|
135
|
+
* The globalConfig instance shared across both CommonJS and ESM builds.
|
|
136
|
+
* Attached to `globalThis` (mirroring `__zod_globalRegistry`) so that a
|
|
137
|
+
* single config object is used regardless of how Zod is loaded — CJS,
|
|
138
|
+
* ESM, multiple bundles in a monorepo, etc. This means `z.config(...)`
|
|
139
|
+
* applied against any one instance is observed by all of them, and
|
|
140
|
+
* pre-populating it before Zod loads (e.g. `globalThis.__zod_globalConfig
|
|
141
|
+
* = { jitless: true }` in an inline script) takes effect immediately on
|
|
142
|
+
* import.
|
|
143
|
+
*/
|
|
144
|
+
__zod_globalConfig?: $ZodConfig;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
(globalThis as GlobalThisWithConfig).__zod_globalConfig ??= {};
|
|
148
|
+
export const globalConfig: $ZodConfig = (globalThis as GlobalThisWithConfig).__zod_globalConfig!;
|
|
134
149
|
|
|
135
150
|
export function config(newConfig?: Partial<$ZodConfig>): $ZodConfig {
|
|
136
151
|
if (newConfig) Object.assign(globalConfig, newConfig);
|
|
@@ -91,6 +91,7 @@ interface $ZodIssueInvalidUnionNoMatch extends $ZodIssueBase {
|
|
|
91
91
|
readonly errors: $ZodIssue[][];
|
|
92
92
|
readonly input?: unknown;
|
|
93
93
|
readonly discriminator?: string | undefined;
|
|
94
|
+
readonly options?: util.Primitive[];
|
|
94
95
|
readonly inclusive?: true;
|
|
95
96
|
}
|
|
96
97
|
|
|
@@ -291,32 +292,35 @@ export function formatError<T>(error: $ZodError<T>): $ZodFormattedError<T>;
|
|
|
291
292
|
export function formatError<T, U>(error: $ZodError<T>, mapper?: (issue: $ZodIssue) => U): $ZodFormattedError<T, U>;
|
|
292
293
|
export function formatError<T, U>(error: $ZodError<T>, mapper = (issue: $ZodIssue) => issue.message as U) {
|
|
293
294
|
const fieldErrors: $ZodFormattedError<T> = { _errors: [] } as any;
|
|
294
|
-
const processError = (error: { issues: $ZodIssue[] }) => {
|
|
295
|
+
const processError = (error: { issues: $ZodIssue[] }, path: PropertyKey[] = []) => {
|
|
295
296
|
for (const issue of error.issues) {
|
|
296
297
|
if (issue.code === "invalid_union" && issue.errors.length) {
|
|
297
|
-
issue.errors.map((issues) => processError({ issues }));
|
|
298
|
+
issue.errors.map((issues) => processError({ issues }, [...path, ...issue.path]));
|
|
298
299
|
} else if (issue.code === "invalid_key") {
|
|
299
|
-
processError({ issues: issue.issues });
|
|
300
|
+
processError({ issues: issue.issues }, [...path, ...issue.path]);
|
|
300
301
|
} else if (issue.code === "invalid_element") {
|
|
301
|
-
processError({ issues: issue.issues });
|
|
302
|
-
} else if (issue.path.length === 0) {
|
|
303
|
-
(fieldErrors as any)._errors.push(mapper(issue));
|
|
302
|
+
processError({ issues: issue.issues }, [...path, ...issue.path]);
|
|
304
303
|
} else {
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
304
|
+
const fullpath = [...path, ...issue.path];
|
|
305
|
+
if (fullpath.length === 0) {
|
|
306
|
+
(fieldErrors as any)._errors.push(mapper(issue));
|
|
307
|
+
} else {
|
|
308
|
+
let curr: any = fieldErrors;
|
|
309
|
+
let i = 0;
|
|
310
|
+
while (i < fullpath.length) {
|
|
311
|
+
const el = fullpath[i]!;
|
|
312
|
+
const terminal = i === fullpath.length - 1;
|
|
313
|
+
|
|
314
|
+
if (!terminal) {
|
|
315
|
+
curr[el] = curr[el] || { _errors: [] };
|
|
316
|
+
} else {
|
|
317
|
+
curr[el] = curr[el] || { _errors: [] };
|
|
318
|
+
curr[el]._errors.push(mapper(issue));
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
curr = curr[el];
|
|
322
|
+
i++;
|
|
316
323
|
}
|
|
317
|
-
|
|
318
|
-
curr = curr[el];
|
|
319
|
-
i++;
|
|
320
324
|
}
|
|
321
325
|
}
|
|
322
326
|
}
|
|
@@ -332,7 +336,10 @@ export type $ZodErrorTree<T, U = string> = T extends util.Primitive
|
|
|
332
336
|
: T extends any[]
|
|
333
337
|
? { errors: U[]; items?: Array<$ZodErrorTree<T[number], U>> }
|
|
334
338
|
: T extends object
|
|
335
|
-
? {
|
|
339
|
+
? {
|
|
340
|
+
errors: U[];
|
|
341
|
+
properties?: { [K in keyof T]?: $ZodErrorTree<T[K], U> };
|
|
342
|
+
}
|
|
336
343
|
: { errors: U[] };
|
|
337
344
|
|
|
338
345
|
export function treeifyError<T>(error: $ZodError<T>): $ZodErrorTree<T>;
|
|
@@ -343,11 +350,11 @@ export function treeifyError<T, U>(error: $ZodError<T>, mapper = (issue: $ZodIss
|
|
|
343
350
|
for (const issue of error.issues) {
|
|
344
351
|
if (issue.code === "invalid_union" && issue.errors.length) {
|
|
345
352
|
// regular union error
|
|
346
|
-
issue.errors.map((issues) => processError({ issues }, issue.path));
|
|
353
|
+
issue.errors.map((issues) => processError({ issues }, [...path, ...issue.path]));
|
|
347
354
|
} else if (issue.code === "invalid_key") {
|
|
348
|
-
processError({ issues: issue.issues }, issue.path);
|
|
355
|
+
processError({ issues: issue.issues }, [...path, ...issue.path]);
|
|
349
356
|
} else if (issue.code === "invalid_element") {
|
|
350
|
-
processError({ issues: issue.issues }, issue.path);
|
|
357
|
+
processError({ issues: issue.issues }, [...path, ...issue.path]);
|
|
351
358
|
} else {
|
|
352
359
|
const fullpath = [...path, ...issue.path];
|
|
353
360
|
if (fullpath.length === 0) {
|