Skip to content

Commit

Permalink
Add overload
Browse files Browse the repository at this point in the history
  • Loading branch information
colinhacks committed Apr 29, 2024
1 parent cb33faf commit f594c84
Show file tree
Hide file tree
Showing 6 changed files with 105 additions and 17 deletions.
28 changes: 25 additions & 3 deletions deno/lib/__tests__/json.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,17 @@ import * as z from "../index.ts";
// @ts-ignore TS2304
const isDeno = typeof Deno === "object";

test("overload types", () => {
const schema = z.string().json();
z.util.assertEqual<typeof schema, z.ZodString>(true);
const schema2 = z.string().json(z.number());
z.util.assertEqual<
typeof schema2,
z.ZodPipeline<z.ZodEffects<z.ZodString, any, string>, z.ZodNumber>
>(true);
const r2 = schema2.parse("12");
z.util.assertEqual<number, typeof r2>(true);
});
test("parse string to json", async () => {
const Env = z.object({
myJsonConfig: z.string().json(z.object({ foo: z.number() })),
Expand Down Expand Up @@ -62,9 +73,7 @@ test("parse string to json", async () => {
{
code: "invalid_string",
validation: "json",
message: isDeno
? `Unexpected token 'T', "This is no"... is not valid JSON`
: "Unexpected token T in JSON at position 0",
message: "Invalid json",
path: ["myJsonConfig"],
},
{
Expand All @@ -78,3 +87,16 @@ test("parse string to json", async () => {
},
});
});

test("no argument", () => {
const schema = z.string().json();
z.util.assertEqual<typeof schema, z.ZodString>(true);
z.string().json().parse(`{}`);
z.string().json().parse(`null`);
z.string().json().parse(`12`);
z.string().json().parse(`{ "test": "test"}`);
expect(() => z.string().json().parse(`asdf`)).toThrow();
expect(() => z.string().json().parse(`{ "test": undefined }`)).toThrow();
expect(() => z.string().json().parse(`{ "test": 12n }`)).toThrow();
expect(() => z.string().json().parse(`{ test: "test" }`)).toThrow();
});
32 changes: 28 additions & 4 deletions deno/lib/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -569,6 +569,7 @@ export type ZodStringCheck =
precision: number | null;
message?: string;
}
<<<<<<< HEAD
| {
kind: "date";
// withDate: true;
Expand All @@ -582,6 +583,10 @@ export type ZodStringCheck =
| { kind: "duration"; message?: string }
| { kind: "ip"; version?: IpVersion; message?: string }
| { kind: "base64"; message?: string };
=======
| { kind: "ip"; version?: IpVersion; message?: string }
| { kind: "json"; message?: string };
>>>>>>> ca9c3e1 (Add overload)

export interface ZodStringDef extends ZodTypeDef {
checks: ZodStringCheck[];
Expand Down Expand Up @@ -1019,12 +1024,23 @@ export class ZodString extends ZodType<string, ZodStringDef, string> {
});
status.dirty();
}
<<<<<<< HEAD
} else if (check.kind === "base64") {
if (!base64Regex.test(input.data)) {
ctx = this._getOrReturnCtx(input, ctx);
addIssueToContext(ctx, {
validation: "base64",
code: ZodIssueCode.invalid_string,
=======
} else if (check.kind === "json") {
try {
JSON.parse(input.data);
} catch (err) {
ctx = this._getOrReturnCtx(input, ctx);
addIssueToContext(ctx, {
code: ZodIssueCode.invalid_string,
validation: "json",
>>>>>>> ca9c3e1 (Add overload)
message: check.message,
});
status.dirty();
Expand Down Expand Up @@ -1199,19 +1215,27 @@ export class ZodString extends ZodType<string, ZodStringDef, string> {
});
}

json<T extends ZodTypeAny>(shape: T) {
return this.transform((val, ctx) => {
json(message?: errorUtil.ErrMessage): this;
json<T extends ZodTypeAny>(
pipeTo: T
): ZodPipeline<ZodEffects<this, any, input<this>>, T>;
json(input?: errorUtil.ErrMessage | ZodTypeAny) {
if (!(input instanceof ZodType)) {
return this._addCheck({ kind: "json", ...errorUtil.errToObj(input) });
}
const schema = this.transform((val, ctx) => {
try {
return JSON.parse(val);
} catch (error: unknown) {
ctx.addIssue({
code: ZodIssueCode.invalid_string,
validation: "json",
message: (error as Error).message,
// message: (error as Error).message,
});
return NEVER;
}
}).pipe(shape);
});
return input ? schema.pipe(input) : schema;
}

min(minLength: number, message?: errorUtil.ErrMessage) {
Expand Down
2 changes: 1 addition & 1 deletion playground.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
import { z } from "./src/index";

z.string().parse("asdf");
z;
28 changes: 25 additions & 3 deletions src/__tests__/json.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,17 @@ import * as z from "../index";
// @ts-ignore TS2304
const isDeno = typeof Deno === "object";

test("overload types", () => {
const schema = z.string().json();
z.util.assertEqual<typeof schema, z.ZodString>(true);
const schema2 = z.string().json(z.number());
z.util.assertEqual<
typeof schema2,
z.ZodPipeline<z.ZodEffects<z.ZodString, any, string>, z.ZodNumber>
>(true);
const r2 = schema2.parse("12");
z.util.assertEqual<number, typeof r2>(true);
});
test("parse string to json", async () => {
const Env = z.object({
myJsonConfig: z.string().json(z.object({ foo: z.number() })),
Expand Down Expand Up @@ -61,9 +72,7 @@ test("parse string to json", async () => {
{
code: "invalid_string",
validation: "json",
message: isDeno
? `Unexpected token 'T', "This is no"... is not valid JSON`
: "Unexpected token T in JSON at position 0",
message: "Invalid json",
path: ["myJsonConfig"],
},
{
Expand All @@ -77,3 +86,16 @@ test("parse string to json", async () => {
},
});
});

test("no argument", () => {
const schema = z.string().json();
z.util.assertEqual<typeof schema, z.ZodString>(true);
z.string().json().parse(`{}`);
z.string().json().parse(`null`);
z.string().json().parse(`12`);
z.string().json().parse(`{ "test": "test"}`);
expect(() => z.string().json().parse(`asdf`)).toThrow();
expect(() => z.string().json().parse(`{ "test": undefined }`)).toThrow();
expect(() => z.string().json().parse(`{ "test": 12n }`)).toThrow();
expect(() => z.string().json().parse(`{ test: "test" }`)).toThrow();
});
1 change: 0 additions & 1 deletion src/locales/en.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { util } from "../helpers";

import { ZodErrorMap, ZodIssueCode } from "../ZodError";

const errorMap: ZodErrorMap = (issue, _ctx) => {
Expand Down
31 changes: 26 additions & 5 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -581,7 +581,8 @@ export type ZodStringCheck =
}
| { kind: "duration"; message?: string }
| { kind: "ip"; version?: IpVersion; message?: string }
| { kind: "base64"; message?: string };
| { kind: "base64"; message?: string }
| { kind: "json"; message?: string };

export interface ZodStringDef extends ZodTypeDef {
checks: ZodStringCheck[];
Expand Down Expand Up @@ -1029,6 +1030,18 @@ export class ZodString extends ZodType<string, ZodStringDef, string> {
});
status.dirty();
}
} else if (check.kind === "json") {
try {
JSON.parse(input.data);
} catch (err) {
ctx = this._getOrReturnCtx(input, ctx);
addIssueToContext(ctx, {
code: ZodIssueCode.invalid_string,
validation: "json",
message: check.message,
});
status.dirty();
}
} else {
util.assertNever(check);
}
Expand Down Expand Up @@ -1199,19 +1212,27 @@ export class ZodString extends ZodType<string, ZodStringDef, string> {
});
}

json<T extends ZodTypeAny>(shape: T) {
return this.transform((val, ctx) => {
json(message?: errorUtil.ErrMessage): this;
json<T extends ZodTypeAny>(
pipeTo: T
): ZodPipeline<ZodEffects<this, any, input<this>>, T>;
json(input?: errorUtil.ErrMessage | ZodTypeAny) {
if (!(input instanceof ZodType)) {
return this._addCheck({ kind: "json", ...errorUtil.errToObj(input) });
}
const schema = this.transform((val, ctx) => {
try {
return JSON.parse(val);
} catch (error: unknown) {
ctx.addIssue({
code: ZodIssueCode.invalid_string,
validation: "json",
message: (error as Error).message,
// message: (error as Error).message,
});
return NEVER;
}
}).pipe(shape);
});
return input ? schema.pipe(input) : schema;
}

min(minLength: number, message?: errorUtil.ErrMessage) {
Expand Down

0 comments on commit f594c84

Please sign in to comment.