void 1.1.11 → 1.1.12

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.
Files changed (152) hide show
  1. package/dist/{account-cmd-R35a4Oa8.mjs → account-cmd-Cj6sCMTk.mjs} +4 -4
  2. package/dist/{auth-link-VHmiKZmP.mjs → auth-link-Dj7lAC_K.mjs} +4 -4
  3. package/dist/{auth-router-O_Wrs5kg.mjs → auth-router-CNsMOFCa.mjs} +2 -2
  4. package/dist/{build-cmd-CMZiMn46.mjs → build-cmd-ByhegwRC.mjs} +2 -2
  5. package/dist/{cache-TZ5Ab3d7.mjs → cache-CEFb5ban.mjs} +2 -2
  6. package/dist/{cancel-deploy-DXoR6oC3.mjs → cancel-deploy-CaARY26n.mjs} +2 -2
  7. package/dist/{cf-build-output-Bc8i3dzE.mjs → cf-build-output-ChEKWan2.mjs} +71 -7
  8. package/dist/cf-build-output-Dcmxa-Zm.mjs +1 -0
  9. package/dist/{cf-user-agent-ChjQp2MU.mjs → cf-command-values-b8OqDoo9.mjs} +5 -16
  10. package/dist/cf-user-agent-BkEHPDLA.mjs +16 -0
  11. package/dist/cli/cli.mjs +135 -31
  12. package/dist/cli/cloudflare-operation-process.mjs +46 -9
  13. package/dist/{client-GuSO3v_x.mjs → client-BdzxubTS.mjs} +57 -12
  14. package/dist/client-DAnfyMe9.mjs +1 -0
  15. package/dist/{cloudflare-cmd-ZSErUl6Y.mjs → cloudflare-cmd-D_2-Q-_i.mjs} +1 -1
  16. package/dist/{cloudflare-operations-Cm8lVx7W.mjs → cloudflare-operations-BFLCpUCV.mjs} +1 -1
  17. package/dist/{cloudflare-operations-DH3GedbV.mjs → cloudflare-operations-D5PLrOqD.mjs} +14 -4
  18. package/dist/{connect-yQuLbuiJ.mjs → connect-C4_m2moF.mjs} +4 -4
  19. package/dist/{create-project-CGOo_OL_.mjs → create-project-CvuYDD-l.mjs} +1 -1
  20. package/dist/{create-project-DEEWJX_M.mjs → create-project-D8jQTwVQ.mjs} +2 -2
  21. package/dist/{db-COI-yTJE.mjs → db-BsiOAa0A.mjs} +58 -8
  22. package/dist/{delete-PgN6L_9N.mjs → delete-CAma7nFi.mjs} +2 -2
  23. package/dist/{deploy-DsW-PrRQ.mjs → deploy-D1gIPiAq.mjs} +118 -36
  24. package/dist/deploy-Dc0XsCQj.mjs +2 -0
  25. package/dist/{deploy-managed-static-Dqz06S2u.mjs → deploy-managed-static-B9KVxY3X.mjs} +64 -18
  26. package/dist/{deploy-transport-nY3vLXPL.mjs → deploy-transport-B3mtEi_q.mjs} +1 -1
  27. package/dist/deploy.d.mts +22 -1
  28. package/dist/deploy.mjs +45 -4
  29. package/dist/{domain-DKlNI0SR.mjs → domain-BAdwm-QS.mjs} +3 -3
  30. package/dist/{email-C0s3OvJk.mjs → email-MwjA7kaL.mjs} +4 -4
  31. package/dist/{env-BX2JFsgF.mjs → env-B163-G1s.mjs} +3 -3
  32. package/dist/{fetch-DHLOuPyk.d.mts → fetch-CUX0tB78.d.mts} +14 -1
  33. package/dist/fetch-CtESUYWd.mjs +26 -0
  34. package/dist/{fetch-error-Dj3crt0e.mjs → fetch-error-Bw0n-IY-.mjs} +1 -1
  35. package/dist/{fetch-stream-PGgz4uGz.mjs → fetch-stream-BspOeTAI.mjs} +1 -1
  36. package/dist/{fetch-stream-CNxOrBdP.d.mts → fetch-stream-DfkAzZf-.d.mts} +1 -1
  37. package/dist/{gen-Bj6ZkOcI.mjs → gen-CYN3wiov.mjs} +1 -1
  38. package/dist/gen-Cf-RBVg4.mjs +1 -0
  39. package/dist/{github-cmd-DQDryS-5.mjs → github-cmd-C8QsnJQs.mjs} +2 -2
  40. package/dist/{handler-_PqY82xe.d.mts → handler-D5K_yP6T.d.mts} +1 -1
  41. package/dist/{help-D49SL_lN.mjs → help-B2sFwn9b.mjs} +44 -3
  42. package/dist/help-w-xlx_kq.mjs +1 -0
  43. package/dist/index.d.mts +1 -1
  44. package/dist/index.mjs +38 -71
  45. package/dist/{init-DyTEY04s.mjs → init-DGFQMnbk.mjs} +6 -6
  46. package/dist/{link-CgOVn9EC.mjs → link-CwrfpjIM.mjs} +3 -3
  47. package/dist/{list-CUfD9RSb.mjs → list-hKoW5z-b.mjs} +3 -3
  48. package/dist/{live-DJONVlQK.d.mts → live-JheIDZKc.d.mts} +1 -1
  49. package/dist/login-08mBwZfI.mjs +1 -0
  50. package/dist/{login-BJvGW5Eu.mjs → login-f2eu2TQh.mjs} +3 -3
  51. package/dist/{logs-DeizBI4j.mjs → logs-CEWqD-_B.mjs} +3 -3
  52. package/dist/{migrate-8rk56vV8.mjs → migrate-DYfdWBXt.mjs} +1 -1
  53. package/dist/migrate-Di-4EuoE.mjs +1 -0
  54. package/dist/nitro.mjs +1 -1
  55. package/dist/operator-cmd-Bv20yLu2.mjs +1 -0
  56. package/dist/{operator-cmd-CA5QQyvE.mjs → operator-cmd-DCr_QGMH.mjs} +4 -4
  57. package/dist/{output-Ba6ZbrzY.mjs → output-CKguMgr7.mjs} +13 -1
  58. package/dist/pages/client.d.mts +2 -2
  59. package/dist/pages/client.mjs +18 -5
  60. package/dist/pages/index.d.mts +1 -1
  61. package/dist/pages/index.mjs +1 -1
  62. package/dist/pages/islands-plugin.d.mts +43 -5
  63. package/dist/pages/islands-plugin.mjs +98 -27
  64. package/dist/pages/protocol.d.mts +2 -2
  65. package/dist/pages/protocol.mjs +1 -1
  66. package/dist/pages/serialize.d.mts +2 -2
  67. package/dist/pages/serialize.mjs +1 -1
  68. package/dist/{platform-auth-config-CZaY812e.mjs → platform-auth-config-qGvEuns3.mjs} +5 -5
  69. package/dist/{platform-auth-protection-U9HCqoXv.mjs → platform-auth-protection-CyLcD6ot.mjs} +3 -3
  70. package/dist/{platform-auth-recovery-B0BV2hfV.mjs → platform-auth-recovery-B2LKI8V2.mjs} +3 -3
  71. package/dist/{platform-cmd-D9lwFpcl.mjs → platform-cmd-B2ec5eFg.mjs} +1 -1
  72. package/dist/{platform-cmd-CXrjk4fb.mjs → platform-cmd-CX7phm7V.mjs} +5 -5
  73. package/dist/{platform-domain-CXyq-68_.mjs → platform-domain-DDNK2y-4.mjs} +3 -3
  74. package/dist/{platform-lifecycle-D0TdyXbN.mjs → platform-lifecycle-3CR98Tg2.mjs} +386 -36
  75. package/dist/{platform-lifecycle-Dz2cJsLX.mjs → platform-lifecycle-CWc5gr6c.mjs} +1 -1
  76. package/dist/{platform-management-BvgbusqL.mjs → platform-management-DAE6g2QU.mjs} +1 -1
  77. package/dist/{platform-management-CnXhgxTM.mjs → platform-management-o3LCCeE4.mjs} +40 -2
  78. package/dist/{platform-plans-config-BWn1S2Rv.mjs → platform-plans-config-CBMZxCep.mjs} +1 -1
  79. package/dist/{platform-recovery-CH_fThW6.mjs → platform-recovery-Dmsg7lWA.mjs} +2 -2
  80. package/dist/{platform-setup-YvN9VQXV.mjs → platform-setup-hFbnWAVQ.mjs} +1 -1
  81. package/dist/{prepare-2XD6kh77.mjs → prepare-HKo7Rh5V.mjs} +1 -1
  82. package/dist/{project-cmd-CpLYflCH.mjs → project-cmd-8ylYGx-O.mjs} +17 -17
  83. package/dist/{project-team-CTSY7W7Q.mjs → project-team-Bvpl78we.mjs} +2 -2
  84. package/dist/{project-token-Cybtlfbl.mjs → project-token-QWHoJH2t.mjs} +2 -2
  85. package/dist/{project-zero-trust-DKOtqyvu.mjs → project-zero-trust-8tJ-RFvu.mjs} +2 -2
  86. package/dist/{protocol-B8sI8dRD.d.mts → protocol-Ssc_LhHj.d.mts} +1 -1
  87. package/dist/{protocol-RNP0u7UY.mjs → protocol-bAUUkx70.mjs} +1 -1
  88. package/dist/{provision-UcYjpTRh.mjs → provision-BgXFDv0d.mjs} +1 -1
  89. package/dist/{provision-BuifYvLc.mjs → provision-DZKYCEJg.mjs} +3 -2
  90. package/dist/{requests-Ryiazz9i.mjs → requests-Vk5Zyhcy.mjs} +2 -2
  91. package/dist/{rollback-Or0EV3rP.mjs → rollback-CH4yMQys.mjs} +9 -8
  92. package/dist/runtime/client-react.d.mts +2 -2
  93. package/dist/runtime/client-react.mjs +3 -3
  94. package/dist/runtime/client-solid.d.mts +2 -2
  95. package/dist/runtime/client-solid.mjs +3 -3
  96. package/dist/runtime/client-svelte.d.mts +2 -2
  97. package/dist/runtime/client-svelte.mjs +3 -3
  98. package/dist/runtime/client-vue.d.mts +2 -2
  99. package/dist/runtime/client-vue.mjs +3 -3
  100. package/dist/runtime/client.d.mts +2 -2
  101. package/dist/runtime/client.mjs +3 -3
  102. package/dist/runtime/fetch-server.d.mts +8 -0
  103. package/dist/runtime/fetch-server.mjs +30 -0
  104. package/dist/runtime/fetch-stream.d.mts +2 -2
  105. package/dist/runtime/fetch-stream.mjs +2 -2
  106. package/dist/runtime/fetch.d.mts +2 -2
  107. package/dist/runtime/fetch.mjs +3 -3
  108. package/dist/runtime/handler.d.mts +1 -1
  109. package/dist/runtime/live-client.d.mts +1 -1
  110. package/dist/runtime/live.d.mts +1 -1
  111. package/dist/runtime/routing.d.mts +1 -1
  112. package/dist/runtime/routing.mjs +1 -1
  113. package/dist/runtime/validator.d.mts +1 -1
  114. package/dist/runtime/ws-server.d.mts +1 -1
  115. package/dist/runtime/ws.d.mts +1 -1
  116. package/dist/{secret-CClHaFxm.mjs → secret-wr6Sn4Xa.mjs} +3 -3
  117. package/dist/serialize-DtR8Vwa_.d.mts +18 -0
  118. package/dist/serialize-YHvlcG3Q.mjs +31 -0
  119. package/dist/{subcommand-prompt-Bm3ZlYgA.mjs → subcommand-prompt-CNZc4XUd.mjs} +1 -1
  120. package/dist/{wrapper-BOigE1xJ.mjs → wrapper-DGsYwNi6.mjs} +2 -0
  121. package/dist/{ws-CsBNxv86.d.mts → ws-nnFnAyQb.d.mts} +1 -1
  122. package/docs/guide/deployment.md +2 -0
  123. package/docs/guide/edge/headers.md +1 -1
  124. package/docs/guide/email/receiving.md +1 -1
  125. package/docs/guide/email/sending.md +3 -3
  126. package/docs/guide/pages-routing/markdown.md +3 -1
  127. package/docs/guide/platform/administration/email.md +7 -1
  128. package/docs/guide/platform/installation/ci.md +2 -0
  129. package/docs/guide/platform/installation/credentials.md +23 -5
  130. package/docs/guide/platform/installation/maintenance.md +32 -2
  131. package/docs/guide/platform/installation/setup.md +1 -1
  132. package/docs/guide/typed-fetch.md +1 -1
  133. package/docs/integrations/cloudflare.md +1 -1
  134. package/docs/integrations/frameworks/tanstack-start.md +25 -0
  135. package/docs/reference/api/deploy.md +35 -3
  136. package/docs/reference/cli/database.md +15 -0
  137. package/docs/reference/cli/platform-installation.md +2 -0
  138. package/docs/reference/cli/project.md +4 -2
  139. package/docs/reference/cli.md +1 -0
  140. package/docs/reference/config.md +1 -1
  141. package/package.json +8 -7
  142. package/dist/cf-build-output-BU3hqdHu.mjs +0 -1
  143. package/dist/client-DrdeJgHR.mjs +0 -1
  144. package/dist/deploy-CxNgEYr4.mjs +0 -2
  145. package/dist/fetch-sAcwjzLO.mjs +0 -18
  146. package/dist/gen-DsCukhuw.mjs +0 -1
  147. package/dist/help-DOFygYi4.mjs +0 -1
  148. package/dist/login-alAlxw4S.mjs +0 -1
  149. package/dist/migrate-D2odrAmh.mjs +0 -1
  150. package/dist/operator-cmd-D7toMPJ9.mjs +0 -1
  151. package/dist/serialize-BtQyaYoC.mjs +0 -20
  152. package/dist/serialize-CfSwWfF2.d.mts +0 -10
@@ -1,3 +1,4 @@
1
+ import { t as ISLAND_FRONTMATTER_ID } from "../serialize-YHvlcG3Q.mjs";
1
2
  import { t as interpolateRouteParams } from "../route-url-BjGv_KKY.mjs";
2
3
  import { n as parseCacheFor, t as PrefetchCache } from "../prefetch-Bsc_Pb6c.mjs";
3
4
  import { readUsageLimit } from "@void/edge";
@@ -245,6 +246,15 @@ function createScrollRestoration() {
245
246
  };
246
247
  }
247
248
  //#endregion
249
+ //#region src/pages/url.ts
250
+ function isSameOrigin(url, origin) {
251
+ if (url.protocol === "capacitor:") {
252
+ const current = new URL(origin);
253
+ return current.protocol === "capacitor:" && url.host !== "" && url.host === current.host;
254
+ }
255
+ return url.origin === origin;
256
+ }
257
+ //#endregion
248
258
  //#region src/pages/navigation-engine.ts
249
259
  const PAGE_DATA_SCRIPT_ID = "__VOID_PAGE_DATA__";
250
260
  const STATIC_PAGE_DATA_PREFIX = "/_void/pages";
@@ -541,8 +551,8 @@ async function createPageNavigationEngine(config) {
541
551
  }
542
552
  async function loadNavigationShell(id, url, fetchUrl, method, options, signal, commitTarget, deferredRegistry) {
543
553
  const target = new URL(url, window.location.origin);
544
- if (target.protocol !== "http:" && target.protocol !== "https:") throw new Error(`Void Router: refusing to navigate to a ${target.protocol} URL.`);
545
- if (target.origin !== window.location.origin) {
554
+ if (target.protocol !== "http:" && target.protocol !== "https:" && target.protocol !== "capacitor:") throw new Error(`Void Router: refusing to navigate to a ${target.protocol} URL.`);
555
+ if (!isSameOrigin(target, window.location.origin)) {
546
556
  if (method !== "GET") throw new Error("Void Router: non-GET visits must target the current origin.");
547
557
  window.location.href = url;
548
558
  return;
@@ -596,7 +606,7 @@ async function createPageNavigationEngine(config) {
596
606
  }
597
607
  if (response?.redirected) {
598
608
  const redirectUrl = new URL(response.url, window.location.origin);
599
- if (redirectUrl.origin !== window.location.origin) {
609
+ if (!isSameOrigin(redirectUrl, window.location.origin)) {
600
610
  window.location.href = method === "GET" ? url : response.url;
601
611
  return;
602
612
  }
@@ -960,7 +970,7 @@ function toUrl(value) {
960
970
  function normalizeUrl(value) {
961
971
  if (typeof value === "string" && value.startsWith("#")) return value;
962
972
  const url = toUrl(value);
963
- return url.origin === getUrlOrigin() ? url.pathname + url.search + url.hash : url.href;
973
+ return isSameOrigin(url, getUrlOrigin()) ? url.pathname + url.search + url.hash : url.href;
964
974
  }
965
975
  function navigationMethod(method) {
966
976
  const normalized = method.toUpperCase();
@@ -1206,12 +1216,15 @@ function scheduleHydration(el, loader, props, strategy, hydrateFn) {
1206
1216
  }
1207
1217
  }
1208
1218
  function initIslands(islands, hydrateFn) {
1219
+ const frontmatterText = document.getElementById(ISLAND_FRONTMATTER_ID)?.textContent;
1220
+ const frontmatter = frontmatterText ? JSON.parse(frontmatterText) : {};
1221
+ const hydrate = (el, mod, props) => hydrateFn(el, mod, props, frontmatter);
1209
1222
  document.querySelectorAll("[data-island]").forEach((el) => {
1210
1223
  const id = el.getAttribute("data-island");
1211
1224
  const props = JSON.parse(el.getAttribute("data-props") || "{}");
1212
1225
  const strategy = el.getAttribute("data-hydrate") || "load";
1213
1226
  const loader = islands[id];
1214
- if (loader) scheduleHydration(el, loader, props, strategy, hydrateFn);
1227
+ if (loader) scheduleHydration(el, loader, props, strategy, hydrate);
1215
1228
  });
1216
1229
  }
1217
1230
  //#endregion
@@ -1,7 +1,7 @@
1
1
  import { a as renderHtmlAttrs, i as renderHeadToString, n as HeadDescriptor, o as resolveHead, r as renderBodyAttrs, t as HeadConfig } from "../head-C8K_iGe6.mjs";
2
2
  import "../config-7qoq2p9v.mjs";
3
3
  import { i as PageDefinition, n as LayoutDefinition, o as PageScanResult, r as NamedLayoutDefinition } from "../types-7AIz0OZu.mjs";
4
- import { t as serializePageData } from "../serialize-CfSwWfF2.mjs";
4
+ import { r as serializePageData } from "../serialize-DtR8Vwa_.mjs";
5
5
  //#region src/project-paths.d.ts
6
6
  type ProjectPaths = {
7
7
  root: string;
@@ -4,7 +4,7 @@ import { d as readConfig } from "../config-D26zcdKy.mjs";
4
4
  import { a as resolveNamedLayout, i as resolveLayoutIds, n as resolveEffectiveLayoutChain, o as toLayoutId, r as resolveLayoutChain, t as scanPages } from "../scan-D2-FcLHs.mjs";
5
5
  import { r as parseRedirectsFile } from "../headers-Bi4bOAwp.mjs";
6
6
  import { i as resolveHead, n as renderHeadToString, r as renderHtmlAttrs, t as renderBodyAttrs } from "../head-D2VF4ApL.mjs";
7
- import { t as serializePageData } from "../serialize-BtQyaYoC.mjs";
7
+ import { r as serializePageData } from "../serialize-YHvlcG3Q.mjs";
8
8
  //#region src/pages/manifest.ts
9
9
  /**
10
10
  * Generates the component import map and layout tree as code strings.
@@ -1,5 +1,5 @@
1
1
  import { o as PageScanResult } from "../types-7AIz0OZu.mjs";
2
- import { ResolvedConfig, ViteDevServer } from "vite";
2
+ import { Plugin, ResolvedConfig, ViteDevServer } from "vite";
3
3
  //#region ../../node_modules/.pnpm/magic-string@1.4.3/node_modules/magic-string/dist/index.d.mts
4
4
  //#region src/SourceMap.d.ts
5
5
  interface SourceMapOptions {
@@ -290,11 +290,49 @@ export type IslandEntry = {
290
290
  /** Resolve a relative import specifier to an absolute path by checking extensions. */
291
291
  export declare function resolveSpecifier(specifier: string, importerDir: string, extensions: Array<string>): string | null;
292
292
  /**
293
- * Check whether the islands client bundle is needed by scanning file contents.
294
- * Returns true if any island/layout file has island imports or CSS,
295
- * or any .md file has a `<script>` block.
293
+ * Whether the app has island pages (`*.island.*` files or Markdown). Their
294
+ * layouts can reach a stylesheet through a component, which only the module
295
+ * graph shows, so the islands client entry is built for every such app.
296
296
  */
297
- export declare function needsIslandClientBundle(dir: string, islandFilePattern: RegExp, checkStyleBlocks: boolean): boolean;
297
+ export declare function hasIslandPages(root: string, pagesDir: string): Promise<boolean>;
298
+ /**
299
+ * The layouts of every island page, outermost first, then the pages. All
300
+ * island pages share one production stylesheet, so layout styles come first.
301
+ */
302
+ export declare function islandStyleRoots(pageScan: PageScanResult, pagesDir: string): Array<string>;
303
+ type ModuleImports = {
304
+ importedIds: ReadonlyArray<string>;
305
+ };
306
+ /**
307
+ * Stylesheets the roots reach through static imports, in import order (like
308
+ * the dev CSS collector). Returns null when the roots are not in the graph.
309
+ * The walk also enters island components, as dev does: a layout can render
310
+ * one without hydrating it, and a page links its styles before it hydrates.
311
+ */
312
+ export declare function collectIslandStyles(getModuleInfo: (id: string) => ModuleImports | null, roots: ReadonlyArray<string>): Array<string> | null;
313
+ type IslandBuildContext = {
314
+ environment?: {
315
+ config: {
316
+ consumer: string;
317
+ };
318
+ };
319
+ getModuleInfo(id: string): ModuleImports | null;
320
+ };
321
+ /**
322
+ * Call from `buildEnd`. Island pages render only on the server, so the server
323
+ * build has resolved their imports (aliases, packages, Vue and Svelte style
324
+ * blocks) and the client build has not. Records the stylesheets of island pages
325
+ * and their layouts for the islands client entry, which builds after it.
326
+ */
327
+ export declare function recordIslandStyles(context: IslandBuildContext, pageScan: PageScanResult | null, pagesDir: string): void;
328
+ /** The stylesheets that the server build recorded, or null without a server build. */
329
+ export declare function recordedIslandStyles(pagesDir: string): ReadonlyArray<string> | null;
330
+ /**
331
+ * Keeps the CSS modules (`*.module.css`, Vue `<style module>`) that the
332
+ * islands client entry imports. Vite marks a CSS module as free of side
333
+ * effects, so the entry's bare import would drop it and its rules.
334
+ */
335
+ export declare function islandStylesPlugin(pagesDir: string): Plugin;
298
336
  /**
299
337
  * Rewrite a matched CSS import line so relative specifiers resolve from the
300
338
  * virtual module. Absolute and bare specifiers are kept as-is.
@@ -1,7 +1,7 @@
1
1
  import { c as resolve, n as dirname } from "../dist-ipQi0Q8y.mjs";
2
2
  import { c as findIslandImports, l as findStaticCssImports, n as resolveEffectiveLayoutChain, s as editIslandSource, t as scanPages } from "../scan-D2-FcLHs.mjs";
3
- import { existsSync, readFileSync, readdirSync } from "node:fs";
4
- import { normalizePath } from "vite";
3
+ import { existsSync, readFileSync } from "node:fs";
4
+ import { isCSSRequest, normalizePath } from "vite";
5
5
  //#region src/pages/islands-plugin.ts
6
6
  const ISLANDS_RENDERER_ID = "virtual:void-islands-renderer";
7
7
  const ISLANDS_CLIENT_ENTRY_ID = "virtual:void-islands-client";
@@ -16,34 +16,105 @@ function resolveSpecifier(specifier, importerDir, extensions) {
16
16
  return null;
17
17
  }
18
18
  /**
19
- * Check whether the islands client bundle is needed by scanning file contents.
20
- * Returns true if any island/layout file has island imports or CSS,
21
- * or any .md file has a `<script>` block.
19
+ * Whether the app has island pages (`*.island.*` files or Markdown). Their
20
+ * layouts can reach a stylesheet through a component, which only the module
21
+ * graph shows, so the islands client entry is built for every such app.
22
22
  */
23
- function needsIslandClientBundle(dir, islandFilePattern, checkStyleBlocks) {
24
- const cssImportRe = /import\b[^"']*["'][^"']+\.(?:css|scss|sass|less|styl|stylus|pcss|postcss)["']/;
25
- const mdScriptRe = /^<script\b/m;
26
- const styleRe = checkStyleBlocks ? /<style\b/ : null;
23
+ async function hasIslandPages(root, pagesDir) {
24
+ if (!existsSync(pagesDir)) return false;
27
25
  try {
28
- for (const entry of readdirSync(dir, {
29
- withFileTypes: true,
30
- recursive: true
31
- })) {
32
- if (!entry.isFile()) continue;
33
- const name = entry.name;
34
- if (islandFilePattern.test(name) || name.startsWith("layout.") || name.startsWith("_")) {
35
- const content = readFileSync(resolve(entry.parentPath, name), "utf-8");
36
- if (hasIslandImports(content, name)) return true;
37
- if (styleRe && styleRe.test(content)) return true;
38
- if (cssImportRe.test(content)) return true;
39
- }
40
- if (name.endsWith(".md")) {
41
- const content = readFileSync(resolve(entry.parentPath, name), "utf-8");
42
- if (mdScriptRe.test(content)) return true;
26
+ return (await scanPages(root, { pagesDir })).pages.some((page) => page.island);
27
+ } catch {
28
+ return false;
29
+ }
30
+ }
31
+ /**
32
+ * The layouts of every island page, outermost first, then the pages. All
33
+ * island pages share one production stylesheet, so layout styles come first.
34
+ */
35
+ function islandStyleRoots(pageScan, pagesDir) {
36
+ const layouts = /* @__PURE__ */ new Set();
37
+ const pages = [];
38
+ for (const page of pageScan.pages) {
39
+ if (!page.island) continue;
40
+ for (const layout of resolveEffectiveLayoutChain(page, pageScan.layouts, pageScan.namedLayouts)) layouts.add(normalizePath(resolve(pagesDir, layout.filePath)));
41
+ pages.push(normalizePath(resolve(pagesDir, page.componentPath)));
42
+ }
43
+ return [...layouts, ...pages];
44
+ }
45
+ /** A stylesheet that a page links, not one imported as a string or a URL. */
46
+ function isLinkedStylesheet(id) {
47
+ if (!isCSSRequest(id)) return false;
48
+ const query = id.indexOf("?");
49
+ if (query === -1) return true;
50
+ for (const param of id.slice(query + 1).split("&")) {
51
+ const key = param.split("=")[0];
52
+ if (key === "inline" || key === "url" || key === "raw") return false;
53
+ }
54
+ return true;
55
+ }
56
+ /**
57
+ * Stylesheets the roots reach through static imports, in import order (like
58
+ * the dev CSS collector). Returns null when the roots are not in the graph.
59
+ * The walk also enters island components, as dev does: a layout can render
60
+ * one without hydrating it, and a page links its styles before it hydrates.
61
+ */
62
+ function collectIslandStyles(getModuleInfo, roots) {
63
+ if (!roots.some((root) => getModuleInfo(root))) return null;
64
+ const styles = [];
65
+ const seen = /* @__PURE__ */ new Set();
66
+ const pending = [...roots].reverse();
67
+ while (pending.length > 0) {
68
+ const id = pending.pop();
69
+ if (seen.has(id)) continue;
70
+ seen.add(id);
71
+ if (isLinkedStylesheet(id)) {
72
+ if (!id.startsWith("\0")) styles.push(id);
73
+ continue;
74
+ }
75
+ const imported = getModuleInfo(id)?.importedIds ?? [];
76
+ for (let index = imported.length - 1; index >= 0; index--) pending.push(imported[index]);
77
+ }
78
+ return styles;
79
+ }
80
+ const islandStylesByPagesDir = /* @__PURE__ */ new Map();
81
+ /**
82
+ * Call from `buildEnd`. Island pages render only on the server, so the server
83
+ * build has resolved their imports (aliases, packages, Vue and Svelte style
84
+ * blocks) and the client build has not. Records the stylesheets of island pages
85
+ * and their layouts for the islands client entry, which builds after it.
86
+ */
87
+ function recordIslandStyles(context, pageScan, pagesDir) {
88
+ if (!pageScan || context.environment?.config.consumer !== "server") return;
89
+ const styles = collectIslandStyles((id) => context.getModuleInfo(id), islandStyleRoots(pageScan, pagesDir));
90
+ if (styles) islandStylesByPagesDir.set(normalizePath(pagesDir), styles);
91
+ }
92
+ /** The stylesheets that the server build recorded, or null without a server build. */
93
+ function recordedIslandStyles(pagesDir) {
94
+ return islandStylesByPagesDir.get(normalizePath(pagesDir)) ?? null;
95
+ }
96
+ /**
97
+ * Keeps the CSS modules (`*.module.css`, Vue `<style module>`) that the
98
+ * islands client entry imports. Vite marks a CSS module as free of side
99
+ * effects, so the entry's bare import would drop it and its rules.
100
+ */
101
+ function islandStylesPlugin(pagesDir) {
102
+ return {
103
+ name: "void:islands-styles",
104
+ apply: "build",
105
+ enforce: "post",
106
+ transform: {
107
+ order: "post",
108
+ filter: { id: /\.module\./ },
109
+ handler(code, id) {
110
+ if (this.environment.config.consumer === "client" && recordedIslandStyles(pagesDir)?.includes(id)) return {
111
+ code,
112
+ map: null,
113
+ moduleSideEffects: "no-treeshake"
114
+ };
43
115
  }
44
116
  }
45
- } catch {}
46
- return false;
117
+ };
47
118
  }
48
119
  /**
49
120
  * Rewrite a matched CSS import line so relative specifiers resolve from the
@@ -128,4 +199,4 @@ function watchPagesForRescan(server, pagesDir, root, onRescan) {
128
199
  return { flush: () => pending ?? Promise.resolve() };
129
200
  }
130
201
  //#endregion
131
- export { ISLANDS_CLIENT_ENTRY_ID, ISLANDS_RENDERER_ID, computePagesNeedingClientJS, editIslandSource, extractCssImports, findIslandImports, findStaticCssImports, needsIslandClientBundle, resolveSpecifier, rewriteCssImportForVirtualModule, watchPagesForRescan };
202
+ export { ISLANDS_CLIENT_ENTRY_ID, ISLANDS_RENDERER_ID, collectIslandStyles, computePagesNeedingClientJS, editIslandSource, extractCssImports, findIslandImports, findStaticCssImports, hasIslandPages, islandStyleRoots, islandStylesPlugin, recordIslandStyles, recordedIslandStyles, resolveSpecifier, rewriteCssImportForVirtualModule, watchPagesForRescan };
@@ -1,3 +1,3 @@
1
- import { w as ValidationError } from "../handler-_PqY82xe.mjs";
2
- import { a as handlePageMutation, i as handlePageGet, n as PageRenderResult, o as safeJsonStringify, r as flattenValidationErrors, t as PageObject } from "../protocol-B8sI8dRD.mjs";
1
+ import { w as ValidationError } from "../handler-D5K_yP6T.mjs";
2
+ import { a as handlePageMutation, i as handlePageGet, n as PageRenderResult, o as safeJsonStringify, r as flattenValidationErrors, t as PageObject } from "../protocol-Ssc_LhHj.mjs";
3
3
  export { PageObject, PageRenderResult, ValidationError, flattenValidationErrors, handlePageGet, handlePageMutation, safeJsonStringify };
@@ -1,3 +1,3 @@
1
1
  import { t as ValidationError } from "../validation-error-Dg9Recn1.mjs";
2
- import { i as safeJsonStringify, n as handlePageGet, r as handlePageMutation, t as flattenValidationErrors } from "../protocol-RNP0u7UY.mjs";
2
+ import { i as safeJsonStringify, n as handlePageGet, r as handlePageMutation, t as flattenValidationErrors } from "../protocol-bAUUkx70.mjs";
3
3
  export { ValidationError, flattenValidationErrors, handlePageGet, handlePageMutation, safeJsonStringify };
@@ -1,2 +1,2 @@
1
- import { t as serializePageData } from "../serialize-CfSwWfF2.mjs";
2
- export { serializePageData };
1
+ import { n as islandFrontmatterScript, r as serializePageData, t as ISLAND_FRONTMATTER_ID } from "../serialize-DtR8Vwa_.mjs";
2
+ export { ISLAND_FRONTMATTER_ID, islandFrontmatterScript, serializePageData };
@@ -1 +1 @@
1
- export { t as serializePageData } from "../serialize-BtQyaYoC.mjs";
1
+ export { t as ISLAND_FRONTMATTER_ID, n as islandFrontmatterScript, r as serializePageData } from "../serialize-YHvlcG3Q.mjs";
@@ -1,10 +1,10 @@
1
1
  import { u as openBrowser } from "./auth-B6iOCjKI.mjs";
2
2
  import { A as confirm, K as select, U as password, X as text, z as multiselect } from "./dist-BVdsO7Py.mjs";
3
- import { l as formatUrl, m as printSuccess } from "./output-Ba6ZbrzY.mjs";
3
+ import { l as formatUrl, m as printSuccess } from "./output-CKguMgr7.mjs";
4
4
  import { n as OperatorClient } from "./operator-client-C-ROjk1I.mjs";
5
5
  import { a as resolveOperatorOrigin, r as readOperatorToken } from "./operator-auth-Cr2zCc-J.mjs";
6
- import { i as humanLines } from "./operator-cmd-CA5QQyvE.mjs";
7
- import { o as platformPromptAnswer } from "./platform-setup-YvN9VQXV.mjs";
6
+ import { i as humanLines } from "./operator-cmd-DCr_QGMH.mjs";
7
+ import { o as platformPromptAnswer } from "./platform-setup-hFbnWAVQ.mjs";
8
8
  import { parsePlatformAdmissionPolicy, parsePlatformLoginConfiguration } from "@void/platform";
9
9
  import { stripVTControlCharacters } from "node:util";
10
10
  import { setTimeout } from "node:timers/promises";
@@ -142,11 +142,11 @@ async function configurationInput(args, existing) {
142
142
  }
143
143
  async function runPlatformAuthConfig(args) {
144
144
  if (args.action === "recover") {
145
- const { runPlatformAuthRecovery } = await import("./platform-auth-recovery-B0BV2hfV.mjs");
145
+ const { runPlatformAuthRecovery } = await import("./platform-auth-recovery-B2LKI8V2.mjs");
146
146
  return runPlatformAuthRecovery(args);
147
147
  }
148
148
  if (args.action === "protection") {
149
- const { runPlatformProtectionConfig } = await import("./platform-auth-protection-U9HCqoXv.mjs");
149
+ const { runPlatformProtectionConfig } = await import("./platform-auth-protection-CyLcD6ot.mjs");
150
150
  return runPlatformProtectionConfig(args);
151
151
  }
152
152
  const origin = resolveOperatorOrigin(args.connection);
@@ -2,11 +2,11 @@ import { S as writePendingInstallationSecrets, c as normalizePlatformApiUrl, m a
2
2
  import { t as cfAccessHeaders } from "./cf-access-BM9G0lhO.mjs";
3
3
  import { t as ensurePlatformAccessToken } from "./cf-access-CWP4avfP.mjs";
4
4
  import { A as confirm, tt as isCancel } from "./dist-BVdsO7Py.mjs";
5
- import { m as printSuccess } from "./output-Ba6ZbrzY.mjs";
5
+ import { m as printSuccess } from "./output-CKguMgr7.mjs";
6
6
  import { n as OperatorClient } from "./operator-client-C-ROjk1I.mjs";
7
7
  import { a as resolveOperatorOrigin, r as readOperatorToken } from "./operator-auth-Cr2zCc-J.mjs";
8
- import { G as PlatformCloudflareClient, H as parsePlatformAccessSetupSpec, R as resolvePlatformCloudflareCredential, U as preparePlatformAccessSetup, V as checkpointPlatformAccessResources, n as resolvePlatformInstallDatabaseUrl, u as acquirePlatformDatabaseLifecycleLock } from "./platform-lifecycle-D0TdyXbN.mjs";
9
- import { d as verifyPlatformInstallationOwnership, l as selectAuthoritativePlatformManifest } from "./platform-management-CnXhgxTM.mjs";
8
+ import { G as checkpointPlatformAccessResources, H as resolvePlatformCloudflareCredential, K as parsePlatformAccessSetupSpec, Y as PlatformCloudflareClient, m as acquirePlatformDatabaseLifecycleLock, n as resolvePlatformInstallDatabaseUrl, q as preparePlatformAccessSetup } from "./platform-lifecycle-3CR98Tg2.mjs";
9
+ import { d as verifyPlatformInstallationOwnership, l as selectAuthoritativePlatformManifest } from "./platform-management-o3LCCeE4.mjs";
10
10
  import { parsePlatformAccessProtection, platformProtectionProofMessage } from "@void/platform";
11
11
  import { createHmac } from "node:crypto";
12
12
  import { readFile } from "node:fs/promises";
@@ -1,10 +1,10 @@
1
1
  import { m as readInstallationRecoverySecrets, t as acquirePlatformLifecycleLock, v as resolveInstallationManifest } from "./platform-registry-B9mWX9LO.mjs";
2
2
  import { u as openBrowser } from "./auth-B6iOCjKI.mjs";
3
3
  import { A as confirm, tt as isCancel } from "./dist-BVdsO7Py.mjs";
4
- import { l as formatUrl, m as printSuccess } from "./output-Ba6ZbrzY.mjs";
4
+ import { l as formatUrl, m as printSuccess } from "./output-CKguMgr7.mjs";
5
5
  import { a as resolveOperatorOrigin } from "./operator-auth-Cr2zCc-J.mjs";
6
- import { G as PlatformCloudflareClient, R as resolvePlatformCloudflareCredential, d as acquirePlatformDatabaseLifecycleLockConnection, f as platformDatabaseClientUrl, n as resolvePlatformInstallDatabaseUrl } from "./platform-lifecycle-D0TdyXbN.mjs";
7
- import { d as verifyPlatformInstallationOwnership, l as selectAuthoritativePlatformManifest } from "./platform-management-CnXhgxTM.mjs";
6
+ import { H as resolvePlatformCloudflareCredential, Y as PlatformCloudflareClient, g as platformDatabaseClientUrl, h as acquirePlatformDatabaseLifecycleLockConnection, n as resolvePlatformInstallDatabaseUrl } from "./platform-lifecycle-3CR98Tg2.mjs";
7
+ import { d as verifyPlatformInstallationOwnership, l as selectAuthoritativePlatformManifest } from "./platform-management-o3LCCeE4.mjs";
8
8
  import { parsePlatformAccessProtection, parsePlatformAdmissionPolicy, parsePlatformLoginConfiguration, platformAuthenticationRecoveryMessage, validatePlatformAdmissionPolicy } from "@void/platform";
9
9
  import { createCipheriv, createDecipheriv, createHash, createHmac, hkdfSync, randomBytes, randomUUID } from "node:crypto";
10
10
  import { setTimeout } from "node:timers/promises";
@@ -1 +1 @@
1
- export { t as discoverPlatform, r as runPlatformCommand } from "./platform-cmd-CXrjk4fb.mjs";
1
+ export { t as discoverPlatform, r as runPlatformCommand } from "./platform-cmd-CX7phm7V.mjs";
@@ -2,7 +2,7 @@ import { b as selectPlatformConnection, c as normalizePlatformApiUrl, i as getAc
2
2
  import { t as cfAccessHeaders } from "./cf-access-BM9G0lhO.mjs";
3
3
  import { r as isCloudflareAccessChallenge, t as ensurePlatformAccessToken } from "./cf-access-CWP4avfP.mjs";
4
4
  import { K as select, L as log, X as text, tt as isCancel } from "./dist-BVdsO7Py.mjs";
5
- import { f as import_picocolors, l as formatUrl, m as printSuccess } from "./output-Ba6ZbrzY.mjs";
5
+ import { f as import_picocolors, l as formatUrl, m as printSuccess } from "./output-CKguMgr7.mjs";
6
6
  import { n as readPlatformDiscoveryResponse, t as PlatformDisabledError } from "./platform-discovery-CHhNs8Nn.mjs";
7
7
  //#region src/cli/platform-cmd.ts
8
8
  function normalizePlatformInputUrl(input) {
@@ -99,16 +99,16 @@ async function runPlatformCommand(_root, args) {
99
99
  const { parsePlatformArgs } = await import("./platform-args-B_LrqEZB.mjs");
100
100
  return runPlatformCommand(_root, parsePlatformArgs(["config", group]));
101
101
  }
102
- const { runPlatformPlansConfig } = await import("./platform-plans-config-BWn1S2Rv.mjs");
102
+ const { runPlatformPlansConfig } = await import("./platform-plans-config-CBMZxCep.mjs");
103
103
  await runPlatformPlansConfig(args);
104
104
  return;
105
105
  }
106
- const { runPlatformAuthConfig } = await import("./platform-auth-config-CZaY812e.mjs");
106
+ const { runPlatformAuthConfig } = await import("./platform-auth-config-qGvEuns3.mjs");
107
107
  await runPlatformAuthConfig(args);
108
108
  return;
109
109
  }
110
110
  if (args.subcommand === "operator") {
111
- const { runOperatorCommand } = await import("./operator-cmd-D7toMPJ9.mjs");
111
+ const { runOperatorCommand } = await import("./operator-cmd-Bv20yLu2.mjs");
112
112
  await runOperatorCommand(args);
113
113
  return;
114
114
  }
@@ -176,7 +176,7 @@ async function runPlatformCommand(_root, args) {
176
176
  console.log(`Capabilities: ${Object.entries(discovery.capabilities).filter(([, enabled]) => enabled).map(([name]) => name).join(", ")}`);
177
177
  return;
178
178
  }
179
- const { runPlatformLifecycleCommand } = await import("./platform-lifecycle-Dz2cJsLX.mjs");
179
+ const { runPlatformLifecycleCommand } = await import("./platform-lifecycle-CWc5gr6c.mjs");
180
180
  await runPlatformLifecycleCommand(args);
181
181
  }
182
182
  function showSavedInstallationStatus(manifest) {
@@ -1,9 +1,9 @@
1
1
  import { m as readInstallationRecoverySecrets, t as acquirePlatformLifecycleLock, x as writeInstallationManifest, y as savePlatformConnection } from "./platform-registry-B9mWX9LO.mjs";
2
2
  import { t as cfAccessHeaders } from "./cf-access-BM9G0lhO.mjs";
3
3
  import { A as confirm, X as text, tt as isCancel } from "./dist-BVdsO7Py.mjs";
4
- import { m as printSuccess, p as note } from "./output-Ba6ZbrzY.mjs";
5
- import { G as PlatformCloudflareClient, L as assertPlatformOperatorCredentialCanApplyPlan, R as resolvePlatformCloudflareCredential, S as recordResource, T as createPlatformInstallPlan, n as resolvePlatformInstallDatabaseUrl, t as assertNoninteractivePlatformMutationAcknowledged, u as acquirePlatformDatabaseLifecycleLock, w as recordPlatformWorkerTraffic, y as createPlatformHealthProbeToken } from "./platform-lifecycle-D0TdyXbN.mjs";
6
- import { d as verifyPlatformInstallationOwnership, l as selectAuthoritativePlatformManifest, o as resolveInstalledPlatformManifest } from "./platform-management-CnXhgxTM.mjs";
4
+ import { m as printSuccess, p as note } from "./output-CKguMgr7.mjs";
5
+ import { C as createPlatformHealthProbeToken, E as recordResource, H as resolvePlatformCloudflareCredential, O as recordPlatformWorkerTraffic, V as assertPlatformOperatorCredentialCanApplyPlan, Y as PlatformCloudflareClient, k as createPlatformInstallPlan, m as acquirePlatformDatabaseLifecycleLock, n as resolvePlatformInstallDatabaseUrl, t as assertNoninteractivePlatformMutationAcknowledged } from "./platform-lifecycle-3CR98Tg2.mjs";
6
+ import { d as verifyPlatformInstallationOwnership, l as selectAuthoritativePlatformManifest, o as resolveInstalledPlatformManifest } from "./platform-management-o3LCCeE4.mjs";
7
7
  import { PLATFORM_HEALTH_HOSTNAME_LABEL, PLATFORM_REMOTE_INSTALLATION_MANIFEST_KEY, createApplicationRoutes, createPlatformDeploymentManifest, normalizeApplicationDomain } from "@void/platform";
8
8
  //#region src/cli/platform-domain.ts
9
9
  function platformDomainTarget(manifest, domain, zone, dedicatedZone) {