@troyio/vite-file-router 0.4.0 → 0.5.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/README.md +664 -484
- package/devtools/app.js +1546 -143
- package/devtools/index.html +153 -33
- package/devtools/style.css +1490 -231
- package/dist/devtools-app.d.ts +97 -0
- package/dist/devtools.d.ts +75 -0
- package/dist/generator.d.ts +8 -1
- package/dist/index.d.ts +29 -3
- package/dist/index.js +904 -31
- package/dist/scanner.d.ts +2 -1
- package/package.json +1 -1
- package/types/index.d.ts +3 -0
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { type RouteMatchResult } from "./devtools";
|
|
2
|
+
import type { RouteManifestNode } from "./scanner";
|
|
3
|
+
/** HMR events the dev-only client in `virtual:routes` sends to the server. */
|
|
4
|
+
export declare const APP_LOCATION_EVENT = "vite-file-router:location";
|
|
5
|
+
export declare const APP_DATA_EVENT = "vite-file-router:data";
|
|
6
|
+
/** Sent from the server to the app: navigate one tab to a URL. */
|
|
7
|
+
export declare const APP_NAVIGATE_EVENT = "vite-file-router:navigate";
|
|
8
|
+
/**
|
|
9
|
+
* Checks a URL the panel asks an app tab to open. Only same-origin paths are
|
|
10
|
+
* allowed, so the panel can't send the app to another site.
|
|
11
|
+
*/
|
|
12
|
+
export declare function isAppPath(url: unknown): url is string;
|
|
13
|
+
/** The part of Vite's HMR client used to message one app tab. */
|
|
14
|
+
export type AppClient = {
|
|
15
|
+
send(event: string, payload?: unknown): void;
|
|
16
|
+
};
|
|
17
|
+
/** An open browser tab running the app, and the route it's on. */
|
|
18
|
+
export type AppTab = {
|
|
19
|
+
id: string;
|
|
20
|
+
url: string;
|
|
21
|
+
title: string;
|
|
22
|
+
connectedAt: number;
|
|
23
|
+
updatedAt: number;
|
|
24
|
+
match: RouteMatchResult;
|
|
25
|
+
};
|
|
26
|
+
/** `next` means middleware passed control on to the next handler. */
|
|
27
|
+
export type RouteDataOutcome = "data" | "response" | "redirect" | "error" | "next";
|
|
28
|
+
/** One loader, action, or `shouldRevalidate` call reported by the app. */
|
|
29
|
+
export type RouteDataEvent = {
|
|
30
|
+
/** Increasing number, unique for this dev-server session. */
|
|
31
|
+
id: number;
|
|
32
|
+
tabId: string;
|
|
33
|
+
type: "loader" | "action" | "middleware" | "revalidate";
|
|
34
|
+
/** React Router route ID, `file-route:` plus the route directory. */
|
|
35
|
+
routeId: string;
|
|
36
|
+
url?: string;
|
|
37
|
+
method?: string;
|
|
38
|
+
startedAt: number;
|
|
39
|
+
duration?: number;
|
|
40
|
+
outcome?: RouteDataOutcome;
|
|
41
|
+
status?: number;
|
|
42
|
+
location?: string;
|
|
43
|
+
message?: string;
|
|
44
|
+
/** A short JSON preview of returned data. */
|
|
45
|
+
preview?: string;
|
|
46
|
+
/** For `revalidate` events: whether the loader runs. */
|
|
47
|
+
decision?: boolean;
|
|
48
|
+
defaultShouldRevalidate?: boolean;
|
|
49
|
+
/** Route params passed to the handler. */
|
|
50
|
+
params?: Record<string, string>;
|
|
51
|
+
/** The submitted body of an action request. */
|
|
52
|
+
body?: RouteRequestBody;
|
|
53
|
+
/** Serialized returned (or thrown, non-`Error`) data, capped in size. */
|
|
54
|
+
data?: string;
|
|
55
|
+
dataTruncated?: boolean;
|
|
56
|
+
/** Response headers, from a `Response` or React Router's `data()`. */
|
|
57
|
+
headers?: [string, string][];
|
|
58
|
+
responseBody?: string;
|
|
59
|
+
errorName?: string;
|
|
60
|
+
stack?: string;
|
|
61
|
+
/** For `revalidate` events: the URL being left. */
|
|
62
|
+
currentUrl?: string;
|
|
63
|
+
formMethod?: string;
|
|
64
|
+
actionStatus?: number;
|
|
65
|
+
};
|
|
66
|
+
export type RouteRequestBody = {
|
|
67
|
+
kind: "form";
|
|
68
|
+
entries: [string, string][];
|
|
69
|
+
} | {
|
|
70
|
+
kind: "text";
|
|
71
|
+
contentType?: string;
|
|
72
|
+
text: string;
|
|
73
|
+
};
|
|
74
|
+
/**
|
|
75
|
+
* Validates an event from the browser. Anything a page sends over the HMR
|
|
76
|
+
* channel is untrusted, so only known fields of the expected types are kept.
|
|
77
|
+
*/
|
|
78
|
+
export declare function sanitizeDataEvent(input: unknown, id: number): RouteDataEvent | undefined;
|
|
79
|
+
/**
|
|
80
|
+
* Tracks the app tabs connected to the dev server and their recent loader
|
|
81
|
+
* and action calls, and tells the panel when either changes.
|
|
82
|
+
*/
|
|
83
|
+
export declare function createAppTracker(options: {
|
|
84
|
+
getManifest: () => RouteManifestNode;
|
|
85
|
+
onTabsChange: (tabs: AppTab[]) => void;
|
|
86
|
+
onActivity: (event: RouteDataEvent) => void;
|
|
87
|
+
}): {
|
|
88
|
+
tabs: () => AppTab[];
|
|
89
|
+
activity: () => RouteDataEvent[];
|
|
90
|
+
updateLocation(client: object, input: unknown): Promise<void>;
|
|
91
|
+
/** The HMR client for an app tab, to send it events such as navigation. */
|
|
92
|
+
clientFor(tabId: string): AppClient | undefined;
|
|
93
|
+
disconnect(client: object): void;
|
|
94
|
+
/** Re-matches every tab, for example after route files change. */
|
|
95
|
+
rematch(): Promise<void>;
|
|
96
|
+
record(input: unknown): void;
|
|
97
|
+
};
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import type { IncomingMessage, ServerResponse } from "node:http";
|
|
2
|
+
import type { RouteConflict } from "./generator";
|
|
3
|
+
import type { RouteFileKind, RouteManifestNode } from "./scanner";
|
|
4
|
+
export declare const ROUTE_INSPECTOR_PATH = "/__vite-file-router/";
|
|
5
|
+
export declare const ROUTE_INSPECTOR_DATA_PATH = "/__vite-file-router-data";
|
|
6
|
+
export declare const ROUTE_INSPECTOR_EVENTS_PATH = "/__vite-file-router-events";
|
|
7
|
+
export declare const ROUTE_INSPECTOR_MATCH_PATH = "/__vite-file-router-match";
|
|
8
|
+
export declare const ROUTE_INSPECTOR_NAVIGATE_PATH = "/__vite-file-router-navigate";
|
|
9
|
+
export type RouteInspectorState = {
|
|
10
|
+
/** Absolute Vite project root, so the panel can open files in an editor. */
|
|
11
|
+
projectRoot: string;
|
|
12
|
+
/** The routes directory, relative to the project root with `/` separators. */
|
|
13
|
+
directory: string;
|
|
14
|
+
manifest: RouteManifestNode;
|
|
15
|
+
conflicts: RouteConflict[];
|
|
16
|
+
warnings: RouteWarning[];
|
|
17
|
+
};
|
|
18
|
+
export type RouteWarningKind = "no-error-boundary" | "no-not-found" | "missing-export";
|
|
19
|
+
export type RouteWarning = {
|
|
20
|
+
kind: RouteWarningKind;
|
|
21
|
+
severity: "warning" | "info";
|
|
22
|
+
/**
|
|
23
|
+
* The route's position in the manifest: `0` for the root, then child
|
|
24
|
+
* indexes joined with dots, such as `0.2.1`.
|
|
25
|
+
*/
|
|
26
|
+
key: string;
|
|
27
|
+
fullPath: string;
|
|
28
|
+
message: string;
|
|
29
|
+
/** Project-relative files the warning is about. */
|
|
30
|
+
files: string[];
|
|
31
|
+
};
|
|
32
|
+
/** Whether module source code (probably) has a named export. */
|
|
33
|
+
export declare function hasNamedExport(source: string, name: string): boolean;
|
|
34
|
+
/**
|
|
35
|
+
* Finds routes that are missing a file they likely need: an error file for a
|
|
36
|
+
* loader, action, or middleware, a root not-found page, or the expected export
|
|
37
|
+
* of a data module. `readSource` reads a project-relative file.
|
|
38
|
+
*/
|
|
39
|
+
export declare function findRouteWarnings(manifest: RouteManifestNode, readSource?: (file: string) => string | undefined): RouteWarning[];
|
|
40
|
+
export type RouteMatchSegment = {
|
|
41
|
+
fullPath: string;
|
|
42
|
+
segment: string | null;
|
|
43
|
+
routeGroup: boolean;
|
|
44
|
+
files: Partial<Record<RouteFileKind, string>>;
|
|
45
|
+
};
|
|
46
|
+
export type RouteMatchResult = {
|
|
47
|
+
matched: false;
|
|
48
|
+
pathname: string;
|
|
49
|
+
} | {
|
|
50
|
+
matched: true;
|
|
51
|
+
pathname: string;
|
|
52
|
+
params: Record<string, string | undefined>;
|
|
53
|
+
/** Directory routes from the root down to the matched route. */
|
|
54
|
+
chain: RouteMatchSegment[];
|
|
55
|
+
page?: string;
|
|
56
|
+
notFound?: string;
|
|
57
|
+
layouts: string[];
|
|
58
|
+
loaders: string[];
|
|
59
|
+
middleware: string[];
|
|
60
|
+
loading?: string;
|
|
61
|
+
error?: string;
|
|
62
|
+
};
|
|
63
|
+
export declare function matchRouteManifest(manifest: RouteManifestNode, url: string): Promise<RouteMatchResult>;
|
|
64
|
+
/** Pushes route state to open DevTools panels over Server-Sent Events. */
|
|
65
|
+
export declare function createRouteEventStream(getState: () => RouteInspectorState,
|
|
66
|
+
/** Extra events sent to each panel when it connects. */
|
|
67
|
+
getSnapshot?: () => [event: string, data: unknown][]): {
|
|
68
|
+
clients: Set<ServerResponse<IncomingMessage>>;
|
|
69
|
+
connect(request: IncomingMessage, response: ServerResponse): void;
|
|
70
|
+
/** Coalesces bursts of file events (such as a folder rename) into one push. */
|
|
71
|
+
notify(): void;
|
|
72
|
+
/** Sends a named event to every connected panel right away. */
|
|
73
|
+
broadcast(event: string, data: unknown): void;
|
|
74
|
+
close(): void;
|
|
75
|
+
};
|
package/dist/generator.d.ts
CHANGED
|
@@ -1,4 +1,11 @@
|
|
|
1
1
|
import { type Node } from "./scanner";
|
|
2
|
+
export type GenerateOptions = {
|
|
3
|
+
/**
|
|
4
|
+
* Add a client that reports the app's location and its loader and action
|
|
5
|
+
* calls to the DevTools panel over Vite's HMR channel. Dev server only.
|
|
6
|
+
*/
|
|
7
|
+
devClient?: boolean;
|
|
8
|
+
};
|
|
2
9
|
export type GeneratedRoutes = {
|
|
3
10
|
imports: string[];
|
|
4
11
|
helpers: string[];
|
|
@@ -19,4 +26,4 @@ export declare class RouteConflictError extends Error {
|
|
|
19
26
|
}
|
|
20
27
|
export declare function findPageRouteConflicts(node: Node, pages?: Map<string, string[]>, segments?: string[], root?: boolean): RouteConflict[];
|
|
21
28
|
export declare function getRouteId(directory: string, projectRoot: string): string;
|
|
22
|
-
export declare function generate(node: Node, root?: boolean, projectRoot?: string): GeneratedRoutes;
|
|
29
|
+
export declare function generate(node: Node, root?: boolean, projectRoot?: string, options?: GenerateOptions): GeneratedRoutes;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,14 +1,40 @@
|
|
|
1
1
|
import type { Plugin } from "vite";
|
|
2
|
+
import { type RouteWarning, type RouteWarningKind } from "./devtools";
|
|
2
3
|
import { type RouteConventions } from "./scanner";
|
|
3
4
|
export type RoutesOptions = {
|
|
4
5
|
directory?: string;
|
|
5
6
|
conventions?: RouteConventions;
|
|
6
7
|
/**
|
|
7
8
|
* Where to write the generated route type declarations, relative to the Vite
|
|
8
|
-
* project root.
|
|
9
|
-
*
|
|
9
|
+
* project root.
|
|
10
|
+
*
|
|
11
|
+
* - `"auto"` writes `src/route-types.d.ts`, but only when the project root
|
|
12
|
+
* has a `tsconfig.json` or `jsconfig.json`, so JavaScript projects without
|
|
13
|
+
* one get no extra file.
|
|
14
|
+
* - A path ending in `.d.ts` always writes to that path.
|
|
15
|
+
* - `false` never writes the file.
|
|
16
|
+
* @default "auto"
|
|
10
17
|
*/
|
|
11
|
-
dts?: string | false;
|
|
18
|
+
dts?: "auto" | string | false;
|
|
19
|
+
/**
|
|
20
|
+
* What to do with route warnings during `vite build`: a loader, action, or
|
|
21
|
+
* middleware with no error file at or above it, no root not-found page, or
|
|
22
|
+
* a data module missing its expected export.
|
|
23
|
+
*
|
|
24
|
+
* - `"warn"` prints them as Vite warnings.
|
|
25
|
+
* - `"error"` fails the build, for example in CI.
|
|
26
|
+
* - `false` turns them off.
|
|
27
|
+
* - An object sets the `level` and lists warning kinds to `ignore`.
|
|
28
|
+
* @default "warn"
|
|
29
|
+
*/
|
|
30
|
+
warnings?: RouteWarningsOption;
|
|
31
|
+
};
|
|
32
|
+
export type RouteWarningsOption = "warn" | "error" | false | {
|
|
33
|
+
level?: "warn" | "error";
|
|
34
|
+
ignore?: RouteWarningKind[];
|
|
12
35
|
};
|
|
36
|
+
export type { RouteWarning, RouteWarningKind } from "./devtools";
|
|
13
37
|
export type { RouteConventions, RouteFileKind, RouteManifestNode, } from "./scanner";
|
|
38
|
+
/** Formats route warnings for the terminal, grouped by route. */
|
|
39
|
+
export declare function formatRouteWarnings(warnings: RouteWarning[]): string;
|
|
14
40
|
export declare function routes(input?: string | RoutesOptions): Plugin;
|