diff --git a/src/common/url.t-test.ts b/src/common/url.t-test.ts index 0f9170c..990c6d4 100644 --- a/src/common/url.t-test.ts +++ b/src/common/url.t-test.ts @@ -29,8 +29,13 @@ type ToUrlParamPatternTestCases = [ Expect, `/${string}/b`>>, Expect, `/${string}/${string}`>>, Expect< - // @ts-expect-error URL is not supported - Equal, `"https://example.com}`> + Equal, "https://example.com"> + >, + Expect< + Equal< + ToUrlParamPattern<"https://example.com/:a">, + `https://example.com/${string}` + > >, ]; @@ -45,7 +50,6 @@ type ToUrlPatternTestCases = [ `/users/${string}?key=value` > >, - // @ts-expect-error URL is not supported Expect, "https://example.com">>, ]; diff --git a/src/common/url.ts b/src/common/url.ts index d404915..c63fd37 100644 --- a/src/common/url.ts +++ b/src/common/url.ts @@ -29,11 +29,13 @@ export type UrlPrefixPattern = `${UrlPrefix}${string}`; * // => "/users/${string}" * ``` */ -export type ToUrlParamPattern = T extends `${infer O}:${infer R}` - ? R extends `${string}/${infer L}` - ? `${O}${string}/${ToUrlParamPattern}` - : `${O}${string}` - : T; +export type ToUrlParamPattern = T extends `${infer O}://${infer R}` + ? `${O}://${ToUrlParamPattern}` + : T extends `${infer O}:${infer R}` + ? R extends `${string}/${infer L}` + ? `${O}${string}/${ToUrlParamPattern}` + : `${O}${string}` + : T; /** * Convert URL definition with query to acceptable URL pattern diff --git a/src/fetch/index.t-test.ts b/src/fetch/index.t-test.ts index 1d7d9bf..49e4e66 100644 --- a/src/fetch/index.t-test.ts +++ b/src/fetch/index.t-test.ts @@ -71,6 +71,12 @@ import JSONT from "../json"; await f("/users"); } + { + await f("/users?a=1", { + headers: { "Content-Type": "application/json" }, + }); + } + { const res = await f("/users", { method: "post", @@ -103,3 +109,23 @@ import JSONT from "../json"; } })(); } + +{ + type Spec = DefineApiEndpoints<{ + "/users": { + get: { + headers: { Cookie: `a=${string}` }; + resBody: { + 200: { prop: string }; + }; + }; + }; + }>; + (async () => { + const basePath = "https://example.com/api"; + const f = fetch as FetchT; + await f(`${basePath}/users`, { + headers: { Cookie: "a=b" }, + }); + })(); +} diff --git a/src/fetch/index.ts b/src/fetch/index.ts index be528dd..320f169 100644 --- a/src/fetch/index.ts +++ b/src/fetch/index.ts @@ -5,12 +5,12 @@ import { MergeApiResponses, Method, NormalizePath, + ParseURL, Replace, } from "../common"; import { MatchedPatterns, UrlPrefixPattern, - ParseURL, ToUrlParamPattern, } from "../common"; import { TypedString } from "../json"; @@ -32,15 +32,13 @@ export interface RequestInitT< /** * FetchT is a type for window.fetch like function but more strict type information */ -type FetchT = < +type FetchT = < Input extends - | `${ToUrlParamPattern}${ToUrlParamPattern}` - | `${ToUrlParamPattern}${ToUrlParamPattern}?${string}`, - InputPath extends Replace< - NormalizePath["path"]>, - ToUrlParamPattern, - "" - >, + | `${ToUrlParamPattern}${ToUrlParamPattern}` + | `${ToUrlParamPattern}${ToUrlParamPattern}?${string}`, + InputPath extends ParseURL< + Replace, NormalizePath, ""> + >["path"], CandidatePaths extends MatchedPatterns, InputMethod extends CaseInsensitiveMethod = "get", M extends Method = Lowercase,