diff --git a/packages/better-fetch/src/create-fetch/index.ts b/packages/better-fetch/src/create-fetch/index.ts index 098c0f5..5947c23 100644 --- a/packages/better-fetch/src/create-fetch/index.ts +++ b/packages/better-fetch/src/create-fetch/index.ts @@ -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, diff --git a/packages/better-fetch/src/create-fetch/schema.ts b/packages/better-fetch/src/create-fetch/schema.ts index bbd3be1..e762310 100644 --- a/packages/better-fetch/src/create-fetch/schema.ts +++ b/packages/better-fetch/src/create-fetch/schema.ts @@ -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; }; diff --git a/packages/better-fetch/src/create-fetch/types.ts b/packages/better-fetch/src/create-fetch/types.ts index c655647..16427af 100644 --- a/packages/better-fetch/src/create-fetch/types.ts +++ b/packages/better-fetch/src/create-fetch/types.ts @@ -16,7 +16,7 @@ export type CreateFetchOption = BetterFetchOption & { }; type WithRequired = T & { [P in K]-?: T[P] }; -type InferBody = T extends ZodSchema ? z.infer : any; +type InferBody = T extends ZodSchema ? z.input : any; type InferParamPath = Path extends `${infer _Start}:${infer Param}/${infer Rest}` @@ -28,7 +28,7 @@ type InferParamPath = : {}; export type InferParam = Param extends ZodSchema - ? z.infer + ? z.input : InferParamPath; export type InferOptions = WithRequired< @@ -42,7 +42,7 @@ export type InferOptions = WithRequired< : never >; -export type InferQuery = Q extends z.ZodSchema ? z.infer : any; +export type InferQuery = Q extends z.ZodSchema ? z.input : any; export type IsFieldOptional = T extends z.ZodSchema ? T extends z.ZodOptional diff --git a/packages/better-fetch/src/test/create.test.ts b/packages/better-fetch/src/test/create.test.ts index 57c6d70..206a571 100644 --- a/packages/better-fetch/src/test/create.test.ts +++ b/packages/better-fetch/src/test/create.test.ts @@ -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({ diff --git a/packages/better-fetch/src/test/fetch.test.ts b/packages/better-fetch/src/test/fetch.test.ts index 30b5910..768e88a 100644 --- a/packages/better-fetch/src/test/fetch.test.ts +++ b/packages/better-fetch/src/test/fetch.test.ts @@ -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";