@virentia/router-paths 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +57 -0
- package/dist/index.cjs +181 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +40 -0
- package/dist/index.d.cts.map +1 -0
- package/dist/index.d.mts +40 -0
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +179 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +35 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Virentia
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# @virentia/router-paths
|
|
2
|
+
|
|
3
|
+
Typed path compiler for Virentia Router.
|
|
4
|
+
|
|
5
|
+
It turns route templates into parser and builder functions. The router uses this package internally, and it can also be used by adapters, tests, and tools that need the same path semantics without creating routes.
|
|
6
|
+
|
|
7
|
+
## Links
|
|
8
|
+
|
|
9
|
+
- Documentation: [movpushmov.dev/virentia/router/paths](https://movpushmov.dev/virentia/router/paths)
|
|
10
|
+
|
|
11
|
+
## Install
|
|
12
|
+
|
|
13
|
+
```sh
|
|
14
|
+
pnpm add @virentia/router-paths
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Compile
|
|
18
|
+
|
|
19
|
+
```ts
|
|
20
|
+
import { compile } from "@virentia/router-paths";
|
|
21
|
+
|
|
22
|
+
const profilePath = compile("/profile/:id<number>");
|
|
23
|
+
|
|
24
|
+
profilePath.parse("/profile/42");
|
|
25
|
+
// { path: "/profile/42", params: { id: 42 } }
|
|
26
|
+
|
|
27
|
+
profilePath.build({ id: 42 });
|
|
28
|
+
// "/profile/42"
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Templates support plain string params, `number` params, literal unions, optional params, repeated params, and ranged params.
|
|
32
|
+
|
|
33
|
+
```ts
|
|
34
|
+
const filesPath = compile("/files/:path<string|image>{1,3}");
|
|
35
|
+
|
|
36
|
+
filesPath.parse("/files/string/image");
|
|
37
|
+
// { path: "/files/string/image", params: { path: ["string", "image"] } }
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Express conversion
|
|
41
|
+
|
|
42
|
+
`convertPath` converts Virentia templates into an express-compatible shape for integrations that need route matching outside the Virentia router.
|
|
43
|
+
|
|
44
|
+
```ts
|
|
45
|
+
import { convertPath } from "@virentia/router-paths";
|
|
46
|
+
|
|
47
|
+
convertPath("/files/:id<number>?", "express");
|
|
48
|
+
// "/files{/:id}"
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Main API
|
|
52
|
+
|
|
53
|
+
`compile`, `convertPath`, `Builder`, `Parser`, `ParseUrlParams`, `ValidatePath`.
|
|
54
|
+
|
|
55
|
+
## License
|
|
56
|
+
|
|
57
|
+
MIT © 2026 movpushmov
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
//#region lib/get-token-parameters.ts
|
|
3
|
+
function getTokenParameters(match) {
|
|
4
|
+
if (!match) return null;
|
|
5
|
+
const [, name, rawGenericProps, rawArrayProps, modifier] = match;
|
|
6
|
+
return {
|
|
7
|
+
name,
|
|
8
|
+
genericProps: rawGenericProps?.slice(1, -1).replaceAll(" ", ""),
|
|
9
|
+
arrayProps: rawArrayProps?.slice(1, -1).split(",").map((value) => Number(value)),
|
|
10
|
+
modifier
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
//#endregion
|
|
14
|
+
//#region lib/prepare-builder.ts
|
|
15
|
+
function prepareBuilder(tokens) {
|
|
16
|
+
return ((params = void 0) => {
|
|
17
|
+
const result = [];
|
|
18
|
+
if (tokens.length === 0) return "/";
|
|
19
|
+
for (const token of tokens) {
|
|
20
|
+
if (token.type === "const") {
|
|
21
|
+
result.push(token.name);
|
|
22
|
+
continue;
|
|
23
|
+
}
|
|
24
|
+
const value = params?.[token.name];
|
|
25
|
+
if (value == null) continue;
|
|
26
|
+
if (Array.isArray(value)) for (const item of value) result.push(String(item));
|
|
27
|
+
else result.push(String(value));
|
|
28
|
+
}
|
|
29
|
+
return `/${result.join("/")}`;
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
//#endregion
|
|
33
|
+
//#region lib/prepare-parser.ts
|
|
34
|
+
function prepareParser(tokens) {
|
|
35
|
+
return (input) => {
|
|
36
|
+
const rawTokens = input.split("/").map((part) => part.trim()).filter((part) => part !== "");
|
|
37
|
+
let params = null;
|
|
38
|
+
function setKey(key, value) {
|
|
39
|
+
params ??= {};
|
|
40
|
+
params[key] = value;
|
|
41
|
+
}
|
|
42
|
+
if (tokens.length === 0) return rawTokens.length === 0 ? {
|
|
43
|
+
path: input,
|
|
44
|
+
params: null
|
|
45
|
+
} : null;
|
|
46
|
+
for (let i = 0; i < tokens.length; i += 1) {
|
|
47
|
+
const token = tokens[i];
|
|
48
|
+
if (!token) return null;
|
|
49
|
+
if (token.type === "const") {
|
|
50
|
+
if (token.name !== rawTokens.shift()) return null;
|
|
51
|
+
continue;
|
|
52
|
+
}
|
|
53
|
+
const { arrayProps, genericProps, required } = token.payload;
|
|
54
|
+
if (arrayProps) {
|
|
55
|
+
const array = [];
|
|
56
|
+
let rawToken;
|
|
57
|
+
while (true) {
|
|
58
|
+
rawToken = rawTokens.shift();
|
|
59
|
+
if (!rawToken) break;
|
|
60
|
+
const parsed = parseToken(rawToken, genericProps);
|
|
61
|
+
if (!parsed.success) return null;
|
|
62
|
+
array.push(parsed.value);
|
|
63
|
+
if (array.length >= (arrayProps.max ?? Infinity)) break;
|
|
64
|
+
}
|
|
65
|
+
if (array.length < (arrayProps.min ?? 0)) return null;
|
|
66
|
+
if (rawTokens.length > 0 && !tokens[i + 1]) return null;
|
|
67
|
+
setKey(token.name, array);
|
|
68
|
+
continue;
|
|
69
|
+
}
|
|
70
|
+
const rawToken = rawTokens.shift();
|
|
71
|
+
if (required && !rawToken) return null;
|
|
72
|
+
if (!rawToken) {
|
|
73
|
+
setKey(token.name, void 0);
|
|
74
|
+
continue;
|
|
75
|
+
}
|
|
76
|
+
const parsed = parseToken(rawToken, genericProps);
|
|
77
|
+
if (!parsed.success) return null;
|
|
78
|
+
setKey(token.name, parsed.value);
|
|
79
|
+
}
|
|
80
|
+
if (rawTokens.length > 0) return null;
|
|
81
|
+
return {
|
|
82
|
+
path: input,
|
|
83
|
+
params
|
|
84
|
+
};
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
function parseToken(rawToken, genericProps) {
|
|
88
|
+
if (genericProps?.type === "number") {
|
|
89
|
+
if (Number.isNaN(Number(rawToken))) return { success: false };
|
|
90
|
+
return {
|
|
91
|
+
success: true,
|
|
92
|
+
value: Number(rawToken)
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
if (genericProps?.type === "union") {
|
|
96
|
+
if (!genericProps.items.includes(rawToken)) return { success: false };
|
|
97
|
+
return {
|
|
98
|
+
success: true,
|
|
99
|
+
value: rawToken
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
return {
|
|
103
|
+
success: true,
|
|
104
|
+
value: rawToken
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
//#endregion
|
|
108
|
+
//#region lib/compile.ts
|
|
109
|
+
function compile(path) {
|
|
110
|
+
const tokens = [];
|
|
111
|
+
const regexp = /:(\w+)(<[\s?\w|]+>)?({\d+,\d+})?([+*?])?/;
|
|
112
|
+
const parsedTokens = path.split("/").filter(Boolean);
|
|
113
|
+
for (const parsedToken of parsedTokens) {
|
|
114
|
+
const parameters = getTokenParameters(parsedToken.match(regexp));
|
|
115
|
+
if (!parameters) {
|
|
116
|
+
tokens.push({
|
|
117
|
+
type: "const",
|
|
118
|
+
name: parsedToken,
|
|
119
|
+
payload: void 0
|
|
120
|
+
});
|
|
121
|
+
continue;
|
|
122
|
+
}
|
|
123
|
+
const { arrayProps, genericProps, modifier, name } = parameters;
|
|
124
|
+
if (!name) throw new Error(`Invalid path: "${path}". Name for argument must be provided`);
|
|
125
|
+
const token = {
|
|
126
|
+
type: "parameter",
|
|
127
|
+
name,
|
|
128
|
+
payload: { required: true }
|
|
129
|
+
};
|
|
130
|
+
if (genericProps === "number") token.payload.genericProps = { type: "number" };
|
|
131
|
+
if (genericProps?.includes("|")) token.payload.genericProps = {
|
|
132
|
+
type: "union",
|
|
133
|
+
items: genericProps.split("|")
|
|
134
|
+
};
|
|
135
|
+
switch (modifier) {
|
|
136
|
+
case "*":
|
|
137
|
+
token.payload.arrayProps = {};
|
|
138
|
+
break;
|
|
139
|
+
case "+":
|
|
140
|
+
token.payload.arrayProps = { min: 1 };
|
|
141
|
+
break;
|
|
142
|
+
case "?":
|
|
143
|
+
token.payload.required = false;
|
|
144
|
+
break;
|
|
145
|
+
}
|
|
146
|
+
if (arrayProps) token.payload.arrayProps = {
|
|
147
|
+
...token.payload.arrayProps,
|
|
148
|
+
min: arrayProps[0],
|
|
149
|
+
max: arrayProps[1]
|
|
150
|
+
};
|
|
151
|
+
tokens.push(token);
|
|
152
|
+
}
|
|
153
|
+
return {
|
|
154
|
+
parse: prepareParser(tokens),
|
|
155
|
+
build: prepareBuilder(tokens)
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
//#endregion
|
|
159
|
+
//#region lib/convert-path.ts
|
|
160
|
+
const cases = { express: [
|
|
161
|
+
[/:id<.+>/g, ":id"],
|
|
162
|
+
[/:id\+/g, "*id"],
|
|
163
|
+
[/:id\*/g, "*id"],
|
|
164
|
+
[/:id\{.+\}/g, "*id"],
|
|
165
|
+
[/([a-zA-Z0-9:/_.]+)\/([*:])id\?/g, "$1{/$2id}"],
|
|
166
|
+
[/([*:])id\?/g, "{$1id}"]
|
|
167
|
+
] };
|
|
168
|
+
function convertPath(path, mode) {
|
|
169
|
+
switch (mode) {
|
|
170
|
+
case "express": {
|
|
171
|
+
let nextPath = path;
|
|
172
|
+
for (const [regex, replacement] of cases.express) if (nextPath.match(regex)) nextPath = nextPath.replace(regex, replacement);
|
|
173
|
+
return nextPath;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
//#endregion
|
|
178
|
+
exports.compile = compile;
|
|
179
|
+
exports.convertPath = convertPath;
|
|
180
|
+
|
|
181
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.cjs","names":[],"sources":["../lib/get-token-parameters.ts","../lib/prepare-builder.ts","../lib/prepare-parser.ts","../lib/compile.ts","../lib/convert-path.ts"],"sourcesContent":["interface TokenParameters {\n name: string | undefined;\n genericProps: string | undefined;\n arrayProps: [number, number] | undefined;\n modifier: string | undefined;\n}\n\nexport function getTokenParameters(match: RegExpMatchArray | null): TokenParameters | null {\n if (!match) {\n return null;\n }\n\n const [, name, rawGenericProps, rawArrayProps, modifier] = match;\n const genericProps = rawGenericProps?.slice(1, -1).replaceAll(\" \", \"\");\n const arrayProps = rawArrayProps\n ?.slice(1, -1)\n .split(\",\")\n .map((value) => Number(value)) as [number, number] | undefined;\n\n return {\n name,\n genericProps,\n arrayProps,\n modifier\n };\n}\n","import type { Builder, Token } from \"./types\";\n\nexport function prepareBuilder<T>(tokens: Token[]): Builder<T> {\n return ((params: any = undefined) => {\n const result: string[] = [];\n\n if (tokens.length === 0) {\n return \"/\";\n }\n\n for (const token of tokens) {\n if (token.type === \"const\") {\n result.push(token.name);\n continue;\n }\n\n const value = params?.[token.name];\n\n if (value == null) {\n continue;\n }\n\n if (Array.isArray(value)) {\n for (const item of value) {\n result.push(String(item));\n }\n } else {\n result.push(String(value));\n }\n }\n\n return `/${result.join(\"/\")}`;\n }) as Builder<T>;\n}\n","import type { Parser, Token } from \"./types\";\n\nexport function prepareParser<T>(tokens: Token[]): Parser<T> {\n return (input) => {\n const rawTokens = input\n .split(\"/\")\n .map((part) => part.trim())\n .filter((part) => part !== \"\");\n\n let params: Record<string, unknown> | null = null;\n\n function setKey(key: string, value: unknown) {\n params ??= {};\n params[key] = value;\n }\n\n if (tokens.length === 0) {\n return rawTokens.length === 0 ? { path: input, params: null as T } : null;\n }\n\n for (let i = 0; i < tokens.length; i += 1) {\n const token = tokens[i];\n\n if (!token) {\n return null;\n }\n\n if (token.type === \"const\") {\n if (token.name !== rawTokens.shift()) {\n return null;\n }\n\n continue;\n }\n\n const { arrayProps, genericProps, required } = token.payload;\n\n if (arrayProps) {\n const array: unknown[] = [];\n let rawToken: string | undefined;\n\n while (true) {\n rawToken = rawTokens.shift();\n\n if (!rawToken) {\n break;\n }\n\n const parsed = parseToken(rawToken, genericProps);\n\n if (!parsed.success) {\n return null;\n }\n\n array.push(parsed.value);\n\n if (array.length >= (arrayProps.max ?? Infinity)) {\n break;\n }\n }\n\n if (array.length < (arrayProps.min ?? 0)) {\n return null;\n }\n\n if (rawTokens.length > 0 && !tokens[i + 1]) {\n return null;\n }\n\n setKey(token.name, array);\n continue;\n }\n\n const rawToken = rawTokens.shift();\n\n if (required && !rawToken) {\n return null;\n }\n\n if (!rawToken) {\n setKey(token.name, undefined);\n continue;\n }\n\n const parsed = parseToken(rawToken, genericProps);\n\n if (!parsed.success) {\n return null;\n }\n\n setKey(token.name, parsed.value);\n }\n\n if (rawTokens.length > 0) {\n return null;\n }\n\n return { path: input, params: params as T };\n };\n}\n\nfunction parseToken(\n rawToken: string,\n genericProps: { type: \"union\"; items: string[] } | { type: \"number\" } | undefined,\n): { success: true; value: unknown } | { success: false } {\n if (genericProps?.type === \"number\") {\n if (Number.isNaN(Number(rawToken))) {\n return { success: false };\n }\n\n return { success: true, value: Number(rawToken) };\n }\n\n if (genericProps?.type === \"union\") {\n if (!genericProps.items.includes(rawToken)) {\n return { success: false };\n }\n\n return { success: true, value: rawToken };\n }\n\n return { success: true, value: rawToken };\n}\n","import { getTokenParameters } from \"./get-token-parameters\";\nimport { prepareBuilder } from \"./prepare-builder\";\nimport { prepareParser } from \"./prepare-parser\";\nimport type { ParameterToken, ParseUrlParams, Token } from \"./types\";\n\nexport function compile<T extends string, Params = ParseUrlParams<T>>(path: T) {\n const tokens: Token[] = [];\n const regexp = /:(\\w+)(<[\\s?\\w|]+>)?({\\d+,\\d+})?([+*?])?/;\n const parsedTokens = path.split(\"/\").filter(Boolean);\n\n for (const parsedToken of parsedTokens) {\n const parameters = getTokenParameters(parsedToken.match(regexp));\n\n if (!parameters) {\n tokens.push({ type: \"const\", name: parsedToken, payload: undefined });\n continue;\n }\n\n const { arrayProps, genericProps, modifier, name } = parameters;\n\n if (!name) {\n throw new Error(`Invalid path: \"${path}\". Name for argument must be provided`);\n }\n\n const token: ParameterToken = {\n type: \"parameter\",\n name,\n payload: {\n required: true\n }\n };\n\n if (genericProps === \"number\") {\n token.payload.genericProps = { type: \"number\" };\n }\n\n if (genericProps?.includes(\"|\")) {\n token.payload.genericProps = {\n type: \"union\",\n items: genericProps.split(\"|\")\n };\n }\n\n switch (modifier) {\n case \"*\": {\n token.payload.arrayProps = {};\n break;\n }\n case \"+\": {\n token.payload.arrayProps = { min: 1 };\n break;\n }\n case \"?\": {\n token.payload.required = false;\n break;\n }\n }\n\n if (arrayProps) {\n token.payload.arrayProps = {\n ...token.payload.arrayProps,\n min: arrayProps[0],\n max: arrayProps[1]\n };\n }\n\n tokens.push(token);\n }\n\n return {\n parse: prepareParser<Params>(tokens),\n build: prepareBuilder<Params>(tokens)\n };\n}\n","type CompatibilityMode = \"express\";\n\nconst cases = {\n express: [\n [/:id<.+>/g, \":id\"],\n [/:id\\+/g, \"*id\"],\n [/:id\\*/g, \"*id\"],\n [/:id\\{.+\\}/g, \"*id\"],\n [/([a-zA-Z0-9:/_.]+)\\/([*:])id\\?/g, \"$1{/$2id}\"],\n [/([*:])id\\?/g, \"{$1id}\"]\n ]\n} as const;\n\nexport function convertPath(path: string, mode: CompatibilityMode): string {\n switch (mode) {\n case \"express\": {\n let nextPath = path;\n\n for (const [regex, replacement] of cases.express) {\n if (nextPath.match(regex)) {\n nextPath = nextPath.replace(regex, replacement);\n }\n }\n\n return nextPath;\n }\n }\n}\n"],"mappings":"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"}
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
//#region lib/types.d.ts
|
|
2
|
+
type ReplaceAll<S, From extends string, To extends string> = From extends "" ? S : S extends `${infer R1}${From}${infer R2}` ? `${R1}${To}${ReplaceAll<R2, From, To>}` : S;
|
|
3
|
+
type Parameter<Name extends string, Payload> = { [Key in Name]: Payload };
|
|
4
|
+
type WithModifier<Type, T extends string> = T extends `${infer _K}{${infer _Start},${infer _End}}+` ? Type[] : T extends `${infer _K}{${infer _Start},${infer _End}}*` ? Type[] : T extends `${infer _K}{${infer _Start},${infer _End}}?` ? Type[] | undefined : T extends `${infer _K}{${infer _Start},${infer _End}}` ? Type[] : T extends `${infer _K}+` ? Type[] : T extends `${infer _K}*` ? Type[] : T extends `${infer _K}?` ? Type | undefined : Type;
|
|
5
|
+
type WithoutModifier$1<T extends string> = T extends `${infer K}{${infer _Start},${infer _End}}${infer _Modifier}` ? K : T extends `${infer K}{${infer _Start},${infer _End}}` ? K : T extends `${infer K}?` ? K : T extends `${infer K}*` ? K : T extends `${infer K}+` ? K : T;
|
|
6
|
+
type Union<T extends string, Result = void> = T extends `${infer Start}|${infer Tail}` ? Union<Tail, Result extends void ? Start : Result | Start> : Result extends void ? T : Result | T;
|
|
7
|
+
type GenericType<T extends string> = ReplaceAll<T, " ", ""> extends infer Trimmed ? Trimmed extends "number" ? number : Trimmed extends `${infer _A}|${infer _B}` ? Union<Trimmed & string> : Trimmed : never;
|
|
8
|
+
type UrlParameter<T extends string> = T extends `:${infer Name}<${infer Type}>${infer Modifier}` ? Parameter<WithoutModifier$1<Name>, WithModifier<GenericType<Type>, T>> : T extends `:${infer Name}<${infer Type}>` ? Parameter<Name, GenericType<Type>> : T extends `:${infer Name}` ? Parameter<WithoutModifier$1<Name>, WithModifier<string, T>> : never;
|
|
9
|
+
type UrlParams<T extends string, Result = void> = T extends `/:${infer Parameter}/${infer Route}` ? Result extends void ? UrlParams<`/${Route}`, UrlParameter<`:${Parameter}`>> : UrlParams<`/${Route}`, Result & UrlParameter<`:${Parameter}`>> : T extends `/:${infer Parameter}` ? Result extends void ? UrlParameter<`:${Parameter}`> : Result & UrlParameter<`:${Parameter}`> : T extends `/${infer _Static}/${infer Next}` ? UrlParams<`/${Next}`, Result> : Result;
|
|
10
|
+
type Unwrap<Result extends UrlParams<any, void>> = { [Key in keyof Result]: Result[Key] };
|
|
11
|
+
type ParseUrlParams<T extends string> = Unwrap<UrlParams<T>>;
|
|
12
|
+
type Builder<T> = [T] extends [void] ? (params?: T) => string : (params: T) => string;
|
|
13
|
+
type Parser<T> = (path: string) => {
|
|
14
|
+
path: string;
|
|
15
|
+
params: T;
|
|
16
|
+
} | null;
|
|
17
|
+
//#endregion
|
|
18
|
+
//#region lib/compile.d.ts
|
|
19
|
+
declare function compile<T extends string, Params = ParseUrlParams<T>>(path: T): {
|
|
20
|
+
parse: Parser<Params>;
|
|
21
|
+
build: Builder<Params>;
|
|
22
|
+
};
|
|
23
|
+
//#endregion
|
|
24
|
+
//#region lib/convert-path.d.ts
|
|
25
|
+
type CompatibilityMode = "express";
|
|
26
|
+
declare function convertPath(path: string, mode: CompatibilityMode): string;
|
|
27
|
+
//#endregion
|
|
28
|
+
//#region lib/validate-path.d.ts
|
|
29
|
+
type SplitPath<S> = string extends S ? string[] : S extends `${infer Head}/${infer Tail}` ? Head extends "" ? SplitPath<Tail> : Tail extends "" ? [Head] : [Head, ...SplitPath<Tail>] : [S];
|
|
30
|
+
type JoinPath<T extends any[]> = `/${Join<T>}`;
|
|
31
|
+
type Join<T extends any[]> = T["length"] extends 0 ? never : T extends [infer F, ...infer Rest] ? Join<Rest> extends infer Tail ? [Tail] extends [never] ? `${F & string}` : `${F & string}/${Tail & string}` : never : never;
|
|
32
|
+
type ValidateRange<Range> = Range extends `${infer L},${infer R}` ? L extends `${number}` ? R extends `${number}` ? ["valid", `{${Range}`] : ["invalid", `{${L},number}`] : R extends `${number}` ? ["invalid", `{number,${R}}`] : ["invalid", `{number,number}`] : ["invalid", `{number,number}`];
|
|
33
|
+
type ValidateTypes<GenTypes> = GenTypes extends "number" ? "valid" : GenTypes extends "" ? ["invalid", "<number,union>"] : GenTypes extends `${string}|${string}` | string ? "valid" : ["invalid", "<number,union>"];
|
|
34
|
+
type ValidateTokenBase<Token extends string, PostFix extends string = ""> = Token extends `${infer Param}<${infer Types}>{${infer Range}}` ? ValidateTypes<Types> extends ["invalid", infer TypesReplacer] ? ["invalid", `:${Param}${TypesReplacer & string}{${Range}}${PostFix}`] : ValidateRange<Range> extends ["invalid", infer RangeReplacer] ? ["invalid", `:${Param}<${Types}>${RangeReplacer & string}${PostFix}`] : "valid" : Token extends `${infer Param}<${infer Types}>` ? ValidateTypes<Types> extends ["invalid", infer TypesReplacer] ? ["invalid", `:${Param}${TypesReplacer & string}${PostFix}`] : "valid" : Token extends `${infer Param}{${infer Range}}` ? ValidateRange<Range> extends ["invalid", infer RangeReplacer] ? ["invalid", `:${Param}${RangeReplacer & string}${PostFix}`] : "valid" : "valid";
|
|
35
|
+
type ValidateToken<Token> = Token extends `:${infer RawParam}` ? RawParam extends `${infer WithoutModifier}${"*" | "?" | "+"}` ? RawParam extends `${WithoutModifier}${infer Modifier}` ? ValidateTokenBase<WithoutModifier, Modifier> : never : ValidateTokenBase<RawParam> : "valid";
|
|
36
|
+
type ValidateTokens<Path, Current, Res extends string[] = []> = Current extends [infer Token, ...infer Rest] ? ValidateToken<ReplaceAll<Token, " ", "">> extends ["invalid", infer TokenReplacer] ? ["invalid", JoinPath<[...Res, TokenReplacer, ...Rest]>] : ValidateTokens<Path, Rest, [...Res, Token & string]> : Path;
|
|
37
|
+
type ValidatePath<Path> = ValidateTokens<Path, SplitPath<Path>>;
|
|
38
|
+
//#endregion
|
|
39
|
+
export { type Builder, type ParseUrlParams, type Parser, type ValidatePath, compile, convertPath };
|
|
40
|
+
//# sourceMappingURL=index.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.cts","names":[],"sources":["../lib/types.ts","../lib/compile.ts","../lib/convert-path.ts","../lib/validate-path.ts"],"mappings":"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"}
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
//#region lib/types.d.ts
|
|
2
|
+
type ReplaceAll<S, From extends string, To extends string> = From extends "" ? S : S extends `${infer R1}${From}${infer R2}` ? `${R1}${To}${ReplaceAll<R2, From, To>}` : S;
|
|
3
|
+
type Parameter<Name extends string, Payload> = { [Key in Name]: Payload };
|
|
4
|
+
type WithModifier<Type, T extends string> = T extends `${infer _K}{${infer _Start},${infer _End}}+` ? Type[] : T extends `${infer _K}{${infer _Start},${infer _End}}*` ? Type[] : T extends `${infer _K}{${infer _Start},${infer _End}}?` ? Type[] | undefined : T extends `${infer _K}{${infer _Start},${infer _End}}` ? Type[] : T extends `${infer _K}+` ? Type[] : T extends `${infer _K}*` ? Type[] : T extends `${infer _K}?` ? Type | undefined : Type;
|
|
5
|
+
type WithoutModifier$1<T extends string> = T extends `${infer K}{${infer _Start},${infer _End}}${infer _Modifier}` ? K : T extends `${infer K}{${infer _Start},${infer _End}}` ? K : T extends `${infer K}?` ? K : T extends `${infer K}*` ? K : T extends `${infer K}+` ? K : T;
|
|
6
|
+
type Union<T extends string, Result = void> = T extends `${infer Start}|${infer Tail}` ? Union<Tail, Result extends void ? Start : Result | Start> : Result extends void ? T : Result | T;
|
|
7
|
+
type GenericType<T extends string> = ReplaceAll<T, " ", ""> extends infer Trimmed ? Trimmed extends "number" ? number : Trimmed extends `${infer _A}|${infer _B}` ? Union<Trimmed & string> : Trimmed : never;
|
|
8
|
+
type UrlParameter<T extends string> = T extends `:${infer Name}<${infer Type}>${infer Modifier}` ? Parameter<WithoutModifier$1<Name>, WithModifier<GenericType<Type>, T>> : T extends `:${infer Name}<${infer Type}>` ? Parameter<Name, GenericType<Type>> : T extends `:${infer Name}` ? Parameter<WithoutModifier$1<Name>, WithModifier<string, T>> : never;
|
|
9
|
+
type UrlParams<T extends string, Result = void> = T extends `/:${infer Parameter}/${infer Route}` ? Result extends void ? UrlParams<`/${Route}`, UrlParameter<`:${Parameter}`>> : UrlParams<`/${Route}`, Result & UrlParameter<`:${Parameter}`>> : T extends `/:${infer Parameter}` ? Result extends void ? UrlParameter<`:${Parameter}`> : Result & UrlParameter<`:${Parameter}`> : T extends `/${infer _Static}/${infer Next}` ? UrlParams<`/${Next}`, Result> : Result;
|
|
10
|
+
type Unwrap<Result extends UrlParams<any, void>> = { [Key in keyof Result]: Result[Key] };
|
|
11
|
+
type ParseUrlParams<T extends string> = Unwrap<UrlParams<T>>;
|
|
12
|
+
type Builder<T> = [T] extends [void] ? (params?: T) => string : (params: T) => string;
|
|
13
|
+
type Parser<T> = (path: string) => {
|
|
14
|
+
path: string;
|
|
15
|
+
params: T;
|
|
16
|
+
} | null;
|
|
17
|
+
//#endregion
|
|
18
|
+
//#region lib/compile.d.ts
|
|
19
|
+
declare function compile<T extends string, Params = ParseUrlParams<T>>(path: T): {
|
|
20
|
+
parse: Parser<Params>;
|
|
21
|
+
build: Builder<Params>;
|
|
22
|
+
};
|
|
23
|
+
//#endregion
|
|
24
|
+
//#region lib/convert-path.d.ts
|
|
25
|
+
type CompatibilityMode = "express";
|
|
26
|
+
declare function convertPath(path: string, mode: CompatibilityMode): string;
|
|
27
|
+
//#endregion
|
|
28
|
+
//#region lib/validate-path.d.ts
|
|
29
|
+
type SplitPath<S> = string extends S ? string[] : S extends `${infer Head}/${infer Tail}` ? Head extends "" ? SplitPath<Tail> : Tail extends "" ? [Head] : [Head, ...SplitPath<Tail>] : [S];
|
|
30
|
+
type JoinPath<T extends any[]> = `/${Join<T>}`;
|
|
31
|
+
type Join<T extends any[]> = T["length"] extends 0 ? never : T extends [infer F, ...infer Rest] ? Join<Rest> extends infer Tail ? [Tail] extends [never] ? `${F & string}` : `${F & string}/${Tail & string}` : never : never;
|
|
32
|
+
type ValidateRange<Range> = Range extends `${infer L},${infer R}` ? L extends `${number}` ? R extends `${number}` ? ["valid", `{${Range}`] : ["invalid", `{${L},number}`] : R extends `${number}` ? ["invalid", `{number,${R}}`] : ["invalid", `{number,number}`] : ["invalid", `{number,number}`];
|
|
33
|
+
type ValidateTypes<GenTypes> = GenTypes extends "number" ? "valid" : GenTypes extends "" ? ["invalid", "<number,union>"] : GenTypes extends `${string}|${string}` | string ? "valid" : ["invalid", "<number,union>"];
|
|
34
|
+
type ValidateTokenBase<Token extends string, PostFix extends string = ""> = Token extends `${infer Param}<${infer Types}>{${infer Range}}` ? ValidateTypes<Types> extends ["invalid", infer TypesReplacer] ? ["invalid", `:${Param}${TypesReplacer & string}{${Range}}${PostFix}`] : ValidateRange<Range> extends ["invalid", infer RangeReplacer] ? ["invalid", `:${Param}<${Types}>${RangeReplacer & string}${PostFix}`] : "valid" : Token extends `${infer Param}<${infer Types}>` ? ValidateTypes<Types> extends ["invalid", infer TypesReplacer] ? ["invalid", `:${Param}${TypesReplacer & string}${PostFix}`] : "valid" : Token extends `${infer Param}{${infer Range}}` ? ValidateRange<Range> extends ["invalid", infer RangeReplacer] ? ["invalid", `:${Param}${RangeReplacer & string}${PostFix}`] : "valid" : "valid";
|
|
35
|
+
type ValidateToken<Token> = Token extends `:${infer RawParam}` ? RawParam extends `${infer WithoutModifier}${"*" | "?" | "+"}` ? RawParam extends `${WithoutModifier}${infer Modifier}` ? ValidateTokenBase<WithoutModifier, Modifier> : never : ValidateTokenBase<RawParam> : "valid";
|
|
36
|
+
type ValidateTokens<Path, Current, Res extends string[] = []> = Current extends [infer Token, ...infer Rest] ? ValidateToken<ReplaceAll<Token, " ", "">> extends ["invalid", infer TokenReplacer] ? ["invalid", JoinPath<[...Res, TokenReplacer, ...Rest]>] : ValidateTokens<Path, Rest, [...Res, Token & string]> : Path;
|
|
37
|
+
type ValidatePath<Path> = ValidateTokens<Path, SplitPath<Path>>;
|
|
38
|
+
//#endregion
|
|
39
|
+
export { type Builder, type ParseUrlParams, type Parser, type ValidatePath, compile, convertPath };
|
|
40
|
+
//# sourceMappingURL=index.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../lib/types.ts","../lib/compile.ts","../lib/convert-path.ts","../lib/validate-path.ts"],"mappings":"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"}
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
//#region lib/get-token-parameters.ts
|
|
2
|
+
function getTokenParameters(match) {
|
|
3
|
+
if (!match) return null;
|
|
4
|
+
const [, name, rawGenericProps, rawArrayProps, modifier] = match;
|
|
5
|
+
return {
|
|
6
|
+
name,
|
|
7
|
+
genericProps: rawGenericProps?.slice(1, -1).replaceAll(" ", ""),
|
|
8
|
+
arrayProps: rawArrayProps?.slice(1, -1).split(",").map((value) => Number(value)),
|
|
9
|
+
modifier
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
//#endregion
|
|
13
|
+
//#region lib/prepare-builder.ts
|
|
14
|
+
function prepareBuilder(tokens) {
|
|
15
|
+
return ((params = void 0) => {
|
|
16
|
+
const result = [];
|
|
17
|
+
if (tokens.length === 0) return "/";
|
|
18
|
+
for (const token of tokens) {
|
|
19
|
+
if (token.type === "const") {
|
|
20
|
+
result.push(token.name);
|
|
21
|
+
continue;
|
|
22
|
+
}
|
|
23
|
+
const value = params?.[token.name];
|
|
24
|
+
if (value == null) continue;
|
|
25
|
+
if (Array.isArray(value)) for (const item of value) result.push(String(item));
|
|
26
|
+
else result.push(String(value));
|
|
27
|
+
}
|
|
28
|
+
return `/${result.join("/")}`;
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
//#endregion
|
|
32
|
+
//#region lib/prepare-parser.ts
|
|
33
|
+
function prepareParser(tokens) {
|
|
34
|
+
return (input) => {
|
|
35
|
+
const rawTokens = input.split("/").map((part) => part.trim()).filter((part) => part !== "");
|
|
36
|
+
let params = null;
|
|
37
|
+
function setKey(key, value) {
|
|
38
|
+
params ??= {};
|
|
39
|
+
params[key] = value;
|
|
40
|
+
}
|
|
41
|
+
if (tokens.length === 0) return rawTokens.length === 0 ? {
|
|
42
|
+
path: input,
|
|
43
|
+
params: null
|
|
44
|
+
} : null;
|
|
45
|
+
for (let i = 0; i < tokens.length; i += 1) {
|
|
46
|
+
const token = tokens[i];
|
|
47
|
+
if (!token) return null;
|
|
48
|
+
if (token.type === "const") {
|
|
49
|
+
if (token.name !== rawTokens.shift()) return null;
|
|
50
|
+
continue;
|
|
51
|
+
}
|
|
52
|
+
const { arrayProps, genericProps, required } = token.payload;
|
|
53
|
+
if (arrayProps) {
|
|
54
|
+
const array = [];
|
|
55
|
+
let rawToken;
|
|
56
|
+
while (true) {
|
|
57
|
+
rawToken = rawTokens.shift();
|
|
58
|
+
if (!rawToken) break;
|
|
59
|
+
const parsed = parseToken(rawToken, genericProps);
|
|
60
|
+
if (!parsed.success) return null;
|
|
61
|
+
array.push(parsed.value);
|
|
62
|
+
if (array.length >= (arrayProps.max ?? Infinity)) break;
|
|
63
|
+
}
|
|
64
|
+
if (array.length < (arrayProps.min ?? 0)) return null;
|
|
65
|
+
if (rawTokens.length > 0 && !tokens[i + 1]) return null;
|
|
66
|
+
setKey(token.name, array);
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
const rawToken = rawTokens.shift();
|
|
70
|
+
if (required && !rawToken) return null;
|
|
71
|
+
if (!rawToken) {
|
|
72
|
+
setKey(token.name, void 0);
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
const parsed = parseToken(rawToken, genericProps);
|
|
76
|
+
if (!parsed.success) return null;
|
|
77
|
+
setKey(token.name, parsed.value);
|
|
78
|
+
}
|
|
79
|
+
if (rawTokens.length > 0) return null;
|
|
80
|
+
return {
|
|
81
|
+
path: input,
|
|
82
|
+
params
|
|
83
|
+
};
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
function parseToken(rawToken, genericProps) {
|
|
87
|
+
if (genericProps?.type === "number") {
|
|
88
|
+
if (Number.isNaN(Number(rawToken))) return { success: false };
|
|
89
|
+
return {
|
|
90
|
+
success: true,
|
|
91
|
+
value: Number(rawToken)
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
if (genericProps?.type === "union") {
|
|
95
|
+
if (!genericProps.items.includes(rawToken)) return { success: false };
|
|
96
|
+
return {
|
|
97
|
+
success: true,
|
|
98
|
+
value: rawToken
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
return {
|
|
102
|
+
success: true,
|
|
103
|
+
value: rawToken
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
//#endregion
|
|
107
|
+
//#region lib/compile.ts
|
|
108
|
+
function compile(path) {
|
|
109
|
+
const tokens = [];
|
|
110
|
+
const regexp = /:(\w+)(<[\s?\w|]+>)?({\d+,\d+})?([+*?])?/;
|
|
111
|
+
const parsedTokens = path.split("/").filter(Boolean);
|
|
112
|
+
for (const parsedToken of parsedTokens) {
|
|
113
|
+
const parameters = getTokenParameters(parsedToken.match(regexp));
|
|
114
|
+
if (!parameters) {
|
|
115
|
+
tokens.push({
|
|
116
|
+
type: "const",
|
|
117
|
+
name: parsedToken,
|
|
118
|
+
payload: void 0
|
|
119
|
+
});
|
|
120
|
+
continue;
|
|
121
|
+
}
|
|
122
|
+
const { arrayProps, genericProps, modifier, name } = parameters;
|
|
123
|
+
if (!name) throw new Error(`Invalid path: "${path}". Name for argument must be provided`);
|
|
124
|
+
const token = {
|
|
125
|
+
type: "parameter",
|
|
126
|
+
name,
|
|
127
|
+
payload: { required: true }
|
|
128
|
+
};
|
|
129
|
+
if (genericProps === "number") token.payload.genericProps = { type: "number" };
|
|
130
|
+
if (genericProps?.includes("|")) token.payload.genericProps = {
|
|
131
|
+
type: "union",
|
|
132
|
+
items: genericProps.split("|")
|
|
133
|
+
};
|
|
134
|
+
switch (modifier) {
|
|
135
|
+
case "*":
|
|
136
|
+
token.payload.arrayProps = {};
|
|
137
|
+
break;
|
|
138
|
+
case "+":
|
|
139
|
+
token.payload.arrayProps = { min: 1 };
|
|
140
|
+
break;
|
|
141
|
+
case "?":
|
|
142
|
+
token.payload.required = false;
|
|
143
|
+
break;
|
|
144
|
+
}
|
|
145
|
+
if (arrayProps) token.payload.arrayProps = {
|
|
146
|
+
...token.payload.arrayProps,
|
|
147
|
+
min: arrayProps[0],
|
|
148
|
+
max: arrayProps[1]
|
|
149
|
+
};
|
|
150
|
+
tokens.push(token);
|
|
151
|
+
}
|
|
152
|
+
return {
|
|
153
|
+
parse: prepareParser(tokens),
|
|
154
|
+
build: prepareBuilder(tokens)
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
//#endregion
|
|
158
|
+
//#region lib/convert-path.ts
|
|
159
|
+
const cases = { express: [
|
|
160
|
+
[/:id<.+>/g, ":id"],
|
|
161
|
+
[/:id\+/g, "*id"],
|
|
162
|
+
[/:id\*/g, "*id"],
|
|
163
|
+
[/:id\{.+\}/g, "*id"],
|
|
164
|
+
[/([a-zA-Z0-9:/_.]+)\/([*:])id\?/g, "$1{/$2id}"],
|
|
165
|
+
[/([*:])id\?/g, "{$1id}"]
|
|
166
|
+
] };
|
|
167
|
+
function convertPath(path, mode) {
|
|
168
|
+
switch (mode) {
|
|
169
|
+
case "express": {
|
|
170
|
+
let nextPath = path;
|
|
171
|
+
for (const [regex, replacement] of cases.express) if (nextPath.match(regex)) nextPath = nextPath.replace(regex, replacement);
|
|
172
|
+
return nextPath;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
//#endregion
|
|
177
|
+
export { compile, convertPath };
|
|
178
|
+
|
|
179
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../lib/get-token-parameters.ts","../lib/prepare-builder.ts","../lib/prepare-parser.ts","../lib/compile.ts","../lib/convert-path.ts"],"sourcesContent":["interface TokenParameters {\n name: string | undefined;\n genericProps: string | undefined;\n arrayProps: [number, number] | undefined;\n modifier: string | undefined;\n}\n\nexport function getTokenParameters(match: RegExpMatchArray | null): TokenParameters | null {\n if (!match) {\n return null;\n }\n\n const [, name, rawGenericProps, rawArrayProps, modifier] = match;\n const genericProps = rawGenericProps?.slice(1, -1).replaceAll(\" \", \"\");\n const arrayProps = rawArrayProps\n ?.slice(1, -1)\n .split(\",\")\n .map((value) => Number(value)) as [number, number] | undefined;\n\n return {\n name,\n genericProps,\n arrayProps,\n modifier\n };\n}\n","import type { Builder, Token } from \"./types\";\n\nexport function prepareBuilder<T>(tokens: Token[]): Builder<T> {\n return ((params: any = undefined) => {\n const result: string[] = [];\n\n if (tokens.length === 0) {\n return \"/\";\n }\n\n for (const token of tokens) {\n if (token.type === \"const\") {\n result.push(token.name);\n continue;\n }\n\n const value = params?.[token.name];\n\n if (value == null) {\n continue;\n }\n\n if (Array.isArray(value)) {\n for (const item of value) {\n result.push(String(item));\n }\n } else {\n result.push(String(value));\n }\n }\n\n return `/${result.join(\"/\")}`;\n }) as Builder<T>;\n}\n","import type { Parser, Token } from \"./types\";\n\nexport function prepareParser<T>(tokens: Token[]): Parser<T> {\n return (input) => {\n const rawTokens = input\n .split(\"/\")\n .map((part) => part.trim())\n .filter((part) => part !== \"\");\n\n let params: Record<string, unknown> | null = null;\n\n function setKey(key: string, value: unknown) {\n params ??= {};\n params[key] = value;\n }\n\n if (tokens.length === 0) {\n return rawTokens.length === 0 ? { path: input, params: null as T } : null;\n }\n\n for (let i = 0; i < tokens.length; i += 1) {\n const token = tokens[i];\n\n if (!token) {\n return null;\n }\n\n if (token.type === \"const\") {\n if (token.name !== rawTokens.shift()) {\n return null;\n }\n\n continue;\n }\n\n const { arrayProps, genericProps, required } = token.payload;\n\n if (arrayProps) {\n const array: unknown[] = [];\n let rawToken: string | undefined;\n\n while (true) {\n rawToken = rawTokens.shift();\n\n if (!rawToken) {\n break;\n }\n\n const parsed = parseToken(rawToken, genericProps);\n\n if (!parsed.success) {\n return null;\n }\n\n array.push(parsed.value);\n\n if (array.length >= (arrayProps.max ?? Infinity)) {\n break;\n }\n }\n\n if (array.length < (arrayProps.min ?? 0)) {\n return null;\n }\n\n if (rawTokens.length > 0 && !tokens[i + 1]) {\n return null;\n }\n\n setKey(token.name, array);\n continue;\n }\n\n const rawToken = rawTokens.shift();\n\n if (required && !rawToken) {\n return null;\n }\n\n if (!rawToken) {\n setKey(token.name, undefined);\n continue;\n }\n\n const parsed = parseToken(rawToken, genericProps);\n\n if (!parsed.success) {\n return null;\n }\n\n setKey(token.name, parsed.value);\n }\n\n if (rawTokens.length > 0) {\n return null;\n }\n\n return { path: input, params: params as T };\n };\n}\n\nfunction parseToken(\n rawToken: string,\n genericProps: { type: \"union\"; items: string[] } | { type: \"number\" } | undefined,\n): { success: true; value: unknown } | { success: false } {\n if (genericProps?.type === \"number\") {\n if (Number.isNaN(Number(rawToken))) {\n return { success: false };\n }\n\n return { success: true, value: Number(rawToken) };\n }\n\n if (genericProps?.type === \"union\") {\n if (!genericProps.items.includes(rawToken)) {\n return { success: false };\n }\n\n return { success: true, value: rawToken };\n }\n\n return { success: true, value: rawToken };\n}\n","import { getTokenParameters } from \"./get-token-parameters\";\nimport { prepareBuilder } from \"./prepare-builder\";\nimport { prepareParser } from \"./prepare-parser\";\nimport type { ParameterToken, ParseUrlParams, Token } from \"./types\";\n\nexport function compile<T extends string, Params = ParseUrlParams<T>>(path: T) {\n const tokens: Token[] = [];\n const regexp = /:(\\w+)(<[\\s?\\w|]+>)?({\\d+,\\d+})?([+*?])?/;\n const parsedTokens = path.split(\"/\").filter(Boolean);\n\n for (const parsedToken of parsedTokens) {\n const parameters = getTokenParameters(parsedToken.match(regexp));\n\n if (!parameters) {\n tokens.push({ type: \"const\", name: parsedToken, payload: undefined });\n continue;\n }\n\n const { arrayProps, genericProps, modifier, name } = parameters;\n\n if (!name) {\n throw new Error(`Invalid path: \"${path}\". Name for argument must be provided`);\n }\n\n const token: ParameterToken = {\n type: \"parameter\",\n name,\n payload: {\n required: true\n }\n };\n\n if (genericProps === \"number\") {\n token.payload.genericProps = { type: \"number\" };\n }\n\n if (genericProps?.includes(\"|\")) {\n token.payload.genericProps = {\n type: \"union\",\n items: genericProps.split(\"|\")\n };\n }\n\n switch (modifier) {\n case \"*\": {\n token.payload.arrayProps = {};\n break;\n }\n case \"+\": {\n token.payload.arrayProps = { min: 1 };\n break;\n }\n case \"?\": {\n token.payload.required = false;\n break;\n }\n }\n\n if (arrayProps) {\n token.payload.arrayProps = {\n ...token.payload.arrayProps,\n min: arrayProps[0],\n max: arrayProps[1]\n };\n }\n\n tokens.push(token);\n }\n\n return {\n parse: prepareParser<Params>(tokens),\n build: prepareBuilder<Params>(tokens)\n };\n}\n","type CompatibilityMode = \"express\";\n\nconst cases = {\n express: [\n [/:id<.+>/g, \":id\"],\n [/:id\\+/g, \"*id\"],\n [/:id\\*/g, \"*id\"],\n [/:id\\{.+\\}/g, \"*id\"],\n [/([a-zA-Z0-9:/_.]+)\\/([*:])id\\?/g, \"$1{/$2id}\"],\n [/([*:])id\\?/g, \"{$1id}\"]\n ]\n} as const;\n\nexport function convertPath(path: string, mode: CompatibilityMode): string {\n switch (mode) {\n case \"express\": {\n let nextPath = path;\n\n for (const [regex, replacement] of cases.express) {\n if (nextPath.match(regex)) {\n nextPath = nextPath.replace(regex, replacement);\n }\n }\n\n return nextPath;\n }\n }\n}\n"],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@virentia/router-paths",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Typed route path compiler for Virentia Router",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "https://github.com/virentia-labs/router.git",
|
|
10
|
+
"directory": "packages/paths"
|
|
11
|
+
},
|
|
12
|
+
"main": "./dist/index.cjs",
|
|
13
|
+
"module": "./dist/index.mjs",
|
|
14
|
+
"types": "./dist/index.d.mts",
|
|
15
|
+
"exports": {
|
|
16
|
+
".": {
|
|
17
|
+
"types": "./dist/index.d.mts",
|
|
18
|
+
"import": "./dist/index.mjs",
|
|
19
|
+
"require": "./dist/index.cjs"
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
"files": [
|
|
23
|
+
"dist"
|
|
24
|
+
],
|
|
25
|
+
"publishConfig": {
|
|
26
|
+
"access": "public"
|
|
27
|
+
},
|
|
28
|
+
"devDependencies": {
|
|
29
|
+
"vitest": "^4.0.18"
|
|
30
|
+
},
|
|
31
|
+
"scripts": {
|
|
32
|
+
"build": "tsdown",
|
|
33
|
+
"test": "vitest run"
|
|
34
|
+
}
|
|
35
|
+
}
|