Skip to content

Commit

Permalink
feat: input, params and query validation on schema
Browse files Browse the repository at this point in the history
  • Loading branch information
Bekacru committed Jul 26, 2024
1 parent 7d6e344 commit 2882e7d
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 8 deletions.
18 changes: 16 additions & 2 deletions packages/better-fetch/src/create-fetch/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,25 @@ const applySchemaPlugin = (config: CreateFetchOption) =>
}
const keySchema = schema.schema[urlKey];
if (keySchema) {
const opts = {
let opts = {
...options,
method: keySchema.method,
output: keySchema.output,
...options,
};
if (!options?.disableValidation) {
opts = {
...opts,
body: keySchema.input
? keySchema.input.parse(options?.body)
: options?.body,
params: keySchema.params
? keySchema.params.parse(options?.params)
: options?.params,
query: keySchema.query
? keySchema.query.parse(options?.query)
: options?.query,
};
}
return {
url,
options: opts,
Expand Down
3 changes: 1 addition & 2 deletions packages/better-fetch/src/create-fetch/schema.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
import type { ZodSchema, z } from "zod";
import type { StringLiteralUnion } from "../type-utils";

export type ParameterSchema = z.ZodString | z.ZodNumber;
export type FetchSchema = {
input?: ZodSchema;
output?: ZodSchema;
query?: ZodSchema;
params?: z.ZodObject<{
[key: string]: ParameterSchema;
[key: string]: ZodSchema;
}>;
method?: Methods;
};
Expand Down
6 changes: 3 additions & 3 deletions packages/better-fetch/src/create-fetch/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export type CreateFetchOption = BetterFetchOption & {
};

type WithRequired<T, K extends keyof T | never> = T & { [P in K]-?: T[P] };
type InferBody<T> = T extends ZodSchema ? z.infer<T> : any;
type InferBody<T> = T extends ZodSchema ? z.input<T> : any;

type InferParamPath<Path> =
Path extends `${infer _Start}:${infer Param}/${infer Rest}`
Expand All @@ -28,7 +28,7 @@ type InferParamPath<Path> =
: {};

export type InferParam<Path, Param> = Param extends ZodSchema
? z.infer<Param>
? z.input<Param>
: InferParamPath<Path>;

export type InferOptions<T extends FetchSchema, Key> = WithRequired<
Expand All @@ -42,7 +42,7 @@ export type InferOptions<T extends FetchSchema, Key> = WithRequired<
: never
>;

export type InferQuery<Q> = Q extends z.ZodSchema ? z.infer<Q> : any;
export type InferQuery<Q> = Q extends z.ZodSchema ? z.input<Q> : any;

export type IsFieldOptional<T> = T extends z.ZodSchema
? T extends z.ZodOptional<any>
Expand Down
41 changes: 41 additions & 0 deletions packages/better-fetch/src/test/create.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,47 @@ describe("create-fetch-runtime-test", () => {
expect(f("/post")).rejects.toThrowError(ZodError);
});

it("should parse params and other inputs", async () => {
const $fetch = createFetch({
schema: createSchema({
"/path/:code/:phone": {
params: z.object({
code: z.number().default(1),
phone: z.string().default("123456789"),
}),
input: z.object({
code: z.number().default(1),
phone: z.string(),
}),
query: z.object({
code: z.number(),
phone: z.string().default("123"),
}),
},
}),
baseURL: "http://localhost:4001",
customFetchImpl: async (url, req) => {
return new Response();
},
onRequest(context) {
expect(context.params).toEqual({ code: 1, phone: "123456789" });
expect(JSON.parse(context.body)).toEqual({ code: 1, phone: "test" });
expect(context.query).toEqual({ code: 1, phone: "123" });
},
});
await $fetch("/path/:code/:phone", {
params: {
code: 1,
},
body: {
phone: "test",
},
query: {
code: 1,
},
});
});

it("should validate response and return data if validation passes", async () => {
const res = await $fetch("/echo", {
output: z.object({
Expand Down
2 changes: 1 addition & 1 deletion packages/better-fetch/src/test/fetch.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { BetterFetchError, betterFetch, createFetch } from "..";
import { router } from "./test-router";
import { getURL } from "../url";

describe.skip("fetch", () => {
describe("fetch", () => {
const getURL = (path?: string) =>
path ? `http://localhost:4000/${path}` : "http://localhost:4000";

Expand Down

0 comments on commit 2882e7d

Please sign in to comment.