Skip to content

Commit ce3fe54

Browse files
authored
Normalize path (#27)
1 parent 642073f commit ce3fe54

File tree

4 files changed

+66
-2
lines changed

4 files changed

+66
-2
lines changed

src/common/type.t-test.ts

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
import { Equal, Expect } from "./type-test";
2-
import { ExtractByPrefix, FilterNever, Replace, Split } from "./type";
2+
import {
3+
ExtractByPrefix,
4+
FilterNever,
5+
Replace,
6+
ReplaceAll,
7+
Split,
8+
} from "./type";
9+
import { NormalizePath } from "./url";
310

411
// eslint-disable-next-line @typescript-eslint/no-unused-vars
512
type FilterNeverCases = [
@@ -29,6 +36,20 @@ type ReplaceTestCases = [
2936
Expect<Equal<Replace<"abcd", "bc", "-">, "a-d">>,
3037
];
3138

39+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
40+
type ReplaceAllTestCases = [
41+
Expect<Equal<ReplaceAll<"a", "a", "-">, "-">>,
42+
Expect<Equal<ReplaceAll<"a", "noexist", "-">, "a">>,
43+
Expect<Equal<ReplaceAll<"a", "a", "a">, "a">>,
44+
Expect<Equal<ReplaceAll<"abcd", "ab", "-">, "-cd">>,
45+
Expect<Equal<ReplaceAll<"abcd", "cd", "-">, "ab-">>,
46+
Expect<Equal<ReplaceAll<"abcd", "bc", "-">, "a-d">>,
47+
Expect<Equal<ReplaceAll<"aab", "a", "-">, "--b">>,
48+
Expect<Equal<ReplaceAll<"aba", "a", "-">, "-b-">>,
49+
Expect<Equal<ReplaceAll<"aabaa", "aa", "-">, "-b-">>,
50+
Expect<Equal<ReplaceAll<"aaaba", "aa", "-">, "-aba">>,
51+
];
52+
3253
// eslint-disable-next-line @typescript-eslint/no-unused-vars
3354
type ExtractByPrefixTestCases = [
3455
Expect<Equal<ExtractByPrefix<"", "">, "">>,
@@ -41,3 +62,10 @@ type ExtractByPrefixTestCases = [
4162
Expect<Equal<ExtractByPrefix<":a" | ":b", ":">, "a" | "b">>,
4263
Expect<Equal<ExtractByPrefix<":a" | ":b" | ":c", ":">, "a" | "b" | "c">>,
4364
];
65+
66+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
67+
type NormalizePathTestCases = [
68+
Expect<Equal<NormalizePath<"users//">, "users/">>,
69+
Expect<Equal<NormalizePath<"//users">, "/users">>,
70+
Expect<Equal<NormalizePath<"users//:userId">, "users/:userId">>,
71+
];

src/common/type.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,28 @@ export type Replace<
2929
To extends string,
3030
> = S extends `${infer P}${From}${infer R}` ? `${P}${To}${R}` : S;
3131

32+
/**
33+
* Replace all substring
34+
* S: source string
35+
* From: substring to be replaced
36+
* To: substring to replace
37+
*
38+
* @example
39+
* ```
40+
* type T0 = ReplaceAll<"aabaa", "aa", "-">;
41+
* // => "-b-"
42+
* ```
43+
*/
44+
export type ReplaceAll<
45+
S extends string,
46+
From extends string,
47+
To extends string,
48+
> = From extends ""
49+
? S
50+
: S extends `${infer P}${From}${infer R}`
51+
? `${P}${To}${ReplaceAll<R, From, To>}`
52+
: S;
53+
3254
/**
3355
* Split string by delimiter
3456
* S: source string

src/common/url.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,3 +126,16 @@ export type ParseURL<T extends string> = ParseOriginAndPath<
126126
? ParseQueryString<SplitUrlAndQueryString<T>["qs"]>
127127
: Record<string, never>;
128128
};
129+
130+
/**
131+
* Normalize path
132+
*
133+
* @example
134+
* ```
135+
* type T0 = NormalizePath<"users//:userId">;
136+
* // => "users/:userId"
137+
* ```
138+
*/
139+
export type NormalizePath<T extends string> = T extends `${infer P}//${infer Q}`
140+
? NormalizePath<`${P}/${Q}`>
141+
: T;

src/fetch/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import {
33
ApiEndpoints,
44
MergeApiResponses,
55
Method,
6+
NormalizePath,
67
Replace,
78
} from "../common";
89
import {
@@ -30,7 +31,7 @@ type FetchT<Origin extends UrlPrefixPattern, E extends ApiEndpoints> = <
3031
| `${ToUrlParamPattern<Origin>}${ToUrlParamPattern<keyof E & string>}`
3132
| `${ToUrlParamPattern<Origin>}${ToUrlParamPattern<keyof E & string>}?${string}`,
3233
InputPath extends Replace<
33-
ParseURL<Input>["path"],
34+
NormalizePath<ParseURL<Input>["path"]>,
3435
ToUrlParamPattern<Origin>,
3536
""
3637
>,

0 commit comments

Comments
 (0)