void 1.2.0 → 1.3.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/dist/{account-cmd-CdUll_35.mjs → account-cmd-B4i71m7k.mjs} +3 -3
- package/dist/{application-analysis-fEqoSeMp.mjs → application-analysis-DYdVoMAY.mjs} +8 -6
- package/dist/{application-routing-DAhNP4u3.mjs → application-routing-C8EqRDfv.mjs} +3 -1
- package/dist/{auth-link-C87vGXM-.mjs → auth-link-BKwHPbdv.mjs} +3 -3
- package/dist/{auth-router-6I81r-ix.mjs → auth-router-DqLx8E0F.mjs} +2 -2
- package/dist/{better-auth-shared-D-6z0q0f.mjs → better-auth-shared-7FM3Uk2N.mjs} +48 -2
- package/dist/{build-cmd-ex1g-j_e.mjs → build-cmd-Dy4psnt1.mjs} +1 -1
- package/dist/{cache-oHzrnY3z.mjs → cache-DV37S6dl.mjs} +1 -1
- package/dist/{cancel-deploy-viAMD0Q_.mjs → cancel-deploy-DMPyu1Vt.mjs} +1 -1
- package/dist/{cf-build-output-BhVxldCw.mjs → cf-build-output-Bapzc_8Z.mjs} +102 -1
- package/dist/cf-build-output-DlBkWdNU.mjs +1 -0
- package/dist/cli/cli.mjs +41 -32
- package/dist/cli/cloudflare-operation-process.mjs +27 -6
- package/dist/cli/env-schema-probe.mjs +2 -2
- package/dist/{client-BEkdj1kx.mjs → client-BEMtySaV.mjs} +8 -1
- package/dist/client-DyxPQnF_.mjs +1 -0
- package/dist/{cloudflare-cmd-DMzCv12s.mjs → cloudflare-cmd-BaqIigwI.mjs} +1 -1
- package/dist/{cloudflare-connect-CCRTVg-I.mjs → cloudflare-connect-pNLQmr_e.mjs} +1 -1
- package/dist/{cloudflare-operations-DsSaw2BT.mjs → cloudflare-operations-PCM4wucv.mjs} +1 -1
- package/dist/{cloudflare-operations-Dh9dEHJj.mjs → cloudflare-operations-vP3b5CQf.mjs} +3 -3
- package/dist/config-BTu1o3Dc.mjs +49 -0
- package/dist/{config-DQfHOKh9.d.mts → config-Du88-7Y8.d.mts} +2 -1
- package/dist/config-entry.d.mts +1 -1
- package/dist/{connect-k7R2rPVA.mjs → connect-DwVsBvVh.mjs} +4 -4
- package/dist/{create-project-DTuy-l0z.mjs → create-project-CgrnvzyA.mjs} +1 -1
- package/dist/{create-project-DV71ol5d.mjs → create-project-CjzbBlTv.mjs} +1 -1
- package/dist/{db-DVOkLH5X.mjs → db-rvo64snS.mjs} +13 -13
- package/dist/{delete-BbP5eopu.mjs → delete-DWX6dP4M.mjs} +1 -1
- package/dist/deploy-CtHE2A3R.mjs +2 -0
- package/dist/{deploy-7H32EnUs.mjs → deploy-hRPvw8ci.mjs} +229 -69
- package/dist/{deploy-managed-static-DlvcvnQT.mjs → deploy-managed-static-CDYA2p3L.mjs} +30 -14
- package/dist/{deploy-transport-BzGEj0Ge.mjs → deploy-transport-JCxw7QDi.mjs} +3 -3
- package/dist/deploy.mjs +4 -3
- package/dist/{dispatch-DoUnxTNo.mjs → dispatch-OVLeWW8K.mjs} +71 -2
- package/dist/{domain-CA2wBgra.mjs → domain-CH5iBD9Y.mjs} +2 -2
- package/dist/{email-DXpCc77w.mjs → email-CbTO1l78.mjs} +58 -9
- package/dist/{email-cloudflare-D03g2TkS.mjs → email-cloudflare-B8-pq_-W.mjs} +106 -5
- package/dist/{env-DgOQ9_8S.mjs → env-BBdw236G.mjs} +3 -3
- package/dist/{env-BJjULvL0.mjs → env-BaMz0j7H.mjs} +6 -1
- package/dist/{env-validation-BmsdCZEk.mjs → env-validation-BfBVvBNe.mjs} +1 -1
- package/dist/{env-validation-Dwq3PJzK.mjs → env-validation-XcukUlFM.mjs} +1 -1
- package/dist/{gen-BfmcIi2g.mjs → gen-CCx3t2Ju.mjs} +1 -1
- package/dist/gen-TgXy93Rr.mjs +1 -0
- package/dist/{github-cmd-CY9LUqLh.mjs → github-cmd-BzkRLkbg.mjs} +1 -1
- package/dist/{handler-BbkSPzGF.d.mts → handler-CQv5YDS0.d.mts} +1 -1
- package/dist/{help-CxSlPpzJ.mjs → help-CKbrhZha.mjs} +16 -1
- package/dist/help-qOZr3wng.mjs +1 -0
- package/dist/index.d.mts +2 -4
- package/dist/index.mjs +317 -122
- package/dist/{info-7VDlhtyy.mjs → info-oBm8yK8J.mjs} +2 -2
- package/dist/{init-DxYyOs4-.mjs → init-CBp_uMve.mjs} +217 -197
- package/dist/{link-Ddmod1dZ.mjs → link-Dt_QXmM4.mjs} +2 -2
- package/dist/{list-MogaugiO.mjs → list-DF6asTdt.mjs} +2 -2
- package/dist/{live-Bt8Y_0bg.d.mts → live-CXJ9yC98.d.mts} +1 -1
- package/dist/{local-d1-BHBnKWRb.mjs → local-d1-CUhH3qtj.mjs} +1 -1
- package/dist/{login-Cttnagmm.mjs → login-BjSyhXlT.mjs} +2 -2
- package/dist/login-Cdo8Aco1.mjs +1 -0
- package/dist/{logs-CAszUWZI.mjs → logs-DmvBl6xA.mjs} +2 -2
- package/dist/{migrate-DyT2jJ8y.mjs → migrate-BXRHpYwR.mjs} +1 -1
- package/dist/migrate-COPncCGx.mjs +1 -0
- package/dist/nitro.mjs +2 -2
- package/dist/{node-WB7c2N4L.mjs → node-DtD7ZiPf.mjs} +4 -4
- package/dist/{operator-args-UnE8Y2eK.mjs → operator-args-BsJIYXaT.mjs} +8 -1
- package/dist/operator-cmd-DDiX7Y3f.mjs +1 -0
- package/dist/{operator-cmd-skshjMGl.mjs → operator-cmd-DjZKGGgN.mjs} +4 -3
- package/dist/pages/client.d.mts +21 -4
- package/dist/pages/client.mjs +174 -35
- package/dist/pages/index.d.mts +18 -2
- package/dist/pages/index.mjs +2 -52
- package/dist/pages/islands-plugin.d.mts +1 -1
- package/dist/pages/islands-plugin.mjs +9 -3
- package/dist/pages/protocol.d.mts +2 -2
- package/dist/platform-args-BC8_hsDj.mjs +1 -0
- package/dist/{platform-args-DVbVClZl.mjs → platform-args-BMD2gjc_.mjs} +1 -1
- package/dist/{platform-auth-config-C-pm5Qzx.mjs → platform-auth-config-BgnuMbml.mjs} +3 -3
- package/dist/{platform-auth-protection-SHhvim1L.mjs → platform-auth-protection-NjRejttU.mjs} +2 -2
- package/dist/{platform-auth-recovery-DXVWs-wA.mjs → platform-auth-recovery-Ug12d9W5.mjs} +2 -2
- package/dist/{platform-cmd-PiNRkopU.mjs → platform-cmd-BYKLMPCn.mjs} +1 -1
- package/dist/{platform-cmd-D5I1beUX.mjs → platform-cmd-HByuZAO7.mjs} +4 -4
- package/dist/{platform-domain-jpmBfZeb.mjs → platform-domain-DLSQ8GF8.mjs} +2 -2
- package/dist/{platform-lifecycle-DyKmuNY6.mjs → platform-lifecycle-3dwFJmnq.mjs} +102 -40
- package/dist/{platform-lifecycle-DH3Yr1qQ.mjs → platform-lifecycle-BRqcxerG.mjs} +1 -1
- package/dist/{platform-management-7m-PLaPJ.mjs → platform-management-ZK6XcbCo.mjs} +1 -1
- package/dist/{platform-management--vDwSn35.mjs → platform-management-ZZ6bQM5j.mjs} +1 -1
- package/dist/{platform-recovery-BiNpZZab.mjs → platform-recovery-8vNE5dNN.mjs} +2 -2
- package/dist/{plugin-inference-DUjCd55H.mjs → plugin-inference-CeiB6BG5.mjs} +53 -18
- package/dist/{prepare-BcAE5Sdj.mjs → prepare-5BR7Splm.mjs} +1 -1
- package/dist/prepare-B3VrSF1Z.mjs +1 -0
- package/dist/{prepare-DA-17DhO.mjs → prepare-Dseww74N.mjs} +4 -4
- package/dist/{prerender-render-Cijv7UFo.mjs → prerender-render-CaShbHJ3.mjs} +13 -1
- package/dist/prerender-render.d.mts +1 -0
- package/dist/prerender-render.mjs +1 -1
- package/dist/{project-cmd-DA4K5faU.mjs → project-cmd-CjLNNxwe.mjs} +15 -15
- package/dist/{project-team-CQBNveX3.mjs → project-team-DE5drjcl.mjs} +1 -1
- package/dist/{project-token-CCalFyQf.mjs → project-token-XEYEXfiJ.mjs} +1 -1
- package/dist/{project-zero-trust-DPnkiEuT.mjs → project-zero-trust-6VPU8zmV.mjs} +1 -1
- package/dist/{protocol-BBDpJz3G.d.mts → protocol-BekmFxCI.d.mts} +2 -2
- package/dist/{provision-DtROpNNI.mjs → provision-B7UFrBH7.mjs} +1 -1
- package/dist/{provision-BFLCrnUp.mjs → provision-Chq0NRAV.mjs} +1 -1
- package/dist/{requests-BpH0kImL.mjs → requests-CG-Pj8ze.mjs} +1 -1
- package/dist/{rollback-CXS1tAa-.mjs → rollback-CIrm2txZ.mjs} +2 -2
- package/dist/{route-types-BZi26DVS.mjs → route-types--PAOzHlH.mjs} +49 -28
- package/dist/routes-stub.d.mts +22 -13
- package/dist/runtime/better-auth-mysql.mjs +1 -1
- package/dist/runtime/better-auth-pg.mjs +1 -1
- package/dist/runtime/better-auth.mjs +1 -1
- package/dist/runtime/handler.d.mts +1 -1
- package/dist/runtime/live-client.d.mts +1 -1
- package/dist/runtime/live.d.mts +1 -1
- package/dist/runtime/log.mjs +19 -1
- package/dist/runtime/routing.d.mts +2 -2
- package/dist/runtime/routing.mjs +4 -3
- package/dist/runtime/validator.d.mts +1 -1
- package/dist/runtime/ws-server.d.mts +1 -1
- package/dist/runtime/ws.d.mts +1 -1
- package/dist/{scan-8IzYXiU_.mjs → scan-N9WzdcAl.mjs} +302 -23
- package/dist/{secret-BbXHfLAt.mjs → secret-BL6g7mF5.mjs} +3 -3
- package/dist/static-asset-marker-Btf-6oCD.mjs +32 -0
- package/dist/{types-7AIz0OZu.d.mts → types-w72dljaA.d.mts} +6 -1
- package/dist/{version-metadata-tS39iW09.mjs → version-metadata-DmaZNTYW.mjs} +1 -1
- package/dist/worker-conditions-AWFRcFxR.mjs +11 -0
- package/dist/{wrangler-F96NnLyb.mjs → wrangler-CDiEBCdS.mjs} +2 -1
- package/dist/wrangler-DOPr4jyI.mjs +1 -0
- package/dist/{wrapper-D3sZyh2C.mjs → wrapper-CEiDeCqD.mjs} +6 -10
- package/dist/{ws-BH-im_tX.d.mts → ws-D1zWiB_P.d.mts} +1 -1
- package/docs/guide/auth.md +3 -1
- package/docs/guide/edge/static-assets.md +10 -0
- package/docs/guide/email/domains.md +1 -1
- package/docs/guide/email/receiving.md +2 -0
- package/docs/guide/email/sending.md +1 -1
- package/docs/guide/pages-routing/actions-and-forms.md +19 -13
- package/docs/guide/pages-routing/markdown.md +2 -0
- package/docs/guide/pages-routing/overview.md +34 -3
- package/docs/guide/platform/administration/email.md +18 -0
- package/docs/guide/platform/installation/prerequisites.md +9 -4
- package/docs/guide/platform/installation/uninstall.md +2 -0
- package/docs/guide/queues.md +13 -1
- package/docs/guide/quickstart.md +26 -1
- package/docs/guide/sandboxes.md +2 -2
- package/docs/guide/server-routing.md +38 -2
- package/docs/guide/type-safety.md +7 -7
- package/docs/guide/websockets.md +4 -2
- package/docs/reference/api/pages.md +4 -4
- package/docs/reference/cli/email.md +13 -0
- package/docs/reference/cli/platform-email.md +2 -2
- package/docs/reference/cli.md +2 -1
- package/docs/reference/structure.md +3 -1
- package/package.json +8 -7
- package/sandbox.Dockerfile +1 -1
- package/templates/assets/icons.svg +49 -0
- package/templates/assets/react.svg +1 -0
- package/templates/assets/solid.svg +1 -0
- package/templates/assets/stack.svg +35 -0
- package/templates/assets/svelte.svg +1 -0
- package/templates/assets/void.svg +5 -0
- package/templates/assets/vue.svg +1 -0
- package/dist/cf-build-output-BJHuSsVN.mjs +0 -1
- package/dist/client-BiRDZTSd.mjs +0 -1
- package/dist/config-CyUJzi3q.mjs +0 -32
- package/dist/deploy-CE0Ev0Ob.mjs +0 -2
- package/dist/gen-NrOlWZaG.mjs +0 -1
- package/dist/help-BeAFFE5C.mjs +0 -1
- package/dist/login-DgDwlKc_.mjs +0 -1
- package/dist/migrate-n49ZeS1X.mjs +0 -1
- package/dist/operator-cmd-d2MvJOrl.mjs +0 -1
- package/dist/parse-filename-DioPHiR9.mjs +0 -77
- package/dist/platform-args-kQrgxScY.mjs +0 -1
- package/dist/prepare-C4I0f--h.mjs +0 -1
- package/dist/wrangler-BLb3_luP.mjs +0 -1
package/dist/runtime/log.mjs
CHANGED
|
@@ -1,4 +1,22 @@
|
|
|
1
1
|
//#region src/runtime/log.ts
|
|
2
|
+
function errorReplacer() {
|
|
3
|
+
const seen = /* @__PURE__ */ new WeakSet();
|
|
4
|
+
return (_key, value) => {
|
|
5
|
+
if (!(value instanceof Error)) return value;
|
|
6
|
+
if (seen.has(value)) return {
|
|
7
|
+
name: value.name,
|
|
8
|
+
message: value.message
|
|
9
|
+
};
|
|
10
|
+
seen.add(value);
|
|
11
|
+
return {
|
|
12
|
+
...value,
|
|
13
|
+
name: value.name,
|
|
14
|
+
message: value.message,
|
|
15
|
+
stack: value.stack,
|
|
16
|
+
cause: value.cause
|
|
17
|
+
};
|
|
18
|
+
};
|
|
19
|
+
}
|
|
2
20
|
function format(message, fields) {
|
|
3
21
|
try {
|
|
4
22
|
const payload = Object.create(null);
|
|
@@ -8,7 +26,7 @@ function format(message, fields) {
|
|
|
8
26
|
if (typeof value === "function") continue;
|
|
9
27
|
payload[key] = value;
|
|
10
28
|
}
|
|
11
|
-
return JSON.stringify(payload);
|
|
29
|
+
return JSON.stringify(payload, errorReplacer());
|
|
12
30
|
} catch {
|
|
13
31
|
return JSON.stringify({
|
|
14
32
|
msg: message,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { A as filterInternalBindings, M as createClientAssetTags, N as createManifestLoader, O as createAssetFallback, j as ClientAssetTags, k as createWorkerFetch } from "../handler-
|
|
2
|
-
import { a as handlePageMutation, i as handlePageGet } from "../protocol-
|
|
1
|
+
import { A as filterInternalBindings, M as createClientAssetTags, N as createManifestLoader, O as createAssetFallback, j as ClientAssetTags, k as createWorkerFetch } from "../handler-CQv5YDS0.mjs";
|
|
2
|
+
import { a as handlePageMutation, i as handlePageGet } from "../protocol-BekmFxCI.mjs";
|
|
3
3
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
4
4
|
import { Context, Hono, MiddlewareHandler } from "hono";
|
|
5
5
|
//#region src/runtime/routing-errors.d.ts
|
package/dist/runtime/routing.mjs
CHANGED
|
@@ -3,6 +3,7 @@ import { t as convertReturnValue } from "../response-Tn7rU0MV.mjs";
|
|
|
3
3
|
import { i as searchWithoutActionKey, n as hasActionKey, r as markActionKey, t as actionKeySegment } from "../action-key-XZ9HkWAO.mjs";
|
|
4
4
|
import { n as handlePageGet, r as handlePageMutation } from "../protocol-DimNxVRr.mjs";
|
|
5
5
|
import { t as VoidAssetRewriteError } from "../handler-BZ1t7-Rv.mjs";
|
|
6
|
+
import { n as markStaticAsset } from "../static-asset-marker-Btf-6oCD.mjs";
|
|
6
7
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
7
8
|
import { compilePattern, matchPattern, matchPatternCaptures, mergeQueryIntoLocation, substituteParams } from "@void/edge";
|
|
8
9
|
//#region src/runtime/routing-worker.ts
|
|
@@ -189,7 +190,7 @@ function createPagesFallback(options) {
|
|
|
189
190
|
if (path === "/api" || path.startsWith("/api/") || c.req.method !== "GET" && c.req.method !== "HEAD") return c.text("Not Found", 404);
|
|
190
191
|
const assets = c.env?.ASSETS;
|
|
191
192
|
const assetResponse = assets && typeof assets.fetch === "function" ? await assets.fetch(c.req.raw) : options.routing.markNoMatch(c.req.raw, new Response("Not Found", { status: 404 }));
|
|
192
|
-
if (assetResponse.status !== 404) return cachePolicy(c.req.raw, c.env, assetResponse);
|
|
193
|
+
if (assetResponse.status !== 404) return markStaticAsset(c, await cachePolicy(c.req.raw, c.env, assetResponse));
|
|
193
194
|
const fallback = options.fallbackRules ? await options.routing.applyFallback(c, options.fallbackRules) : void 0;
|
|
194
195
|
if (fallback) return fallback;
|
|
195
196
|
if (path.includes("/.") || path.substring(path.lastIndexOf("/") + 1).includes(".")) return options.errors.serveCustomPage(c, 404, "Not Found");
|
|
@@ -207,7 +208,7 @@ function createSsrFallback(options) {
|
|
|
207
208
|
const binding = c.env?.ASSETS;
|
|
208
209
|
if (!binding || typeof binding.fetch !== "function") return options.routing.markNoMatch(c.req.raw, new Response("Not Found", { status: 404 }));
|
|
209
210
|
const response = await binding.fetch(c.req.raw);
|
|
210
|
-
return response.status === 404 ? options.routing.markNoMatch(c.req.raw, new Response("Not Found", { status: 404 })) : cachePolicy(c.req.raw, c.env, response);
|
|
211
|
+
return response.status === 404 ? options.routing.markNoMatch(c.req.raw, new Response("Not Found", { status: 404 })) : markStaticAsset(c, await cachePolicy(c.req.raw, c.env, response));
|
|
211
212
|
};
|
|
212
213
|
return async (c) => {
|
|
213
214
|
if (options.nodeTarget && options.fallbackRules) {
|
|
@@ -237,7 +238,7 @@ function createAssetNotFound(options) {
|
|
|
237
238
|
const assets = c.env?.ASSETS;
|
|
238
239
|
if (assets && typeof assets.fetch === "function") {
|
|
239
240
|
const response = await assets.fetch(c.req.raw);
|
|
240
|
-
if (response.status !== 404) return cachePolicy(c.req.raw, c.env, response);
|
|
241
|
+
if (response.status !== 404) return markStaticAsset(c, await cachePolicy(c.req.raw, c.env, response));
|
|
241
242
|
}
|
|
242
243
|
}
|
|
243
244
|
return (options.fallbackRules ? await options.routing.applyFallback(c, options.fallbackRules) : void 0) ?? options.routing.markNoMatch(c.req.raw, new Response("Not Found", { status: 404 }));
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { D as runValidation, E as ValidatorSlots, T as HandlerInput } from "../handler-
|
|
1
|
+
import { D as runValidation, E as ValidatorSlots, T as HandlerInput } from "../handler-CQv5YDS0.mjs";
|
|
2
2
|
export { HandlerInput, ValidatorSlots, runValidation };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { n as AuthState } from "../auth-DkcFflXV.mjs";
|
|
2
2
|
import { r as VoidAuthRuntimeOptions, t as VoidAuthEnv } from "../better-auth-shared-DVk2DkTW.mjs";
|
|
3
|
-
import { f as WebSocketInstanceKey, t as AnyWebSocketDefinition } from "../ws-
|
|
3
|
+
import { f as WebSocketInstanceKey, t as AnyWebSocketDefinition } from "../ws-D1zWiB_P.mjs";
|
|
4
4
|
//#region src/runtime/ws-server.d.ts
|
|
5
5
|
export type WebSocketRouteMeta = {
|
|
6
6
|
name?: string;
|
package/dist/runtime/ws.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as RoomDefinition, c as VoidSocket, d as WebSocketConnection, f as WebSocketInstanceKey, h as defineWebSocket, i as RoomController, l as VoidSocketCloseEvent, m as defineRoom, n as ConnectCommonOptions, o as SocketContext, p as connect, r as RoomContext, s as SocketDefinition, t as AnyWebSocketDefinition, u as WebSocketBaseContext } from "../ws-
|
|
1
|
+
import { a as RoomDefinition, c as VoidSocket, d as WebSocketConnection, f as WebSocketInstanceKey, h as defineWebSocket, i as RoomController, l as VoidSocketCloseEvent, m as defineRoom, n as ConnectCommonOptions, o as SocketContext, p as connect, r as RoomContext, s as SocketDefinition, t as AnyWebSocketDefinition, u as WebSocketBaseContext } from "../ws-D1zWiB_P.mjs";
|
|
2
2
|
export { AnyWebSocketDefinition, ConnectCommonOptions, RoomContext, RoomController, RoomDefinition, SocketContext, SocketDefinition, VoidSocket, VoidSocketCloseEvent, WebSocketBaseContext, WebSocketConnection, WebSocketInstanceKey, connect, defineRoom, defineWebSocket };
|
|
@@ -1,13 +1,136 @@
|
|
|
1
|
-
import { a as join, n as dirname, r as extname, t as basename } from "./dist-ipQi0Q8y.mjs";
|
|
1
|
+
import { a as join, l as toSlash, n as dirname, r as extname, t as basename } from "./dist-ipQi0Q8y.mjs";
|
|
2
2
|
import { n as readProjectPaths } from "./project-paths-DGu_QZ_Q.mjs";
|
|
3
3
|
import { t as glob } from "./dist-D15hFhP0.mjs";
|
|
4
4
|
import { n as isIdentifier, o as moduleExportName, r as isLiteral } from "./ast-CsZ_q_gc.mjs";
|
|
5
5
|
import { a as staticLiteral, i as staticExportInitializers, t as bindingNames } from "./ast-bindings-C3yaPs1y.mjs";
|
|
6
|
-
import { n as parseRouteFilename } from "./parse-filename-DioPHiR9.mjs";
|
|
7
6
|
import { i as voidWarn } from "./log-BMwmN5Ae.mjs";
|
|
8
7
|
import { t as MagicString } from "./dist-Cegxq8gs.mjs";
|
|
9
|
-
import { existsSync, readFileSync } from "node:fs";
|
|
8
|
+
import { existsSync, readFileSync, statSync } from "node:fs";
|
|
10
9
|
import { parseSync } from "vite";
|
|
10
|
+
//#region src/shared/route-extensions.ts
|
|
11
|
+
const ROUTE_EXTENSIONS = [
|
|
12
|
+
"ts",
|
|
13
|
+
"tsx",
|
|
14
|
+
"js",
|
|
15
|
+
"jsx",
|
|
16
|
+
"mjs",
|
|
17
|
+
"mts"
|
|
18
|
+
];
|
|
19
|
+
const ROUTE_EXTENSIONS_SET = new Set(ROUTE_EXTENSIONS.map((ext) => `.${ext}`));
|
|
20
|
+
//#endregion
|
|
21
|
+
//#region src/router/parse-filename.ts
|
|
22
|
+
const ENV_SUFFIXES = ["dev", "prod"];
|
|
23
|
+
function parsePath(relativePath, isWebSocketRoute) {
|
|
24
|
+
const filePath = relativePath;
|
|
25
|
+
let path = relativePath.replace(/\\/g, "/");
|
|
26
|
+
for (const ext of ROUTE_EXTENSIONS) if (path.endsWith(`.${ext}`)) {
|
|
27
|
+
path = path.slice(0, -(ext.length + 1));
|
|
28
|
+
break;
|
|
29
|
+
}
|
|
30
|
+
if (isWebSocketRoute && path.endsWith(".ws")) path = path.slice(0, -3);
|
|
31
|
+
const segments = path.split("/");
|
|
32
|
+
let filename = segments.pop();
|
|
33
|
+
let env = null;
|
|
34
|
+
for (const suffix of ENV_SUFFIXES) if (filename.endsWith(`.${suffix}`)) {
|
|
35
|
+
env = suffix;
|
|
36
|
+
filename = filename.slice(0, -(suffix.length + 1));
|
|
37
|
+
break;
|
|
38
|
+
}
|
|
39
|
+
segments.push(filename);
|
|
40
|
+
if (segments[segments.length - 1] === "index") segments.pop();
|
|
41
|
+
const filtered = segments.filter((s) => !s.startsWith("(") || !s.endsWith(")"));
|
|
42
|
+
const params = [];
|
|
43
|
+
let catchAll = false;
|
|
44
|
+
return {
|
|
45
|
+
pattern: "/" + filtered.map((segment) => {
|
|
46
|
+
if (segment.startsWith("[...") && segment.endsWith("]")) {
|
|
47
|
+
const paramName = segment.slice(4, -1);
|
|
48
|
+
catchAll = true;
|
|
49
|
+
if (paramName) {
|
|
50
|
+
params.push(paramName);
|
|
51
|
+
return `:${paramName}{.+}`;
|
|
52
|
+
}
|
|
53
|
+
return "*";
|
|
54
|
+
}
|
|
55
|
+
if (segment.startsWith("[") && segment.endsWith("]")) {
|
|
56
|
+
const paramName = segment.slice(1, -1);
|
|
57
|
+
params.push(paramName);
|
|
58
|
+
return `:${paramName}`;
|
|
59
|
+
}
|
|
60
|
+
return segment;
|
|
61
|
+
}).join("/"),
|
|
62
|
+
methods: [],
|
|
63
|
+
params,
|
|
64
|
+
catchAll,
|
|
65
|
+
env,
|
|
66
|
+
filePath
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Parse a route filename (relative to routes/) into a RouteDefinition.
|
|
71
|
+
*
|
|
72
|
+
* Rules (applied in order):
|
|
73
|
+
* 1. Strip file extension (.ts, .tsx, .js, .jsx, .mts, .mjs)
|
|
74
|
+
* 2. Check for env suffix (.dev, .prod) → strip and record
|
|
75
|
+
* 3. Strip trailing "index" segment
|
|
76
|
+
* 4. Remove route group directories: (groupname)
|
|
77
|
+
* 5. Convert [param] → :param, [...param] → :param{.+}, [...] → *
|
|
78
|
+
* 6. Prefix with /
|
|
79
|
+
*/
|
|
80
|
+
function parseRouteFilename(relativePath) {
|
|
81
|
+
return parsePath(relativePath, false);
|
|
82
|
+
}
|
|
83
|
+
/** Parse a `.ws.*` route filename into a regular route definition. */
|
|
84
|
+
function parseWebSocketFilename(relativePath) {
|
|
85
|
+
return parsePath(relativePath, true);
|
|
86
|
+
}
|
|
87
|
+
function isRouteEnabledForEnvironment(route, environment) {
|
|
88
|
+
return environment === void 0 || route.env === null || route.env === environment;
|
|
89
|
+
}
|
|
90
|
+
//#endregion
|
|
91
|
+
//#region src/shared/source-analysis-cache.ts
|
|
92
|
+
/**
|
|
93
|
+
* How long after a file changes its stat is trusted to identify its contents.
|
|
94
|
+
* Some file systems keep coarse timestamps (FAT: 2 s, HFS+: 1 s, ext4: one
|
|
95
|
+
* kernel tick) and Linux reuses inodes, so a second write inside that window
|
|
96
|
+
* can leave the signature unchanged. Like Git's racily clean index entries,
|
|
97
|
+
* values derived from recently changed files are recomputed on the next read.
|
|
98
|
+
*/
|
|
99
|
+
const RACY_WINDOW_MS = 3e3;
|
|
100
|
+
const entries = /* @__PURE__ */ new Map();
|
|
101
|
+
/**
|
|
102
|
+
* Derive a value from a source file, reusing it while the file is unchanged.
|
|
103
|
+
* A dev server rescans every source file on each file event, and several
|
|
104
|
+
* plugins scan the same pages, but only edited files need to be read and
|
|
105
|
+
* parsed again. `kind` separates analyses of the same file. `derive` must be a
|
|
106
|
+
* pure function of the source, and callers must not mutate its result.
|
|
107
|
+
*/
|
|
108
|
+
function deriveFromSource(path, kind, derive) {
|
|
109
|
+
const key = toSlash(path);
|
|
110
|
+
const stat = statSync(key, {
|
|
111
|
+
bigint: true,
|
|
112
|
+
throwIfNoEntry: false
|
|
113
|
+
});
|
|
114
|
+
if (!stat) return derive(readFileSync(key, "utf-8"));
|
|
115
|
+
const signature = `${stat.ino}:${stat.size}:${stat.mtimeNs}:${stat.ctimeNs}`;
|
|
116
|
+
const changedAt = Number((stat.mtimeNs > stat.ctimeNs ? stat.mtimeNs : stat.ctimeNs) / 1000000n);
|
|
117
|
+
const trusted = Date.now() - changedAt > RACY_WINDOW_MS;
|
|
118
|
+
const entry = entries.get(key);
|
|
119
|
+
if (trusted && entry?.signature === signature && entry.derived.has(kind)) return entry.derived.get(kind);
|
|
120
|
+
const value = derive(readFileSync(key, "utf-8"));
|
|
121
|
+
if (!trusted) entries.delete(key);
|
|
122
|
+
else if (entry?.signature === signature) entry.derived.set(kind, value);
|
|
123
|
+
else entries.set(key, {
|
|
124
|
+
signature,
|
|
125
|
+
derived: /* @__PURE__ */ new Map([[kind, value]])
|
|
126
|
+
});
|
|
127
|
+
return value;
|
|
128
|
+
}
|
|
129
|
+
/** Forget values derived from a file. Dev servers call this for watcher events. */
|
|
130
|
+
function invalidateSourceAnalysis(path) {
|
|
131
|
+
entries.delete(toSlash(path));
|
|
132
|
+
}
|
|
133
|
+
//#endregion
|
|
11
134
|
//#region src/pages/island-imports.ts
|
|
12
135
|
/** The whole JS/TS module, or each `<script>` block of a Vue/Svelte SFC with its offset in the file. */
|
|
13
136
|
function scriptBlocks(code, filename) {
|
|
@@ -150,6 +273,99 @@ function resolveLayoutIds(page, layouts, namedLayouts) {
|
|
|
150
273
|
return resolveEffectiveLayoutEntries(page, layouts, namedLayouts).map((layout) => layout.id);
|
|
151
274
|
}
|
|
152
275
|
//#endregion
|
|
276
|
+
//#region src/pages/manifest.ts
|
|
277
|
+
/**
|
|
278
|
+
* Generates the component import map and layout tree as code strings.
|
|
279
|
+
* Used by both SSR renderer and client entry virtual modules.
|
|
280
|
+
*
|
|
281
|
+
* Client entries load this eagerly, so it grows with every page. Each page id
|
|
282
|
+
* is written once, identical layout chains are shared, and static routes are
|
|
283
|
+
* matched by exact lookup instead of a RegExp per page. The emitted bindings
|
|
284
|
+
* (`components`, `layoutTree`, `routeMeta`, `matchRoute`) keep their shape;
|
|
285
|
+
* `matchRoute` takes a decoded pathname (see `decodePagePath`).
|
|
286
|
+
*/
|
|
287
|
+
function generateComponentManifest(scan, pagesDir) {
|
|
288
|
+
const load = (filePath) => `() => import(${JSON.stringify(`${pagesDir}/${filePath}`)})`;
|
|
289
|
+
const pageIds = new Set(scan.pages.map((page) => page.componentId));
|
|
290
|
+
const layoutKey = (id) => {
|
|
291
|
+
if (!pageIds.has(id)) return id;
|
|
292
|
+
const slash = id.lastIndexOf("/");
|
|
293
|
+
return id.slice(0, slash + 1) + "_" + id.slice(slash + 1);
|
|
294
|
+
};
|
|
295
|
+
const chains = [];
|
|
296
|
+
const chainIndexes = /* @__PURE__ */ new Map();
|
|
297
|
+
const staticRows = [];
|
|
298
|
+
const dynamicRows = [];
|
|
299
|
+
let inStaticPrefix = true;
|
|
300
|
+
for (const page of scan.pages) {
|
|
301
|
+
const chain = JSON.stringify(resolveLayoutIds(page, scan.layouts, scan.namedLayouts).map(layoutKey));
|
|
302
|
+
let chainIndex = chain === "[]" ? -1 : chainIndexes.get(chain);
|
|
303
|
+
if (chainIndex === void 0) {
|
|
304
|
+
chainIndex = chains.push(chain) - 1;
|
|
305
|
+
chainIndexes.set(chain, chainIndex);
|
|
306
|
+
}
|
|
307
|
+
const id = JSON.stringify(page.componentId);
|
|
308
|
+
inStaticPrefix &&= isStaticPattern(page.pattern);
|
|
309
|
+
if (inStaticPrefix) {
|
|
310
|
+
const pattern = page.pattern === `/${page.componentId}` ? "" : `, ${JSON.stringify(page.pattern)}`;
|
|
311
|
+
staticRows.push(` [${id}, ${load(page.componentPath)}, ${chainIndex}${pattern}],`);
|
|
312
|
+
} else dynamicRows.push(` [${patternToRegex(page.pattern)}, ${id}, ${load(page.componentPath)}, ${chainIndex}],`);
|
|
313
|
+
}
|
|
314
|
+
const lines = [];
|
|
315
|
+
lines.push("const components = {};");
|
|
316
|
+
lines.push(`const __voidLayoutChains = [${chains.join(", ")}];`);
|
|
317
|
+
lines.push("const __voidStaticRoutes = [", ...staticRows, "];");
|
|
318
|
+
lines.push("const __voidDynamicRoutes = [", ...dynamicRows, "];");
|
|
319
|
+
lines.push(`const layoutTree = {};
|
|
320
|
+
const __voidStaticRouteIds = new Map();
|
|
321
|
+
for (const [id, load, chain, pattern = "/" + id] of __voidStaticRoutes) {
|
|
322
|
+
components[id] = load;
|
|
323
|
+
if (chain >= 0) layoutTree[id] = __voidLayoutChains[chain];
|
|
324
|
+
if (!__voidStaticRouteIds.has(pattern)) __voidStaticRouteIds.set(pattern, id);
|
|
325
|
+
}
|
|
326
|
+
const routes = [];
|
|
327
|
+
for (const [pattern, id, load, chain] of __voidDynamicRoutes) {
|
|
328
|
+
components[id] = load;
|
|
329
|
+
if (chain >= 0) layoutTree[id] = __voidLayoutChains[chain];
|
|
330
|
+
routes.push({ pattern, id });
|
|
331
|
+
}`);
|
|
332
|
+
for (const layout of [...scan.layouts, ...scan.namedLayouts]) lines.push(`components[${JSON.stringify(layoutKey(toLayoutId(layout)))}] = ${load(layout.filePath)};`);
|
|
333
|
+
lines.push("const routeMeta = {");
|
|
334
|
+
for (const page of scan.pages) if (page.island) lines.push(` ${JSON.stringify(page.componentId)}: { island: true },`);
|
|
335
|
+
lines.push("};");
|
|
336
|
+
lines.push(`function matchRoute(path) {
|
|
337
|
+
const id = __voidStaticRouteIds.get(path);
|
|
338
|
+
if (id !== undefined) return id;
|
|
339
|
+
for (const r of routes) {
|
|
340
|
+
if (r.pattern.test(path)) return r.id;
|
|
341
|
+
}
|
|
342
|
+
return null;
|
|
343
|
+
}`);
|
|
344
|
+
return lines.join("\n");
|
|
345
|
+
}
|
|
346
|
+
const REGEX_SYNTAX = ".*+?^${}()|[]\\";
|
|
347
|
+
/** The capture group for `*`, `:name{.+}` and `:name`; other segments match as written. */
|
|
348
|
+
function captureGroup(segment) {
|
|
349
|
+
if (segment === "*") return "(.*)";
|
|
350
|
+
if (segment.length < 2 || segment[0] !== ":") return;
|
|
351
|
+
const name = segment.endsWith("{.+}") ? segment.slice(1, -4) : "";
|
|
352
|
+
return name && !name.includes("{") && !name.includes("}") ? "(.+)" : "([^\\/]+)";
|
|
353
|
+
}
|
|
354
|
+
/** Whether `patternToRegex` matches only the pattern's own text. */
|
|
355
|
+
function isStaticPattern(pattern) {
|
|
356
|
+
return pattern.split("/").every((segment) => captureGroup(segment) === void 0);
|
|
357
|
+
}
|
|
358
|
+
/** The RegExp literal a page pattern matches with, the same on the client and the server. */
|
|
359
|
+
function patternToRegex(pattern) {
|
|
360
|
+
return `/^${pattern.split("/").map((segment) => {
|
|
361
|
+
const group = captureGroup(segment);
|
|
362
|
+
if (group) return group;
|
|
363
|
+
let literal = "";
|
|
364
|
+
for (const char of segment) literal += REGEX_SYNTAX.includes(char) ? "\\" + char : char;
|
|
365
|
+
return literal;
|
|
366
|
+
}).join("\\/")}$/`;
|
|
367
|
+
}
|
|
368
|
+
//#endregion
|
|
153
369
|
//#region src/pages/scan.ts
|
|
154
370
|
const COMPONENT_EXTENSIONS = [
|
|
155
371
|
"vue",
|
|
@@ -158,13 +374,6 @@ const COMPONENT_EXTENSIONS = [
|
|
|
158
374
|
"svelte",
|
|
159
375
|
"md"
|
|
160
376
|
];
|
|
161
|
-
const SERVER_EXTENSIONS = [
|
|
162
|
-
"ts",
|
|
163
|
-
"tsx",
|
|
164
|
-
"js",
|
|
165
|
-
"mjs",
|
|
166
|
-
"mts"
|
|
167
|
-
];
|
|
168
377
|
const PAGE_METHODS = /* @__PURE__ */ new Set([
|
|
169
378
|
"loader",
|
|
170
379
|
"action",
|
|
@@ -173,6 +382,8 @@ const PAGE_METHODS = /* @__PURE__ */ new Set([
|
|
|
173
382
|
const MAX_REVALIDATE = 31536e3;
|
|
174
383
|
/** Layout paths already reported; a dev server rescans pages on every file change. */
|
|
175
384
|
const warnedLayoutPaths = /* @__PURE__ */ new Set();
|
|
385
|
+
/** Unreachable pages already reported, for the same reason. */
|
|
386
|
+
const warnedShadowedPages = /* @__PURE__ */ new Set();
|
|
176
387
|
function componentLayout(source, filename) {
|
|
177
388
|
if (!source.includes("layout")) return;
|
|
178
389
|
for (const script of scriptBlocks(source, filename)) {
|
|
@@ -255,6 +466,23 @@ function resolvePageRendering(page, options) {
|
|
|
255
466
|
shouldPrerender: prerenderMode === "force" || prerenderMode === "auto" && inferAutoPrerender(page, options)
|
|
256
467
|
};
|
|
257
468
|
}
|
|
469
|
+
/**
|
|
470
|
+
* The environment a file under pages/ is limited to, read from its name the way
|
|
471
|
+
* scanPages does: `home.dev.tsx`, `home.dev.island.vue` and `home.dev.server.ts`
|
|
472
|
+
* give 'dev'. Files the scanner skips (`_` segments, other extensions) give null.
|
|
473
|
+
*/
|
|
474
|
+
function pageFileEnvironment(relativePath) {
|
|
475
|
+
const segments = toSlash(relativePath).split("/");
|
|
476
|
+
if (segments.some((segment) => segment.startsWith("_"))) return null;
|
|
477
|
+
const file = segments[segments.length - 1];
|
|
478
|
+
const ext = extname(file);
|
|
479
|
+
let base = basename(file, ext);
|
|
480
|
+
if (ROUTE_EXTENSIONS_SET.has(ext) && base.endsWith(".server")) base = base.slice(0, -7);
|
|
481
|
+
else if (COMPONENT_EXTENSIONS.includes(ext.slice(1))) {
|
|
482
|
+
if (base.endsWith(".island")) base = base.slice(0, -7);
|
|
483
|
+
} else return null;
|
|
484
|
+
return base.endsWith(".dev") ? "dev" : base.endsWith(".prod") ? "prod" : null;
|
|
485
|
+
}
|
|
258
486
|
async function scanPages(root, options) {
|
|
259
487
|
const pagesDir = options?.pagesDir ?? options?.paths?.pagesDir ?? readProjectPaths(root).pagesDir;
|
|
260
488
|
if (!existsSync(pagesDir)) return {
|
|
@@ -270,11 +498,12 @@ async function scanPages(root, options) {
|
|
|
270
498
|
const pages = [];
|
|
271
499
|
const layouts = [];
|
|
272
500
|
const namedLayouts = [];
|
|
273
|
-
for (const file of files) {
|
|
501
|
+
for (const file of files.sort()) {
|
|
274
502
|
const segments = file.split("/");
|
|
275
503
|
if (segments.some((s) => s.startsWith("_") && s !== "_layouts")) continue;
|
|
276
504
|
const ext = extname(file);
|
|
277
505
|
let base = basename(file, ext);
|
|
506
|
+
if (base.endsWith(".server") && ROUTE_EXTENSIONS_SET.has(ext)) continue;
|
|
278
507
|
let island;
|
|
279
508
|
let hasIslandSuffix = false;
|
|
280
509
|
if (base.endsWith(".island")) {
|
|
@@ -302,8 +531,8 @@ async function scanPages(root, options) {
|
|
|
302
531
|
});
|
|
303
532
|
continue;
|
|
304
533
|
}
|
|
305
|
-
const
|
|
306
|
-
|
|
534
|
+
const route = parseRouteFilename(hasIslandSuffix ? file.replace(`.island${ext}`, ".ts") : file.replace(ext, ".ts"));
|
|
535
|
+
if (!isRouteEnabledForEnvironment(route, options?.environment)) continue;
|
|
307
536
|
const componentId = file.replace(ext, "").replace(/\.island$/, "").replace(/\/index$/, "").replace(/^index$/, "") || "index";
|
|
308
537
|
let serverPath = null;
|
|
309
538
|
const methods = [];
|
|
@@ -312,11 +541,11 @@ async function scanPages(root, options) {
|
|
|
312
541
|
let ssr;
|
|
313
542
|
let hasGetPrerenderPaths;
|
|
314
543
|
const serverBase = hasIslandSuffix ? file.replace(`.island${ext}`, "") : file.replace(ext, "");
|
|
315
|
-
for (const serverExt of
|
|
544
|
+
for (const serverExt of ROUTE_EXTENSIONS) {
|
|
316
545
|
const candidate = `${serverBase}.server.${serverExt}`;
|
|
317
546
|
if (existsSync(join(pagesDir, candidate))) {
|
|
318
547
|
serverPath = candidate;
|
|
319
|
-
const metadata =
|
|
548
|
+
const metadata = deriveFromSource(join(pagesDir, candidate), "page-server", (source) => detectPageServerMetadata(source, candidate));
|
|
320
549
|
methods.push(...metadata.methods);
|
|
321
550
|
revalidate = metadata.revalidate;
|
|
322
551
|
prerender = metadata.prerender;
|
|
@@ -338,11 +567,11 @@ async function scanPages(root, options) {
|
|
|
338
567
|
if (rendering.shouldPrerender && revalidate === void 0) revalidate = MAX_REVALIDATE;
|
|
339
568
|
let metadata;
|
|
340
569
|
let layout;
|
|
341
|
-
if (ext === ".md") {
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
570
|
+
if (ext === ".md") ({metadata, layout} = deriveFromSource(join(pagesDir, file), "page-markdown", (source) => ({
|
|
571
|
+
metadata: extractFrontmatterMeta(source),
|
|
572
|
+
layout: extractFrontmatterLayout(source)
|
|
573
|
+
})));
|
|
574
|
+
else layout = deriveFromSource(join(pagesDir, file), "page-layout", (source) => componentLayout(source, file));
|
|
346
575
|
pages.push({
|
|
347
576
|
pattern: route.pattern,
|
|
348
577
|
params: route.params,
|
|
@@ -357,8 +586,9 @@ async function scanPages(root, options) {
|
|
|
357
586
|
...rendering,
|
|
358
587
|
hasGetPrerenderPaths,
|
|
359
588
|
island,
|
|
360
|
-
metadata,
|
|
361
|
-
layout
|
|
589
|
+
metadata: metadata ? { ...metadata } : void 0,
|
|
590
|
+
layout,
|
|
591
|
+
...route.env ? { env: route.env } : {}
|
|
362
592
|
});
|
|
363
593
|
}
|
|
364
594
|
pages.sort((a, b) => {
|
|
@@ -367,6 +597,14 @@ async function scanPages(root, options) {
|
|
|
367
597
|
if (aDynamic !== b.pattern.includes(":")) return aDynamic ? 1 : -1;
|
|
368
598
|
return a.pattern.localeCompare(b.pattern);
|
|
369
599
|
});
|
|
600
|
+
if (options?.checkRoutes !== false) {
|
|
601
|
+
const environments = options?.environment ? [options.environment] : ["dev", "prod"];
|
|
602
|
+
for (const environment of environments) {
|
|
603
|
+
const live = pages.filter((page) => isRouteEnabledForEnvironment({ env: page.env ?? null }, environment));
|
|
604
|
+
assertOnePagePerRoute(live);
|
|
605
|
+
warnShadowedPages(pagesDir, live);
|
|
606
|
+
}
|
|
607
|
+
}
|
|
370
608
|
for (const page of pages) {
|
|
371
609
|
if (page.island) continue;
|
|
372
610
|
const dir = dirname(page.componentPath);
|
|
@@ -393,6 +631,47 @@ async function scanPages(root, options) {
|
|
|
393
631
|
namedLayouts
|
|
394
632
|
};
|
|
395
633
|
}
|
|
634
|
+
function compareText(left, right) {
|
|
635
|
+
return left < right ? -1 : left > right ? 1 : 0;
|
|
636
|
+
}
|
|
637
|
+
/** Group sorted pages by `key`, keeping only groups with more than one page. */
|
|
638
|
+
function pagesSharing(pages, key) {
|
|
639
|
+
const groups = /* @__PURE__ */ new Map();
|
|
640
|
+
for (const page of pages) {
|
|
641
|
+
const group = groups.get(key(page));
|
|
642
|
+
if (group) group.push(page);
|
|
643
|
+
else groups.set(key(page), [page]);
|
|
644
|
+
}
|
|
645
|
+
return [...groups.values()].filter((group) => group.length > 1);
|
|
646
|
+
}
|
|
647
|
+
/**
|
|
648
|
+
* Two files for one path have no stable winner: the server and the client can
|
|
649
|
+
* each pick a different one, and the order can change between runs.
|
|
650
|
+
*/
|
|
651
|
+
function assertOnePagePerRoute(pages) {
|
|
652
|
+
assertNoneShare(pages, (page) => page.pattern, "pages: Multiple page files resolve to the same route:", "Keep one page file per route and rename or remove the others.");
|
|
653
|
+
assertNoneShare(pages, (page) => page.componentId, "pages: Multiple page files resolve to the same page id:", "Rename or remove one of them.");
|
|
654
|
+
}
|
|
655
|
+
function assertNoneShare(pages, key, title, hint) {
|
|
656
|
+
const clashes = pagesSharing(pages, key).map((group) => ({
|
|
657
|
+
key: key(group[0]),
|
|
658
|
+
files: group.map((page) => page.componentPath).sort(compareText)
|
|
659
|
+
})).sort((left, right) => compareText(left.key, right.key)).map((clash) => ` ${JSON.stringify(clash.key)}: ${clash.files.map((file) => JSON.stringify(file)).join(", ")}`);
|
|
660
|
+
if (clashes.length > 0) throw new Error([
|
|
661
|
+
title,
|
|
662
|
+
...clashes,
|
|
663
|
+
hint
|
|
664
|
+
].join("\n"));
|
|
665
|
+
}
|
|
666
|
+
/** Dynamic routes that match the same URLs, such as [id] and [slug]: only the first is ever used. */
|
|
667
|
+
function warnShadowedPages(pagesDir, pages) {
|
|
668
|
+
for (const [used, ...shadowed] of pagesSharing(pages, (page) => patternToRegex(page.pattern))) for (const page of shadowed) {
|
|
669
|
+
const key = `${pagesDir}\0${used.componentPath}\0${page.componentPath}`;
|
|
670
|
+
if (warnedShadowedPages.has(key)) continue;
|
|
671
|
+
warnedShadowedPages.add(key);
|
|
672
|
+
voidWarn(`pages: Page '${page.componentPath}' (${page.pattern}) is never used: '${used.componentPath}' (${used.pattern}) matches the same URLs first. Remove one of them.`);
|
|
673
|
+
}
|
|
674
|
+
}
|
|
396
675
|
const LEADING_SCRIPT_RE = /^<script\b[^>]*>[\s\S]*?<\/script>\s*\n?/;
|
|
397
676
|
/** Return the raw YAML frontmatter of markdown source, after any leading <script> block. */
|
|
398
677
|
function markdownFrontmatter(source) {
|
|
@@ -424,4 +703,4 @@ function extractFrontmatterLayout(source) {
|
|
|
424
703
|
return value;
|
|
425
704
|
}
|
|
426
705
|
//#endregion
|
|
427
|
-
export {
|
|
706
|
+
export { resolveLayoutChain as a, editIslandSource as c, deriveFromSource as d, invalidateSourceAnalysis as f, ROUTE_EXTENSIONS as g, parseWebSocketFilename as h, resolveEffectiveLayoutChain as i, findIslandImports as l, parseRouteFilename as m, scanPages as n, resolveLayoutIds as o, isRouteEnabledForEnvironment as p, generateComponentManifest as r, resolveNamedLayout as s, pageFileEnvironment as t, findStaticCssImports as u };
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { n as readDeploymentPlatform, r as readProjectConfig } from "./project-rqDnVsJN.mjs";
|
|
2
2
|
import { c as getToken } from "./auth-B6iOCjKI.mjs";
|
|
3
3
|
import { A as confirm, H as outro, L as log, O as cancel, U as password, tt as isCancel } from "./dist-Cor9XGoz.mjs";
|
|
4
|
-
import { r as PlatformClient } from "./client-
|
|
4
|
+
import { r as PlatformClient } from "./client-BEMtySaV.mjs";
|
|
5
5
|
import { m as printSuccess, o as formatCount, p as note } from "./output-BpgYODYx.mjs";
|
|
6
6
|
import { a as resolveProjectBySlug, t as getRequestedProjectSlug } from "./resolve-project-Xoi6eTWY.mjs";
|
|
7
|
-
import { _ as validateSecretValues } from "./env-validation-
|
|
7
|
+
import { _ as validateSecretValues } from "./env-validation-XcukUlFM.mjs";
|
|
8
8
|
import { readFileSync } from "node:fs";
|
|
9
9
|
//#region src/cli/secret.ts
|
|
10
10
|
async function runSecretCommand(root, args) {
|
|
@@ -93,7 +93,7 @@ async function resolveSecretBackend(root, args) {
|
|
|
93
93
|
}
|
|
94
94
|
async function resolveCloudflareSecretBackend(root, args) {
|
|
95
95
|
if (args.projectName) throw new Error("secret: --project selects a Void platform project and is not used for direct Cloudflare apps.");
|
|
96
|
-
const { deleteCloudflareSecret, listCloudflareSecrets, putCloudflareSecret, resolveCloudflareOperationContext, syncCloudflareSecrets } = await import("./cloudflare-operations-
|
|
96
|
+
const { deleteCloudflareSecret, listCloudflareSecrets, putCloudflareSecret, resolveCloudflareOperationContext, syncCloudflareSecrets } = await import("./cloudflare-operations-PCM4wucv.mjs");
|
|
97
97
|
const context = resolveCloudflareOperationContext(root);
|
|
98
98
|
return {
|
|
99
99
|
target: "Cloudflare Worker",
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
//#region src/runtime/static-asset-marker.ts
|
|
2
|
+
const STATIC_ASSET_KEY = "__voidStaticAsset";
|
|
3
|
+
/**
|
|
4
|
+
* Records that the fallback answered with a file from the ASSETS binding: the
|
|
5
|
+
* Cache-Control it carried and its body stream. The value lives on the
|
|
6
|
+
* context, not on the response object: `c.header()` after the handler rebuilds
|
|
7
|
+
* `c.res`, so a response identity check would miss the file. The rebuild keeps
|
|
8
|
+
* the body stream, while a middleware that swaps the body does not.
|
|
9
|
+
*/
|
|
10
|
+
function markStaticAsset(c, response) {
|
|
11
|
+
const mark = {
|
|
12
|
+
policy: response.headers.get("cache-control") ?? "",
|
|
13
|
+
body: response.body
|
|
14
|
+
};
|
|
15
|
+
c.set(STATIC_ASSET_KEY, mark);
|
|
16
|
+
return response;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* True when the final response is still the marked file: a success status, the
|
|
20
|
+
* same body and Cache-Control the fallback served, and no cookie added by
|
|
21
|
+
* later middleware.
|
|
22
|
+
*/
|
|
23
|
+
function isUnchangedStaticAsset(c) {
|
|
24
|
+
const mark = c.get(STATIC_ASSET_KEY);
|
|
25
|
+
return mark !== void 0 && [
|
|
26
|
+
200,
|
|
27
|
+
206,
|
|
28
|
+
304
|
|
29
|
+
].includes(c.res.status) && c.res.body === mark.body && (c.res.headers.get("cache-control") ?? "") === mark.policy && !c.res.headers.has("set-cookie");
|
|
30
|
+
}
|
|
31
|
+
//#endregion
|
|
32
|
+
export { markStaticAsset as n, isUnchangedStaticAsset as t };
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
//#region src/router/parse-filename.d.ts
|
|
2
|
+
type RouteEnvironment = "dev" | "prod";
|
|
3
|
+
//#endregion
|
|
1
4
|
//#region src/pages/types.d.ts
|
|
2
5
|
type ExplicitBoolean = true | false | undefined;
|
|
3
6
|
type SsrMode = "auto" | "server" | "client";
|
|
@@ -43,6 +46,8 @@ type PageDefinition = {
|
|
|
43
46
|
};
|
|
44
47
|
/** Named layout selection: "name", "!name", or false */
|
|
45
48
|
layout?: string | false;
|
|
49
|
+
/** Environment from a `.dev` / `.prod` file suffix. Unset means both. */
|
|
50
|
+
env?: RouteEnvironment;
|
|
46
51
|
};
|
|
47
52
|
type LayoutDefinition = {
|
|
48
53
|
/** Directory path relative to pages/, e.g. "" (root) or "users" */
|
|
@@ -76,4 +81,4 @@ type DevCssAsset = {
|
|
|
76
81
|
css: string;
|
|
77
82
|
};
|
|
78
83
|
//#endregion
|
|
79
|
-
export { PageRenderMode as a, PageDefinition as i, LayoutDefinition as n, PageScanResult as o, NamedLayoutDefinition as r, DevCssAsset as t };
|
|
84
|
+
export { PageRenderMode as a, PageDefinition as i, LayoutDefinition as n, PageScanResult as o, NamedLayoutDefinition as r, RouteEnvironment as s, DevCssAsset as t };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { a as join } from "./dist-ipQi0Q8y.mjs";
|
|
2
|
-
import { l as bindingNamesForField, p as findBindingNameOwner } from "./wrangler-
|
|
2
|
+
import { l as bindingNamesForField, p as findBindingNameOwner } from "./wrangler-CDiEBCdS.mjs";
|
|
3
3
|
//#region src/shared/untrusted-env.ts
|
|
4
4
|
/** Authentication inputs that Wrangler may consume from the environment. */
|
|
5
5
|
const WRANGLER_AUTH_CREDENTIAL_ENV_VARS = [
|
|
@@ -666,9 +666,10 @@ function writeProvisionedWranglerConfig(root, patch, options) {
|
|
|
666
666
|
const matches = [];
|
|
667
667
|
for (let i = 0; i < currentList.length; i++) if (currentList[i].binding === entry.binding) matches.push(i);
|
|
668
668
|
if (matches.length > 1) throw new Error(`deploy: cannot update "${configPath}" — queue producer binding ${JSON.stringify(entry.binding)} is declared ${matches.length} times across producers. A producer binding must map to exactly one queue, so wrangler rejects this config. Remove the duplicate producers and retry.`);
|
|
669
|
+
const voidOwned = reconcileManagedQueues && managedProducerBindings.has(String(entry.binding));
|
|
669
670
|
if (matches.length === 1) {
|
|
670
671
|
const existing = currentList[matches[0]];
|
|
671
|
-
if (existing.queue !== entry.queue) throw new Error(`deploy: cannot update "${configPath}" — queue producer binding ${JSON.stringify(entry.binding)} is already bound to queue ${JSON.stringify(existing.queue)}, but queue ${JSON.stringify(entry.queue)} also requests it. A producer binding must map to exactly one queue. Rename or remove the conflicting producer and retry.`);
|
|
672
|
+
if (existing.queue !== entry.queue && !voidOwned) throw new Error(`deploy: cannot update "${configPath}" — queue producer binding ${JSON.stringify(entry.binding)} is already bound to queue ${JSON.stringify(existing.queue)}, but queue ${JSON.stringify(entry.queue)} also requests it. A producer binding must map to exactly one queue. Rename or remove the conflicting producer and retry.`);
|
|
672
673
|
}
|
|
673
674
|
index = matches.length === 1 ? matches[0] : -1;
|
|
674
675
|
workerBindingOwners ??= collectWorkerBindingNames(parseJsonc(text));
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { b as readRootWranglerConfig } from "./wrangler-CDiEBCdS.mjs";
|