@wecode-ai/weibo-openclaw-plugin 2.2.3 → 2.2.5
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 +4 -1
- package/node_modules/tar/dist/commonjs/pack.d.ts.map +1 -1
- package/node_modules/tar/dist/commonjs/pack.js +41 -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 +4 -1
- package/node_modules/tar/dist/esm/pack.d.ts.map +1 -1
- package/node_modules/tar/dist/esm/pack.js +41 -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 +3 -2
- package/skills/weibo-creator/SKILL.md +296 -0
- package/skills/weibo-creator/references/creator-v-upgrade.md +27 -0
- package/skills/weibo-creator/scripts/weibo-creator.js +212 -0
- package/skills/weibo-cron/SKILL.md +1 -1
- package/skills/weibo-cron/references/HEARTBEAT-PROCESS.md +1 -1
- package/skills/weibo-crowd/SKILL.md +1 -1
- package/skills/weibo-crowd/references/SILICON-TEAHOUSE-RULES.md +3 -2
- 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
|
@@ -143,6 +143,12 @@ test("assignability", () => {
|
|
|
143
143
|
z.unknown().pipe(z.number()) satisfies z.core.$ZodPipe;
|
|
144
144
|
z.unknown().pipe(z.number()) satisfies z.ZodPipe;
|
|
145
145
|
|
|
146
|
+
// $ZodPreprocess
|
|
147
|
+
z.preprocess((v) => v, z.number()) satisfies z.core.$ZodPreprocess;
|
|
148
|
+
z.preprocess((v) => v, z.number()) satisfies z.ZodPreprocess;
|
|
149
|
+
z.preprocess((v) => v, z.number()) satisfies z.core.$ZodPipe<z.core.$ZodTransform, z.ZodNumber>;
|
|
150
|
+
z.preprocess((v) => v, z.number()) satisfies z.ZodPipe<z.core.$ZodTransform, z.ZodNumber>;
|
|
151
|
+
|
|
146
152
|
// $ZodSuccess
|
|
147
153
|
z.success(z.string()) satisfies z.core.$ZodSuccess;
|
|
148
154
|
z.success(z.string()) satisfies z.ZodSuccess;
|
|
@@ -128,7 +128,9 @@ test("native enum", () => {
|
|
|
128
128
|
fruit: z.nativeEnum(Fruits).catch(Fruits.apple),
|
|
129
129
|
});
|
|
130
130
|
|
|
131
|
+
// Absent keys flow through to the catch handler.
|
|
131
132
|
expect(schema.parse({})).toEqual({ fruit: Fruits.apple });
|
|
133
|
+
expect(schema.parse({}, { jitless: true })).toEqual({ fruit: Fruits.apple });
|
|
132
134
|
expect(schema.parse({ fruit: 15 })).toEqual({ fruit: Fruits.apple });
|
|
133
135
|
});
|
|
134
136
|
|
|
@@ -138,6 +140,7 @@ test("enum", () => {
|
|
|
138
140
|
});
|
|
139
141
|
|
|
140
142
|
expect(schema.parse({})).toEqual({ fruit: "apple" });
|
|
143
|
+
expect(schema.parse({}, { jitless: true })).toEqual({ fruit: "apple" });
|
|
141
144
|
expect(schema.parse({ fruit: true })).toEqual({ fruit: "apple" });
|
|
142
145
|
expect(schema.parse({ fruit: 15 })).toEqual({ fruit: "apple" });
|
|
143
146
|
});
|
|
@@ -274,3 +277,50 @@ test("direction-aware catch", () => {
|
|
|
274
277
|
// But valid values should still work in reverse
|
|
275
278
|
expect(z.encode(schema, "world")).toBe("world");
|
|
276
279
|
});
|
|
280
|
+
|
|
281
|
+
test("optional clobbers catch through pipe boundaries", () => {
|
|
282
|
+
expect(
|
|
283
|
+
z
|
|
284
|
+
.string()
|
|
285
|
+
.catch("X")
|
|
286
|
+
.transform((s) => s + "!")
|
|
287
|
+
.optional()
|
|
288
|
+
.parse(undefined)
|
|
289
|
+
).toBeUndefined();
|
|
290
|
+
expect(z.string().catch("X").pipe(z.string()).optional().parse(undefined)).toBeUndefined();
|
|
291
|
+
expect(
|
|
292
|
+
z
|
|
293
|
+
.string()
|
|
294
|
+
.catch("X")
|
|
295
|
+
.transform((s) => s + "!")
|
|
296
|
+
.transform((s) => s.toLowerCase())
|
|
297
|
+
.optional()
|
|
298
|
+
.parse(undefined)
|
|
299
|
+
).toBeUndefined();
|
|
300
|
+
expect(
|
|
301
|
+
z
|
|
302
|
+
.object({
|
|
303
|
+
a: z
|
|
304
|
+
.string()
|
|
305
|
+
.catch("X")
|
|
306
|
+
.transform((s) => s + "!")
|
|
307
|
+
.optional(),
|
|
308
|
+
})
|
|
309
|
+
.parse({})
|
|
310
|
+
).toEqual({});
|
|
311
|
+
|
|
312
|
+
expect(
|
|
313
|
+
z
|
|
314
|
+
.string()
|
|
315
|
+
.catch("X")
|
|
316
|
+
.transform((s) => s + "!")
|
|
317
|
+
.parse("hi")
|
|
318
|
+
).toBe("hi!");
|
|
319
|
+
expect(
|
|
320
|
+
z
|
|
321
|
+
.string()
|
|
322
|
+
.catch("X")
|
|
323
|
+
.transform((s) => s + "!")
|
|
324
|
+
.parse(123)
|
|
325
|
+
).toBe("X!");
|
|
326
|
+
});
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { expect, expectTypeOf, test } from "vitest";
|
|
1
|
+
import { describe, expect, expectTypeOf, test } from "vitest";
|
|
2
2
|
import * as z from "zod/v4";
|
|
3
3
|
|
|
4
4
|
const isoDateCodec = z.codec(
|
|
@@ -560,3 +560,144 @@ test("async codec functionality", async () => {
|
|
|
560
560
|
const mixedResult = await z.decodeAsync(mixedCodec, "123");
|
|
561
561
|
expect(mixedResult).toBe(123);
|
|
562
562
|
});
|
|
563
|
+
|
|
564
|
+
test("invertCodec basic", () => {
|
|
565
|
+
const inverted = z.invertCodec(isoDateCodec);
|
|
566
|
+
|
|
567
|
+
const testDate = new Date("2024-01-15T10:30:00.000Z");
|
|
568
|
+
const decoded = z.decode(inverted, testDate);
|
|
569
|
+
expect(typeof decoded).toBe("string");
|
|
570
|
+
expect(decoded).toBe("2024-01-15T10:30:00.000Z");
|
|
571
|
+
|
|
572
|
+
const encoded = z.encode(inverted, "2024-01-15T10:30:00.000Z");
|
|
573
|
+
expect(encoded).toBeInstanceOf(Date);
|
|
574
|
+
expect(encoded.toISOString()).toBe("2024-01-15T10:30:00.000Z");
|
|
575
|
+
});
|
|
576
|
+
|
|
577
|
+
test("invertCodec round trip", () => {
|
|
578
|
+
const inverted = z.invertCodec(isoDateCodec);
|
|
579
|
+
const testDate = new Date("2024-06-01T12:00:00.000Z");
|
|
580
|
+
|
|
581
|
+
const toStr = z.decode(inverted, testDate);
|
|
582
|
+
const backToDate = z.encode(inverted, toStr);
|
|
583
|
+
expect(backToDate.toISOString()).toBe(testDate.toISOString());
|
|
584
|
+
});
|
|
585
|
+
|
|
586
|
+
test("invertCodec types", () => {
|
|
587
|
+
const inverted = z.invertCodec(isoDateCodec);
|
|
588
|
+
|
|
589
|
+
type InvIn = z.input<typeof inverted>;
|
|
590
|
+
type InvOut = z.output<typeof inverted>;
|
|
591
|
+
expectTypeOf<InvIn>().toEqualTypeOf<Date>();
|
|
592
|
+
expectTypeOf<InvOut>().toEqualTypeOf<string>();
|
|
593
|
+
});
|
|
594
|
+
|
|
595
|
+
test("invertCodec is its own inverse", () => {
|
|
596
|
+
const doubleInverted = z.invertCodec(z.invertCodec(isoDateCodec));
|
|
597
|
+
const testIsoString = "2024-03-10T08:00:00.000Z";
|
|
598
|
+
|
|
599
|
+
const decoded = z.decode(doubleInverted, testIsoString);
|
|
600
|
+
expect(decoded).toBeInstanceOf(Date);
|
|
601
|
+
expect(decoded.toISOString()).toBe(testIsoString);
|
|
602
|
+
|
|
603
|
+
const encoded = z.encode(doubleInverted, decoded);
|
|
604
|
+
expect(encoded).toBe(testIsoString);
|
|
605
|
+
});
|
|
606
|
+
|
|
607
|
+
test("invertCodec with custom codec", () => {
|
|
608
|
+
const intToString = z.codec(z.int(), z.string().regex(/^\d+$/), {
|
|
609
|
+
decode: (num) => num.toString(),
|
|
610
|
+
encode: (str) => Number.parseInt(str, 10),
|
|
611
|
+
});
|
|
612
|
+
|
|
613
|
+
const stringToInt = z.invertCodec(intToString);
|
|
614
|
+
const result = z.decode(stringToInt, "42");
|
|
615
|
+
expect(result).toBe(42);
|
|
616
|
+
|
|
617
|
+
const back = z.encode(stringToInt, 42);
|
|
618
|
+
expect(back).toBe("42");
|
|
619
|
+
});
|
|
620
|
+
|
|
621
|
+
describe("context immutability", () => {
|
|
622
|
+
test("decode/encode", () => {
|
|
623
|
+
const stringToDateCodec = z.codec(z.iso.datetime(), z.date(), {
|
|
624
|
+
decode: (isoString) => new Date(isoString),
|
|
625
|
+
encode: (date) => date.toISOString(),
|
|
626
|
+
});
|
|
627
|
+
|
|
628
|
+
const ctx = { reportInput: true } as const;
|
|
629
|
+
|
|
630
|
+
const result1 = z.decode(stringToDateCodec, "2024-01-15T10:30:00.000Z", ctx);
|
|
631
|
+
expect(result1).toBeInstanceOf(Date);
|
|
632
|
+
|
|
633
|
+
expect(ctx).toEqual({ reportInput: true });
|
|
634
|
+
expect("async" in ctx).toBe(false);
|
|
635
|
+
expect("direction" in ctx).toBe(false);
|
|
636
|
+
|
|
637
|
+
const result2 = z.decode(stringToDateCodec, "2024-12-25T15:45:30.123Z", ctx);
|
|
638
|
+
expect(result2).toBeInstanceOf(Date);
|
|
639
|
+
|
|
640
|
+
expect(ctx).toEqual({ reportInput: true });
|
|
641
|
+
expect("async" in ctx).toBe(false);
|
|
642
|
+
expect("direction" in ctx).toBe(false);
|
|
643
|
+
|
|
644
|
+
z.encode(stringToDateCodec, new Date("2024-01-01T00:00:00.000Z"), ctx);
|
|
645
|
+
expect(ctx).toEqual({ reportInput: true });
|
|
646
|
+
expect("direction" in ctx).toBe(false);
|
|
647
|
+
|
|
648
|
+
z.safeEncode(stringToDateCodec, new Date("2024-01-01T00:00:00.000Z"), ctx);
|
|
649
|
+
expect(ctx).toEqual({ reportInput: true });
|
|
650
|
+
expect("direction" in ctx).toBe(false);
|
|
651
|
+
});
|
|
652
|
+
|
|
653
|
+
test("parse functions", () => {
|
|
654
|
+
const schema = z.string().min(1);
|
|
655
|
+
const ctx = { reportInput: true } as const;
|
|
656
|
+
|
|
657
|
+
z.parse(schema, "asdf", ctx);
|
|
658
|
+
expect(ctx).toEqual({ reportInput: true });
|
|
659
|
+
expect("async" in ctx).toBe(false);
|
|
660
|
+
|
|
661
|
+
z.safeParse(schema, "asdf", ctx);
|
|
662
|
+
expect(ctx).toEqual({ reportInput: true });
|
|
663
|
+
expect("async" in ctx).toBe(false);
|
|
664
|
+
});
|
|
665
|
+
|
|
666
|
+
test("async functions", async () => {
|
|
667
|
+
const stringToDateCodec = z.codec(z.iso.datetime(), z.date(), {
|
|
668
|
+
decode: (isoString) => new Date(isoString),
|
|
669
|
+
encode: (date) => date.toISOString(),
|
|
670
|
+
});
|
|
671
|
+
|
|
672
|
+
const ctx = { reportInput: true } as const;
|
|
673
|
+
|
|
674
|
+
const schema = z.string();
|
|
675
|
+
await z.parseAsync(schema, "asdf", ctx);
|
|
676
|
+
expect(ctx).toEqual({ reportInput: true });
|
|
677
|
+
expect("async" in ctx).toBe(false);
|
|
678
|
+
|
|
679
|
+
await z.safeParseAsync(schema, "asdf", ctx);
|
|
680
|
+
expect(ctx).toEqual({ reportInput: true });
|
|
681
|
+
expect("async" in ctx).toBe(false);
|
|
682
|
+
|
|
683
|
+
await z.decodeAsync(stringToDateCodec, "2024-01-15T10:30:00.000Z", ctx);
|
|
684
|
+
expect(ctx).toEqual({ reportInput: true });
|
|
685
|
+
expect("async" in ctx).toBe(false);
|
|
686
|
+
expect("direction" in ctx).toBe(false);
|
|
687
|
+
|
|
688
|
+
await z.encodeAsync(stringToDateCodec, new Date("2024-01-01T00:00:00.000Z"), ctx);
|
|
689
|
+
expect(ctx).toEqual({ reportInput: true });
|
|
690
|
+
expect("async" in ctx).toBe(false);
|
|
691
|
+
expect("direction" in ctx).toBe(false);
|
|
692
|
+
|
|
693
|
+
await z.safeDecodeAsync(stringToDateCodec, "2024-01-15T10:30:00.000Z", ctx);
|
|
694
|
+
expect(ctx).toEqual({ reportInput: true });
|
|
695
|
+
expect("async" in ctx).toBe(false);
|
|
696
|
+
expect("direction" in ctx).toBe(false);
|
|
697
|
+
|
|
698
|
+
await z.safeEncodeAsync(stringToDateCodec, new Date("2024-01-01T00:00:00.000Z"), ctx);
|
|
699
|
+
expect(ctx).toEqual({ reportInput: true });
|
|
700
|
+
expect("async" in ctx).toBe(false);
|
|
701
|
+
expect("direction" in ctx).toBe(false);
|
|
702
|
+
});
|
|
703
|
+
});
|
|
@@ -332,6 +332,50 @@ test("defaulted array schema returns shallow clone", () => {
|
|
|
332
332
|
expect(result1).toEqual(result2);
|
|
333
333
|
});
|
|
334
334
|
|
|
335
|
+
test("defaulted Map schema returns shallow clone", () => {
|
|
336
|
+
const schema = z.map(z.string(), z.number()).default(new Map([["a", 1]]));
|
|
337
|
+
const result1 = schema.parse(undefined);
|
|
338
|
+
const result2 = schema.parse(undefined);
|
|
339
|
+
expect(result1).not.toBe(result2);
|
|
340
|
+
expect(result1).toEqual(result2);
|
|
341
|
+
});
|
|
342
|
+
|
|
343
|
+
test("defaulted Set schema returns shallow clone", () => {
|
|
344
|
+
const schema = z.set(z.string()).default(new Set(["x"]));
|
|
345
|
+
const result1 = schema.parse(undefined);
|
|
346
|
+
const result2 = schema.parse(undefined);
|
|
347
|
+
expect(result1).not.toBe(result2);
|
|
348
|
+
expect(result1).toEqual(result2);
|
|
349
|
+
});
|
|
350
|
+
|
|
351
|
+
test("mutations on defaulted Map do not affect subsequent parses", () => {
|
|
352
|
+
const schema = z.map(z.string(), z.number()).default(new Map());
|
|
353
|
+
const result1 = schema.parse(undefined);
|
|
354
|
+
const result2 = schema.parse(undefined);
|
|
355
|
+
result1.set("key1", 1);
|
|
356
|
+
result2.set("key2", 2);
|
|
357
|
+
expect(result1.size).toBe(1);
|
|
358
|
+
expect(result1.get("key1")).toBe(1);
|
|
359
|
+
expect(result1.has("key2")).toBe(false);
|
|
360
|
+
expect(result2.size).toBe(1);
|
|
361
|
+
expect(result2.get("key2")).toBe(2);
|
|
362
|
+
expect(result2.has("key1")).toBe(false);
|
|
363
|
+
});
|
|
364
|
+
|
|
365
|
+
test("mutations on defaulted Set do not affect subsequent parses", () => {
|
|
366
|
+
const schema = z.set(z.string()).default(new Set());
|
|
367
|
+
const result1 = schema.parse(undefined);
|
|
368
|
+
const result2 = schema.parse(undefined);
|
|
369
|
+
result1.add("item1");
|
|
370
|
+
result2.add("item2");
|
|
371
|
+
expect(result1.size).toBe(1);
|
|
372
|
+
expect(result1.has("item1")).toBe(true);
|
|
373
|
+
expect(result1.has("item2")).toBe(false);
|
|
374
|
+
expect(result2.size).toBe(1);
|
|
375
|
+
expect(result2.has("item2")).toBe(true);
|
|
376
|
+
expect(result2.has("item1")).toBe(false);
|
|
377
|
+
});
|
|
378
|
+
|
|
335
379
|
test("direction-aware defaults", () => {
|
|
336
380
|
const schema = z.string().default("hello");
|
|
337
381
|
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
import { expect, test } from "vitest";
|
|
2
|
+
import * as z from "zod/v4";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Schema methods are exposed in a way that works when detached from the
|
|
6
|
+
* schema instance — `const opt = schema.optional; opt()` must produce a
|
|
7
|
+
* working `ZodOptional`, not a corrupt one. This pattern is used in real
|
|
8
|
+
* code (e.g. `arr.map(schema.parse)`, `arr.map(schema.optional)`,
|
|
9
|
+
* destructuring inside utility functions).
|
|
10
|
+
*
|
|
11
|
+
* This test caught a regression in colinhacks/zod#5870 where a memory
|
|
12
|
+
* optimization moved methods to the prototype and made `this`-binding
|
|
13
|
+
* required, silently breaking any detached usage.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
const probeArgs: Record<string, unknown[]> = {
|
|
17
|
+
// ZodType
|
|
18
|
+
optional: [],
|
|
19
|
+
exactOptional: [],
|
|
20
|
+
nullable: [],
|
|
21
|
+
nullish: [],
|
|
22
|
+
array: [],
|
|
23
|
+
describe: ["x"],
|
|
24
|
+
brand: [],
|
|
25
|
+
readonly: [],
|
|
26
|
+
default: ["fallback"],
|
|
27
|
+
catch: ["fallback"],
|
|
28
|
+
// _ZodString
|
|
29
|
+
min: [1],
|
|
30
|
+
max: [10],
|
|
31
|
+
length: [5],
|
|
32
|
+
nonempty: [],
|
|
33
|
+
trim: [],
|
|
34
|
+
toLowerCase: [],
|
|
35
|
+
toUpperCase: [],
|
|
36
|
+
// ZodString format methods
|
|
37
|
+
email: [],
|
|
38
|
+
url: [],
|
|
39
|
+
uuid: [],
|
|
40
|
+
cuid: [],
|
|
41
|
+
cuid2: [],
|
|
42
|
+
ulid: [],
|
|
43
|
+
base64: [],
|
|
44
|
+
base64url: [],
|
|
45
|
+
ipv4: [],
|
|
46
|
+
ipv6: [],
|
|
47
|
+
// ZodNumber
|
|
48
|
+
int: [],
|
|
49
|
+
positive: [],
|
|
50
|
+
negative: [],
|
|
51
|
+
finite: [],
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
test("detached parse-family methods work without `this` binding", () => {
|
|
55
|
+
const schema = z.string();
|
|
56
|
+
const { parse, safeParse } = schema;
|
|
57
|
+
|
|
58
|
+
expect(parse("hello")).toBe("hello");
|
|
59
|
+
expect(safeParse("hello").success).toBe(true);
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
test("detached schema.optional() returns a working ZodOptional", () => {
|
|
63
|
+
const schema = z.string();
|
|
64
|
+
const opt = schema.optional;
|
|
65
|
+
|
|
66
|
+
const detached = opt();
|
|
67
|
+
|
|
68
|
+
expect(detached).toBeInstanceOf(z.ZodOptional);
|
|
69
|
+
expect(detached.safeParse("hello").success).toBe(true);
|
|
70
|
+
expect(detached.safeParse(undefined).success).toBe(true);
|
|
71
|
+
expect(detached.safeParse(123).success).toBe(false);
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
test("detached schema.nullable() returns a working ZodNullable", () => {
|
|
75
|
+
const schema = z.string();
|
|
76
|
+
const nul = schema.nullable;
|
|
77
|
+
|
|
78
|
+
const detached = nul();
|
|
79
|
+
|
|
80
|
+
expect(detached).toBeInstanceOf(z.ZodNullable);
|
|
81
|
+
expect(detached.safeParse("hello").success).toBe(true);
|
|
82
|
+
expect(detached.safeParse(null).success).toBe(true);
|
|
83
|
+
expect(detached.safeParse(123).success).toBe(false);
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
test("detached schema.array() returns a working ZodArray", () => {
|
|
87
|
+
const schema = z.string();
|
|
88
|
+
const arr = schema.array;
|
|
89
|
+
|
|
90
|
+
const detached = arr();
|
|
91
|
+
|
|
92
|
+
expect(detached).toBeInstanceOf(z.ZodArray);
|
|
93
|
+
expect(detached.safeParse(["a", "b"]).success).toBe(true);
|
|
94
|
+
expect(detached.safeParse([1, 2]).success).toBe(false);
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
test("detached schema.describe() returns a described schema", () => {
|
|
98
|
+
const schema = z.string();
|
|
99
|
+
const describe = schema.describe;
|
|
100
|
+
|
|
101
|
+
const described = describe("hello world");
|
|
102
|
+
|
|
103
|
+
expect(described.description).toBe("hello world");
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
test("detached refinement still validates", () => {
|
|
107
|
+
const schema = z.string();
|
|
108
|
+
const refine = schema.refine;
|
|
109
|
+
|
|
110
|
+
const refined = refine((s: string) => s.startsWith("x"), "must start with x");
|
|
111
|
+
|
|
112
|
+
expect(refined.safeParse("xhello").success).toBe(true);
|
|
113
|
+
expect(refined.safeParse("hello").success).toBe(false);
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
test("detached chained calls work — schema.optional then parse", () => {
|
|
117
|
+
const schema = z.string();
|
|
118
|
+
const opt = schema.optional;
|
|
119
|
+
const optionalSchema = opt();
|
|
120
|
+
const { parse } = optionalSchema;
|
|
121
|
+
|
|
122
|
+
expect(parse("hi")).toBe("hi");
|
|
123
|
+
expect(parse(undefined)).toBe(undefined);
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
test("detached parse can be called as a free function", () => {
|
|
127
|
+
const schema = z.string();
|
|
128
|
+
const parse = schema.parse;
|
|
129
|
+
const inputs = ["a", "b", "c"];
|
|
130
|
+
|
|
131
|
+
const results = inputs.map((v) => parse(v));
|
|
132
|
+
|
|
133
|
+
expect(results).toEqual(["a", "b", "c"]);
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
test("detached methods on z.number() work", () => {
|
|
137
|
+
const schema = z.number();
|
|
138
|
+
|
|
139
|
+
const min = schema.min;
|
|
140
|
+
const max = schema.max;
|
|
141
|
+
const positive = schema.positive;
|
|
142
|
+
|
|
143
|
+
expect(min(5).safeParse(3).success).toBe(false);
|
|
144
|
+
expect(max(5).safeParse(7).success).toBe(false);
|
|
145
|
+
expect(positive().safeParse(-1).success).toBe(false);
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
test("detached object methods work", () => {
|
|
149
|
+
const schema = z.object({ a: z.string(), b: z.number() });
|
|
150
|
+
|
|
151
|
+
const pick = schema.pick;
|
|
152
|
+
const omit = schema.omit;
|
|
153
|
+
const partial = schema.partial;
|
|
154
|
+
const extend = schema.extend;
|
|
155
|
+
|
|
156
|
+
expect(Object.keys(pick({ a: true })._zod.def.shape)).toEqual(["a"]);
|
|
157
|
+
expect(Object.keys(omit({ a: true })._zod.def.shape)).toEqual(["b"]);
|
|
158
|
+
expect(partial().safeParse({}).success).toBe(true);
|
|
159
|
+
const extended = extend({ c: z.boolean() });
|
|
160
|
+
expect(Object.keys(extended._zod.def.shape).sort()).toEqual(["a", "b", "c"]);
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
// Sweep across many builder methods at once. If any of them break with the
|
|
164
|
+
// `const m = schema.foo; m(...)` pattern, this test will report which.
|
|
165
|
+
test("broad sweep: detaching builder methods does not throw or produce a corrupt schema", () => {
|
|
166
|
+
const stringSchema = z.string();
|
|
167
|
+
const numberSchema = z.number();
|
|
168
|
+
|
|
169
|
+
const broken: Array<{ method: string; reason: string }> = [];
|
|
170
|
+
|
|
171
|
+
for (const [methodName, args] of Object.entries(probeArgs)) {
|
|
172
|
+
const target: any = methodName in stringSchema ? stringSchema : methodName in numberSchema ? numberSchema : null;
|
|
173
|
+
if (!target) continue;
|
|
174
|
+
|
|
175
|
+
const detached = target[methodName] as Function | undefined;
|
|
176
|
+
if (typeof detached !== "function") continue;
|
|
177
|
+
|
|
178
|
+
try {
|
|
179
|
+
const result = detached(...args);
|
|
180
|
+
// If the detached call returned a schema, sanity-check it parses
|
|
181
|
+
// its base type. (e.g. `optional()` should accept its inner type.)
|
|
182
|
+
if (result && typeof result === "object" && "_zod" in result && typeof (result as any).safeParse === "function") {
|
|
183
|
+
const probeValue = target === stringSchema ? "x" : 1;
|
|
184
|
+
const r = (result as any).safeParse(probeValue);
|
|
185
|
+
// success or a clean failure are both fine — we only fail on throw or
|
|
186
|
+
// on a schema with corrupt internal state (innerType undefined etc).
|
|
187
|
+
if (r === undefined || (typeof r === "object" && !("success" in r))) {
|
|
188
|
+
broken.push({ method: methodName, reason: "safeParse returned malformed result" });
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
} catch (err: any) {
|
|
192
|
+
broken.push({ method: methodName, reason: err?.message ?? String(err) });
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
expect(broken).toEqual([]);
|
|
197
|
+
});
|
|
@@ -158,10 +158,14 @@ test("invalid discriminator value", () => {
|
|
|
158
158
|
"errors": [],
|
|
159
159
|
"note": "No matching discriminator",
|
|
160
160
|
"discriminator": "type",
|
|
161
|
+
"options": [
|
|
162
|
+
"a",
|
|
163
|
+
"b"
|
|
164
|
+
],
|
|
161
165
|
"path": [
|
|
162
166
|
"type"
|
|
163
167
|
],
|
|
164
|
-
"message": "Invalid
|
|
168
|
+
"message": "Invalid discriminator value. Expected 'a' | 'b'"
|
|
165
169
|
}
|
|
166
170
|
]],
|
|
167
171
|
"success": false,
|
|
@@ -260,6 +264,9 @@ test("valid discriminator value, invalid data", () => {
|
|
|
260
264
|
});
|
|
261
265
|
|
|
262
266
|
test("wrong schema - missing discriminator", () => {
|
|
267
|
+
// @ts-expect-error missing discriminator property
|
|
268
|
+
z.discriminatedUnion("type", [z.object({ value: z.string() })]);
|
|
269
|
+
|
|
263
270
|
try {
|
|
264
271
|
z.discriminatedUnion("type", [
|
|
265
272
|
z.object({ type: z.literal("a"), a: z.string() }),
|
|
@@ -659,3 +666,29 @@ test("def", () => {
|
|
|
659
666
|
expect(schema.def.discriminator).toEqual("type");
|
|
660
667
|
expect(schema.def.unionFallback).toEqual(true);
|
|
661
668
|
});
|
|
669
|
+
|
|
670
|
+
test("encode with codec discriminator", () => {
|
|
671
|
+
const codec1 = z.codec(z.literal(1), z.literal("one"), {
|
|
672
|
+
decode: () => "one" as const,
|
|
673
|
+
encode: () => 1 as const,
|
|
674
|
+
});
|
|
675
|
+
|
|
676
|
+
const codec2 = z.codec(z.literal(2), z.literal("two"), {
|
|
677
|
+
decode: () => "two" as const,
|
|
678
|
+
encode: () => 2 as const,
|
|
679
|
+
});
|
|
680
|
+
|
|
681
|
+
const schema = z.discriminatedUnion("type", [
|
|
682
|
+
z.object({ type: codec1, value: z.string() }),
|
|
683
|
+
z.object({ type: codec2, value: z.number() }),
|
|
684
|
+
]);
|
|
685
|
+
|
|
686
|
+
// decode (forward) should work
|
|
687
|
+
const decoded = schema.decode({ type: 1, value: "hello" });
|
|
688
|
+
expect(decoded).toEqual({ type: "one", value: "hello" });
|
|
689
|
+
|
|
690
|
+
// encode (backward) should also work — the discriminator values differ
|
|
691
|
+
// between forward (1, 2) and backward ("one", "two") directions
|
|
692
|
+
const encoded = z.encode(schema, { type: "one", value: "hello" });
|
|
693
|
+
expect(encoded).toEqual({ type: 1, value: "hello" });
|
|
694
|
+
});
|