diff --git a/packages/better-fetch/src/create-fetch/types.ts b/packages/better-fetch/src/create-fetch/types.ts index 5f07d36..3f33de5 100644 --- a/packages/better-fetch/src/create-fetch/types.ts +++ b/packages/better-fetch/src/create-fetch/types.ts @@ -28,13 +28,13 @@ export type RemoveEmptyString = T extends string : T; export type InferParamPath = - Path extends `${infer _Start}:${infer Param}/${infer Rest}` + Path extends `${infer _Start}/:${infer Param}/${infer Rest}` ? { [K in | Param | keyof InferParamPath as RemoveEmptyString]: string; } - : Path extends `${infer _Start}:${infer Param}` + : Path extends `${infer _Start}/:${infer Param}` ? { [K in Param]: string } : Path extends `${infer _Start}/${infer Rest}` ? InferParamPath diff --git a/packages/better-fetch/src/test/create.test.ts b/packages/better-fetch/src/test/create.test.ts index 7fd39a0..3c3657d 100644 --- a/packages/better-fetch/src/test/create.test.ts +++ b/packages/better-fetch/src/test/create.test.ts @@ -270,10 +270,8 @@ describe("create-fetch-type-test", () => { const res = await $fetch("/", { throw: true, }); - expectTypeOf(res).toMatchTypeOf< - { message: string } - >(); - }) + expectTypeOf(res).toMatchTypeOf<{ message: string }>(); + }); it("should return unknown if no output is defined", () => { const res = $fetch("/"); @@ -423,8 +421,8 @@ describe("create-fetch-type-test", () => { params: {}, }); $fetch("/post/:id/:title", { + // @ts-expect-error params: { - //@ts-expect-error title: 1, }, }); diff --git a/packages/better-fetch/src/test/fetch.test.ts b/packages/better-fetch/src/test/fetch.test.ts index 5bdde68..495f731 100644 --- a/packages/better-fetch/src/test/fetch.test.ts +++ b/packages/better-fetch/src/test/fetch.test.ts @@ -566,6 +566,19 @@ describe("url", () => { expect(url.toString()).toBe("http://localhost:4001/param/%23test/item%201"); }); + it("dynamic params should not collide with url", async () => { + const url = getURL("/v1/places:searchNearby", { + baseURL: "http://localhost:4000", + params: { + searchNearby: "test", + }, + }); + + expect(url.toString()).toBe( + "http://localhost:4000/v1/places:searchNearby", + ); + }); + it("should expand array values into multiple query parameters", () => { const url = getURL("/test", { query: { diff --git a/packages/better-fetch/src/url.ts b/packages/better-fetch/src/url.ts index 1f9af3d..8064fbc 100644 --- a/packages/better-fetch/src/url.ts +++ b/packages/better-fetch/src/url.ts @@ -51,12 +51,16 @@ export function getURL(url: string, option?: BetterFetchOption) { } } else { for (const [key, value] of Object.entries(params)) { - path = path.replace(`:${key}`, String(value)); + path = path.replace(`/:${key}`, `/${value}`); } } } - path = path.split("/").map(encodeURIComponent).join("/"); + path = path + .split("/") + // decode colon again so fetch doesn't break + .map((segment) => encodeURIComponent(segment).replace(/%3A/g, ":")) + .join("/"); if (path.startsWith("/")) path = path.slice(1); let queryParamString = queryParams.toString(); queryParamString =