@jlnstack/routes 0.0.6 → 0.0.8
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/README.md +5 -0
- package/dist/index.cjs +89 -0
- package/dist/index.d.cts +54 -0
- package/dist/index.d.cts.map +1 -0
- package/dist/index.d.mts +54 -0
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +90 -0
- package/dist/index.mjs.map +1 -0
- package/dist/proxy.cjs +19 -0
- package/dist/proxy.mjs +19 -0
- package/dist/proxy.mjs.map +1 -0
- package/package.json +1 -1
package/README.md
ADDED
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
const require_proxy = require('./proxy.cjs');
|
|
2
|
+
|
|
3
|
+
//#region src/index.ts
|
|
4
|
+
function isStandardSchema(value) {
|
|
5
|
+
return typeof value === "object" && value !== null && "~standard" in value && typeof value["~standard"] === "object";
|
|
6
|
+
}
|
|
7
|
+
function findMatchingRoute(segments, schemaMap) {
|
|
8
|
+
for (const routePattern of Object.keys(schemaMap)) {
|
|
9
|
+
const patternSegments = routePattern.split("/").filter(Boolean);
|
|
10
|
+
if (patternSegments.length !== segments.length) continue;
|
|
11
|
+
if (patternSegments.every((pattern, i) => {
|
|
12
|
+
if (pattern.startsWith("[") && pattern.endsWith("]")) return true;
|
|
13
|
+
if (pattern.startsWith("[[") && pattern.endsWith("]]")) return true;
|
|
14
|
+
return pattern === segments[i];
|
|
15
|
+
})) return routePattern;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
function validateParams(params, schemas) {
|
|
19
|
+
const validated = {};
|
|
20
|
+
for (const [key, value] of Object.entries(params)) {
|
|
21
|
+
const schema = schemas[key];
|
|
22
|
+
if (isStandardSchema(schema)) {
|
|
23
|
+
const result = schema["~standard"].validate(value);
|
|
24
|
+
if (result instanceof Promise) throw new Error(`Async validation is not supported for param "${key}"`);
|
|
25
|
+
if (result.issues) {
|
|
26
|
+
var _result$issues$;
|
|
27
|
+
throw new Error(`Validation failed for param "${key}": ${(_result$issues$ = result.issues[0]) === null || _result$issues$ === void 0 ? void 0 : _result$issues$.message}`);
|
|
28
|
+
}
|
|
29
|
+
validated[key] = result.value;
|
|
30
|
+
} else validated[key] = value;
|
|
31
|
+
}
|
|
32
|
+
return validated;
|
|
33
|
+
}
|
|
34
|
+
function createRoutesWithConfig(config) {
|
|
35
|
+
const paramSchemas = {};
|
|
36
|
+
if (config) for (const [route, routeConfig] of Object.entries(config)) {
|
|
37
|
+
const rc = routeConfig;
|
|
38
|
+
if (rc === null || rc === void 0 ? void 0 : rc.params) paramSchemas[route] = rc.params;
|
|
39
|
+
}
|
|
40
|
+
return require_proxy.createRecursiveProxy(({ path, args }) => {
|
|
41
|
+
var _args$;
|
|
42
|
+
const segments = path.slice(0, -1);
|
|
43
|
+
const rawParams = (_args$ = args[0]) !== null && _args$ !== void 0 ? _args$ : {};
|
|
44
|
+
const searchParams = args[1];
|
|
45
|
+
const appendSearchParams = (basePath$1) => {
|
|
46
|
+
if (!searchParams || Object.keys(searchParams).length === 0) return basePath$1;
|
|
47
|
+
const urlSearchParams$1 = new URLSearchParams();
|
|
48
|
+
for (const [key, value] of Object.entries(searchParams)) {
|
|
49
|
+
if (value === void 0 || value === null) continue;
|
|
50
|
+
if (Array.isArray(value)) for (const v of value) urlSearchParams$1.append(key, String(v));
|
|
51
|
+
else urlSearchParams$1.append(key, String(value));
|
|
52
|
+
}
|
|
53
|
+
const queryString$1 = urlSearchParams$1.toString();
|
|
54
|
+
return queryString$1 ? `${basePath$1}?${queryString$1}` : basePath$1;
|
|
55
|
+
};
|
|
56
|
+
if (segments.length === 0) return appendSearchParams("/");
|
|
57
|
+
let params = rawParams;
|
|
58
|
+
if (Object.keys(paramSchemas).length > 0) {
|
|
59
|
+
const matchingRoute = findMatchingRoute(segments, paramSchemas);
|
|
60
|
+
if (matchingRoute && matchingRoute in paramSchemas) {
|
|
61
|
+
const routeSchemas = paramSchemas[matchingRoute];
|
|
62
|
+
params = validateParams(rawParams, routeSchemas);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
const resolved = segments.flatMap((seg) => {
|
|
66
|
+
if (!(seg in params)) return seg;
|
|
67
|
+
const value = params[seg];
|
|
68
|
+
if (Array.isArray(value)) return value;
|
|
69
|
+
if (value === void 0) return [];
|
|
70
|
+
return String(value);
|
|
71
|
+
});
|
|
72
|
+
const basePath = resolved.length === 0 ? "/" : `/${resolved.join("/")}`;
|
|
73
|
+
if (!searchParams || Object.keys(searchParams).length === 0) return basePath;
|
|
74
|
+
const urlSearchParams = new URLSearchParams();
|
|
75
|
+
for (const [key, value] of Object.entries(searchParams)) {
|
|
76
|
+
if (value === void 0 || value === null) continue;
|
|
77
|
+
if (Array.isArray(value)) for (const v of value) urlSearchParams.append(key, String(v));
|
|
78
|
+
else urlSearchParams.append(key, String(value));
|
|
79
|
+
}
|
|
80
|
+
const queryString = urlSearchParams.toString();
|
|
81
|
+
return queryString ? `${basePath}?${queryString}` : basePath;
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
function createRoutes() {
|
|
85
|
+
return (config) => createRoutesWithConfig(config);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
//#endregion
|
|
89
|
+
exports.createRoutes = createRoutes;
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { StandardSchemaV1 } from "@standard-schema/spec";
|
|
2
|
+
|
|
3
|
+
//#region src/index.d.ts
|
|
4
|
+
type ValidParamValue = string | number | boolean | bigint | string[] | readonly string[];
|
|
5
|
+
type ParamMapValue = ValidParamValue | StandardSchemaV1<unknown, ValidParamValue>;
|
|
6
|
+
type ParamMapConstraint<Routes extends string> = { [K in Routes]?: Record<string, ParamMapValue> };
|
|
7
|
+
type SearchParamValue = string | number | boolean | string[] | StandardSchemaV1<unknown, string | number | boolean | string[]>;
|
|
8
|
+
type SearchParamMapConstraint<Routes extends string> = { [K in Routes]?: Record<string, SearchParamValue> };
|
|
9
|
+
type ExtractRouteParams<Route extends string> = Route extends `${string}[[...${infer Param}]]${infer Rest}` ? Param | ExtractRouteParams<Rest> : Route extends `${string}[...${infer Param}]${infer Rest}` ? Param | ExtractRouteParams<Rest> : Route extends `${string}[${infer Param}]${infer Rest}` ? Param | ExtractRouteParams<Rest> : never;
|
|
10
|
+
type RouteConfigFor<Route extends string> = {
|
|
11
|
+
params?: { [K in ExtractRouteParams<Route>]?: ParamMapValue };
|
|
12
|
+
searchParams?: Record<string, SearchParamValue>;
|
|
13
|
+
};
|
|
14
|
+
type RoutesConfigConstraint<Routes extends string, T = {}> = { [K in Routes]?: RouteConfigFor<K> } & { [K in keyof T]: K extends Routes ? RouteConfigFor<K> : never };
|
|
15
|
+
type ExtractParamMap<Routes extends string, Config> = { [K in Routes]: K extends keyof Config ? Config[K] extends {
|
|
16
|
+
params: infer P extends Record<string, ParamMapValue>;
|
|
17
|
+
} ? P : undefined : undefined };
|
|
18
|
+
type ExtractSearchParamMap<Routes extends string, Config> = { [K in Routes]: K extends keyof Config ? Config[K] extends {
|
|
19
|
+
searchParams: infer SP extends Record<string, SearchParamValue>;
|
|
20
|
+
} ? SP : undefined : undefined };
|
|
21
|
+
type ExtractSearchParamType<T> = T extends StandardSchemaV1 ? StandardSchemaV1.InferOutput<T> : T;
|
|
22
|
+
type SearchParamsFor<Routes extends string, Path extends string, SearchParamMap extends SearchParamMapConstraint<Routes>> = Path extends keyof SearchParamMap ? SearchParamMap[Path] extends infer SP ? SP extends Record<string, SearchParamValue> ? { [K in keyof SP]?: ExtractSearchParamType<SP[K]> } : Record<string, string | number | boolean | string[] | undefined> : Record<string, string | number | boolean | string[] | undefined> : Record<string, string | number | boolean | string[] | undefined>;
|
|
23
|
+
type ExtractParamType<T> = T extends StandardSchemaV1 ? StandardSchemaV1.InferOutput<T> : T;
|
|
24
|
+
type FindParamInMap<Routes extends string, CurrentPath extends string, ParamName extends string, ParamMap extends ParamMapConstraint<Routes>> = { [R in Routes]: R extends `${CurrentPath}${"" | `/${string}`}` ? R extends keyof ParamMap ? ParamName extends keyof NonNullable<ParamMap[R]> ? ExtractParamType<NonNullable<ParamMap[R]>[ParamName]> : never : never : never }[Routes];
|
|
25
|
+
type GetParamType<Routes extends string, CurrentPath extends string, ParamName extends string, ParamMap extends ParamMapConstraint<Routes>, DefaultType> = [FindParamInMap<Routes, CurrentPath, ParamName, ParamMap>] extends [never] ? DefaultType : FindParamInMap<Routes, CurrentPath, ParamName, ParamMap>;
|
|
26
|
+
type SegmentName<S extends string> = S extends `[...${infer N}]` ? N : S extends `[[...${infer N}]]` ? N : S extends `[${infer N}]` ? N : S;
|
|
27
|
+
type ChildSegments<Routes extends string, Path extends string> = Routes extends `${Path}/${infer Next}/${string}` ? SegmentName<Next> : Routes extends `${Path}/${infer Next}` ? SegmentName<Next> : never;
|
|
28
|
+
type IsDynamicSegment<S extends string> = S extends `[${string}]` | `[...${string}]` | `[[...${string}]]` ? true : false;
|
|
29
|
+
type IsCatchAllSegment<S extends string> = S extends `[...${string}]` ? true : false;
|
|
30
|
+
type IsOptionalCatchAllSegment<S extends string> = S extends `[[...${string}]]` ? true : false;
|
|
31
|
+
type GetOriginalSegment<Routes extends string, Path extends string, Seg extends string> = Routes extends `${Path}/${infer Next}/${string}` ? SegmentName<Next> extends Seg ? Next : never : Routes extends `${Path}/${infer Next}` ? SegmentName<Next> extends Seg ? Next : never : never;
|
|
32
|
+
type IsDynamicAtPath<Routes extends string, Path extends string, Seg extends string> = GetOriginalSegment<Routes, Path, Seg> extends infer Original ? Original extends string ? IsDynamicSegment<Original> extends true ? true : false : false : false;
|
|
33
|
+
type IsCatchAllAtPath<Routes extends string, Path extends string, Seg extends string> = GetOriginalSegment<Routes, Path, Seg> extends infer Original ? Original extends string ? IsCatchAllSegment<Original> extends true ? true : false : false : false;
|
|
34
|
+
type IsOptionalCatchAllAtPath<Routes extends string, Path extends string, Seg extends string> = GetOriginalSegment<Routes, Path, Seg> extends infer Original ? Original extends string ? IsOptionalCatchAllSegment<Original> extends true ? true : false : false : false;
|
|
35
|
+
type Join<T extends readonly string[], Sep extends string> = T extends readonly [infer First extends string, ...infer Rest extends readonly string[]] ? Rest["length"] extends 0 ? First : `${First}${Sep}${Join<Rest, Sep>}` : "";
|
|
36
|
+
type Stringify<T> = T extends string | number | boolean | bigint ? `${T}` : never;
|
|
37
|
+
type UnionToIntersection<U> = (U extends unknown ? (k: U) => void : never) extends ((k: infer I) => void) ? I : never;
|
|
38
|
+
type UnionToLast<U> = UnionToIntersection<U extends unknown ? () => U : never> extends (() => infer R) ? R : never;
|
|
39
|
+
type UnionToTuple<U, R extends unknown[] = [], Last = UnionToLast<U>> = [U] extends [never] ? R : UnionToTuple<Exclude<U, Last>, [Last, ...R]>;
|
|
40
|
+
type JoinStrings<T extends readonly string[], Sep extends string = "&"> = T extends readonly [infer Only extends string] ? Only : T extends readonly [infer First extends string, ...infer Rest extends readonly string[]] ? `${First}${Sep}${JoinStrings<Rest, Sep>}` : "";
|
|
41
|
+
type ArrayToQueryPairs<K extends string, T extends readonly unknown[]> = T extends readonly [infer First, ...infer Rest extends readonly unknown[]] ? First extends string | number | boolean | bigint ? Rest["length"] extends 0 ? `${K}=${First}` : `${K}=${First}` | ArrayToQueryPairs<K, Rest> : never : never;
|
|
42
|
+
type QueryPairs<T extends Record<string, unknown>> = { [K in keyof T]-?: T[K] extends undefined | never ? never : T[K] extends readonly (string | number | boolean | bigint)[] ? ArrayToQueryPairs<K & string, T[K]> : `${K & string}=${Stringify<T[K]>}` }[keyof T];
|
|
43
|
+
type BuildQueryString<T extends Record<string, unknown>> = JoinStrings<UnionToTuple<QueryPairs<T>> extends readonly string[] ? UnionToTuple<QueryPairs<T>> : never>;
|
|
44
|
+
type AppendQuery<Path extends string, SP> = SP extends Record<string, unknown> ? [keyof SP] extends [never] ? Path : BuildQueryString<SP> extends infer QS extends string ? QS extends "" ? Path : `${Path}?${QS}` : Path : Path;
|
|
45
|
+
type ReplaceDynamicSegments<Path extends string, P extends Record<string, unknown>> = Path extends `${infer Start}/[[...${infer Param}]]${infer Rest}` ? Param extends keyof P ? P[Param] extends readonly string[] ? `${ReplaceDynamicSegments<Start, P>}/${Join<P[Param], "/">}${ReplaceDynamicSegments<Rest, P>}` : `${ReplaceDynamicSegments<Start, P>}${ReplaceDynamicSegments<Rest, P>}` : `${ReplaceDynamicSegments<Start, P>}${ReplaceDynamicSegments<Rest, P>}` : Path extends `${infer Start}/[...${infer Param}]${infer Rest}` ? Param extends keyof P ? P[Param] extends readonly string[] ? `${ReplaceDynamicSegments<Start, P>}/${Join<P[Param], "/">}${ReplaceDynamicSegments<Rest, P>}` : `${ReplaceDynamicSegments<Start, P>}/[...${Param}]${ReplaceDynamicSegments<Rest, P>}` : `${ReplaceDynamicSegments<Start, P>}/[...${Param}]${ReplaceDynamicSegments<Rest, P>}` : Path extends `${infer Start}/[${infer Param}]${infer Rest}` ? Param extends keyof P ? Stringify<P[Param]> extends string ? `${Start}/${Stringify<P[Param]>}${ReplaceDynamicSegments<Rest, P>}` : `${Start}/[${Param}]${ReplaceDynamicSegments<Rest, P>}` : `${Start}/[${Param}]${ReplaceDynamicSegments<Rest, P>}` : Path;
|
|
46
|
+
type NextPath<Routes extends string, Path extends string, Seg extends string> = Path extends "" ? `/${GetOriginalSegment<Routes, Path, Seg>}` : `${Path}/${GetOriginalSegment<Routes, Path, Seg>}`;
|
|
47
|
+
type RouteNode<R extends string, Path extends string, Params extends Record<string, unknown> = {}, ParamMap extends ParamMapConstraint<R> = {}, SearchParamMap extends SearchParamMapConstraint<R> = {}> = {
|
|
48
|
+
getRoute: [keyof Params] extends [never] ? <const SP extends SearchParamsFor<R, Path extends "" ? "/" : Path, SearchParamMap> | undefined = undefined>(params?: undefined, searchParams?: SP) => AppendQuery<Path extends "" ? "/" : Path, SP> : <const P extends Params, const SP extends SearchParamsFor<R, Path, SearchParamMap> | undefined = undefined>(params: P, searchParams?: SP) => AppendQuery<ReplaceDynamicSegments<Path, P>, SP>;
|
|
49
|
+
} & { [Seg in ChildSegments<R, Path>]: RouteNode<R, NextPath<R, Path, Seg>, IsOptionalCatchAllAtPath<R, Path, Seg> extends true ? Params & { [K in Seg]?: GetParamType<R, NextPath<R, Path, Seg>, K, ParamMap, string[]> } : IsCatchAllAtPath<R, Path, Seg> extends true ? Params & { [K in Seg]: GetParamType<R, NextPath<R, Path, Seg>, K, ParamMap, string[]> } : IsDynamicAtPath<R, Path, Seg> extends true ? Params & { [K in Seg]: GetParamType<R, NextPath<R, Path, Seg>, K, ParamMap, string> } : Params, ParamMap, SearchParamMap> };
|
|
50
|
+
type Routes<R extends string, Config = {}> = RouteNode<R, "", {}, ExtractParamMap<R, Config>, ExtractSearchParamMap<R, Config>>;
|
|
51
|
+
declare function createRoutes<const R extends string>(): <const Config extends RoutesConfigConstraint<R, Config>>(config?: Config) => Routes<R, Config>;
|
|
52
|
+
//#endregion
|
|
53
|
+
export { Routes, createRoutes };
|
|
54
|
+
//# sourceMappingURL=index.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.cts","names":[],"sources":["../src/index.ts"],"sourcesContent":[],"mappings":"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"}
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { StandardSchemaV1 } from "@standard-schema/spec";
|
|
2
|
+
|
|
3
|
+
//#region src/index.d.ts
|
|
4
|
+
type ValidParamValue = string | number | boolean | bigint | string[] | readonly string[];
|
|
5
|
+
type ParamMapValue = ValidParamValue | StandardSchemaV1<unknown, ValidParamValue>;
|
|
6
|
+
type ParamMapConstraint<Routes extends string> = { [K in Routes]?: Record<string, ParamMapValue> };
|
|
7
|
+
type SearchParamValue = string | number | boolean | string[] | StandardSchemaV1<unknown, string | number | boolean | string[]>;
|
|
8
|
+
type SearchParamMapConstraint<Routes extends string> = { [K in Routes]?: Record<string, SearchParamValue> };
|
|
9
|
+
type ExtractRouteParams<Route extends string> = Route extends `${string}[[...${infer Param}]]${infer Rest}` ? Param | ExtractRouteParams<Rest> : Route extends `${string}[...${infer Param}]${infer Rest}` ? Param | ExtractRouteParams<Rest> : Route extends `${string}[${infer Param}]${infer Rest}` ? Param | ExtractRouteParams<Rest> : never;
|
|
10
|
+
type RouteConfigFor<Route extends string> = {
|
|
11
|
+
params?: { [K in ExtractRouteParams<Route>]?: ParamMapValue };
|
|
12
|
+
searchParams?: Record<string, SearchParamValue>;
|
|
13
|
+
};
|
|
14
|
+
type RoutesConfigConstraint<Routes extends string, T = {}> = { [K in Routes]?: RouteConfigFor<K> } & { [K in keyof T]: K extends Routes ? RouteConfigFor<K> : never };
|
|
15
|
+
type ExtractParamMap<Routes extends string, Config> = { [K in Routes]: K extends keyof Config ? Config[K] extends {
|
|
16
|
+
params: infer P extends Record<string, ParamMapValue>;
|
|
17
|
+
} ? P : undefined : undefined };
|
|
18
|
+
type ExtractSearchParamMap<Routes extends string, Config> = { [K in Routes]: K extends keyof Config ? Config[K] extends {
|
|
19
|
+
searchParams: infer SP extends Record<string, SearchParamValue>;
|
|
20
|
+
} ? SP : undefined : undefined };
|
|
21
|
+
type ExtractSearchParamType<T> = T extends StandardSchemaV1 ? StandardSchemaV1.InferOutput<T> : T;
|
|
22
|
+
type SearchParamsFor<Routes extends string, Path extends string, SearchParamMap extends SearchParamMapConstraint<Routes>> = Path extends keyof SearchParamMap ? SearchParamMap[Path] extends infer SP ? SP extends Record<string, SearchParamValue> ? { [K in keyof SP]?: ExtractSearchParamType<SP[K]> } : Record<string, string | number | boolean | string[] | undefined> : Record<string, string | number | boolean | string[] | undefined> : Record<string, string | number | boolean | string[] | undefined>;
|
|
23
|
+
type ExtractParamType<T> = T extends StandardSchemaV1 ? StandardSchemaV1.InferOutput<T> : T;
|
|
24
|
+
type FindParamInMap<Routes extends string, CurrentPath extends string, ParamName extends string, ParamMap extends ParamMapConstraint<Routes>> = { [R in Routes]: R extends `${CurrentPath}${"" | `/${string}`}` ? R extends keyof ParamMap ? ParamName extends keyof NonNullable<ParamMap[R]> ? ExtractParamType<NonNullable<ParamMap[R]>[ParamName]> : never : never : never }[Routes];
|
|
25
|
+
type GetParamType<Routes extends string, CurrentPath extends string, ParamName extends string, ParamMap extends ParamMapConstraint<Routes>, DefaultType> = [FindParamInMap<Routes, CurrentPath, ParamName, ParamMap>] extends [never] ? DefaultType : FindParamInMap<Routes, CurrentPath, ParamName, ParamMap>;
|
|
26
|
+
type SegmentName<S extends string> = S extends `[...${infer N}]` ? N : S extends `[[...${infer N}]]` ? N : S extends `[${infer N}]` ? N : S;
|
|
27
|
+
type ChildSegments<Routes extends string, Path extends string> = Routes extends `${Path}/${infer Next}/${string}` ? SegmentName<Next> : Routes extends `${Path}/${infer Next}` ? SegmentName<Next> : never;
|
|
28
|
+
type IsDynamicSegment<S extends string> = S extends `[${string}]` | `[...${string}]` | `[[...${string}]]` ? true : false;
|
|
29
|
+
type IsCatchAllSegment<S extends string> = S extends `[...${string}]` ? true : false;
|
|
30
|
+
type IsOptionalCatchAllSegment<S extends string> = S extends `[[...${string}]]` ? true : false;
|
|
31
|
+
type GetOriginalSegment<Routes extends string, Path extends string, Seg extends string> = Routes extends `${Path}/${infer Next}/${string}` ? SegmentName<Next> extends Seg ? Next : never : Routes extends `${Path}/${infer Next}` ? SegmentName<Next> extends Seg ? Next : never : never;
|
|
32
|
+
type IsDynamicAtPath<Routes extends string, Path extends string, Seg extends string> = GetOriginalSegment<Routes, Path, Seg> extends infer Original ? Original extends string ? IsDynamicSegment<Original> extends true ? true : false : false : false;
|
|
33
|
+
type IsCatchAllAtPath<Routes extends string, Path extends string, Seg extends string> = GetOriginalSegment<Routes, Path, Seg> extends infer Original ? Original extends string ? IsCatchAllSegment<Original> extends true ? true : false : false : false;
|
|
34
|
+
type IsOptionalCatchAllAtPath<Routes extends string, Path extends string, Seg extends string> = GetOriginalSegment<Routes, Path, Seg> extends infer Original ? Original extends string ? IsOptionalCatchAllSegment<Original> extends true ? true : false : false : false;
|
|
35
|
+
type Join<T extends readonly string[], Sep extends string> = T extends readonly [infer First extends string, ...infer Rest extends readonly string[]] ? Rest["length"] extends 0 ? First : `${First}${Sep}${Join<Rest, Sep>}` : "";
|
|
36
|
+
type Stringify<T> = T extends string | number | boolean | bigint ? `${T}` : never;
|
|
37
|
+
type UnionToIntersection<U> = (U extends unknown ? (k: U) => void : never) extends ((k: infer I) => void) ? I : never;
|
|
38
|
+
type UnionToLast<U> = UnionToIntersection<U extends unknown ? () => U : never> extends (() => infer R) ? R : never;
|
|
39
|
+
type UnionToTuple<U, R extends unknown[] = [], Last = UnionToLast<U>> = [U] extends [never] ? R : UnionToTuple<Exclude<U, Last>, [Last, ...R]>;
|
|
40
|
+
type JoinStrings<T extends readonly string[], Sep extends string = "&"> = T extends readonly [infer Only extends string] ? Only : T extends readonly [infer First extends string, ...infer Rest extends readonly string[]] ? `${First}${Sep}${JoinStrings<Rest, Sep>}` : "";
|
|
41
|
+
type ArrayToQueryPairs<K extends string, T extends readonly unknown[]> = T extends readonly [infer First, ...infer Rest extends readonly unknown[]] ? First extends string | number | boolean | bigint ? Rest["length"] extends 0 ? `${K}=${First}` : `${K}=${First}` | ArrayToQueryPairs<K, Rest> : never : never;
|
|
42
|
+
type QueryPairs<T extends Record<string, unknown>> = { [K in keyof T]-?: T[K] extends undefined | never ? never : T[K] extends readonly (string | number | boolean | bigint)[] ? ArrayToQueryPairs<K & string, T[K]> : `${K & string}=${Stringify<T[K]>}` }[keyof T];
|
|
43
|
+
type BuildQueryString<T extends Record<string, unknown>> = JoinStrings<UnionToTuple<QueryPairs<T>> extends readonly string[] ? UnionToTuple<QueryPairs<T>> : never>;
|
|
44
|
+
type AppendQuery<Path extends string, SP> = SP extends Record<string, unknown> ? [keyof SP] extends [never] ? Path : BuildQueryString<SP> extends infer QS extends string ? QS extends "" ? Path : `${Path}?${QS}` : Path : Path;
|
|
45
|
+
type ReplaceDynamicSegments<Path extends string, P extends Record<string, unknown>> = Path extends `${infer Start}/[[...${infer Param}]]${infer Rest}` ? Param extends keyof P ? P[Param] extends readonly string[] ? `${ReplaceDynamicSegments<Start, P>}/${Join<P[Param], "/">}${ReplaceDynamicSegments<Rest, P>}` : `${ReplaceDynamicSegments<Start, P>}${ReplaceDynamicSegments<Rest, P>}` : `${ReplaceDynamicSegments<Start, P>}${ReplaceDynamicSegments<Rest, P>}` : Path extends `${infer Start}/[...${infer Param}]${infer Rest}` ? Param extends keyof P ? P[Param] extends readonly string[] ? `${ReplaceDynamicSegments<Start, P>}/${Join<P[Param], "/">}${ReplaceDynamicSegments<Rest, P>}` : `${ReplaceDynamicSegments<Start, P>}/[...${Param}]${ReplaceDynamicSegments<Rest, P>}` : `${ReplaceDynamicSegments<Start, P>}/[...${Param}]${ReplaceDynamicSegments<Rest, P>}` : Path extends `${infer Start}/[${infer Param}]${infer Rest}` ? Param extends keyof P ? Stringify<P[Param]> extends string ? `${Start}/${Stringify<P[Param]>}${ReplaceDynamicSegments<Rest, P>}` : `${Start}/[${Param}]${ReplaceDynamicSegments<Rest, P>}` : `${Start}/[${Param}]${ReplaceDynamicSegments<Rest, P>}` : Path;
|
|
46
|
+
type NextPath<Routes extends string, Path extends string, Seg extends string> = Path extends "" ? `/${GetOriginalSegment<Routes, Path, Seg>}` : `${Path}/${GetOriginalSegment<Routes, Path, Seg>}`;
|
|
47
|
+
type RouteNode<R extends string, Path extends string, Params extends Record<string, unknown> = {}, ParamMap extends ParamMapConstraint<R> = {}, SearchParamMap extends SearchParamMapConstraint<R> = {}> = {
|
|
48
|
+
getRoute: [keyof Params] extends [never] ? <const SP extends SearchParamsFor<R, Path extends "" ? "/" : Path, SearchParamMap> | undefined = undefined>(params?: undefined, searchParams?: SP) => AppendQuery<Path extends "" ? "/" : Path, SP> : <const P extends Params, const SP extends SearchParamsFor<R, Path, SearchParamMap> | undefined = undefined>(params: P, searchParams?: SP) => AppendQuery<ReplaceDynamicSegments<Path, P>, SP>;
|
|
49
|
+
} & { [Seg in ChildSegments<R, Path>]: RouteNode<R, NextPath<R, Path, Seg>, IsOptionalCatchAllAtPath<R, Path, Seg> extends true ? Params & { [K in Seg]?: GetParamType<R, NextPath<R, Path, Seg>, K, ParamMap, string[]> } : IsCatchAllAtPath<R, Path, Seg> extends true ? Params & { [K in Seg]: GetParamType<R, NextPath<R, Path, Seg>, K, ParamMap, string[]> } : IsDynamicAtPath<R, Path, Seg> extends true ? Params & { [K in Seg]: GetParamType<R, NextPath<R, Path, Seg>, K, ParamMap, string> } : Params, ParamMap, SearchParamMap> };
|
|
50
|
+
type Routes<R extends string, Config = {}> = RouteNode<R, "", {}, ExtractParamMap<R, Config>, ExtractSearchParamMap<R, Config>>;
|
|
51
|
+
declare function createRoutes<const R extends string>(): <const Config extends RoutesConfigConstraint<R, Config>>(config?: Config) => Routes<R, Config>;
|
|
52
|
+
//#endregion
|
|
53
|
+
export { Routes, createRoutes };
|
|
54
|
+
//# sourceMappingURL=index.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/index.ts"],"sourcesContent":[],"mappings":"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"}
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { createRecursiveProxy } from "./proxy.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/index.ts
|
|
4
|
+
function isStandardSchema(value) {
|
|
5
|
+
return typeof value === "object" && value !== null && "~standard" in value && typeof value["~standard"] === "object";
|
|
6
|
+
}
|
|
7
|
+
function findMatchingRoute(segments, schemaMap) {
|
|
8
|
+
for (const routePattern of Object.keys(schemaMap)) {
|
|
9
|
+
const patternSegments = routePattern.split("/").filter(Boolean);
|
|
10
|
+
if (patternSegments.length !== segments.length) continue;
|
|
11
|
+
if (patternSegments.every((pattern, i) => {
|
|
12
|
+
if (pattern.startsWith("[") && pattern.endsWith("]")) return true;
|
|
13
|
+
if (pattern.startsWith("[[") && pattern.endsWith("]]")) return true;
|
|
14
|
+
return pattern === segments[i];
|
|
15
|
+
})) return routePattern;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
function validateParams(params, schemas) {
|
|
19
|
+
const validated = {};
|
|
20
|
+
for (const [key, value] of Object.entries(params)) {
|
|
21
|
+
const schema = schemas[key];
|
|
22
|
+
if (isStandardSchema(schema)) {
|
|
23
|
+
const result = schema["~standard"].validate(value);
|
|
24
|
+
if (result instanceof Promise) throw new Error(`Async validation is not supported for param "${key}"`);
|
|
25
|
+
if (result.issues) {
|
|
26
|
+
var _result$issues$;
|
|
27
|
+
throw new Error(`Validation failed for param "${key}": ${(_result$issues$ = result.issues[0]) === null || _result$issues$ === void 0 ? void 0 : _result$issues$.message}`);
|
|
28
|
+
}
|
|
29
|
+
validated[key] = result.value;
|
|
30
|
+
} else validated[key] = value;
|
|
31
|
+
}
|
|
32
|
+
return validated;
|
|
33
|
+
}
|
|
34
|
+
function createRoutesWithConfig(config) {
|
|
35
|
+
const paramSchemas = {};
|
|
36
|
+
if (config) for (const [route, routeConfig] of Object.entries(config)) {
|
|
37
|
+
const rc = routeConfig;
|
|
38
|
+
if (rc === null || rc === void 0 ? void 0 : rc.params) paramSchemas[route] = rc.params;
|
|
39
|
+
}
|
|
40
|
+
return createRecursiveProxy(({ path, args }) => {
|
|
41
|
+
var _args$;
|
|
42
|
+
const segments = path.slice(0, -1);
|
|
43
|
+
const rawParams = (_args$ = args[0]) !== null && _args$ !== void 0 ? _args$ : {};
|
|
44
|
+
const searchParams = args[1];
|
|
45
|
+
const appendSearchParams = (basePath$1) => {
|
|
46
|
+
if (!searchParams || Object.keys(searchParams).length === 0) return basePath$1;
|
|
47
|
+
const urlSearchParams$1 = new URLSearchParams();
|
|
48
|
+
for (const [key, value] of Object.entries(searchParams)) {
|
|
49
|
+
if (value === void 0 || value === null) continue;
|
|
50
|
+
if (Array.isArray(value)) for (const v of value) urlSearchParams$1.append(key, String(v));
|
|
51
|
+
else urlSearchParams$1.append(key, String(value));
|
|
52
|
+
}
|
|
53
|
+
const queryString$1 = urlSearchParams$1.toString();
|
|
54
|
+
return queryString$1 ? `${basePath$1}?${queryString$1}` : basePath$1;
|
|
55
|
+
};
|
|
56
|
+
if (segments.length === 0) return appendSearchParams("/");
|
|
57
|
+
let params = rawParams;
|
|
58
|
+
if (Object.keys(paramSchemas).length > 0) {
|
|
59
|
+
const matchingRoute = findMatchingRoute(segments, paramSchemas);
|
|
60
|
+
if (matchingRoute && matchingRoute in paramSchemas) {
|
|
61
|
+
const routeSchemas = paramSchemas[matchingRoute];
|
|
62
|
+
params = validateParams(rawParams, routeSchemas);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
const resolved = segments.flatMap((seg) => {
|
|
66
|
+
if (!(seg in params)) return seg;
|
|
67
|
+
const value = params[seg];
|
|
68
|
+
if (Array.isArray(value)) return value;
|
|
69
|
+
if (value === void 0) return [];
|
|
70
|
+
return String(value);
|
|
71
|
+
});
|
|
72
|
+
const basePath = resolved.length === 0 ? "/" : `/${resolved.join("/")}`;
|
|
73
|
+
if (!searchParams || Object.keys(searchParams).length === 0) return basePath;
|
|
74
|
+
const urlSearchParams = new URLSearchParams();
|
|
75
|
+
for (const [key, value] of Object.entries(searchParams)) {
|
|
76
|
+
if (value === void 0 || value === null) continue;
|
|
77
|
+
if (Array.isArray(value)) for (const v of value) urlSearchParams.append(key, String(v));
|
|
78
|
+
else urlSearchParams.append(key, String(value));
|
|
79
|
+
}
|
|
80
|
+
const queryString = urlSearchParams.toString();
|
|
81
|
+
return queryString ? `${basePath}?${queryString}` : basePath;
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
function createRoutes() {
|
|
85
|
+
return (config) => createRoutesWithConfig(config);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
//#endregion
|
|
89
|
+
export { createRoutes };
|
|
90
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.mjs","names":["basePath","urlSearchParams","queryString"],"sources":["../src/index.ts"],"sourcesContent":["import type { StandardSchemaV1 } from \"@standard-schema/spec\";\nimport { createRecursiveProxy } from \"./proxy\";\n\ntype ValidParamValue =\n | string\n | number\n | boolean\n | bigint\n | string[]\n | readonly string[];\n\ntype ParamMapValue =\n | ValidParamValue\n | StandardSchemaV1<unknown, ValidParamValue>;\n\ntype ParamMapConstraint<Routes extends string> = {\n [K in Routes]?: Record<string, ParamMapValue>;\n};\n\ntype SearchParamValue =\n | string\n | number\n | boolean\n | string[]\n | StandardSchemaV1<unknown, string | number | boolean | string[]>;\n\ntype SearchParamMapConstraint<Routes extends string> = {\n [K in Routes]?: Record<string, SearchParamValue>;\n};\n\ntype ExtractRouteParams<Route extends string> =\n Route extends `${string}[[...${infer Param}]]${infer Rest}`\n ? Param | ExtractRouteParams<Rest>\n : Route extends `${string}[...${infer Param}]${infer Rest}`\n ? Param | ExtractRouteParams<Rest>\n : Route extends `${string}[${infer Param}]${infer Rest}`\n ? Param | ExtractRouteParams<Rest>\n : never;\n\ntype RouteConfigFor<Route extends string> = {\n params?: { [K in ExtractRouteParams<Route>]?: ParamMapValue };\n searchParams?: Record<string, SearchParamValue>;\n};\n\ntype RoutesConfigConstraint<Routes extends string, T = {}> = {\n [K in Routes]?: RouteConfigFor<K>;\n} & {\n [K in keyof T]: K extends Routes ? RouteConfigFor<K> : never;\n};\n\ntype ExtractParamMap<Routes extends string, Config> = {\n [K in Routes]: K extends keyof Config\n ? Config[K] extends {\n params: infer P extends Record<string, ParamMapValue>;\n }\n ? P\n : undefined\n : undefined;\n};\n\ntype ExtractSearchParamMap<Routes extends string, Config> = {\n [K in Routes]: K extends keyof Config\n ? Config[K] extends {\n searchParams: infer SP extends Record<string, SearchParamValue>;\n }\n ? SP\n : undefined\n : undefined;\n};\n\ntype ExtractSearchParamType<T> = T extends StandardSchemaV1\n ? StandardSchemaV1.InferOutput<T>\n : T;\n\ntype SearchParamsFor<\n Routes extends string,\n Path extends string,\n SearchParamMap extends SearchParamMapConstraint<Routes>,\n> = Path extends keyof SearchParamMap\n ? SearchParamMap[Path] extends infer SP\n ? SP extends Record<string, SearchParamValue>\n ? { [K in keyof SP]?: ExtractSearchParamType<SP[K]> }\n : Record<string, string | number | boolean | string[] | undefined>\n : Record<string, string | number | boolean | string[] | undefined>\n : Record<string, string | number | boolean | string[] | undefined>;\n\ntype ExtractParamType<T> = T extends StandardSchemaV1\n ? StandardSchemaV1.InferOutput<T>\n : T;\n\ntype FindParamInMap<\n Routes extends string,\n CurrentPath extends string,\n ParamName extends string,\n ParamMap extends ParamMapConstraint<Routes>,\n> = {\n [R in Routes]: R extends `${CurrentPath}${\"\" | `/${string}`}`\n ? R extends keyof ParamMap\n ? ParamName extends keyof NonNullable<ParamMap[R]>\n ? ExtractParamType<NonNullable<ParamMap[R]>[ParamName]>\n : never\n : never\n : never;\n}[Routes];\n\ntype GetParamType<\n Routes extends string,\n CurrentPath extends string,\n ParamName extends string,\n ParamMap extends ParamMapConstraint<Routes>,\n DefaultType,\n> = [FindParamInMap<Routes, CurrentPath, ParamName, ParamMap>] extends [never]\n ? DefaultType\n : FindParamInMap<Routes, CurrentPath, ParamName, ParamMap>;\n\ntype SegmentName<S extends string> = S extends `[...${infer N}]`\n ? N\n : S extends `[[...${infer N}]]`\n ? N\n : S extends `[${infer N}]`\n ? N\n : S;\n\ntype ChildSegments<\n Routes extends string,\n Path extends string,\n> = Routes extends `${Path}/${infer Next}/${string}`\n ? SegmentName<Next>\n : Routes extends `${Path}/${infer Next}`\n ? SegmentName<Next>\n : never;\n\ntype IsDynamicSegment<S extends string> = S extends\n | `[${string}]`\n | `[...${string}]`\n | `[[...${string}]]`\n ? true\n : false;\n\ntype IsCatchAllSegment<S extends string> = S extends `[...${string}]`\n ? true\n : false;\n\ntype IsOptionalCatchAllSegment<S extends string> = S extends `[[...${string}]]`\n ? true\n : false;\n\ntype GetOriginalSegment<\n Routes extends string,\n Path extends string,\n Seg extends string,\n> = Routes extends `${Path}/${infer Next}/${string}`\n ? SegmentName<Next> extends Seg\n ? Next\n : never\n : Routes extends `${Path}/${infer Next}`\n ? SegmentName<Next> extends Seg\n ? Next\n : never\n : never;\n\ntype IsDynamicAtPath<\n Routes extends string,\n Path extends string,\n Seg extends string,\n> = GetOriginalSegment<Routes, Path, Seg> extends infer Original\n ? Original extends string\n ? IsDynamicSegment<Original> extends true\n ? true\n : false\n : false\n : false;\n\ntype IsCatchAllAtPath<\n Routes extends string,\n Path extends string,\n Seg extends string,\n> = GetOriginalSegment<Routes, Path, Seg> extends infer Original\n ? Original extends string\n ? IsCatchAllSegment<Original> extends true\n ? true\n : false\n : false\n : false;\n\ntype IsOptionalCatchAllAtPath<\n Routes extends string,\n Path extends string,\n Seg extends string,\n> = GetOriginalSegment<Routes, Path, Seg> extends infer Original\n ? Original extends string\n ? IsOptionalCatchAllSegment<Original> extends true\n ? true\n : false\n : false\n : false;\n\ntype Join<\n T extends readonly string[],\n Sep extends string,\n> = T extends readonly [\n infer First extends string,\n ...infer Rest extends readonly string[],\n]\n ? Rest[\"length\"] extends 0\n ? First\n : `${First}${Sep}${Join<Rest, Sep>}`\n : \"\";\n\ntype Stringify<T> = T extends string | number | boolean | bigint\n ? `${T}`\n : never;\n\ntype UnionToIntersection<U> = (\n U extends unknown\n ? (k: U) => void\n : never\n) extends (k: infer I) => void\n ? I\n : never;\n\ntype UnionToLast<U> = UnionToIntersection<\n U extends unknown ? () => U : never\n> extends () => infer R\n ? R\n : never;\n\ntype UnionToTuple<U, R extends unknown[] = [], Last = UnionToLast<U>> = [\n U,\n] extends [never]\n ? R\n : UnionToTuple<Exclude<U, Last>, [Last, ...R]>;\n\ntype JoinStrings<\n T extends readonly string[],\n Sep extends string = \"&\",\n> = T extends readonly [infer Only extends string]\n ? Only\n : T extends readonly [\n infer First extends string,\n ...infer Rest extends readonly string[],\n ]\n ? `${First}${Sep}${JoinStrings<Rest, Sep>}`\n : \"\";\n\ntype ArrayToQueryPairs<\n K extends string,\n T extends readonly unknown[],\n> = T extends readonly [infer First, ...infer Rest extends readonly unknown[]]\n ? First extends string | number | boolean | bigint\n ? Rest[\"length\"] extends 0\n ? `${K}=${First}`\n : `${K}=${First}` | ArrayToQueryPairs<K, Rest>\n : never\n : never;\n\ntype QueryPairs<T extends Record<string, unknown>> = {\n [K in keyof T]-?: T[K] extends undefined | never\n ? never\n : T[K] extends readonly (string | number | boolean | bigint)[]\n ? ArrayToQueryPairs<K & string, T[K]>\n : `${K & string}=${Stringify<T[K]>}`;\n}[keyof T];\n\ntype BuildQueryString<T extends Record<string, unknown>> = JoinStrings<\n UnionToTuple<QueryPairs<T>> extends readonly string[]\n ? UnionToTuple<QueryPairs<T>>\n : never\n>;\n\ntype AppendQuery<Path extends string, SP> = SP extends Record<string, unknown>\n ? [keyof SP] extends [never]\n ? Path\n : BuildQueryString<SP> extends infer QS extends string\n ? QS extends \"\"\n ? Path\n : `${Path}?${QS}`\n : Path\n : Path;\n\ntype ReplaceDynamicSegments<\n Path extends string,\n P extends Record<string, unknown>,\n> = Path extends `${infer Start}/[[...${infer Param}]]${infer Rest}`\n ? Param extends keyof P\n ? P[Param] extends readonly string[]\n ? `${ReplaceDynamicSegments<Start, P>}/${Join<P[Param], \"/\">}${ReplaceDynamicSegments<Rest, P>}`\n : `${ReplaceDynamicSegments<Start, P>}${ReplaceDynamicSegments<Rest, P>}`\n : `${ReplaceDynamicSegments<Start, P>}${ReplaceDynamicSegments<Rest, P>}`\n : Path extends `${infer Start}/[...${infer Param}]${infer Rest}`\n ? Param extends keyof P\n ? P[Param] extends readonly string[]\n ? `${ReplaceDynamicSegments<Start, P>}/${Join<P[Param], \"/\">}${ReplaceDynamicSegments<Rest, P>}`\n : `${ReplaceDynamicSegments<Start, P>}/[...${Param}]${ReplaceDynamicSegments<Rest, P>}`\n : `${ReplaceDynamicSegments<Start, P>}/[...${Param}]${ReplaceDynamicSegments<Rest, P>}`\n : Path extends `${infer Start}/[${infer Param}]${infer Rest}`\n ? Param extends keyof P\n ? Stringify<P[Param]> extends string\n ? `${Start}/${Stringify<P[Param]>}${ReplaceDynamicSegments<Rest, P>}`\n : `${Start}/[${Param}]${ReplaceDynamicSegments<Rest, P>}`\n : `${Start}/[${Param}]${ReplaceDynamicSegments<Rest, P>}`\n : Path;\n\ntype NextPath<\n Routes extends string,\n Path extends string,\n Seg extends string,\n> = Path extends \"\"\n ? `/${GetOriginalSegment<Routes, Path, Seg>}`\n : `${Path}/${GetOriginalSegment<Routes, Path, Seg>}`;\n\ntype RouteNode<\n R extends string,\n Path extends string,\n Params extends Record<string, unknown> = {},\n ParamMap extends ParamMapConstraint<R> = {},\n SearchParamMap extends SearchParamMapConstraint<R> = {},\n> = {\n getRoute: [keyof Params] extends [never]\n ? <\n const SP extends\n | SearchParamsFor<R, Path extends \"\" ? \"/\" : Path, SearchParamMap>\n | undefined = undefined,\n >(\n params?: undefined,\n searchParams?: SP,\n ) => AppendQuery<Path extends \"\" ? \"/\" : Path, SP>\n : <\n const P extends Params,\n const SP extends\n | SearchParamsFor<R, Path, SearchParamMap>\n | undefined = undefined,\n >(\n params: P,\n searchParams?: SP,\n ) => AppendQuery<ReplaceDynamicSegments<Path, P>, SP>;\n} & {\n [Seg in ChildSegments<R, Path>]: RouteNode<\n R,\n NextPath<R, Path, Seg>,\n IsOptionalCatchAllAtPath<R, Path, Seg> extends true\n ? Params & {\n [K in Seg]?: GetParamType<\n R,\n NextPath<R, Path, Seg>,\n K,\n ParamMap,\n string[]\n >;\n }\n : IsCatchAllAtPath<R, Path, Seg> extends true\n ? Params & {\n [K in Seg]: GetParamType<\n R,\n NextPath<R, Path, Seg>,\n K,\n ParamMap,\n string[]\n >;\n }\n : IsDynamicAtPath<R, Path, Seg> extends true\n ? Params & {\n [K in Seg]: GetParamType<\n R,\n NextPath<R, Path, Seg>,\n K,\n ParamMap,\n string\n >;\n }\n : Params,\n ParamMap,\n SearchParamMap\n >;\n};\n\nexport type Routes<R extends string, Config = {}> = RouteNode<\n R,\n \"\",\n {},\n ExtractParamMap<R, Config>,\n ExtractSearchParamMap<R, Config>\n>;\n\nfunction isStandardSchema(\n value: unknown,\n): value is StandardSchemaV1<unknown, unknown> {\n return (\n typeof value === \"object\" &&\n value !== null &&\n \"~standard\" in value &&\n typeof (value as StandardSchemaV1)[\"~standard\"] === \"object\"\n );\n}\n\nfunction findMatchingRoute(\n segments: string[],\n schemaMap: Record<string, Record<string, unknown>>,\n): string | undefined {\n for (const routePattern of Object.keys(schemaMap)) {\n const patternSegments = routePattern.split(\"/\").filter(Boolean);\n if (patternSegments.length !== segments.length) continue;\n\n const matches = patternSegments.every((pattern, i) => {\n if (pattern.startsWith(\"[\") && pattern.endsWith(\"]\")) return true;\n if (pattern.startsWith(\"[[\") && pattern.endsWith(\"]]\")) return true;\n return pattern === segments[i];\n });\n\n if (matches) return routePattern;\n }\n return undefined;\n}\n\nfunction validateParams(\n params: Record<string, unknown>,\n schemas: Record<string, unknown>,\n): Record<string, unknown> {\n const validated: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(params)) {\n const schema = schemas[key];\n if (isStandardSchema(schema)) {\n const result = schema[\"~standard\"].validate(value);\n if (result instanceof Promise) {\n throw new Error(`Async validation is not supported for param \"${key}\"`);\n }\n if (result.issues) {\n throw new Error(\n `Validation failed for param \"${key}\": ${result.issues[0]?.message}`,\n );\n }\n validated[key] = result.value;\n } else {\n validated[key] = value;\n }\n }\n return validated;\n}\n\nfunction createRoutesWithConfig<\n const R extends string,\n const Config extends RoutesConfigConstraint<R, Config>,\n>(config?: Config): Routes<R, Config> {\n const paramSchemas: Record<string, Record<string, unknown>> = {};\n\n if (config) {\n for (const [route, routeConfig] of Object.entries(config)) {\n const rc = routeConfig as {\n params?: Record<string, unknown>;\n searchParams?: Record<string, unknown>;\n };\n if (rc?.params) {\n paramSchemas[route] = rc.params;\n }\n }\n }\n\n return createRecursiveProxy(({ path, args }) => {\n const segments = path.slice(0, -1);\n const rawParams = (args[0] ?? {}) as Record<\n string,\n string | string[] | undefined\n >;\n const searchParams = args[1] as Record<string, unknown> | undefined;\n\n const appendSearchParams = (basePath: string) => {\n if (!searchParams || Object.keys(searchParams).length === 0) {\n return basePath;\n }\n const urlSearchParams = new URLSearchParams();\n for (const [key, value] of Object.entries(searchParams)) {\n if (value === undefined || value === null) continue;\n if (Array.isArray(value)) {\n for (const v of value) {\n urlSearchParams.append(key, String(v));\n }\n } else {\n urlSearchParams.append(key, String(value));\n }\n }\n const queryString = urlSearchParams.toString();\n return queryString ? `${basePath}?${queryString}` : basePath;\n };\n\n if (segments.length === 0) return appendSearchParams(\"/\");\n\n let params = rawParams;\n if (Object.keys(paramSchemas).length > 0) {\n const matchingRoute = findMatchingRoute(segments, paramSchemas);\n if (matchingRoute && matchingRoute in paramSchemas) {\n const routeSchemas = paramSchemas[matchingRoute] as Record<\n string,\n unknown\n >;\n params = validateParams(rawParams, routeSchemas) as typeof rawParams;\n }\n }\n\n const resolved = segments.flatMap((seg) => {\n if (!(seg in params)) return seg;\n const value = params[seg];\n if (Array.isArray(value)) return value;\n if (value === undefined) return [];\n return String(value);\n });\n\n const basePath = resolved.length === 0 ? \"/\" : `/${resolved.join(\"/\")}`;\n if (!searchParams || Object.keys(searchParams).length === 0) {\n return basePath;\n }\n\n const urlSearchParams = new URLSearchParams();\n for (const [key, value] of Object.entries(searchParams)) {\n if (value === undefined || value === null) continue;\n if (Array.isArray(value)) {\n for (const v of value) {\n urlSearchParams.append(key, String(v));\n }\n } else {\n urlSearchParams.append(key, String(value));\n }\n }\n\n const queryString = urlSearchParams.toString();\n return queryString ? `${basePath}?${queryString}` : basePath;\n }) as Routes<R, Config>;\n}\n\nexport function createRoutes<const R extends string>(): <\n const Config extends RoutesConfigConstraint<R, Config>,\n>(\n config?: Config,\n) => Routes<R, Config> {\n return <const Config extends RoutesConfigConstraint<R, Config>>(\n config?: Config,\n ) => createRoutesWithConfig<R, Config>(config);\n}\n"],"mappings":"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"}
|
package/dist/proxy.cjs
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
|
|
2
|
+
//#region src/proxy.ts
|
|
3
|
+
function createRecursiveProxy(callback, path = []) {
|
|
4
|
+
return new Proxy(() => {}, {
|
|
5
|
+
get(_obj, key) {
|
|
6
|
+
if (typeof key !== "string") return void 0;
|
|
7
|
+
return createRecursiveProxy(callback, [...path, key]);
|
|
8
|
+
},
|
|
9
|
+
apply(_1, _2, args) {
|
|
10
|
+
return callback({
|
|
11
|
+
path,
|
|
12
|
+
args
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
//#endregion
|
|
19
|
+
exports.createRecursiveProxy = createRecursiveProxy;
|
package/dist/proxy.mjs
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
//#region src/proxy.ts
|
|
2
|
+
function createRecursiveProxy(callback, path = []) {
|
|
3
|
+
return new Proxy(() => {}, {
|
|
4
|
+
get(_obj, key) {
|
|
5
|
+
if (typeof key !== "string") return void 0;
|
|
6
|
+
return createRecursiveProxy(callback, [...path, key]);
|
|
7
|
+
},
|
|
8
|
+
apply(_1, _2, args) {
|
|
9
|
+
return callback({
|
|
10
|
+
path,
|
|
11
|
+
args
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
//#endregion
|
|
18
|
+
export { createRecursiveProxy };
|
|
19
|
+
//# sourceMappingURL=proxy.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"proxy.mjs","names":[],"sources":["../src/proxy.ts"],"sourcesContent":["interface ProxyCallbackOptions {\n path: readonly string[];\n args: readonly unknown[];\n}\n\ntype ProxyCallback = (opts: ProxyCallbackOptions) => unknown;\n\nexport function createRecursiveProxy(\n callback: ProxyCallback,\n path: readonly string[] = [],\n) {\n const proxy: unknown = new Proxy(() => {}, {\n get(_obj, key) {\n if (typeof key !== \"string\") return undefined;\n return createRecursiveProxy(callback, [...path, key]);\n },\n apply(_1, _2, args) {\n return callback({\n path,\n args,\n });\n },\n });\n\n return proxy;\n}\n"],"mappings":";AAOA,SAAgB,qBACd,UACA,OAA0B,EAAE,EAC5B;AAcA,QAbuB,IAAI,YAAY,IAAI;EACzC,IAAI,MAAM,KAAK;AACb,OAAI,OAAO,QAAQ,SAAU,QAAO;AACpC,UAAO,qBAAqB,UAAU,CAAC,GAAG,MAAM,IAAI,CAAC;;EAEvD,MAAM,IAAI,IAAI,MAAM;AAClB,UAAO,SAAS;IACd;IACA;IACD,CAAC;;EAEL,CAAC"}
|