@chuvenger/devdock 0.3.0 → 0.4.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 +65 -3
- package/dist/chunk-NRBOZ6H5.js +26 -0
- package/dist/chunk-NRBOZ6H5.js.map +1 -0
- package/dist/match-B6LN1RRP.d.cts +10 -0
- package/dist/match-C-mY8W8T.d.ts +10 -0
- package/dist/react-router.cjs +15 -10
- package/dist/react-router.cjs.map +1 -1
- package/dist/react-router.d.cts +2 -7
- package/dist/react-router.d.ts +2 -7
- package/dist/react-router.js +2 -19
- package/dist/react-router.js.map +1 -1
- package/dist/sveltekit.cjs +520 -0
- package/dist/sveltekit.cjs.map +1 -0
- package/dist/sveltekit.d.cts +86 -0
- package/dist/sveltekit.d.ts +86 -0
- package/dist/sveltekit.js +68 -0
- package/dist/sveltekit.js.map +1 -0
- package/package.json +7 -1
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { b as DevDockOptions, c as DevRoute } from './types-fhhRek-e.cjs';
|
|
2
|
+
export { D as DevCommand, a as DevDockInstance, d as DockPosition } from './types-fhhRek-e.cjs';
|
|
3
|
+
import { R as RouteMatcher } from './match-B6LN1RRP.cjs';
|
|
4
|
+
import { DevDockAction } from './svelte.cjs';
|
|
5
|
+
export { c as createDevDock } from './dock-Du6Im767.cjs';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* What `import.meta.glob("/src/routes/**\/+page.svelte")` returns — only the
|
|
9
|
+
* keys matter, so an array of file paths works too.
|
|
10
|
+
*/
|
|
11
|
+
type RouteModules = Record<string, unknown> | string[];
|
|
12
|
+
interface DetectOptions {
|
|
13
|
+
/**
|
|
14
|
+
* Only keep routes that match. A glob string (`*` = any characters), a
|
|
15
|
+
* `RegExp`, or a predicate.
|
|
16
|
+
*/
|
|
17
|
+
match?: RouteMatcher;
|
|
18
|
+
/**
|
|
19
|
+
* Also list the app's ordinary routes, not just the ones under `/dev`.
|
|
20
|
+
* Default: `false`.
|
|
21
|
+
*/
|
|
22
|
+
staticRoutes?: boolean;
|
|
23
|
+
/**
|
|
24
|
+
* Your routes directory, as a name or a trailing path (`"routes"`,
|
|
25
|
+
* `"app/pages"`). Detected from the `src/routes` (or `routes`) segment of
|
|
26
|
+
* each key by default; set it only if your routes live somewhere else.
|
|
27
|
+
*/
|
|
28
|
+
routesDir?: string;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Turn a SvelteKit page file path into the route it serves, or `null` if it
|
|
32
|
+
* isn't a navigable page.
|
|
33
|
+
*
|
|
34
|
+
* Layout groups (`(app)`) and optional params (`[[lang]]`) drop out of the
|
|
35
|
+
* path; required (`[id]`), matched (`[id=int]`) and rest (`[...rest]`) params
|
|
36
|
+
* make the route unnavigable without arguments, so it's skipped.
|
|
37
|
+
*/
|
|
38
|
+
declare function routeFromFile(file: string, options?: Pick<DetectOptions, "routesDir">): string | null;
|
|
39
|
+
/**
|
|
40
|
+
* Flatten a SvelteKit `import.meta.glob` of page files into navigable
|
|
41
|
+
* {@link DevRoute}s.
|
|
42
|
+
*
|
|
43
|
+
* Only dev destinations are returned — anything under `/dev`, by convention.
|
|
44
|
+
* Pass `{ staticRoutes: true }` to list every page instead, and `{ match }`
|
|
45
|
+
* to scope the results. A bare matcher is accepted as shorthand.
|
|
46
|
+
*
|
|
47
|
+
* ```ts
|
|
48
|
+
* const routes = detectRoutes(import.meta.glob("/src/routes/**\/+page.svelte"));
|
|
49
|
+
* ```
|
|
50
|
+
*/
|
|
51
|
+
declare function detectRoutes(modules: RouteModules, options?: DetectOptions | RouteMatcher): DevRoute[];
|
|
52
|
+
interface SvelteKitDevDockOptions extends DevDockOptions, DetectOptions {
|
|
53
|
+
/**
|
|
54
|
+
* Your page files, from `import.meta.glob`. The glob has to be written in
|
|
55
|
+
* your app (Vite resolves it at build time), so pass the result in:
|
|
56
|
+
*
|
|
57
|
+
* ```ts
|
|
58
|
+
* { modules: import.meta.glob("/src/routes/**\/+page.svelte") }
|
|
59
|
+
* ```
|
|
60
|
+
*
|
|
61
|
+
* Detected routes come first; any `routes` you pass are appended.
|
|
62
|
+
*/
|
|
63
|
+
modules?: RouteModules;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Svelte action that mounts a dev dock with the SvelteKit routes detected
|
|
67
|
+
* from `modules`:
|
|
68
|
+
*
|
|
69
|
+
* ```svelte
|
|
70
|
+
* <script lang="ts">
|
|
71
|
+
* import { goto } from "$app/navigation";
|
|
72
|
+
* import { devdock } from "@chuvenger/devdock/sveltekit";
|
|
73
|
+
*
|
|
74
|
+
* const modules = import.meta.glob("/src/routes/**\/+page.svelte");
|
|
75
|
+
* </script>
|
|
76
|
+
*
|
|
77
|
+
* <div use:devdock={{ modules, onNavigate: goto, hotkey: "mod+." }}></div>
|
|
78
|
+
* ```
|
|
79
|
+
*
|
|
80
|
+
* Same contract as the plain `devdock` action: the dock mounts into
|
|
81
|
+
* `document.body` (or `options.container`), so the host element is just an
|
|
82
|
+
* anchor, and reactive options flow through `update`.
|
|
83
|
+
*/
|
|
84
|
+
declare function devdock(_node: HTMLElement, options?: SvelteKitDevDockOptions): DevDockAction;
|
|
85
|
+
|
|
86
|
+
export { type DetectOptions, DevDockAction, DevDockOptions, DevRoute, RouteMatcher, type RouteModules, type SvelteKitDevDockOptions, detectRoutes, devdock, routeFromFile };
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { b as DevDockOptions, c as DevRoute } from './types-fhhRek-e.js';
|
|
2
|
+
export { D as DevCommand, a as DevDockInstance, d as DockPosition } from './types-fhhRek-e.js';
|
|
3
|
+
import { R as RouteMatcher } from './match-C-mY8W8T.js';
|
|
4
|
+
import { DevDockAction } from './svelte.js';
|
|
5
|
+
export { c as createDevDock } from './dock-CvTtAelh.js';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* What `import.meta.glob("/src/routes/**\/+page.svelte")` returns — only the
|
|
9
|
+
* keys matter, so an array of file paths works too.
|
|
10
|
+
*/
|
|
11
|
+
type RouteModules = Record<string, unknown> | string[];
|
|
12
|
+
interface DetectOptions {
|
|
13
|
+
/**
|
|
14
|
+
* Only keep routes that match. A glob string (`*` = any characters), a
|
|
15
|
+
* `RegExp`, or a predicate.
|
|
16
|
+
*/
|
|
17
|
+
match?: RouteMatcher;
|
|
18
|
+
/**
|
|
19
|
+
* Also list the app's ordinary routes, not just the ones under `/dev`.
|
|
20
|
+
* Default: `false`.
|
|
21
|
+
*/
|
|
22
|
+
staticRoutes?: boolean;
|
|
23
|
+
/**
|
|
24
|
+
* Your routes directory, as a name or a trailing path (`"routes"`,
|
|
25
|
+
* `"app/pages"`). Detected from the `src/routes` (or `routes`) segment of
|
|
26
|
+
* each key by default; set it only if your routes live somewhere else.
|
|
27
|
+
*/
|
|
28
|
+
routesDir?: string;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Turn a SvelteKit page file path into the route it serves, or `null` if it
|
|
32
|
+
* isn't a navigable page.
|
|
33
|
+
*
|
|
34
|
+
* Layout groups (`(app)`) and optional params (`[[lang]]`) drop out of the
|
|
35
|
+
* path; required (`[id]`), matched (`[id=int]`) and rest (`[...rest]`) params
|
|
36
|
+
* make the route unnavigable without arguments, so it's skipped.
|
|
37
|
+
*/
|
|
38
|
+
declare function routeFromFile(file: string, options?: Pick<DetectOptions, "routesDir">): string | null;
|
|
39
|
+
/**
|
|
40
|
+
* Flatten a SvelteKit `import.meta.glob` of page files into navigable
|
|
41
|
+
* {@link DevRoute}s.
|
|
42
|
+
*
|
|
43
|
+
* Only dev destinations are returned — anything under `/dev`, by convention.
|
|
44
|
+
* Pass `{ staticRoutes: true }` to list every page instead, and `{ match }`
|
|
45
|
+
* to scope the results. A bare matcher is accepted as shorthand.
|
|
46
|
+
*
|
|
47
|
+
* ```ts
|
|
48
|
+
* const routes = detectRoutes(import.meta.glob("/src/routes/**\/+page.svelte"));
|
|
49
|
+
* ```
|
|
50
|
+
*/
|
|
51
|
+
declare function detectRoutes(modules: RouteModules, options?: DetectOptions | RouteMatcher): DevRoute[];
|
|
52
|
+
interface SvelteKitDevDockOptions extends DevDockOptions, DetectOptions {
|
|
53
|
+
/**
|
|
54
|
+
* Your page files, from `import.meta.glob`. The glob has to be written in
|
|
55
|
+
* your app (Vite resolves it at build time), so pass the result in:
|
|
56
|
+
*
|
|
57
|
+
* ```ts
|
|
58
|
+
* { modules: import.meta.glob("/src/routes/**\/+page.svelte") }
|
|
59
|
+
* ```
|
|
60
|
+
*
|
|
61
|
+
* Detected routes come first; any `routes` you pass are appended.
|
|
62
|
+
*/
|
|
63
|
+
modules?: RouteModules;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Svelte action that mounts a dev dock with the SvelteKit routes detected
|
|
67
|
+
* from `modules`:
|
|
68
|
+
*
|
|
69
|
+
* ```svelte
|
|
70
|
+
* <script lang="ts">
|
|
71
|
+
* import { goto } from "$app/navigation";
|
|
72
|
+
* import { devdock } from "@chuvenger/devdock/sveltekit";
|
|
73
|
+
*
|
|
74
|
+
* const modules = import.meta.glob("/src/routes/**\/+page.svelte");
|
|
75
|
+
* </script>
|
|
76
|
+
*
|
|
77
|
+
* <div use:devdock={{ modules, onNavigate: goto, hotkey: "mod+." }}></div>
|
|
78
|
+
* ```
|
|
79
|
+
*
|
|
80
|
+
* Same contract as the plain `devdock` action: the dock mounts into
|
|
81
|
+
* `document.body` (or `options.container`), so the host element is just an
|
|
82
|
+
* anchor, and reactive options flow through `update`.
|
|
83
|
+
*/
|
|
84
|
+
declare function devdock(_node: HTMLElement, options?: SvelteKitDevDockOptions): DevDockAction;
|
|
85
|
+
|
|
86
|
+
export { type DetectOptions, DevDockAction, DevDockOptions, DevRoute, RouteMatcher, type RouteModules, type SvelteKitDevDockOptions, detectRoutes, devdock, routeFromFile };
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { isMatcher, isDevPath, dedupeByPath, toPredicate } from './chunk-NRBOZ6H5.js';
|
|
2
|
+
import { createDevDock } from './chunk-F2KWDPMA.js';
|
|
3
|
+
export { createDevDock } from './chunk-F2KWDPMA.js';
|
|
4
|
+
|
|
5
|
+
// src/svelte/sveltekit.ts
|
|
6
|
+
var PAGE_FILE = /^\+page(@[^.]*)?\.[^.]+$/;
|
|
7
|
+
function stripRoutesDir(file, routesDir) {
|
|
8
|
+
const path = file.replace(/\\/g, "/");
|
|
9
|
+
const dirs = routesDir ? [routesDir] : ["src/routes", "routes"];
|
|
10
|
+
for (const dir of dirs) {
|
|
11
|
+
const needle = `/${dir.replace(/^\/|\/$/g, "")}/`;
|
|
12
|
+
const at = path.lastIndexOf(needle);
|
|
13
|
+
if (at !== -1) return path.slice(at + needle.length);
|
|
14
|
+
if (path.startsWith(needle.slice(1))) return path.slice(needle.length - 1);
|
|
15
|
+
}
|
|
16
|
+
return routesDir ? null : path.replace(/^\.?\//, "");
|
|
17
|
+
}
|
|
18
|
+
function routeFromFile(file, options = {}) {
|
|
19
|
+
const relative = stripRoutesDir(file, options.routesDir);
|
|
20
|
+
if (relative == null) return null;
|
|
21
|
+
const segments = relative.split("/");
|
|
22
|
+
const filename = segments.pop();
|
|
23
|
+
if (!filename || !PAGE_FILE.test(filename)) return null;
|
|
24
|
+
const kept = [];
|
|
25
|
+
for (const segment of segments) {
|
|
26
|
+
if (!segment || segment === ".") continue;
|
|
27
|
+
if (segment.startsWith("(") && segment.endsWith(")")) continue;
|
|
28
|
+
if (segment.startsWith("[[") && segment.endsWith("]]")) continue;
|
|
29
|
+
if (segment.includes("[")) return null;
|
|
30
|
+
kept.push(segment);
|
|
31
|
+
}
|
|
32
|
+
return `/${kept.join("/")}`;
|
|
33
|
+
}
|
|
34
|
+
function detectRoutes(modules, options = {}) {
|
|
35
|
+
const opts = isMatcher(options) ? { match: options } : options;
|
|
36
|
+
const files = Array.isArray(modules) ? modules : Object.keys(modules);
|
|
37
|
+
const paths = [];
|
|
38
|
+
for (const file of files) {
|
|
39
|
+
const path = routeFromFile(file, opts);
|
|
40
|
+
if (path != null && (opts.staticRoutes === true || isDevPath(path)))
|
|
41
|
+
paths.push(path);
|
|
42
|
+
}
|
|
43
|
+
const routes = dedupeByPath(
|
|
44
|
+
paths.sort().map((path) => ({ path, label: path }))
|
|
45
|
+
);
|
|
46
|
+
return opts.match ? routes.filter(toPredicate(opts.match)) : routes;
|
|
47
|
+
}
|
|
48
|
+
function resolveOptions(options) {
|
|
49
|
+
const { modules, match, staticRoutes, routesDir, ...rest } = options;
|
|
50
|
+
if (!modules) return rest;
|
|
51
|
+
const detected = detectRoutes(modules, { match, staticRoutes, routesDir });
|
|
52
|
+
return { ...rest, routes: [...detected, ...rest.routes ?? []] };
|
|
53
|
+
}
|
|
54
|
+
function devdock(_node, options = {}) {
|
|
55
|
+
const instance = createDevDock(resolveOptions(options));
|
|
56
|
+
return {
|
|
57
|
+
update(next = {}) {
|
|
58
|
+
instance.update(resolveOptions(next));
|
|
59
|
+
},
|
|
60
|
+
destroy() {
|
|
61
|
+
instance.destroy();
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export { detectRoutes, devdock, routeFromFile };
|
|
67
|
+
//# sourceMappingURL=sveltekit.js.map
|
|
68
|
+
//# sourceMappingURL=sveltekit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/svelte/sveltekit.ts"],"names":[],"mappings":";;;;;AAuCA,IAAM,SAAA,GAAY,0BAAA;AAElB,SAAS,cAAA,CAAe,MAAc,SAAA,EAAmC;AACvE,EAAA,MAAM,IAAA,GAAO,IAAA,CAAK,OAAA,CAAQ,KAAA,EAAO,GAAG,CAAA;AACpC,EAAA,MAAM,OAAO,SAAA,GAAY,CAAC,SAAS,CAAA,GAAI,CAAC,cAAc,QAAQ,CAAA;AAC9D,EAAA,KAAA,MAAW,OAAO,IAAA,EAAM;AACtB,IAAA,MAAM,SAAS,CAAA,CAAA,EAAI,GAAA,CAAI,OAAA,CAAQ,UAAA,EAAY,EAAE,CAAC,CAAA,CAAA,CAAA;AAC9C,IAAA,MAAM,EAAA,GAAK,IAAA,CAAK,WAAA,CAAY,MAAM,CAAA;AAClC,IAAA,IAAI,OAAO,EAAA,EAAI,OAAO,KAAK,KAAA,CAAM,EAAA,GAAK,OAAO,MAAM,CAAA;AACnD,IAAA,IAAI,IAAA,CAAK,UAAA,CAAW,MAAA,CAAO,KAAA,CAAM,CAAC,CAAC,CAAA,EAAG,OAAO,IAAA,CAAK,KAAA,CAAM,MAAA,CAAO,MAAA,GAAS,CAAC,CAAA;AAAA,EAC3E;AAEA,EAAA,OAAO,SAAA,GAAY,IAAA,GAAO,IAAA,CAAK,OAAA,CAAQ,UAAU,EAAE,CAAA;AACrD;AAUO,SAAS,aAAA,CACd,IAAA,EACA,OAAA,GAA4C,EAAC,EAC9B;AACf,EAAA,MAAM,QAAA,GAAW,cAAA,CAAe,IAAA,EAAM,OAAA,CAAQ,SAAS,CAAA;AACvD,EAAA,IAAI,QAAA,IAAY,MAAM,OAAO,IAAA;AAC7B,EAAA,MAAM,QAAA,GAAW,QAAA,CAAS,KAAA,CAAM,GAAG,CAAA;AACnC,EAAA,MAAM,QAAA,GAAW,SAAS,GAAA,EAAI;AAC9B,EAAA,IAAI,CAAC,QAAA,IAAY,CAAC,UAAU,IAAA,CAAK,QAAQ,GAAG,OAAO,IAAA;AACnD,EAAA,MAAM,OAAiB,EAAC;AACxB,EAAA,KAAA,MAAW,WAAW,QAAA,EAAU;AAC9B,IAAA,IAAI,CAAC,OAAA,IAAW,OAAA,KAAY,GAAA,EAAK;AAEjC,IAAA,IAAI,QAAQ,UAAA,CAAW,GAAG,KAAK,OAAA,CAAQ,QAAA,CAAS,GAAG,CAAA,EAAG;AAEtD,IAAA,IAAI,QAAQ,UAAA,CAAW,IAAI,KAAK,OAAA,CAAQ,QAAA,CAAS,IAAI,CAAA,EAAG;AACxD,IAAA,IAAI,OAAA,CAAQ,QAAA,CAAS,GAAG,CAAA,EAAG,OAAO,IAAA;AAClC,IAAA,IAAA,CAAK,KAAK,OAAO,CAAA;AAAA,EACnB;AACA,EAAA,OAAO,CAAA,CAAA,EAAI,IAAA,CAAK,IAAA,CAAK,GAAG,CAAC,CAAA,CAAA;AAC3B;AAcO,SAAS,YAAA,CACd,OAAA,EACA,OAAA,GAAwC,EAAC,EAC7B;AACZ,EAAA,MAAM,OAAsB,SAAA,CAAU,OAAO,IAAI,EAAE,KAAA,EAAO,SAAQ,GAAI,OAAA;AACtE,EAAA,MAAM,KAAA,GAAQ,MAAM,OAAA,CAAQ,OAAO,IAAI,OAAA,GAAU,MAAA,CAAO,KAAK,OAAO,CAAA;AACpE,EAAA,MAAM,QAAkB,EAAC;AACzB,EAAA,KAAA,MAAW,QAAQ,KAAA,EAAO;AACxB,IAAA,MAAM,IAAA,GAAO,aAAA,CAAc,IAAA,EAAM,IAAI,CAAA;AACrC,IAAA,IAAI,QAAQ,IAAA,KAAS,IAAA,CAAK,YAAA,KAAiB,IAAA,IAAQ,UAAU,IAAI,CAAA,CAAA;AAC/D,MAAA,KAAA,CAAM,KAAK,IAAI,CAAA;AAAA,EACnB;AACA,EAAA,MAAM,MAAA,GAAS,YAAA;AAAA,IACb,KAAA,CAAM,IAAA,EAAK,CAAE,GAAA,CAAI,CAAC,UAAU,EAAE,IAAA,EAAM,KAAA,EAAO,IAAA,EAAK,CAAE;AAAA,GACpD;AACA,EAAA,OAAO,IAAA,CAAK,QAAQ,MAAA,CAAO,MAAA,CAAO,YAAY,IAAA,CAAK,KAAK,CAAC,CAAA,GAAI,MAAA;AAC/D;AAgBA,SAAS,eAAe,OAAA,EAAkD;AACxE,EAAA,MAAM,EAAE,OAAA,EAAS,KAAA,EAAO,cAAc,SAAA,EAAW,GAAG,MAAK,GAAI,OAAA;AAC7D,EAAA,IAAI,CAAC,SAAS,OAAO,IAAA;AACrB,EAAA,MAAM,WAAW,YAAA,CAAa,OAAA,EAAS,EAAE,KAAA,EAAO,YAAA,EAAc,WAAW,CAAA;AACzE,EAAA,OAAO,EAAE,GAAG,IAAA,EAAM,MAAA,EAAQ,CAAC,GAAG,QAAA,EAAU,GAAI,IAAA,CAAK,MAAA,IAAU,EAAG,CAAA,EAAE;AAClE;AAqBO,SAAS,OAAA,CACd,KAAA,EACA,OAAA,GAAmC,EAAC,EACrB;AACf,EAAA,MAAM,QAAA,GAAW,aAAA,CAAc,cAAA,CAAe,OAAO,CAAC,CAAA;AACtD,EAAA,OAAO;AAAA,IACL,MAAA,CAAO,IAAA,GAAgC,EAAC,EAAG;AACzC,MAAA,QAAA,CAAS,MAAA,CAAO,cAAA,CAAe,IAAI,CAAC,CAAA;AAAA,IACtC,CAAA;AAAA,IACA,OAAA,GAAU;AACR,MAAA,QAAA,CAAS,OAAA,EAAQ;AAAA,IACnB;AAAA,GACF;AACF","file":"sveltekit.js","sourcesContent":["import { createDevDock } from \"../core/dock\";\nimport type { DevDockOptions, DevRoute } from \"../core/types\";\nimport {\n dedupeByPath,\n isDevPath,\n isMatcher,\n toPredicate,\n type RouteMatcher,\n} from \"../core/match\";\nimport type { DevDockAction } from \"./index\";\n\nexport type { RouteMatcher };\n\n/**\n * What `import.meta.glob(\"/src/routes/**\\/+page.svelte\")` returns — only the\n * keys matter, so an array of file paths works too.\n */\nexport type RouteModules = Record<string, unknown> | string[];\n\nexport interface DetectOptions {\n /**\n * Only keep routes that match. A glob string (`*` = any characters), a\n * `RegExp`, or a predicate.\n */\n match?: RouteMatcher;\n /**\n * Also list the app's ordinary routes, not just the ones under `/dev`.\n * Default: `false`.\n */\n staticRoutes?: boolean;\n /**\n * Your routes directory, as a name or a trailing path (`\"routes\"`,\n * `\"app/pages\"`). Detected from the `src/routes` (or `routes`) segment of\n * each key by default; set it only if your routes live somewhere else.\n */\n routesDir?: string;\n}\n\n/** Page files SvelteKit renders: `+page.svelte`, `+page.ts`, `+page@(app).svelte`… */\nconst PAGE_FILE = /^\\+page(@[^.]*)?\\.[^.]+$/;\n\nfunction stripRoutesDir(file: string, routesDir?: string): string | null {\n const path = file.replace(/\\\\/g, \"/\");\n const dirs = routesDir ? [routesDir] : [\"src/routes\", \"routes\"];\n for (const dir of dirs) {\n const needle = `/${dir.replace(/^\\/|\\/$/g, \"\")}/`;\n const at = path.lastIndexOf(needle);\n if (at !== -1) return path.slice(at + needle.length);\n if (path.startsWith(needle.slice(1))) return path.slice(needle.length - 1);\n }\n // Relative glob from inside the routes directory, e.g. \"./dev/+page.svelte\".\n return routesDir ? null : path.replace(/^\\.?\\//, \"\");\n}\n\n/**\n * Turn a SvelteKit page file path into the route it serves, or `null` if it\n * isn't a navigable page.\n *\n * Layout groups (`(app)`) and optional params (`[[lang]]`) drop out of the\n * path; required (`[id]`), matched (`[id=int]`) and rest (`[...rest]`) params\n * make the route unnavigable without arguments, so it's skipped.\n */\nexport function routeFromFile(\n file: string,\n options: Pick<DetectOptions, \"routesDir\"> = {},\n): string | null {\n const relative = stripRoutesDir(file, options.routesDir);\n if (relative == null) return null;\n const segments = relative.split(\"/\");\n const filename = segments.pop();\n if (!filename || !PAGE_FILE.test(filename)) return null;\n const kept: string[] = [];\n for (const segment of segments) {\n if (!segment || segment === \".\") continue;\n // Layout group — organizes files, not URLs.\n if (segment.startsWith(\"(\") && segment.endsWith(\")\")) continue;\n // Optional param: the route is reachable without it.\n if (segment.startsWith(\"[[\") && segment.endsWith(\"]]\")) continue;\n if (segment.includes(\"[\")) return null;\n kept.push(segment);\n }\n return `/${kept.join(\"/\")}`;\n}\n\n/**\n * Flatten a SvelteKit `import.meta.glob` of page files into navigable\n * {@link DevRoute}s.\n *\n * Only dev destinations are returned — anything under `/dev`, by convention.\n * Pass `{ staticRoutes: true }` to list every page instead, and `{ match }`\n * to scope the results. A bare matcher is accepted as shorthand.\n *\n * ```ts\n * const routes = detectRoutes(import.meta.glob(\"/src/routes/**\\/+page.svelte\"));\n * ```\n */\nexport function detectRoutes(\n modules: RouteModules,\n options: DetectOptions | RouteMatcher = {},\n): DevRoute[] {\n const opts: DetectOptions = isMatcher(options) ? { match: options } : options;\n const files = Array.isArray(modules) ? modules : Object.keys(modules);\n const paths: string[] = [];\n for (const file of files) {\n const path = routeFromFile(file, opts);\n if (path != null && (opts.staticRoutes === true || isDevPath(path)))\n paths.push(path);\n }\n const routes = dedupeByPath(\n paths.sort().map((path) => ({ path, label: path })),\n );\n return opts.match ? routes.filter(toPredicate(opts.match)) : routes;\n}\n\nexport interface SvelteKitDevDockOptions extends DevDockOptions, DetectOptions {\n /**\n * Your page files, from `import.meta.glob`. The glob has to be written in\n * your app (Vite resolves it at build time), so pass the result in:\n *\n * ```ts\n * { modules: import.meta.glob(\"/src/routes/**\\/+page.svelte\") }\n * ```\n *\n * Detected routes come first; any `routes` you pass are appended.\n */\n modules?: RouteModules;\n}\n\nfunction resolveOptions(options: SvelteKitDevDockOptions): DevDockOptions {\n const { modules, match, staticRoutes, routesDir, ...rest } = options;\n if (!modules) return rest;\n const detected = detectRoutes(modules, { match, staticRoutes, routesDir });\n return { ...rest, routes: [...detected, ...(rest.routes ?? [])] };\n}\n\n/**\n * Svelte action that mounts a dev dock with the SvelteKit routes detected\n * from `modules`:\n *\n * ```svelte\n * <script lang=\"ts\">\n * import { goto } from \"$app/navigation\";\n * import { devdock } from \"@chuvenger/devdock/sveltekit\";\n *\n * const modules = import.meta.glob(\"/src/routes/**\\/+page.svelte\");\n * </script>\n *\n * <div use:devdock={{ modules, onNavigate: goto, hotkey: \"mod+.\" }}></div>\n * ```\n *\n * Same contract as the plain `devdock` action: the dock mounts into\n * `document.body` (or `options.container`), so the host element is just an\n * anchor, and reactive options flow through `update`.\n */\nexport function devdock(\n _node: HTMLElement,\n options: SvelteKitDevDockOptions = {},\n): DevDockAction {\n const instance = createDevDock(resolveOptions(options));\n return {\n update(next: SvelteKitDevDockOptions = {}) {\n instance.update(resolveOptions(next));\n },\n destroy() {\n instance.destroy();\n },\n };\n}\n\nexport { createDevDock } from \"../core/dock\";\nexport type { DevDockAction } from \"./index\";\nexport type {\n DevDockOptions,\n DevDockInstance,\n DevRoute,\n DevCommand,\n DockPosition,\n} from \"../core/types\";\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@chuvenger/devdock",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "A tiny dev-only floating button that opens a popup to jump between dev routes and run custom commands.",
|
|
5
5
|
"author": "Ruven Chu",
|
|
6
6
|
"repository": {
|
|
@@ -22,6 +22,7 @@
|
|
|
22
22
|
"react",
|
|
23
23
|
"svelte",
|
|
24
24
|
"react-router",
|
|
25
|
+
"sveltekit",
|
|
25
26
|
"navigation",
|
|
26
27
|
"command-palette"
|
|
27
28
|
],
|
|
@@ -51,6 +52,11 @@
|
|
|
51
52
|
"types": "./dist/svelte.d.ts",
|
|
52
53
|
"import": "./dist/svelte.js",
|
|
53
54
|
"require": "./dist/svelte.cjs"
|
|
55
|
+
},
|
|
56
|
+
"./sveltekit": {
|
|
57
|
+
"types": "./dist/sveltekit.d.ts",
|
|
58
|
+
"import": "./dist/sveltekit.js",
|
|
59
|
+
"require": "./dist/sveltekit.cjs"
|
|
54
60
|
}
|
|
55
61
|
},
|
|
56
62
|
"main": "./dist/index.cjs",
|