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 3a0cdb4 commit ca9c3e1
Show file tree
Hide file tree
Showing 5 changed files with 104 additions and 45 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();
});
31 changes: 26 additions & 5 deletions deno/lib/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -537,7 +537,8 @@ export type ZodStringCheck =
precision: number | null;
message?: string;
}
| { kind: "ip"; version?: IpVersion; message?: string };
| { kind: "ip"; version?: IpVersion; message?: string }
| { kind: "json"; message?: string };

export interface ZodStringDef extends ZodTypeDef {
checks: ZodStringCheck[];
Expand Down Expand Up @@ -845,6 +846,18 @@ export class ZodString extends ZodType<string, ZodStringDef> {
});
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 @@ -957,19 +970,27 @@ export class ZodString extends ZodType<string, ZodStringDef> {
});
}

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
31 changes: 2 additions & 29 deletions playground.ts
Original file line number Diff line number Diff line change
@@ -1,32 +1,5 @@
import { z } from "./src";
import * as mod from "node:module";
z;

// @ts-ignore
// const arg = await import("./index");
// arg;
// require.resolve(arg);

load: {
}
interface A<T> {
name: T;
children: any;
render(): ReadableStream | string;
}
function Hyper<T>(arg: T) {
return function () {} as any as {
prototype: A<T>;
new (): A<T>;
};
}

export default class extends Hyper({ name: 1234 }) {
render() {
// this.name.name;
return `asdf ${this.children} asdf`;
}
}

const a = new Arg();
a.name;
const r = z.string().json().safeParse("asf");
console.log(JSON.stringify(r, null, 2));
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();
});
31 changes: 26 additions & 5 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -537,7 +537,8 @@ export type ZodStringCheck =
precision: number | null;
message?: string;
}
| { kind: "ip"; version?: IpVersion; message?: string };
| { kind: "ip"; version?: IpVersion; message?: string }
| { kind: "json"; message?: string };

export interface ZodStringDef extends ZodTypeDef {
checks: ZodStringCheck[];
Expand Down Expand Up @@ -845,6 +846,18 @@ export class ZodString extends ZodType<string, ZodStringDef> {
});
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 @@ -957,19 +970,27 @@ export class ZodString extends ZodType<string, ZodStringDef> {
});
}

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 ca9c3e1

Please sign in to comment.