davaux 0.8.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/BASELINE.md +169 -0
- package/CLAUDE.md +518 -0
- package/LICENSE +21 -0
- package/README.md +36 -0
- package/ROADMAP.md +198 -0
- package/build.mjs +101 -0
- package/client/control.ts +247 -0
- package/client/hydrate.ts +37 -0
- package/client/index.ts +19 -0
- package/client/jsx-runtime.ts +209 -0
- package/client/resource.ts +122 -0
- package/client/signal.ts +211 -0
- package/client/store.ts +110 -0
- package/client/useHead.ts +63 -0
- package/dist/build/config.d.ts +3 -0
- package/dist/build/config.d.ts.map +1 -0
- package/dist/build/config.js +38 -0
- package/dist/build/config.js.map +7 -0
- package/dist/build/index.d.ts +2 -0
- package/dist/build/index.d.ts.map +1 -0
- package/dist/build/index.js +13 -0
- package/dist/build/index.js.map +7 -0
- package/dist/build/plugins.d.ts +7 -0
- package/dist/build/plugins.d.ts.map +1 -0
- package/dist/build/plugins.js +85 -0
- package/dist/build/plugins.js.map +7 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +427 -0
- package/dist/cli.js.map +7 -0
- package/dist/client/control.d.ts +49 -0
- package/dist/client/control.d.ts.map +1 -0
- package/dist/client/control.js +154 -0
- package/dist/client/control.js.map +7 -0
- package/dist/client/hydrate.d.ts +7 -0
- package/dist/client/hydrate.d.ts.map +1 -0
- package/dist/client/hydrate.js +23 -0
- package/dist/client/hydrate.js.map +7 -0
- package/dist/client/index.d.ts +12 -0
- package/dist/client/index.d.ts.map +1 -0
- package/dist/client/index.js +32 -0
- package/dist/client/index.js.map +7 -0
- package/dist/client/jsx-runtime.d.ts +40 -0
- package/dist/client/jsx-runtime.d.ts.map +1 -0
- package/dist/client/jsx-runtime.js +139 -0
- package/dist/client/jsx-runtime.js.map +7 -0
- package/dist/client/resource.d.ts +31 -0
- package/dist/client/resource.d.ts.map +1 -0
- package/dist/client/resource.js +64 -0
- package/dist/client/resource.js.map +7 -0
- package/dist/client/signal.d.ts +90 -0
- package/dist/client/signal.d.ts.map +1 -0
- package/dist/client/signal.js +115 -0
- package/dist/client/signal.js.map +7 -0
- package/dist/client/store.d.ts +26 -0
- package/dist/client/store.d.ts.map +1 -0
- package/dist/client/store.js +63 -0
- package/dist/client/store.js.map +7 -0
- package/dist/client/useHead.d.ts +28 -0
- package/dist/client/useHead.d.ts.map +1 -0
- package/dist/client/useHead.js +33 -0
- package/dist/client/useHead.js.map +7 -0
- package/dist/config.d.ts +182 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +21 -0
- package/dist/config.js.map +7 -0
- package/dist/create-multisite.d.ts +2 -0
- package/dist/create-multisite.d.ts.map +1 -0
- package/dist/create-multisite.js +291 -0
- package/dist/create-multisite.js.map +7 -0
- package/dist/create.d.ts +2 -0
- package/dist/create.d.ts.map +1 -0
- package/dist/create.js +179 -0
- package/dist/create.js.map +7 -0
- package/dist/dev/blueprints.d.ts +11 -0
- package/dist/dev/blueprints.d.ts.map +1 -0
- package/dist/dev/blueprints.js +65 -0
- package/dist/dev/blueprints.js.map +7 -0
- package/dist/dev/components.d.ts +19 -0
- package/dist/dev/components.d.ts.map +1 -0
- package/dist/dev/components.js +87 -0
- package/dist/dev/components.js.map +7 -0
- package/dist/dev/insert.d.ts +11 -0
- package/dist/dev/insert.d.ts.map +1 -0
- package/dist/dev/insert.js +160 -0
- package/dist/dev/insert.js.map +7 -0
- package/dist/dev/remove.d.ts +53 -0
- package/dist/dev/remove.d.ts.map +1 -0
- package/dist/dev/remove.js +518 -0
- package/dist/dev/remove.js.map +7 -0
- package/dist/dev/watch.d.ts +26 -0
- package/dist/dev/watch.d.ts.map +1 -0
- package/dist/dev/watch.js +2905 -0
- package/dist/dev/watch.js.map +7 -0
- package/dist/errors.d.ts +6 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +63 -0
- package/dist/errors.js.map +7 -0
- package/dist/generate.d.ts +2 -0
- package/dist/generate.d.ts.map +1 -0
- package/dist/generate.js +191 -0
- package/dist/generate.js.map +7 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +57 -0
- package/dist/index.js.map +7 -0
- package/dist/island.d.ts +24 -0
- package/dist/island.d.ts.map +1 -0
- package/dist/island.js +15 -0
- package/dist/island.js.map +7 -0
- package/dist/jsx-runtime.d.ts +406 -0
- package/dist/jsx-runtime.d.ts.map +1 -0
- package/dist/jsx-runtime.js +90 -0
- package/dist/jsx-runtime.js.map +7 -0
- package/dist/link.d.ts +27 -0
- package/dist/link.d.ts.map +1 -0
- package/dist/link.js +29 -0
- package/dist/link.js.map +7 -0
- package/dist/oml/fragment.d.ts +16 -0
- package/dist/oml/fragment.d.ts.map +1 -0
- package/dist/oml/fragment.js +26 -0
- package/dist/oml/fragment.js.map +7 -0
- package/dist/oml/index.d.ts +11 -0
- package/dist/oml/index.d.ts.map +1 -0
- package/dist/oml/index.js +21 -0
- package/dist/oml/index.js.map +7 -0
- package/dist/oml/jsx-runtime.d.ts +34 -0
- package/dist/oml/jsx-runtime.d.ts.map +1 -0
- package/dist/oml/jsx-runtime.js +59 -0
- package/dist/oml/jsx-runtime.js.map +7 -0
- package/dist/oml/jsx.d.ts +14 -0
- package/dist/oml/jsx.d.ts.map +1 -0
- package/dist/oml/jsx.js +96 -0
- package/dist/oml/jsx.js.map +7 -0
- package/dist/oml/page.d.ts +7 -0
- package/dist/oml/page.d.ts.map +1 -0
- package/dist/oml/page.js +6 -0
- package/dist/oml/page.js.map +7 -0
- package/dist/oml/render.d.ts +13 -0
- package/dist/oml/render.d.ts.map +1 -0
- package/dist/oml/render.js +117 -0
- package/dist/oml/render.js.map +7 -0
- package/dist/oml/types.d.ts +79 -0
- package/dist/oml/types.d.ts.map +1 -0
- package/dist/oml/types.js +64 -0
- package/dist/oml/types.js.map +7 -0
- package/dist/router/handler.d.ts +53 -0
- package/dist/router/handler.d.ts.map +1 -0
- package/dist/router/handler.js +342 -0
- package/dist/router/handler.js.map +7 -0
- package/dist/router/matcher.d.ts +21 -0
- package/dist/router/matcher.d.ts.map +1 -0
- package/dist/router/matcher.js +28 -0
- package/dist/router/matcher.js.map +7 -0
- package/dist/router/scanner.d.ts +17 -0
- package/dist/router/scanner.d.ts.map +1 -0
- package/dist/router/scanner.js +197 -0
- package/dist/router/scanner.js.map +7 -0
- package/dist/server/index.d.ts +23 -0
- package/dist/server/index.d.ts.map +1 -0
- package/dist/server/index.js +29 -0
- package/dist/server/index.js.map +7 -0
- package/dist/signal.d.ts +15 -0
- package/dist/signal.d.ts.map +1 -0
- package/dist/signal.js +29 -0
- package/dist/signal.js.map +7 -0
- package/dist/ssg.d.ts +45 -0
- package/dist/ssg.d.ts.map +1 -0
- package/dist/ssg.js +175 -0
- package/dist/ssg.js.map +7 -0
- package/dist/test/actions.test.d.ts +2 -0
- package/dist/test/actions.test.d.ts.map +1 -0
- package/dist/test/body-limits.test.d.ts +2 -0
- package/dist/test/body-limits.test.d.ts.map +1 -0
- package/dist/test/errors.test.d.ts +2 -0
- package/dist/test/errors.test.d.ts.map +1 -0
- package/dist/test/fixtures/routes/[id].page.d.ts +4 -0
- package/dist/test/fixtures/routes/[id].page.d.ts.map +1 -0
- package/dist/test/fixtures/routes/_error.d.ts +3 -0
- package/dist/test/fixtures/routes/_error.d.ts.map +1 -0
- package/dist/test/fixtures/routes/_global.d.ts +3 -0
- package/dist/test/fixtures/routes/_global.d.ts.map +1 -0
- package/dist/test/fixtures/routes/_layout-template.d.ts +3 -0
- package/dist/test/fixtures/routes/_layout-template.d.ts.map +1 -0
- package/dist/test/fixtures/routes/_layout.d.ts +3 -0
- package/dist/test/fixtures/routes/_layout.d.ts.map +1 -0
- package/dist/test/fixtures/routes/_layout_scripts.d.ts +3 -0
- package/dist/test/fixtures/routes/_layout_scripts.d.ts.map +1 -0
- package/dist/test/fixtures/routes/_middleware.d.ts +3 -0
- package/dist/test/fixtures/routes/_middleware.d.ts.map +1 -0
- package/dist/test/fixtures/routes/_redirect301_mw.d.ts +3 -0
- package/dist/test/fixtures/routes/_redirect301_mw.d.ts.map +1 -0
- package/dist/test/fixtures/routes/_redirect_mw.d.ts +3 -0
- package/dist/test/fixtures/routes/_redirect_mw.d.ts.map +1 -0
- package/dist/test/fixtures/routes/about.page.d.ts +3 -0
- package/dist/test/fixtures/routes/about.page.d.ts.map +1 -0
- package/dist/test/fixtures/routes/action.page.d.ts +6 -0
- package/dist/test/fixtures/routes/action.page.d.ts.map +1 -0
- package/dist/test/fixtures/routes/api/form-all.post.d.ts +3 -0
- package/dist/test/fixtures/routes/api/form-all.post.d.ts.map +1 -0
- package/dist/test/fixtures/routes/api/form-limited.post.d.ts +6 -0
- package/dist/test/fixtures/routes/api/form-limited.post.d.ts.map +1 -0
- package/dist/test/fixtures/routes/api/response-obj.get.d.ts +3 -0
- package/dist/test/fixtures/routes/api/response-obj.get.d.ts.map +1 -0
- package/dist/test/fixtures/routes/api/upload.post.d.ts +12 -0
- package/dist/test/fixtures/routes/api/upload.post.d.ts.map +1 -0
- package/dist/test/fixtures/routes/api/users.get.d.ts +6 -0
- package/dist/test/fixtures/routes/api/users.get.d.ts.map +1 -0
- package/dist/test/fixtures/routes/api/xml.get.d.ts +3 -0
- package/dist/test/fixtures/routes/api/xml.get.d.ts.map +1 -0
- package/dist/test/fixtures/routes/auth/_middleware.d.ts +3 -0
- package/dist/test/fixtures/routes/auth/_middleware.d.ts.map +1 -0
- package/dist/test/fixtures/routes/auth/protected.page.d.ts +3 -0
- package/dist/test/fixtures/routes/auth/protected.page.d.ts.map +1 -0
- package/dist/test/fixtures/routes/index.page.d.ts +3 -0
- package/dist/test/fixtures/routes/index.page.d.ts.map +1 -0
- package/dist/test/fixtures/routes/oml.page.d.ts +3 -0
- package/dist/test/fixtures/routes/oml.page.d.ts.map +1 -0
- package/dist/test/fixtures/routes/redirect.page.d.ts +3 -0
- package/dist/test/fixtures/routes/redirect.page.d.ts.map +1 -0
- package/dist/test/fixtures/routes/ssg/[slug].page.d.ts +5 -0
- package/dist/test/fixtures/routes/ssg/[slug].page.d.ts.map +1 -0
- package/dist/test/fixtures/routes/ssg/server.page.d.ts +4 -0
- package/dist/test/fixtures/routes/ssg/server.page.d.ts.map +1 -0
- package/dist/test/fixtures/routes/state.page.d.ts +3 -0
- package/dist/test/fixtures/routes/state.page.d.ts.map +1 -0
- package/dist/test/fixtures/routes/throw.page.d.ts +3 -0
- package/dist/test/fixtures/routes/throw.page.d.ts.map +1 -0
- package/dist/test/fixtures/routes/wiki/[...slug].page.d.ts +3 -0
- package/dist/test/fixtures/routes/wiki/[...slug].page.d.ts.map +1 -0
- package/dist/test/helpers.d.ts +37 -0
- package/dist/test/helpers.d.ts.map +1 -0
- package/dist/test/layouts.test.d.ts +2 -0
- package/dist/test/layouts.test.d.ts.map +1 -0
- package/dist/test/middleware.test.d.ts +2 -0
- package/dist/test/middleware.test.d.ts.map +1 -0
- package/dist/test/multipart.test.d.ts +2 -0
- package/dist/test/multipart.test.d.ts.map +1 -0
- package/dist/test/oml-routing.test.d.ts +2 -0
- package/dist/test/oml-routing.test.d.ts.map +1 -0
- package/dist/test/oml.test.d.ts +2 -0
- package/dist/test/oml.test.d.ts.map +1 -0
- package/dist/test/redirects.test.d.ts +2 -0
- package/dist/test/redirects.test.d.ts.map +1 -0
- package/dist/test/routing.test.d.ts +2 -0
- package/dist/test/routing.test.d.ts.map +1 -0
- package/dist/test/ssg.test.d.ts +2 -0
- package/dist/test/ssg.test.d.ts.map +1 -0
- package/dist/test/web-response.test.d.ts +2 -0
- package/dist/test/web-response.test.d.ts.map +1 -0
- package/dist/types.d.ts +314 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +292 -0
- package/dist/types.js.map +7 -0
- package/package.json +103 -0
- package/pka.config.json +32 -0
- package/src/build/config.ts +42 -0
- package/src/build/index.ts +6 -0
- package/src/build/plugins.ts +118 -0
- package/src/cli.ts +502 -0
- package/src/config.ts +197 -0
- package/src/create-multisite.ts +310 -0
- package/src/create.ts +194 -0
- package/src/dev/blueprints.ts +75 -0
- package/src/dev/components.ts +108 -0
- package/src/dev/insert.ts +221 -0
- package/src/dev/remove.ts +677 -0
- package/src/dev/watch.ts +3098 -0
- package/src/env.d.ts +5 -0
- package/src/errors.ts +64 -0
- package/src/generate.ts +228 -0
- package/src/index.ts +67 -0
- package/src/island.ts +47 -0
- package/src/jsx-runtime.d.ts +408 -0
- package/src/jsx-runtime.d.ts.map +1 -0
- package/src/jsx-runtime.ts +536 -0
- package/src/link.ts +49 -0
- package/src/oml/fragment.ts +54 -0
- package/src/oml/index.ts +21 -0
- package/src/oml/jsx-runtime.ts +121 -0
- package/src/oml/jsx.ts +151 -0
- package/src/oml/page.ts +13 -0
- package/src/oml/render.ts +181 -0
- package/src/oml/types.ts +159 -0
- package/src/router/handler.ts +515 -0
- package/src/router/matcher.ts +52 -0
- package/src/router/scanner.ts +272 -0
- package/src/server/index.ts +49 -0
- package/src/signal.ts +39 -0
- package/src/ssg.ts +253 -0
- package/src/test/actions.test.ts +40 -0
- package/src/test/body-limits.test.ts +83 -0
- package/src/test/errors.test.ts +53 -0
- package/src/test/fixtures/routes/[id].page.ts +3 -0
- package/src/test/fixtures/routes/_error.ts +6 -0
- package/src/test/fixtures/routes/_global.ts +8 -0
- package/src/test/fixtures/routes/_layout-template.ts +7 -0
- package/src/test/fixtures/routes/_layout.ts +7 -0
- package/src/test/fixtures/routes/_layout_scripts.ts +8 -0
- package/src/test/fixtures/routes/_middleware.ts +8 -0
- package/src/test/fixtures/routes/_redirect301_mw.ts +5 -0
- package/src/test/fixtures/routes/_redirect_mw.ts +5 -0
- package/src/test/fixtures/routes/about.page.ts +6 -0
- package/src/test/fixtures/routes/action.page.ts +11 -0
- package/src/test/fixtures/routes/api/form-all.post.ts +5 -0
- package/src/test/fixtures/routes/api/form-limited.post.ts +6 -0
- package/src/test/fixtures/routes/api/response-obj.get.ts +17 -0
- package/src/test/fixtures/routes/api/upload.post.ts +14 -0
- package/src/test/fixtures/routes/api/users.get.ts +3 -0
- package/src/test/fixtures/routes/api/xml.get.ts +5 -0
- package/src/test/fixtures/routes/auth/_middleware.ts +11 -0
- package/src/test/fixtures/routes/auth/protected.page.ts +3 -0
- package/src/test/fixtures/routes/index.page.ts +3 -0
- package/src/test/fixtures/routes/oml.page.ts +7 -0
- package/src/test/fixtures/routes/redirect.page.ts +3 -0
- package/src/test/fixtures/routes/ssg/[slug].page.ts +8 -0
- package/src/test/fixtures/routes/ssg/server.page.ts +5 -0
- package/src/test/fixtures/routes/state.page.ts +4 -0
- package/src/test/fixtures/routes/throw.page.ts +5 -0
- package/src/test/fixtures/routes/wiki/[...slug].page.ts +3 -0
- package/src/test/helpers.ts +132 -0
- package/src/test/layouts.test.ts +76 -0
- package/src/test/middleware.test.ts +69 -0
- package/src/test/multipart.test.ts +91 -0
- package/src/test/oml-routing.test.ts +59 -0
- package/src/test/oml.test.ts +429 -0
- package/src/test/redirects.test.ts +32 -0
- package/src/test/routing.test.ts +118 -0
- package/src/test/ssg.test.ts +273 -0
- package/src/test/web-response.test.ts +33 -0
- package/src/types.ts +670 -0
- package/tsconfig.client.json +17 -0
- package/tsconfig.json +20 -0
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
import { existsSync } from "node:fs";
|
|
2
|
+
import { readdir } from "node:fs/promises";
|
|
3
|
+
import { basename, dirname, join, relative } from "node:path";
|
|
4
|
+
const SUFFIX_MAP = [
|
|
5
|
+
[".page.tsx", "page"],
|
|
6
|
+
[".page.ts", "page"],
|
|
7
|
+
[".page.jsx", "page"],
|
|
8
|
+
[".page.js", "page"],
|
|
9
|
+
[".get.tsx", "get"],
|
|
10
|
+
[".get.ts", "get"],
|
|
11
|
+
[".get.jsx", "get"],
|
|
12
|
+
[".get.js", "get"],
|
|
13
|
+
[".post.tsx", "post"],
|
|
14
|
+
[".post.ts", "post"],
|
|
15
|
+
[".post.jsx", "post"],
|
|
16
|
+
[".post.js", "post"],
|
|
17
|
+
[".put.tsx", "put"],
|
|
18
|
+
[".put.ts", "put"],
|
|
19
|
+
[".put.jsx", "put"],
|
|
20
|
+
[".put.js", "put"],
|
|
21
|
+
[".patch.tsx", "patch"],
|
|
22
|
+
[".patch.ts", "patch"],
|
|
23
|
+
[".patch.jsx", "patch"],
|
|
24
|
+
[".patch.js", "patch"],
|
|
25
|
+
[".delete.tsx", "delete"],
|
|
26
|
+
[".delete.ts", "delete"],
|
|
27
|
+
[".delete.jsx", "delete"],
|
|
28
|
+
[".delete.js", "delete"],
|
|
29
|
+
[".head.ts", "head"],
|
|
30
|
+
[".head.js", "head"],
|
|
31
|
+
[".options.ts", "options"],
|
|
32
|
+
[".options.js", "options"]
|
|
33
|
+
];
|
|
34
|
+
const LAYOUT_NAMES = /* @__PURE__ */ new Set(["_layout.tsx", "_layout.ts", "_layout.jsx", "_layout.js"]);
|
|
35
|
+
const ERROR_PAGE_NAMES = /* @__PURE__ */ new Set(["_error.tsx", "_error.ts", "_error.jsx", "_error.js"]);
|
|
36
|
+
const MIDDLEWARE_NAMES = /* @__PURE__ */ new Set([
|
|
37
|
+
"_middleware.tsx",
|
|
38
|
+
"_middleware.ts",
|
|
39
|
+
"_middleware.jsx",
|
|
40
|
+
"_middleware.js"
|
|
41
|
+
]);
|
|
42
|
+
function resolveRouteSuffix(filename, suffixMap) {
|
|
43
|
+
for (const [suffix, type] of suffixMap) {
|
|
44
|
+
if (filename.endsWith(suffix)) return [filename.slice(0, -suffix.length), type];
|
|
45
|
+
}
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
function segmentToParam(segment) {
|
|
49
|
+
const catchAll = segment.match(/^\[\.\.\.([^\]]+)\]$/);
|
|
50
|
+
if (catchAll) return { pattern: `*${catchAll[1]}`, param: catchAll[1] };
|
|
51
|
+
const m = segment.match(/^\[([^\]]+)\]$/);
|
|
52
|
+
if (m) return { pattern: `:${m[1]}`, param: m[1] };
|
|
53
|
+
return { pattern: segment, param: null };
|
|
54
|
+
}
|
|
55
|
+
function fileToUrlPattern(rel) {
|
|
56
|
+
const params = [];
|
|
57
|
+
const segments = rel.split("/").map((seg) => {
|
|
58
|
+
const { pattern, param } = segmentToParam(seg);
|
|
59
|
+
if (param) params.push(param);
|
|
60
|
+
return pattern;
|
|
61
|
+
});
|
|
62
|
+
if (segments.at(-1) === "index") segments.pop();
|
|
63
|
+
const raw = `/${segments.join("/")}`;
|
|
64
|
+
return { urlPattern: raw.replace(/\/+$/, "") || "/", params };
|
|
65
|
+
}
|
|
66
|
+
async function walk(dir, files = []) {
|
|
67
|
+
const entries = await readdir(dir, { withFileTypes: true });
|
|
68
|
+
for (const entry of entries) {
|
|
69
|
+
const full = join(dir, entry.name);
|
|
70
|
+
entry.isDirectory() ? await walk(full, files) : files.push(full);
|
|
71
|
+
}
|
|
72
|
+
return files;
|
|
73
|
+
}
|
|
74
|
+
async function scanIslands(islandsDir) {
|
|
75
|
+
if (!existsSync(islandsDir)) return [];
|
|
76
|
+
const islands = [];
|
|
77
|
+
async function walkIslands(dir) {
|
|
78
|
+
const entries = await readdir(dir, { withFileTypes: true });
|
|
79
|
+
for (const entry of entries) {
|
|
80
|
+
const full = join(dir, entry.name);
|
|
81
|
+
if (entry.isDirectory()) {
|
|
82
|
+
await walkIslands(full);
|
|
83
|
+
} else if (/\.(tsx?|jsx?)$/.test(entry.name) && !entry.name.startsWith("_")) {
|
|
84
|
+
const id = entry.name.replace(/\.(tsx?|jsx?)$/, "");
|
|
85
|
+
islands.push({ filePath: full, id });
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
await walkIslands(islandsDir);
|
|
90
|
+
return islands;
|
|
91
|
+
}
|
|
92
|
+
const TYPE_METHODS = {
|
|
93
|
+
page: ["GET", "HEAD", "POST"],
|
|
94
|
+
// POST only when an `action` export is present, but we warn conservatively
|
|
95
|
+
get: ["GET", "HEAD"],
|
|
96
|
+
// HEAD checks 'get' in its allowed list
|
|
97
|
+
post: ["POST"],
|
|
98
|
+
put: ["PUT"],
|
|
99
|
+
patch: ["PATCH"],
|
|
100
|
+
delete: ["DELETE"],
|
|
101
|
+
head: ["HEAD"],
|
|
102
|
+
options: ["OPTIONS"]
|
|
103
|
+
};
|
|
104
|
+
function checkConflicts(routes, routesDir) {
|
|
105
|
+
const byPattern = /* @__PURE__ */ new Map();
|
|
106
|
+
for (const route of routes) {
|
|
107
|
+
const group = byPattern.get(route.urlPattern) ?? [];
|
|
108
|
+
group.push(route);
|
|
109
|
+
byPattern.set(route.urlPattern, group);
|
|
110
|
+
}
|
|
111
|
+
for (const [pattern, group] of byPattern) {
|
|
112
|
+
if (group.length < 2) continue;
|
|
113
|
+
for (let i = 0; i < group.length; i++) {
|
|
114
|
+
for (let j = i + 1; j < group.length; j++) {
|
|
115
|
+
const a = group[i];
|
|
116
|
+
const b = group[j];
|
|
117
|
+
const overlap = TYPE_METHODS[a.type].filter((m) => TYPE_METHODS[b.type].includes(m));
|
|
118
|
+
if (overlap.length === 0) continue;
|
|
119
|
+
const aRel = relative(routesDir, a.filePath);
|
|
120
|
+
const bRel = relative(routesDir, b.filePath);
|
|
121
|
+
if (a.type === b.type) {
|
|
122
|
+
console.warn(
|
|
123
|
+
`[davaux] warning: duplicate ${a.type} route at ${pattern}
|
|
124
|
+
${aRel}
|
|
125
|
+
${bRel}
|
|
126
|
+
Only the first will be used.`
|
|
127
|
+
);
|
|
128
|
+
} else {
|
|
129
|
+
const winner = a.type !== "page" ? aRel : bRel;
|
|
130
|
+
console.warn(
|
|
131
|
+
`[davaux] warning: ${overlap.join(" + ")} ${pattern} matched by both ${aRel} (${a.type}) and ${bRel} (${b.type}) \u2014 ${winner} takes priority`
|
|
132
|
+
);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
async function scanRoutes(routesDir, extraSuffixes = []) {
|
|
139
|
+
const suffixMap = [...SUFFIX_MAP, ...extraSuffixes];
|
|
140
|
+
const allFiles = await walk(routesDir);
|
|
141
|
+
const routes = [];
|
|
142
|
+
const layouts = [];
|
|
143
|
+
const middlewares = [];
|
|
144
|
+
let errorPage;
|
|
145
|
+
for (const filePath of allFiles) {
|
|
146
|
+
const rel = relative(routesDir, filePath);
|
|
147
|
+
const name = basename(rel);
|
|
148
|
+
if (LAYOUT_NAMES.has(name)) {
|
|
149
|
+
layouts.push({ filePath, dirPath: dirname(filePath) });
|
|
150
|
+
continue;
|
|
151
|
+
}
|
|
152
|
+
if (ERROR_PAGE_NAMES.has(name)) {
|
|
153
|
+
errorPage ??= filePath;
|
|
154
|
+
continue;
|
|
155
|
+
}
|
|
156
|
+
if (MIDDLEWARE_NAMES.has(name)) {
|
|
157
|
+
middlewares.push({ filePath, dirPath: dirname(filePath) });
|
|
158
|
+
continue;
|
|
159
|
+
}
|
|
160
|
+
if (name.startsWith("_")) continue;
|
|
161
|
+
const resolved = resolveRouteSuffix(rel, suffixMap);
|
|
162
|
+
if (!resolved) {
|
|
163
|
+
if (name.endsWith(".tsx") && dirname(filePath) === routesDir) {
|
|
164
|
+
console.warn(
|
|
165
|
+
`[davaux] warning: ${rel} is not a route file and will be ignored.
|
|
166
|
+
If this is a shared component, move it to src/components/ or co-locate it
|
|
167
|
+
in a subdirectory alongside the routes that use it.`
|
|
168
|
+
);
|
|
169
|
+
}
|
|
170
|
+
continue;
|
|
171
|
+
}
|
|
172
|
+
const [stripped, type] = resolved;
|
|
173
|
+
const { urlPattern, params } = fileToUrlPattern(stripped);
|
|
174
|
+
routes.push({ filePath, urlPattern, type, params });
|
|
175
|
+
}
|
|
176
|
+
checkConflicts(routes, routesDir);
|
|
177
|
+
const TYPE_PRIORITY = { page: 1 };
|
|
178
|
+
const dynamicWeight = (pattern) => {
|
|
179
|
+
const segs = pattern.split("/");
|
|
180
|
+
if (segs.some((s) => s.startsWith("*"))) return 1e3;
|
|
181
|
+
return segs.filter((s) => s.startsWith(":")).length;
|
|
182
|
+
};
|
|
183
|
+
routes.sort((a, b) => {
|
|
184
|
+
const ad = dynamicWeight(a.urlPattern);
|
|
185
|
+
const bd = dynamicWeight(b.urlPattern);
|
|
186
|
+
if (ad !== bd) return ad - bd;
|
|
187
|
+
if (a.urlPattern.length !== b.urlPattern.length)
|
|
188
|
+
return a.urlPattern.length - b.urlPattern.length;
|
|
189
|
+
return (TYPE_PRIORITY[a.type] ?? 0) - (TYPE_PRIORITY[b.type] ?? 0);
|
|
190
|
+
});
|
|
191
|
+
return { routes, layouts, middlewares, errorPage };
|
|
192
|
+
}
|
|
193
|
+
export {
|
|
194
|
+
scanIslands,
|
|
195
|
+
scanRoutes
|
|
196
|
+
};
|
|
197
|
+
//# sourceMappingURL=scanner.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/router/scanner.ts"],
|
|
4
|
+
"sourcesContent": ["import { existsSync } from 'node:fs'\nimport { readdir } from 'node:fs/promises'\nimport { basename, dirname, join, relative } from 'node:path'\nimport type {\n IslandFile,\n LayoutFile,\n MiddlewareFile,\n RouteFile,\n RouteType,\n ScanResult,\n} from '../types.js'\n\n// Maps file suffix \u2192 HTTP route type. Longer suffixes first (more specific).\nconst SUFFIX_MAP: [suffix: string, type: RouteType][] = [\n ['.page.tsx', 'page'],\n ['.page.ts', 'page'],\n ['.page.jsx', 'page'],\n ['.page.js', 'page'],\n ['.get.tsx', 'get'],\n ['.get.ts', 'get'],\n ['.get.jsx', 'get'],\n ['.get.js', 'get'],\n ['.post.tsx', 'post'],\n ['.post.ts', 'post'],\n ['.post.jsx', 'post'],\n ['.post.js', 'post'],\n ['.put.tsx', 'put'],\n ['.put.ts', 'put'],\n ['.put.jsx', 'put'],\n ['.put.js', 'put'],\n ['.patch.tsx', 'patch'],\n ['.patch.ts', 'patch'],\n ['.patch.jsx', 'patch'],\n ['.patch.js', 'patch'],\n ['.delete.tsx', 'delete'],\n ['.delete.ts', 'delete'],\n ['.delete.jsx', 'delete'],\n ['.delete.js', 'delete'],\n ['.head.ts', 'head'],\n ['.head.js', 'head'],\n ['.options.ts', 'options'],\n ['.options.js', 'options'],\n]\n\n// Files beginning with _ are framework-reserved (layouts, middleware, etc.)\nconst LAYOUT_NAMES = new Set(['_layout.tsx', '_layout.ts', '_layout.jsx', '_layout.js'])\n\nconst ERROR_PAGE_NAMES = new Set(['_error.tsx', '_error.ts', '_error.jsx', '_error.js'])\n\nconst MIDDLEWARE_NAMES = new Set([\n '_middleware.tsx',\n '_middleware.ts',\n '_middleware.jsx',\n '_middleware.js',\n])\n\nfunction resolveRouteSuffix(\n filename: string,\n suffixMap: [string, RouteType][],\n): [stripped: string, type: RouteType] | null {\n for (const [suffix, type] of suffixMap) {\n if (filename.endsWith(suffix)) return [filename.slice(0, -suffix.length), type]\n }\n return null\n}\n\nfunction segmentToParam(segment: string): {\n pattern: string\n param: string | null\n} {\n const catchAll = segment.match(/^\\[\\.\\.\\.([^\\]]+)\\]$/)\n if (catchAll) return { pattern: `*${catchAll[1]}`, param: catchAll[1] }\n const m = segment.match(/^\\[([^\\]]+)\\]$/)\n if (m) return { pattern: `:${m[1]}`, param: m[1] }\n return { pattern: segment, param: null }\n}\n\nfunction fileToUrlPattern(rel: string): {\n urlPattern: string\n params: string[]\n} {\n const params: string[] = []\n const segments = rel.split('/').map((seg) => {\n const { pattern, param } = segmentToParam(seg)\n if (param) params.push(param)\n return pattern\n })\n\n if (segments.at(-1) === 'index') segments.pop()\n\n const raw = `/${segments.join('/')}`\n return { urlPattern: raw.replace(/\\/+$/, '') || '/', params }\n}\n\nasync function walk(dir: string, files: string[] = []): Promise<string[]> {\n const entries = await readdir(dir, { withFileTypes: true })\n for (const entry of entries) {\n const full = join(dir, entry.name)\n entry.isDirectory() ? await walk(full, files) : files.push(full)\n }\n return files\n}\n\n/**\n * Recursively scan `islandsDir` for client island component files.\n * Files beginning with `_` are ignored. Returns an empty array when the\n * directory does not exist.\n */\nexport async function scanIslands(islandsDir: string): Promise<IslandFile[]> {\n if (!existsSync(islandsDir)) return []\n\n const islands: IslandFile[] = []\n\n async function walkIslands(dir: string): Promise<void> {\n const entries = await readdir(dir, { withFileTypes: true })\n for (const entry of entries) {\n const full = join(dir, entry.name)\n if (entry.isDirectory()) {\n await walkIslands(full)\n } else if (/\\.(tsx?|jsx?)$/.test(entry.name) && !entry.name.startsWith('_')) {\n const id = entry.name.replace(/\\.(tsx?|jsx?)$/, '')\n islands.push({ filePath: full, id })\n }\n }\n }\n\n await walkIslands(islandsDir)\n return islands\n}\n\n// Which HTTP methods does each route type respond to?\n// Mirrors the METHOD_TYPES map in handler.ts, inverted per type.\nconst TYPE_METHODS: Record<RouteType, string[]> = {\n page: ['GET', 'HEAD', 'POST'], // POST only when an `action` export is present, but we warn conservatively\n get: ['GET', 'HEAD'], // HEAD checks 'get' in its allowed list\n post: ['POST'],\n put: ['PUT'],\n patch: ['PATCH'],\n delete: ['DELETE'],\n head: ['HEAD'],\n options: ['OPTIONS'],\n}\n\nfunction checkConflicts(routes: RouteFile[], routesDir: string): void {\n // Group routes by URL pattern \u2014 conflicts only possible within the same pattern.\n const byPattern = new Map<string, RouteFile[]>()\n for (const route of routes) {\n const group = byPattern.get(route.urlPattern) ?? []\n group.push(route)\n byPattern.set(route.urlPattern, group)\n }\n\n for (const [pattern, group] of byPattern) {\n if (group.length < 2) continue\n\n for (let i = 0; i < group.length; i++) {\n for (let j = i + 1; j < group.length; j++) {\n const a = group[i]\n const b = group[j]\n const overlap = TYPE_METHODS[a.type].filter((m) => TYPE_METHODS[b.type].includes(m))\n if (overlap.length === 0) continue\n\n const aRel = relative(routesDir, a.filePath)\n const bRel = relative(routesDir, b.filePath)\n\n if (a.type === b.type) {\n console.warn(\n `[davaux] warning: duplicate ${a.type} route at ${pattern}\\n` +\n ` ${aRel}\\n` +\n ` ${bRel}\\n` +\n ` Only the first will be used.`,\n )\n } else {\n // Explicit method routes sort before page routes, so they always win.\n const winner = a.type !== 'page' ? aRel : bRel\n console.warn(\n `[davaux] warning: ${overlap.join(' + ')} ${pattern} matched by both ${aRel} (${a.type}) and ${bRel} (${b.type}) \u2014 ${winner} takes priority`,\n )\n }\n }\n }\n }\n}\n\n/**\n * Recursively scan `routesDir` for route, layout, middleware, and error-page files.\n * Routes are sorted so static segments beat dynamic segments, and explicit\n * HTTP-method routes beat page routes at the same URL pattern.\n *\n * @param extraSuffixes - Additional `[suffix, RouteType]` pairs contributed by\n * plugins (e.g. `[['.page.md', 'page']]` from `@davaux/markdown`).\n */\nexport async function scanRoutes(\n routesDir: string,\n extraSuffixes: [string, RouteType][] = [],\n): Promise<ScanResult> {\n const suffixMap: [string, RouteType][] = [...SUFFIX_MAP, ...extraSuffixes]\n const allFiles = await walk(routesDir)\n const routes: RouteFile[] = []\n const layouts: LayoutFile[] = []\n const middlewares: MiddlewareFile[] = []\n let errorPage: string | undefined\n\n for (const filePath of allFiles) {\n const rel = relative(routesDir, filePath)\n const name = basename(rel)\n\n // Framework-reserved file: layout\n if (LAYOUT_NAMES.has(name)) {\n layouts.push({ filePath, dirPath: dirname(filePath) })\n continue\n }\n\n // Framework-reserved file: error page (first one wins)\n if (ERROR_PAGE_NAMES.has(name)) {\n errorPage ??= filePath\n continue\n }\n\n // Framework-reserved file: scoped middleware\n if (MIDDLEWARE_NAMES.has(name)) {\n middlewares.push({ filePath, dirPath: dirname(filePath) })\n continue\n }\n\n // Skip other underscore-prefixed files silently\n if (name.startsWith('_')) continue\n\n const resolved = resolveRouteSuffix(rel, suffixMap)\n if (!resolved) {\n // Warn about .tsx files sitting directly in the routes root \u2014 they look like\n // components that belong in src/components/ rather than src/routes/.\n if (name.endsWith('.tsx') && dirname(filePath) === routesDir) {\n console.warn(\n `[davaux] warning: ${rel} is not a route file and will be ignored.\\n` +\n ` If this is a shared component, move it to src/components/ or co-locate it\\n` +\n ` in a subdirectory alongside the routes that use it.`,\n )\n }\n continue\n }\n\n const [stripped, type] = resolved\n const { urlPattern, params } = fileToUrlPattern(stripped)\n routes.push({ filePath, urlPattern, type, params })\n }\n\n checkConflicts(routes, routesDir)\n\n // Explicit method routes (post, get, put, \u2026) beat page routes at the same URL.\n // This matters for POST: both `login.post.ts` and `login.page.tsx` (with defineAction)\n // resolve to `/login`, but the explicit file should always win.\n const TYPE_PRIORITY: Record<string, number> = { page: 1 } // all explicit methods default to 0\n\n // Static segments before dynamic before catch-all; shorter paths before longer; explicit methods before pages.\n const dynamicWeight = (pattern: string) => {\n const segs = pattern.split('/')\n if (segs.some((s) => s.startsWith('*'))) return 1000\n return segs.filter((s) => s.startsWith(':')).length\n }\n\n routes.sort((a, b) => {\n const ad = dynamicWeight(a.urlPattern)\n const bd = dynamicWeight(b.urlPattern)\n if (ad !== bd) return ad - bd\n if (a.urlPattern.length !== b.urlPattern.length)\n return a.urlPattern.length - b.urlPattern.length\n return (TYPE_PRIORITY[a.type] ?? 0) - (TYPE_PRIORITY[b.type] ?? 0)\n })\n\n return { routes, layouts, middlewares, errorPage }\n}\n"],
|
|
5
|
+
"mappings": "AAAA,SAAS,kBAAkB;AAC3B,SAAS,eAAe;AACxB,SAAS,UAAU,SAAS,MAAM,gBAAgB;AAWlD,MAAM,aAAkD;AAAA,EACtD,CAAC,aAAa,MAAM;AAAA,EACpB,CAAC,YAAY,MAAM;AAAA,EACnB,CAAC,aAAa,MAAM;AAAA,EACpB,CAAC,YAAY,MAAM;AAAA,EACnB,CAAC,YAAY,KAAK;AAAA,EAClB,CAAC,WAAW,KAAK;AAAA,EACjB,CAAC,YAAY,KAAK;AAAA,EAClB,CAAC,WAAW,KAAK;AAAA,EACjB,CAAC,aAAa,MAAM;AAAA,EACpB,CAAC,YAAY,MAAM;AAAA,EACnB,CAAC,aAAa,MAAM;AAAA,EACpB,CAAC,YAAY,MAAM;AAAA,EACnB,CAAC,YAAY,KAAK;AAAA,EAClB,CAAC,WAAW,KAAK;AAAA,EACjB,CAAC,YAAY,KAAK;AAAA,EAClB,CAAC,WAAW,KAAK;AAAA,EACjB,CAAC,cAAc,OAAO;AAAA,EACtB,CAAC,aAAa,OAAO;AAAA,EACrB,CAAC,cAAc,OAAO;AAAA,EACtB,CAAC,aAAa,OAAO;AAAA,EACrB,CAAC,eAAe,QAAQ;AAAA,EACxB,CAAC,cAAc,QAAQ;AAAA,EACvB,CAAC,eAAe,QAAQ;AAAA,EACxB,CAAC,cAAc,QAAQ;AAAA,EACvB,CAAC,YAAY,MAAM;AAAA,EACnB,CAAC,YAAY,MAAM;AAAA,EACnB,CAAC,eAAe,SAAS;AAAA,EACzB,CAAC,eAAe,SAAS;AAC3B;AAGA,MAAM,eAAe,oBAAI,IAAI,CAAC,eAAe,cAAc,eAAe,YAAY,CAAC;AAEvF,MAAM,mBAAmB,oBAAI,IAAI,CAAC,cAAc,aAAa,cAAc,WAAW,CAAC;AAEvF,MAAM,mBAAmB,oBAAI,IAAI;AAAA,EAC/B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAED,SAAS,mBACP,UACA,WAC4C;AAC5C,aAAW,CAAC,QAAQ,IAAI,KAAK,WAAW;AACtC,QAAI,SAAS,SAAS,MAAM,EAAG,QAAO,CAAC,SAAS,MAAM,GAAG,CAAC,OAAO,MAAM,GAAG,IAAI;AAAA,EAChF;AACA,SAAO;AACT;AAEA,SAAS,eAAe,SAGtB;AACA,QAAM,WAAW,QAAQ,MAAM,sBAAsB;AACrD,MAAI,SAAU,QAAO,EAAE,SAAS,IAAI,SAAS,CAAC,CAAC,IAAI,OAAO,SAAS,CAAC,EAAE;AACtE,QAAM,IAAI,QAAQ,MAAM,gBAAgB;AACxC,MAAI,EAAG,QAAO,EAAE,SAAS,IAAI,EAAE,CAAC,CAAC,IAAI,OAAO,EAAE,CAAC,EAAE;AACjD,SAAO,EAAE,SAAS,SAAS,OAAO,KAAK;AACzC;AAEA,SAAS,iBAAiB,KAGxB;AACA,QAAM,SAAmB,CAAC;AAC1B,QAAM,WAAW,IAAI,MAAM,GAAG,EAAE,IAAI,CAAC,QAAQ;AAC3C,UAAM,EAAE,SAAS,MAAM,IAAI,eAAe,GAAG;AAC7C,QAAI,MAAO,QAAO,KAAK,KAAK;AAC5B,WAAO;AAAA,EACT,CAAC;AAED,MAAI,SAAS,GAAG,EAAE,MAAM,QAAS,UAAS,IAAI;AAE9C,QAAM,MAAM,IAAI,SAAS,KAAK,GAAG,CAAC;AAClC,SAAO,EAAE,YAAY,IAAI,QAAQ,QAAQ,EAAE,KAAK,KAAK,OAAO;AAC9D;AAEA,eAAe,KAAK,KAAa,QAAkB,CAAC,GAAsB;AACxE,QAAM,UAAU,MAAM,QAAQ,KAAK,EAAE,eAAe,KAAK,CAAC;AAC1D,aAAW,SAAS,SAAS;AAC3B,UAAM,OAAO,KAAK,KAAK,MAAM,IAAI;AACjC,UAAM,YAAY,IAAI,MAAM,KAAK,MAAM,KAAK,IAAI,MAAM,KAAK,IAAI;AAAA,EACjE;AACA,SAAO;AACT;AAOA,eAAsB,YAAY,YAA2C;AAC3E,MAAI,CAAC,WAAW,UAAU,EAAG,QAAO,CAAC;AAErC,QAAM,UAAwB,CAAC;AAE/B,iBAAe,YAAY,KAA4B;AACrD,UAAM,UAAU,MAAM,QAAQ,KAAK,EAAE,eAAe,KAAK,CAAC;AAC1D,eAAW,SAAS,SAAS;AAC3B,YAAM,OAAO,KAAK,KAAK,MAAM,IAAI;AACjC,UAAI,MAAM,YAAY,GAAG;AACvB,cAAM,YAAY,IAAI;AAAA,MACxB,WAAW,iBAAiB,KAAK,MAAM,IAAI,KAAK,CAAC,MAAM,KAAK,WAAW,GAAG,GAAG;AAC3E,cAAM,KAAK,MAAM,KAAK,QAAQ,kBAAkB,EAAE;AAClD,gBAAQ,KAAK,EAAE,UAAU,MAAM,GAAG,CAAC;AAAA,MACrC;AAAA,IACF;AAAA,EACF;AAEA,QAAM,YAAY,UAAU;AAC5B,SAAO;AACT;AAIA,MAAM,eAA4C;AAAA,EAChD,MAAM,CAAC,OAAO,QAAQ,MAAM;AAAA;AAAA,EAC5B,KAAK,CAAC,OAAO,MAAM;AAAA;AAAA,EACnB,MAAM,CAAC,MAAM;AAAA,EACb,KAAK,CAAC,KAAK;AAAA,EACX,OAAO,CAAC,OAAO;AAAA,EACf,QAAQ,CAAC,QAAQ;AAAA,EACjB,MAAM,CAAC,MAAM;AAAA,EACb,SAAS,CAAC,SAAS;AACrB;AAEA,SAAS,eAAe,QAAqB,WAAyB;AAEpE,QAAM,YAAY,oBAAI,IAAyB;AAC/C,aAAW,SAAS,QAAQ;AAC1B,UAAM,QAAQ,UAAU,IAAI,MAAM,UAAU,KAAK,CAAC;AAClD,UAAM,KAAK,KAAK;AAChB,cAAU,IAAI,MAAM,YAAY,KAAK;AAAA,EACvC;AAEA,aAAW,CAAC,SAAS,KAAK,KAAK,WAAW;AACxC,QAAI,MAAM,SAAS,EAAG;AAEtB,aAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACrC,eAAS,IAAI,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACzC,cAAM,IAAI,MAAM,CAAC;AACjB,cAAM,IAAI,MAAM,CAAC;AACjB,cAAM,UAAU,aAAa,EAAE,IAAI,EAAE,OAAO,CAAC,MAAM,aAAa,EAAE,IAAI,EAAE,SAAS,CAAC,CAAC;AACnF,YAAI,QAAQ,WAAW,EAAG;AAE1B,cAAM,OAAO,SAAS,WAAW,EAAE,QAAQ;AAC3C,cAAM,OAAO,SAAS,WAAW,EAAE,QAAQ;AAE3C,YAAI,EAAE,SAAS,EAAE,MAAM;AACrB,kBAAQ;AAAA,YACN,+BAA+B,EAAE,IAAI,aAAa,OAAO;AAAA,IAClD,IAAI;AAAA,IACJ,IAAI;AAAA;AAAA,UAEb;AAAA,QACF,OAAO;AAEL,gBAAM,SAAS,EAAE,SAAS,SAAS,OAAO;AAC1C,kBAAQ;AAAA,YACN,qBAAqB,QAAQ,KAAK,KAAK,CAAC,IAAI,OAAO,oBAAoB,IAAI,KAAK,EAAE,IAAI,SAAS,IAAI,KAAK,EAAE,IAAI,YAAO,MAAM;AAAA,UAC7H;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AAUA,eAAsB,WACpB,WACA,gBAAuC,CAAC,GACnB;AACrB,QAAM,YAAmC,CAAC,GAAG,YAAY,GAAG,aAAa;AACzE,QAAM,WAAW,MAAM,KAAK,SAAS;AACrC,QAAM,SAAsB,CAAC;AAC7B,QAAM,UAAwB,CAAC;AAC/B,QAAM,cAAgC,CAAC;AACvC,MAAI;AAEJ,aAAW,YAAY,UAAU;AAC/B,UAAM,MAAM,SAAS,WAAW,QAAQ;AACxC,UAAM,OAAO,SAAS,GAAG;AAGzB,QAAI,aAAa,IAAI,IAAI,GAAG;AAC1B,cAAQ,KAAK,EAAE,UAAU,SAAS,QAAQ,QAAQ,EAAE,CAAC;AACrD;AAAA,IACF;AAGA,QAAI,iBAAiB,IAAI,IAAI,GAAG;AAC9B,oBAAc;AACd;AAAA,IACF;AAGA,QAAI,iBAAiB,IAAI,IAAI,GAAG;AAC9B,kBAAY,KAAK,EAAE,UAAU,SAAS,QAAQ,QAAQ,EAAE,CAAC;AACzD;AAAA,IACF;AAGA,QAAI,KAAK,WAAW,GAAG,EAAG;AAE1B,UAAM,WAAW,mBAAmB,KAAK,SAAS;AAClD,QAAI,CAAC,UAAU;AAGb,UAAI,KAAK,SAAS,MAAM,KAAK,QAAQ,QAAQ,MAAM,WAAW;AAC5D,gBAAQ;AAAA,UACN,qBAAqB,GAAG;AAAA;AAAA;AAAA,QAG1B;AAAA,MACF;AACA;AAAA,IACF;AAEA,UAAM,CAAC,UAAU,IAAI,IAAI;AACzB,UAAM,EAAE,YAAY,OAAO,IAAI,iBAAiB,QAAQ;AACxD,WAAO,KAAK,EAAE,UAAU,YAAY,MAAM,OAAO,CAAC;AAAA,EACpD;AAEA,iBAAe,QAAQ,SAAS;AAKhC,QAAM,gBAAwC,EAAE,MAAM,EAAE;AAGxD,QAAM,gBAAgB,CAAC,YAAoB;AACzC,UAAM,OAAO,QAAQ,MAAM,GAAG;AAC9B,QAAI,KAAK,KAAK,CAAC,MAAM,EAAE,WAAW,GAAG,CAAC,EAAG,QAAO;AAChD,WAAO,KAAK,OAAO,CAAC,MAAM,EAAE,WAAW,GAAG,CAAC,EAAE;AAAA,EAC/C;AAEA,SAAO,KAAK,CAAC,GAAG,MAAM;AACpB,UAAM,KAAK,cAAc,EAAE,UAAU;AACrC,UAAM,KAAK,cAAc,EAAE,UAAU;AACrC,QAAI,OAAO,GAAI,QAAO,KAAK;AAC3B,QAAI,EAAE,WAAW,WAAW,EAAE,WAAW;AACvC,aAAO,EAAE,WAAW,SAAS,EAAE,WAAW;AAC5C,YAAQ,cAAc,EAAE,IAAI,KAAK,MAAM,cAAc,EAAE,IAAI,KAAK;AAAA,EAClE,CAAC;AAED,SAAO,EAAE,QAAQ,SAAS,aAAa,UAAU;AACnD;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { type IncomingMessage, type ServerResponse } from 'node:http';
|
|
2
|
+
import type { CompiledApp } from '../router/handler.js';
|
|
3
|
+
/** Options for `startServer()`. */
|
|
4
|
+
export interface ServerOptions {
|
|
5
|
+
/** TCP port to listen on. Default: `3000` */
|
|
6
|
+
port?: number;
|
|
7
|
+
/** Hostname or IP address to bind to. Default: `'localhost'` */
|
|
8
|
+
hostname?: string;
|
|
9
|
+
/**
|
|
10
|
+
* Called before the Davaux dispatcher on every request.
|
|
11
|
+
* Return `true` to signal that the request was fully handled (the dispatcher is skipped).
|
|
12
|
+
*/
|
|
13
|
+
onRequest?: (req: IncomingMessage, res: ServerResponse) => boolean | Promise<boolean>;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Start the HTTP server and begin accepting requests.
|
|
17
|
+
*
|
|
18
|
+
* @param app - A compiled app from `buildApp()`, or a factory function that returns one
|
|
19
|
+
* (useful in development when the app is rebuilt between requests).
|
|
20
|
+
* @returns The underlying `http.Server` instance.
|
|
21
|
+
*/
|
|
22
|
+
export declare function startServer(app: CompiledApp | (() => CompiledApp), options?: ServerOptions): import("node:http").Server<typeof IncomingMessage, typeof ServerResponse>;
|
|
23
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,KAAK,eAAe,EAAE,KAAK,cAAc,EAAE,MAAM,WAAW,CAAA;AACnF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAA;AAGvD,mCAAmC;AACnC,MAAM,WAAW,aAAa;IAC5B,6CAA6C;IAC7C,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,gEAAgE;IAChE,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB;;;OAGG;IACH,SAAS,CAAC,EAAE,CAAC,GAAG,EAAE,eAAe,EAAE,GAAG,EAAE,cAAc,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;CACtF;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,WAAW,GAAG,CAAC,MAAM,WAAW,CAAC,EAAE,OAAO,GAAE,aAAkB,6EAwB9F"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { createServer } from "node:http";
|
|
2
|
+
import { dispatch } from "../router/handler.js";
|
|
3
|
+
function startServer(app, options = {}) {
|
|
4
|
+
const { port = 3e3, hostname = "localhost", onRequest } = options;
|
|
5
|
+
const getApp = typeof app === "function" ? app : () => app;
|
|
6
|
+
const server = createServer(async (req, res) => {
|
|
7
|
+
if (onRequest) {
|
|
8
|
+
const handled = await onRequest(req, res);
|
|
9
|
+
if (handled) return;
|
|
10
|
+
}
|
|
11
|
+
dispatch(req, res, getApp()).catch((err) => {
|
|
12
|
+
console.error("[davaux] Unhandled dispatch error:", err);
|
|
13
|
+
if (!res.headersSent) {
|
|
14
|
+
res.writeHead(500, { "Content-Type": "text/plain" });
|
|
15
|
+
res.end("Internal Server Error");
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
});
|
|
19
|
+
server.listen(port, hostname, () => {
|
|
20
|
+
console.log(`
|
|
21
|
+
davaux http://${hostname}:${port}
|
|
22
|
+
`);
|
|
23
|
+
});
|
|
24
|
+
return server;
|
|
25
|
+
}
|
|
26
|
+
export {
|
|
27
|
+
startServer
|
|
28
|
+
};
|
|
29
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/server/index.ts"],
|
|
4
|
+
"sourcesContent": ["import { createServer, type IncomingMessage, type ServerResponse } from 'node:http'\nimport type { CompiledApp } from '../router/handler.js'\nimport { dispatch } from '../router/handler.js'\n\n/** Options for `startServer()`. */\nexport interface ServerOptions {\n /** TCP port to listen on. Default: `3000` */\n port?: number\n /** Hostname or IP address to bind to. Default: `'localhost'` */\n hostname?: string\n /**\n * Called before the Davaux dispatcher on every request.\n * Return `true` to signal that the request was fully handled (the dispatcher is skipped).\n */\n onRequest?: (req: IncomingMessage, res: ServerResponse) => boolean | Promise<boolean>\n}\n\n/**\n * Start the HTTP server and begin accepting requests.\n *\n * @param app - A compiled app from `buildApp()`, or a factory function that returns one\n * (useful in development when the app is rebuilt between requests).\n * @returns The underlying `http.Server` instance.\n */\nexport function startServer(app: CompiledApp | (() => CompiledApp), options: ServerOptions = {}) {\n const { port = 3000, hostname = 'localhost', onRequest } = options\n const getApp = typeof app === 'function' ? app : () => app\n\n const server = createServer(async (req, res) => {\n if (onRequest) {\n const handled = await onRequest(req, res)\n if (handled) return\n }\n\n dispatch(req, res, getApp()).catch((err) => {\n console.error('[davaux] Unhandled dispatch error:', err)\n if (!res.headersSent) {\n res.writeHead(500, { 'Content-Type': 'text/plain' })\n res.end('Internal Server Error')\n }\n })\n })\n\n server.listen(port, hostname, () => {\n console.log(`\\n davaux http://${hostname}:${port}\\n`)\n })\n\n return server\n}\n"],
|
|
5
|
+
"mappings": "AAAA,SAAS,oBAA+D;AAExE,SAAS,gBAAgB;AAsBlB,SAAS,YAAY,KAAwC,UAAyB,CAAC,GAAG;AAC/F,QAAM,EAAE,OAAO,KAAM,WAAW,aAAa,UAAU,IAAI;AAC3D,QAAM,SAAS,OAAO,QAAQ,aAAa,MAAM,MAAM;AAEvD,QAAM,SAAS,aAAa,OAAO,KAAK,QAAQ;AAC9C,QAAI,WAAW;AACb,YAAM,UAAU,MAAM,UAAU,KAAK,GAAG;AACxC,UAAI,QAAS;AAAA,IACf;AAEA,aAAS,KAAK,KAAK,OAAO,CAAC,EAAE,MAAM,CAAC,QAAQ;AAC1C,cAAQ,MAAM,sCAAsC,GAAG;AACvD,UAAI,CAAC,IAAI,aAAa;AACpB,YAAI,UAAU,KAAK,EAAE,gBAAgB,aAAa,CAAC;AACnD,YAAI,IAAI,uBAAuB;AAAA,MACjC;AAAA,IACF,CAAC;AAAA,EACH,CAAC;AAED,SAAO,OAAO,MAAM,UAAU,MAAM;AAClC,YAAQ,IAAI;AAAA,mBAAsB,QAAQ,IAAI,IAAI;AAAA,CAAI;AAAA,EACxD,CAAC;AAED,SAAO;AACT;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
package/dist/signal.d.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/** A reactive signal: a `[getter, setter]` tuple. On the server this is backed by a plain variable. */
|
|
2
|
+
export type Signal<T> = [get: () => T, set: (value: T) => void];
|
|
3
|
+
/** A read-only derived value: a zero-argument getter that returns the current result. */
|
|
4
|
+
export type ReadonlySignal<T> = () => T;
|
|
5
|
+
/** Server-side stub — returns a getter/setter pair backed by a plain variable. */
|
|
6
|
+
export declare function createSignal<T>(value: T): Signal<T>;
|
|
7
|
+
/** Server-side stub — runs `fn` once synchronously, no reactive tracking. */
|
|
8
|
+
export declare function createEffect(fn: () => void): void;
|
|
9
|
+
/** Server-side stub — evaluates `fn` immediately and returns a static getter. */
|
|
10
|
+
export declare function createMemo<T>(fn: () => T): ReadonlySignal<T>;
|
|
11
|
+
/** Server-side stub — calls `fn` directly with no tracking context. */
|
|
12
|
+
export declare function untrack<T>(fn: () => T): T;
|
|
13
|
+
/** Server-side stub — calls `fn` directly with no batching. */
|
|
14
|
+
export declare function batch<T>(fn: () => T): T;
|
|
15
|
+
//# sourceMappingURL=signal.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"signal.d.ts","sourceRoot":"","sources":["../src/signal.ts"],"names":[],"mappings":"AAGA,uGAAuG;AACvG,MAAM,MAAM,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,EAAE,GAAG,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,CAAC,CAAA;AAE/D,yFAAyF;AACzF,MAAM,MAAM,cAAc,CAAC,CAAC,IAAI,MAAM,CAAC,CAAA;AAEvC,kFAAkF;AAClF,wBAAgB,YAAY,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAOnD;AAED,6EAA6E;AAC7E,wBAAgB,YAAY,CAAC,EAAE,EAAE,MAAM,IAAI,GAAG,IAAI,CAEjD;AAED,iFAAiF;AACjF,wBAAgB,UAAU,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,cAAc,CAAC,CAAC,CAAC,CAG5D;AAED,uEAAuE;AACvE,wBAAgB,OAAO,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,CAEzC;AAED,+DAA+D;AAC/D,wBAAgB,KAAK,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,CAEvC"}
|
package/dist/signal.js
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
function createSignal(value) {
|
|
2
|
+
return [
|
|
3
|
+
() => value,
|
|
4
|
+
(v) => {
|
|
5
|
+
value = v;
|
|
6
|
+
}
|
|
7
|
+
];
|
|
8
|
+
}
|
|
9
|
+
function createEffect(fn) {
|
|
10
|
+
fn();
|
|
11
|
+
}
|
|
12
|
+
function createMemo(fn) {
|
|
13
|
+
const result = fn();
|
|
14
|
+
return () => result;
|
|
15
|
+
}
|
|
16
|
+
function untrack(fn) {
|
|
17
|
+
return fn();
|
|
18
|
+
}
|
|
19
|
+
function batch(fn) {
|
|
20
|
+
return fn();
|
|
21
|
+
}
|
|
22
|
+
export {
|
|
23
|
+
batch,
|
|
24
|
+
createEffect,
|
|
25
|
+
createMemo,
|
|
26
|
+
createSignal,
|
|
27
|
+
untrack
|
|
28
|
+
};
|
|
29
|
+
//# sourceMappingURL=signal.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/signal.ts"],
|
|
4
|
+
"sourcesContent": ["// Server-side stubs \u2014 synchronous values, no reactive graph.\n// The reactive implementations in davaux/client are used inside islands.\n\n/** A reactive signal: a `[getter, setter]` tuple. On the server this is backed by a plain variable. */\nexport type Signal<T> = [get: () => T, set: (value: T) => void]\n\n/** A read-only derived value: a zero-argument getter that returns the current result. */\nexport type ReadonlySignal<T> = () => T\n\n/** Server-side stub \u2014 returns a getter/setter pair backed by a plain variable. */\nexport function createSignal<T>(value: T): Signal<T> {\n return [\n () => value,\n (v: T) => {\n value = v\n },\n ]\n}\n\n/** Server-side stub \u2014 runs `fn` once synchronously, no reactive tracking. */\nexport function createEffect(fn: () => void): void {\n fn()\n}\n\n/** Server-side stub \u2014 evaluates `fn` immediately and returns a static getter. */\nexport function createMemo<T>(fn: () => T): ReadonlySignal<T> {\n const result = fn()\n return () => result\n}\n\n/** Server-side stub \u2014 calls `fn` directly with no tracking context. */\nexport function untrack<T>(fn: () => T): T {\n return fn()\n}\n\n/** Server-side stub \u2014 calls `fn` directly with no batching. */\nexport function batch<T>(fn: () => T): T {\n return fn()\n}\n"],
|
|
5
|
+
"mappings": "AAUO,SAAS,aAAgB,OAAqB;AACnD,SAAO;AAAA,IACL,MAAM;AAAA,IACN,CAAC,MAAS;AACR,cAAQ;AAAA,IACV;AAAA,EACF;AACF;AAGO,SAAS,aAAa,IAAsB;AACjD,KAAG;AACL;AAGO,SAAS,WAAc,IAAgC;AAC5D,QAAM,SAAS,GAAG;AAClB,SAAO,MAAM;AACf;AAGO,SAAS,QAAW,IAAgB;AACzC,SAAO,GAAG;AACZ;AAGO,SAAS,MAAS,IAAgB;AACvC,SAAO,GAAG;AACZ;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
package/dist/ssg.d.ts
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { ScanResult } from './types.js';
|
|
2
|
+
/** Options for `generateStatic()`. All directory paths should be absolute. */
|
|
3
|
+
export interface SsgOptions {
|
|
4
|
+
/** Output directory for generated HTML files. */
|
|
5
|
+
outDir: string;
|
|
6
|
+
/** Build output directory — used to locate `_davaux` assets to copy across. */
|
|
7
|
+
distDir: string;
|
|
8
|
+
/** Public directory to copy into `outDir` after generation. */
|
|
9
|
+
publicDir: string;
|
|
10
|
+
/** Scanned route manifest from `scanRoutes()`. */
|
|
11
|
+
scan: ScanResult;
|
|
12
|
+
/** Client JS bundle URLs injected into every generated page. */
|
|
13
|
+
clientScripts: string[];
|
|
14
|
+
/** Client CSS URLs injected into every generated page. */
|
|
15
|
+
clientStylesheets: string[];
|
|
16
|
+
/** Compiled path to `src/middleware.ts` — applied to every SSG render request. */
|
|
17
|
+
appMiddlewarePath?: string;
|
|
18
|
+
/**
|
|
19
|
+
* Controls the URL-to-filename mapping.
|
|
20
|
+
* - `'always'` — `/about` → `about/index.html` (default)
|
|
21
|
+
* - `'never'` — `/about` → `about.html`
|
|
22
|
+
*/
|
|
23
|
+
trailingSlash?: 'always' | 'never';
|
|
24
|
+
/** Base path for subdirectory deployments (e.g. `'/docs'`). */
|
|
25
|
+
basePath?: string;
|
|
26
|
+
/** Generate a `404.html` from `_error.tsx`. Default: `true` when `_error.tsx` is present. */
|
|
27
|
+
notFound?: boolean;
|
|
28
|
+
/**
|
|
29
|
+
* Generate a `sitemap.xml`. Pass `false` to disable, or `{ baseUrl }` to enable.
|
|
30
|
+
* `baseUrl` is prepended to every URL (e.g. `'https://example.com'`).
|
|
31
|
+
*/
|
|
32
|
+
sitemap?: false | {
|
|
33
|
+
baseUrl: string;
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Pre-render all static pages in the route manifest and write them to `outDir`.
|
|
38
|
+
* Pages with `export const prerender = false` are skipped. Dynamic routes must
|
|
39
|
+
* export `getStaticPaths` to supply the parameter sets to render.
|
|
40
|
+
*
|
|
41
|
+
* Also generates `404.html` (from `_error.tsx`) and `sitemap.xml` when
|
|
42
|
+
* configured, and copies `_davaux` assets and `public/` into `outDir`.
|
|
43
|
+
*/
|
|
44
|
+
export declare function generateStatic(opts: SsgOptions): Promise<void>;
|
|
45
|
+
//# sourceMappingURL=ssg.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ssg.d.ts","sourceRoot":"","sources":["../src/ssg.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAoB,UAAU,EAAE,MAAM,YAAY,CAAA;AAE9D,8EAA8E;AAC9E,MAAM,WAAW,UAAU;IACzB,iDAAiD;IACjD,MAAM,EAAE,MAAM,CAAA;IACd,+EAA+E;IAC/E,OAAO,EAAE,MAAM,CAAA;IACf,+DAA+D;IAC/D,SAAS,EAAE,MAAM,CAAA;IACjB,kDAAkD;IAClD,IAAI,EAAE,UAAU,CAAA;IAChB,gEAAgE;IAChE,aAAa,EAAE,MAAM,EAAE,CAAA;IACvB,0DAA0D;IAC1D,iBAAiB,EAAE,MAAM,EAAE,CAAA;IAC3B,kFAAkF;IAClF,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B;;;;OAIG;IACH,aAAa,CAAC,EAAE,QAAQ,GAAG,OAAO,CAAA;IAClC,+DAA+D;IAC/D,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,6FAA6F;IAC7F,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB;;;OAGG;IACH,OAAO,CAAC,EAAE,KAAK,GAAG;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,CAAA;CACtC;AA+ED;;;;;;;GAOG;AACH,wBAAsB,cAAc,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CA8HpE"}
|
package/dist/ssg.js
ADDED
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
import { existsSync } from "node:fs";
|
|
2
|
+
import { cp, mkdir, writeFile } from "node:fs/promises";
|
|
3
|
+
import { dirname, join, relative } from "node:path";
|
|
4
|
+
import { frameworkWarn } from "./errors.js";
|
|
5
|
+
import { buildApp, dispatch } from "./router/handler.js";
|
|
6
|
+
function makeMockReq(pathname) {
|
|
7
|
+
return {
|
|
8
|
+
method: "GET",
|
|
9
|
+
url: pathname,
|
|
10
|
+
headers: { host: "localhost", cookie: "" },
|
|
11
|
+
on(event, listener) {
|
|
12
|
+
if (event === "end") setImmediate(() => listener());
|
|
13
|
+
return this;
|
|
14
|
+
},
|
|
15
|
+
removeListener() {
|
|
16
|
+
return this;
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
function makeMockRes() {
|
|
21
|
+
let status = 200;
|
|
22
|
+
let body = "";
|
|
23
|
+
let sent = false;
|
|
24
|
+
let ended = false;
|
|
25
|
+
const hdrs = {};
|
|
26
|
+
const res = {
|
|
27
|
+
get statusCode() {
|
|
28
|
+
return status;
|
|
29
|
+
},
|
|
30
|
+
set statusCode(v) {
|
|
31
|
+
status = v;
|
|
32
|
+
},
|
|
33
|
+
get headersSent() {
|
|
34
|
+
return sent;
|
|
35
|
+
},
|
|
36
|
+
get writableEnded() {
|
|
37
|
+
return ended;
|
|
38
|
+
},
|
|
39
|
+
writeHead(code) {
|
|
40
|
+
status = code;
|
|
41
|
+
sent = true;
|
|
42
|
+
},
|
|
43
|
+
end(data) {
|
|
44
|
+
if (data != null) body = typeof data === "string" ? data : data.toString("utf-8");
|
|
45
|
+
ended = true;
|
|
46
|
+
},
|
|
47
|
+
getHeader: (name) => hdrs[name.toLowerCase()],
|
|
48
|
+
setHeader(name, value) {
|
|
49
|
+
hdrs[name.toLowerCase()] = value;
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
return [res, () => ({ status, html: body })];
|
|
53
|
+
}
|
|
54
|
+
function urlToFile(outDir, url, trailingSlash = "always") {
|
|
55
|
+
const trimmed = url.replace(/^\//, "").replace(/\/$/, "");
|
|
56
|
+
if (!trimmed) return join(outDir, "index.html");
|
|
57
|
+
if (trailingSlash === "never") return join(outDir, `${trimmed}.html`);
|
|
58
|
+
return join(outDir, trimmed, "index.html");
|
|
59
|
+
}
|
|
60
|
+
function toSitemapUrl(baseUrl, basePath, urlPath, trailingSlash) {
|
|
61
|
+
const base = baseUrl.replace(/\/$/, "");
|
|
62
|
+
const bp = basePath.replace(/\/$/, "");
|
|
63
|
+
const trimmed = urlPath.replace(/\/$/, "");
|
|
64
|
+
const path = !trimmed ? "/" : trailingSlash === "never" ? trimmed : `${trimmed}/`;
|
|
65
|
+
return `${base}${bp}${path}`;
|
|
66
|
+
}
|
|
67
|
+
async function generateStatic(opts) {
|
|
68
|
+
const {
|
|
69
|
+
outDir,
|
|
70
|
+
distDir,
|
|
71
|
+
publicDir,
|
|
72
|
+
scan,
|
|
73
|
+
appMiddlewarePath,
|
|
74
|
+
trailingSlash = "always",
|
|
75
|
+
basePath = "",
|
|
76
|
+
notFound,
|
|
77
|
+
sitemap
|
|
78
|
+
} = opts;
|
|
79
|
+
const clientScripts = opts.clientScripts.map((s) => `${basePath}${s}`);
|
|
80
|
+
const clientStylesheets = opts.clientStylesheets.map((s) => `${basePath}${s}`);
|
|
81
|
+
const app = buildApp(scan, false, clientScripts, clientStylesheets, appMiddlewarePath, basePath);
|
|
82
|
+
const toRender = [];
|
|
83
|
+
for (const route of scan.routes) {
|
|
84
|
+
if (route.type !== "page") continue;
|
|
85
|
+
const mod = await import(route.filePath);
|
|
86
|
+
if (mod.prerender === false) continue;
|
|
87
|
+
if (route.params.length === 0) {
|
|
88
|
+
toRender.push(route.urlPattern);
|
|
89
|
+
} else {
|
|
90
|
+
const fn = mod.getStaticPaths;
|
|
91
|
+
if (typeof fn !== "function") {
|
|
92
|
+
frameworkWarn(
|
|
93
|
+
`[ssg] skipping ${route.urlPattern} \u2014 dynamic route has no getStaticPaths export`,
|
|
94
|
+
`Add a getStaticPaths export to ${relative(process.cwd(), route.filePath)}:
|
|
95
|
+
|
|
96
|
+
export const getStaticPaths = async () => [
|
|
97
|
+
{ params: { /* param: value */ } },
|
|
98
|
+
]`
|
|
99
|
+
);
|
|
100
|
+
continue;
|
|
101
|
+
}
|
|
102
|
+
const paths = await fn();
|
|
103
|
+
for (const sp of paths) {
|
|
104
|
+
let url = route.urlPattern;
|
|
105
|
+
for (const [k, v] of Object.entries(sp.params)) url = url.replace(`:${k}`, String(v));
|
|
106
|
+
toRender.push(url);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
await mkdir(outDir, { recursive: true });
|
|
111
|
+
let count = 0;
|
|
112
|
+
const renderedUrls = [];
|
|
113
|
+
for (const url of toRender) {
|
|
114
|
+
try {
|
|
115
|
+
const req = makeMockReq(url);
|
|
116
|
+
const [res, result] = makeMockRes();
|
|
117
|
+
await dispatch(req, res, app);
|
|
118
|
+
const { status, html } = result();
|
|
119
|
+
if (status >= 300) {
|
|
120
|
+
frameworkWarn(`[ssg] ${url} \u2192 HTTP ${status} \u2014 skipping`);
|
|
121
|
+
continue;
|
|
122
|
+
}
|
|
123
|
+
const file = urlToFile(outDir, url, trailingSlash);
|
|
124
|
+
await mkdir(dirname(file), { recursive: true });
|
|
125
|
+
const full = html.trimStart().startsWith("<!") ? html : `<!DOCTYPE html>${html}`;
|
|
126
|
+
await writeFile(file, full, "utf-8");
|
|
127
|
+
renderedUrls.push(url);
|
|
128
|
+
count++;
|
|
129
|
+
} catch (err) {
|
|
130
|
+
const detail = err instanceof Error ? err.message : String(err);
|
|
131
|
+
frameworkWarn(`[ssg] ${url} failed to render \u2014 skipping
|
|
132
|
+
${detail}`);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
const shouldGenerateNotFound = notFound !== false && scan.errorPage != null;
|
|
136
|
+
if (shouldGenerateNotFound) {
|
|
137
|
+
try {
|
|
138
|
+
const req = makeMockReq("/__davaux_404__");
|
|
139
|
+
const [res, result] = makeMockRes();
|
|
140
|
+
await dispatch(req, res, app);
|
|
141
|
+
const { html } = result();
|
|
142
|
+
const full = html.trimStart().startsWith("<!") ? html : `<!DOCTYPE html>${html}`;
|
|
143
|
+
await writeFile(join(outDir, "404.html"), full, "utf-8");
|
|
144
|
+
console.log("[davaux] Generated 404.html");
|
|
145
|
+
} catch (err) {
|
|
146
|
+
const detail = err instanceof Error ? err.message : String(err);
|
|
147
|
+
frameworkWarn(`[ssg] Failed to render 404.html \u2014 skipping
|
|
148
|
+
${detail}`);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
if (sitemap !== false && sitemap != null) {
|
|
152
|
+
const entries = renderedUrls.map(
|
|
153
|
+
(url) => ` <url><loc>${toSitemapUrl(sitemap.baseUrl, basePath, url, trailingSlash)}</loc></url>`
|
|
154
|
+
).join("\n");
|
|
155
|
+
const xml = `<?xml version="1.0" encoding="UTF-8"?>
|
|
156
|
+
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
|
157
|
+
${entries}
|
|
158
|
+
</urlset>
|
|
159
|
+
`;
|
|
160
|
+
await writeFile(join(outDir, "sitemap.xml"), xml, "utf-8");
|
|
161
|
+
console.log(`[davaux] Generated sitemap.xml (${renderedUrls.length} URL(s))`);
|
|
162
|
+
}
|
|
163
|
+
const assetsDir = join(distDir, "_davaux");
|
|
164
|
+
if (existsSync(assetsDir)) {
|
|
165
|
+
await cp(assetsDir, join(outDir, "_davaux"), { recursive: true });
|
|
166
|
+
}
|
|
167
|
+
if (existsSync(publicDir)) {
|
|
168
|
+
await cp(publicDir, outDir, { recursive: true });
|
|
169
|
+
}
|
|
170
|
+
console.log(`[davaux] Generated ${count} static page(s) \u2192 ${relative(process.cwd(), outDir)}/`);
|
|
171
|
+
}
|
|
172
|
+
export {
|
|
173
|
+
generateStatic
|
|
174
|
+
};
|
|
175
|
+
//# sourceMappingURL=ssg.js.map
|
package/dist/ssg.js.map
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/ssg.ts"],
|
|
4
|
+
"sourcesContent": ["import { existsSync } from 'node:fs'\nimport { cp, mkdir, writeFile } from 'node:fs/promises'\nimport type { IncomingMessage, ServerResponse } from 'node:http'\nimport { dirname, join, relative } from 'node:path'\nimport { frameworkWarn } from './errors.js'\nimport { buildApp, dispatch } from './router/handler.js'\nimport type { GetStaticPathsFn, ScanResult } from './types.js'\n\n/** Options for `generateStatic()`. All directory paths should be absolute. */\nexport interface SsgOptions {\n /** Output directory for generated HTML files. */\n outDir: string\n /** Build output directory \u2014 used to locate `_davaux` assets to copy across. */\n distDir: string\n /** Public directory to copy into `outDir` after generation. */\n publicDir: string\n /** Scanned route manifest from `scanRoutes()`. */\n scan: ScanResult\n /** Client JS bundle URLs injected into every generated page. */\n clientScripts: string[]\n /** Client CSS URLs injected into every generated page. */\n clientStylesheets: string[]\n /** Compiled path to `src/middleware.ts` \u2014 applied to every SSG render request. */\n appMiddlewarePath?: string\n /**\n * Controls the URL-to-filename mapping.\n * - `'always'` \u2014 `/about` \u2192 `about/index.html` (default)\n * - `'never'` \u2014 `/about` \u2192 `about.html`\n */\n trailingSlash?: 'always' | 'never'\n /** Base path for subdirectory deployments (e.g. `'/docs'`). */\n basePath?: string\n /** Generate a `404.html` from `_error.tsx`. Default: `true` when `_error.tsx` is present. */\n notFound?: boolean\n /**\n * Generate a `sitemap.xml`. Pass `false` to disable, or `{ baseUrl }` to enable.\n * `baseUrl` is prepended to every URL (e.g. `'https://example.com'`).\n */\n sitemap?: false | { baseUrl: string }\n}\n\nfunction makeMockReq(pathname: string): IncomingMessage {\n return {\n method: 'GET',\n url: pathname,\n headers: { host: 'localhost', cookie: '' },\n on(event: string, listener: (...args: unknown[]) => void) {\n // Immediately signal end of body so ctx.json()/ctx.form() resolve empty\n if (event === 'end') setImmediate(() => listener())\n return this\n },\n removeListener() {\n return this\n },\n } as unknown as IncomingMessage\n}\n\nfunction makeMockRes(): [ServerResponse, () => { status: number; html: string }] {\n let status = 200\n let body = ''\n let sent = false\n let ended = false\n const hdrs: Record<string, string | string[]> = {}\n\n const res = {\n get statusCode() {\n return status\n },\n set statusCode(v: number) {\n status = v\n },\n get headersSent() {\n return sent\n },\n get writableEnded() {\n return ended\n },\n writeHead(code: number) {\n status = code\n sent = true\n },\n end(data?: string | Buffer) {\n if (data != null) body = typeof data === 'string' ? data : data.toString('utf-8')\n ended = true\n },\n getHeader: (name: string) => hdrs[name.toLowerCase()],\n setHeader(name: string, value: string | string[]) {\n hdrs[name.toLowerCase()] = value\n },\n } as unknown as ServerResponse\n\n return [res, () => ({ status, html: body })]\n}\n\nfunction urlToFile(\n outDir: string,\n url: string,\n trailingSlash: 'always' | 'never' = 'always',\n): string {\n const trimmed = url.replace(/^\\//, '').replace(/\\/$/, '')\n if (!trimmed) return join(outDir, 'index.html')\n if (trailingSlash === 'never') return join(outDir, `${trimmed}.html`)\n return join(outDir, trimmed, 'index.html')\n}\n\nfunction toSitemapUrl(\n baseUrl: string,\n basePath: string,\n urlPath: string,\n trailingSlash: 'always' | 'never',\n): string {\n const base = baseUrl.replace(/\\/$/, '')\n const bp = basePath.replace(/\\/$/, '')\n const trimmed = urlPath.replace(/\\/$/, '')\n const path = !trimmed ? '/' : trailingSlash === 'never' ? trimmed : `${trimmed}/`\n return `${base}${bp}${path}`\n}\n\n/**\n * Pre-render all static pages in the route manifest and write them to `outDir`.\n * Pages with `export const prerender = false` are skipped. Dynamic routes must\n * export `getStaticPaths` to supply the parameter sets to render.\n *\n * Also generates `404.html` (from `_error.tsx`) and `sitemap.xml` when\n * configured, and copies `_davaux` assets and `public/` into `outDir`.\n */\nexport async function generateStatic(opts: SsgOptions): Promise<void> {\n const {\n outDir,\n distDir,\n publicDir,\n scan,\n appMiddlewarePath,\n trailingSlash = 'always',\n basePath = '',\n notFound,\n sitemap,\n } = opts\n\n // Prepend basePath to injected asset URLs so the rendered HTML references the correct paths\n const clientScripts = opts.clientScripts.map((s) => `${basePath}${s}`)\n const clientStylesheets = opts.clientStylesheets.map((s) => `${basePath}${s}`)\n\n const app = buildApp(scan, false, clientScripts, clientStylesheets, appMiddlewarePath, basePath)\n\n // Collect all URL paths to render\n const toRender: string[] = []\n\n for (const route of scan.routes) {\n if (route.type !== 'page') continue\n\n const mod = (await import(route.filePath)) as Record<string, unknown>\n if (mod.prerender === false) continue\n\n if (route.params.length === 0) {\n toRender.push(route.urlPattern)\n } else {\n const fn = mod.getStaticPaths as GetStaticPathsFn | undefined\n if (typeof fn !== 'function') {\n frameworkWarn(\n `[ssg] skipping ${route.urlPattern} \u2014 dynamic route has no getStaticPaths export`,\n `Add a getStaticPaths export to ${relative(process.cwd(), route.filePath)}:\\n\\n` +\n ` export const getStaticPaths = async () => [\\n` +\n ` { params: { /* param: value */ } },\\n` +\n ` ]`,\n )\n continue\n }\n const paths = await fn()\n for (const sp of paths) {\n let url = route.urlPattern\n for (const [k, v] of Object.entries(sp.params)) url = url.replace(`:${k}`, String(v))\n toRender.push(url)\n }\n }\n }\n\n await mkdir(outDir, { recursive: true })\n\n let count = 0\n const renderedUrls: string[] = []\n\n for (const url of toRender) {\n try {\n const req = makeMockReq(url)\n const [res, result] = makeMockRes()\n await dispatch(req, res, app)\n const { status, html } = result()\n\n if (status >= 300) {\n frameworkWarn(`[ssg] ${url} \u2192 HTTP ${status} \u2014 skipping`)\n continue\n }\n\n const file = urlToFile(outDir, url, trailingSlash)\n await mkdir(dirname(file), { recursive: true })\n const full = html.trimStart().startsWith('<!') ? html : `<!DOCTYPE html>${html}`\n await writeFile(file, full, 'utf-8')\n renderedUrls.push(url)\n count++\n } catch (err) {\n const detail = err instanceof Error ? err.message : String(err)\n frameworkWarn(`[ssg] ${url} failed to render \u2014 skipping\\n ${detail}`)\n }\n }\n\n // Generate 404.html for static hosts (Netlify, GitHub Pages, etc.)\n const shouldGenerateNotFound = notFound !== false && scan.errorPage != null\n if (shouldGenerateNotFound) {\n try {\n const req = makeMockReq('/__davaux_404__')\n const [res, result] = makeMockRes()\n await dispatch(req, res, app)\n const { html } = result()\n const full = html.trimStart().startsWith('<!') ? html : `<!DOCTYPE html>${html}`\n await writeFile(join(outDir, '404.html'), full, 'utf-8')\n console.log('[davaux] Generated 404.html')\n } catch (err) {\n const detail = err instanceof Error ? err.message : String(err)\n frameworkWarn(`[ssg] Failed to render 404.html \u2014 skipping\\n ${detail}`)\n }\n }\n\n // Generate sitemap.xml\n if (sitemap !== false && sitemap != null) {\n const entries = renderedUrls\n .map(\n (url) =>\n ` <url><loc>${toSitemapUrl(sitemap.baseUrl, basePath, url, trailingSlash)}</loc></url>`,\n )\n .join('\\n')\n const xml =\n `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\\n` +\n `<urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\">\\n` +\n `${entries}\\n` +\n `</urlset>\\n`\n await writeFile(join(outDir, 'sitemap.xml'), xml, 'utf-8')\n console.log(`[davaux] Generated sitemap.xml (${renderedUrls.length} URL(s))`)\n }\n\n // Copy _davaux assets (islands, client bundle, CSS)\n const assetsDir = join(distDir, '_davaux')\n if (existsSync(assetsDir)) {\n await cp(assetsDir, join(outDir, '_davaux'), { recursive: true })\n }\n\n // Copy public/ directory if present\n if (existsSync(publicDir)) {\n await cp(publicDir, outDir, { recursive: true })\n }\n\n console.log(`[davaux] Generated ${count} static page(s) \u2192 ${relative(process.cwd(), outDir)}/`)\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"actions.test.d.ts","sourceRoot":"","sources":["../../src/test/actions.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"body-limits.test.d.ts","sourceRoot":"","sources":["../../src/test/body-limits.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.test.d.ts","sourceRoot":"","sources":["../../src/test/errors.test.ts"],"names":[],"mappings":""}
|