@troyio/vite-file-router 0.3.2 → 0.4.1

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/dist/scanner.d.ts CHANGED
@@ -24,6 +24,11 @@ export type RouteManifestNode = {
24
24
  };
25
25
  export declare const DEFAULT_CONVENTIONS: Record<RouteFileKind, string>;
26
26
  export declare function getRouteSegment(name: string): string;
27
- export declare function collectPageRoutePatterns(node: Node, segments?: string[], root?: boolean): string[];
27
+ export type PageRoute = {
28
+ pattern: string;
29
+ node: Node;
30
+ };
31
+ export declare function collectPageRoutes(node: Node, segments?: string[], root?: boolean): PageRoute[];
32
+ export declare function collectPageRoutePatterns(node: Node): string[];
28
33
  export declare function scan(directory: string, conventions?: Record<RouteFileKind, string>): Node;
29
34
  export declare function createRouteManifest(node: Node, projectRoot: string, parentPath?: string, root?: boolean): RouteManifestNode;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@troyio/vite-file-router",
3
- "version": "0.3.2",
3
+ "version": "0.4.1",
4
4
  "description": "File-system routing plugin for Vite",
5
5
  "type": "module",
6
6
  "private": false,
package/types/index.d.ts CHANGED
@@ -1,60 +1,143 @@
1
- /// <reference path="./virtual-routes.d.ts" />
2
-
3
- export { routes } from "../dist/index.js";
4
- export type {
5
- RouteConventions,
6
- RouteFileKind,
7
- RouteManifestNode,
8
- RoutesOptions,
9
- } from "../dist/index.js";
10
-
11
- export type RouteParameterValue = string | number;
12
-
13
- type RouteParametersForSegment<Segment extends string> =
14
- Segment extends `:${infer Name}?`
15
- ? { [Key in Name]?: RouteParameterValue }
16
- : Segment extends `:${infer Name}`
17
- ? { [Key in Name]: RouteParameterValue }
18
- : Segment extends "*"
19
- ? { "*": RouteParameterValue }
20
- : {};
21
-
22
- export type RouteParameters<Path extends string> =
23
- Path extends `${infer Segment}/${infer Rest}`
24
- ? RouteParametersForSegment<Segment> & RouteParameters<Rest>
25
- : RouteParametersForSegment<Path>;
26
-
27
- type RouteParameterShapes<Path extends string> =
28
- Path extends unknown ? RouteParameters<Path> : never;
29
-
30
- type UnionToIntersection<Union> = (
31
- Union extends unknown ? (value: Union) => void : never
32
- ) extends (value: infer Intersection) => void
33
- ? Intersection
34
- : never;
35
-
36
- type RouteRequiresParameters<Path extends string> =
37
- Path extends unknown
38
- ? keyof RouteParameters<Path> extends never
39
- ? false
40
- : true
41
- : never;
42
-
43
- type RouteRequiresRequiredParameters<Path extends string> =
44
- Path extends unknown ? ({} extends RouteParameters<Path> ? false : true) : never;
45
-
46
- type HasParameterShapeMismatch<Path extends string> =
47
- [RouteParameterShapes<Path>] extends [
48
- UnionToIntersection<RouteParameterShapes<Path>>,
49
- ]
50
- ? false
51
- : true;
52
-
53
- export type RoutePathArguments<Path extends string> =
54
- true extends RouteRequiresParameters<Path>
55
- ? HasParameterShapeMismatch<Path> extends true
56
- ? [params: never]
57
- : true extends RouteRequiresRequiredParameters<Path>
58
- ? [params: RouteParameters<Path>]
59
- : [params?: RouteParameters<Path>]
60
- : [];
1
+ /// <reference path="./virtual-routes.d.ts" />
2
+
3
+ import type { useRouteLoaderData } from "react-router";
4
+
5
+ export { routes } from "../dist/index.js";
6
+ export type {
7
+ RouteConventions,
8
+ RouteFileKind,
9
+ RouteManifestNode,
10
+ RoutesOptions,
11
+ } from "../dist/index.js";
12
+
13
+ export type RouteParameterValue = string | number;
14
+
15
+ type RouteParametersForSegment<Segment extends string> =
16
+ Segment extends `:${infer Name}?`
17
+ ? { [Key in Name]?: RouteParameterValue }
18
+ : Segment extends `:${infer Name}`
19
+ ? { [Key in Name]: RouteParameterValue }
20
+ : Segment extends "*"
21
+ ? { "*": RouteParameterValue }
22
+ : {};
23
+
24
+ export type RouteParameters<Path extends string> =
25
+ Path extends `${infer Segment}/${infer Rest}`
26
+ ? RouteParametersForSegment<Segment> & RouteParameters<Rest>
27
+ : RouteParametersForSegment<Path>;
28
+
29
+ type RouteParameterShapes<Path extends string> =
30
+ Path extends unknown ? RouteParameters<Path> : never;
31
+
32
+ type UnionToIntersection<Union> = (
33
+ Union extends unknown ? (value: Union) => void : never
34
+ ) extends (value: infer Intersection) => void
35
+ ? Intersection
36
+ : never;
37
+
38
+ type RouteRequiresParameters<Path extends string> =
39
+ Path extends unknown
40
+ ? keyof RouteParameters<Path> extends never
41
+ ? false
42
+ : true
43
+ : never;
44
+
45
+ type RouteRequiresRequiredParameters<Path extends string> =
46
+ Path extends unknown ? ({} extends RouteParameters<Path> ? false : true) : never;
47
+
48
+ type HasParameterShapeMismatch<Path extends string> =
49
+ [RouteParameterShapes<Path>] extends [
50
+ UnionToIntersection<RouteParameterShapes<Path>>,
51
+ ]
52
+ ? false
53
+ : true;
54
+
55
+ export type RoutePathArguments<Path extends string> =
56
+ true extends RouteRequiresParameters<Path>
57
+ ? HasParameterShapeMismatch<Path> extends true
58
+ ? [params: never]
59
+ : true extends RouteRequiresRequiredParameters<Path>
60
+ ? [params: RouteParameters<Path>]
61
+ : [params?: RouteParameters<Path>]
62
+ : [];
63
+
64
+ /**
65
+ * Filled in by the generated route declarations (`src/route-types.d.ts` by
66
+ * default) through module augmentation. While it is empty, route patterns and
67
+ * loader keys fall back to `string` and loader data to `unknown`.
68
+ */
69
+ // biome-ignore lint/suspicious/noEmptyInterface: augmented by generated code
70
+ export interface Register {}
71
+
72
+ type RegisteredRoutes = Register extends { routes: infer Routes }
73
+ ? Routes
74
+ : never;
75
+ type RegisteredLoaders = Register extends { loaders: infer Loaders }
76
+ ? Loaders
77
+ : never;
78
+ type IsRegistered = [RegisteredRoutes] extends [never] ? false : true;
79
+
80
+ /** A page route pattern discovered from the routes directory. */
81
+ export type RoutePattern = IsRegistered extends true
82
+ ? Extract<keyof RegisteredRoutes, string>
83
+ : string;
84
+
85
+ type PatternsWithLoaders = {
86
+ [Pattern in keyof RegisteredRoutes]: RegisteredRoutes[Pattern] extends {
87
+ loader: null;
88
+ }
89
+ ? never
90
+ : Pattern;
91
+ }[keyof RegisteredRoutes];
92
+
93
+ /**
94
+ * A page pattern whose directory has a loader, or a loader route ID such as
95
+ * `"file-route:src/pages/dashboard"`.
96
+ */
97
+ export type RouteLoaderKey = IsRegistered extends true
98
+ ? Extract<PatternsWithLoaders | keyof RegisteredLoaders, string>
99
+ : string;
100
+
101
+ type LoaderModuleFor<Key> = Key extends keyof RegisteredLoaders
102
+ ? RegisteredLoaders[Key]
103
+ : Key extends keyof RegisteredRoutes
104
+ ? RegisteredRoutes[Key] extends {
105
+ loader: infer Id extends keyof RegisteredLoaders;
106
+ }
107
+ ? RegisteredLoaders[Id]
108
+ : never
109
+ : never;
110
+
111
+ /**
112
+ * The data a route's loader returns, typed the same way as React Router's
113
+ * `useRouteLoaderData<typeof loader>()`.
114
+ */
115
+ export type RouteLoaderData<Key extends string> = IsRegistered extends true
116
+ ? LoaderModuleFor<Key> extends { loader: infer Loader }
117
+ ? NonNullable<ReturnType<typeof useRouteLoaderData<Loader>>>
118
+ : never
119
+ : unknown;
120
+
121
+ type Simplify<Value> = { [Key in keyof Value]: Value[Key] } & {};
122
+
123
+ type RouteParamsForSegment<Segment extends string> =
124
+ Segment extends `:${infer Name}?`
125
+ ? { [Key in Name]?: string | undefined }
126
+ : Segment extends `:${infer Name}`
127
+ ? { [Key in Name]: string }
128
+ : Segment extends "*"
129
+ ? { "*": string }
130
+ : {};
131
+
132
+ type RouteParamsIntersection<Path extends string> =
133
+ Path extends `${infer Segment}/${infer Rest}`
134
+ ? RouteParamsForSegment<Segment> & RouteParamsIntersection<Rest>
135
+ : RouteParamsForSegment<Path>;
136
+
137
+ /**
138
+ * The params React Router's `useParams()` returns for a route pattern, such
139
+ * as `RouteParams<"/users/:id">` → `{ id: string }`.
140
+ */
141
+ export type RouteParams<Path extends string> = Path extends unknown
142
+ ? Simplify<RouteParamsIntersection<Path>>
143
+ : never;
@@ -1,19 +1,46 @@
1
- declare module "virtual:routes" {
2
- import type { RouteObject } from "react-router";
3
- export const routes: RouteObject[];
4
- }
5
-
6
- declare module "virtual:route-manifest" {
7
- import type { RouteManifestNode } from "@troyio/vite-file-router";
8
- export const routeManifest: RouteManifestNode;
9
- }
10
-
11
- declare module "virtual:route-helpers" {
12
- import type { RoutePathArguments } from "@troyio/vite-file-router";
13
-
14
- export const routePatterns: readonly string[];
15
- export function routePath<const Path extends string>(
16
- pattern: Path,
17
- ...args: RoutePathArguments<Path>
18
- ): string;
19
- }
1
+ declare module "virtual:routes" {
2
+ import type { Location, RouteObject } from "react-router";
3
+ export const routes: RouteObject[];
4
+ /**
5
+ * Imports the page, layout, and loader modules for the routes that match a
6
+ * URL, so a later navigation renders without waiting for them. Resolves to
7
+ * `false` when no route matches.
8
+ */
9
+ export function preloadRoute(
10
+ to: string | Partial<Location>,
11
+ basename?: string,
12
+ ): Promise<boolean>;
13
+ }
14
+
15
+ declare module "virtual:route-manifest" {
16
+ import type { RouteManifestNode } from "@troyio/vite-file-router";
17
+ export const routeManifest: RouteManifestNode;
18
+ }
19
+
20
+ declare module "virtual:route-helpers" {
21
+ import type {
22
+ RouteLoaderData,
23
+ RouteLoaderKey,
24
+ RouteParams,
25
+ RoutePathArguments,
26
+ RoutePattern,
27
+ } from "@troyio/vite-file-router";
28
+
29
+ export const routePatterns: readonly RoutePattern[];
30
+ export function routePath<const Path extends RoutePattern>(
31
+ pattern: Path,
32
+ ...args: RoutePathArguments<Path>
33
+ ): string;
34
+ /** React Router's `useParams()`, typed for the given page pattern. */
35
+ export function useRouteParams<const Path extends RoutePattern>(
36
+ pattern: Path,
37
+ ): RouteParams<Path>;
38
+ /**
39
+ * React Router's `useRouteLoaderData()`, typed from the loader module. Pass
40
+ * a page pattern to read the loader in that page's directory, or a loader
41
+ * route ID to read any matched loader.
42
+ */
43
+ export function useRouteData<const Key extends RouteLoaderKey>(
44
+ key: Key,
45
+ ): RouteLoaderData<Key> | undefined;
46
+ }