void 0.23.0 → 0.25.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.
Files changed (169) hide show
  1. package/AGENTS_TEMPLATE.md +1 -1
  2. package/README.md +19 -106
  3. package/dist/{account-cmd-C84Ee8cO.mjs → account-cmd-DcR1ywt8.mjs} +5 -5
  4. package/dist/{auth-CSkdO2Bb.mjs → auth-7wuZ5ob8.mjs} +22 -49
  5. package/dist/auth-CdgZ9uag.mjs +2 -0
  6. package/dist/{auth-link-CioEg6uY.mjs → auth-link-Z6E5DYvM.mjs} +5 -6
  7. package/dist/{auth-router-BsR981d4.mjs → auth-router-BdM4avI8.mjs} +7 -7
  8. package/dist/{build-cmd-LzvNJORH.mjs → build-cmd-CEE7D-hM.mjs} +7 -8
  9. package/dist/{cache-C4MvnrMH.mjs → cache-TcZnBLtH.mjs} +6 -7
  10. package/dist/{cancel-deploy-abUxpP2n.mjs → cancel-deploy-CYoZmcmR.mjs} +4 -6
  11. package/dist/{cf-access-P0iZnu0q.mjs → cf-access-AHKBzmuu.mjs} +4 -48
  12. package/dist/{cf-access-DRsQRe6k.mjs → cf-access-TWNzXltp.mjs} +3 -11
  13. package/dist/cf-build-output-ChY6-XWP.mjs +2 -0
  14. package/dist/cli/cli.mjs +49 -46
  15. package/dist/cli/cloudflare-operation-process.mjs +16 -7
  16. package/dist/cli/env-schema-probe.mjs +3 -3
  17. package/dist/client-B4Me-9HE.mjs +2 -0
  18. package/dist/{client-RV8NVeB8.mjs → client-RsPo8wsP.mjs} +129 -33
  19. package/dist/{cloudflare-cmd-BcrVyTmJ.mjs → cloudflare-cmd-bhwCxAN6.mjs} +2 -2
  20. package/dist/{cloudflare-connect-B8uPZ4nx.mjs → cloudflare-connect-CuhRgk3k.mjs} +2 -2
  21. package/dist/{cloudflare-operations-AiWashgg.mjs → cloudflare-operations-BhbK6yTq.mjs} +1 -1
  22. package/dist/{cloudflare-operations-fxHb-byx.mjs → cloudflare-operations-CjaV4lZi.mjs} +2 -2
  23. package/dist/{connect-Bd4kJd9U.mjs → connect-DCvUmPXY.mjs} +13 -10
  24. package/dist/{create-project-Boczwj5r.mjs → create-project-C734I-Mu.mjs} +1 -1
  25. package/dist/{create-project-bMf6ffLZ.mjs → create-project-eAPgYq35.mjs} +13 -13
  26. package/dist/{db-8uG64XLl.mjs → db-C07GEdKF.mjs} +27 -30
  27. package/dist/{delete-NvbiyeJf.mjs → delete-pKMVsrpJ.mjs} +5 -6
  28. package/dist/deploy-BDu1vhSH.mjs +2 -0
  29. package/dist/{deploy-DzAIwqNU.mjs → deploy-DfsAe-T0.mjs} +9567 -9215
  30. package/dist/{dev-inbox-P0u4tM8Y.mjs → dev-inbox-D64ZKUod.mjs} +5 -6
  31. package/dist/{domain-y5Tvydvo.mjs → domain-D3uA9ize.mjs} +8 -8
  32. package/dist/{email-B3umsW75.mjs → email-z3o2cwjH.mjs} +8 -8
  33. package/dist/{env-BS6qYHDb.mjs → env-3Q8-_2IH.mjs} +7 -9
  34. package/dist/{env-types-C2_bIk_b.mjs → env-types-D5kds_OZ.mjs} +1 -1
  35. package/dist/{env-validation-DbTg7-ar.mjs → env-validation-cZBvGWaP.mjs} +1 -1
  36. package/dist/{env-validation-BPn7vk-V.mjs → env-validation-vBSQ8gw5.mjs} +3 -3
  37. package/dist/gen-ById9r2j.mjs +2 -0
  38. package/dist/{gen-B580--vC.mjs → gen-NjwoG9FK.mjs} +2 -4
  39. package/dist/{github-cmd-v45BdfKX.mjs → github-cmd-DquUq-b1.mjs} +15 -24
  40. package/dist/{headers-DWi2IXWx.mjs → headers-2rKda9Y6.mjs} +1 -1
  41. package/dist/help-DPGBwomV.mjs +2 -0
  42. package/dist/{help-daGKjXGk.mjs → help-DRZXC4fj.mjs} +8 -4
  43. package/dist/{inbound-aVHEUhKo.mjs → inbound-fRkqcXaC.mjs} +1 -1
  44. package/dist/index.d.mts +18 -14
  45. package/dist/index.mjs +2176 -2110
  46. package/dist/{info-B97bTX9N.mjs → info-BmA3_IFZ.mjs} +1 -3
  47. package/dist/{init-Bvy7zrBo.mjs → init-DT7yuuyl.mjs} +28 -27
  48. package/dist/{link-CDqqCjFl.mjs → link-CXOlqh2F.mjs} +6 -7
  49. package/dist/{list-CZj0dzKY.mjs → list-eEWVJEPn.mjs} +8 -9
  50. package/dist/{local-d1-2CMnpuW_.mjs → local-d1-Df4XpwhW.mjs} +1 -1
  51. package/dist/log-vqY3pqwI.mjs +29 -0
  52. package/dist/login-C98-sw79.mjs +2 -0
  53. package/dist/{login-UZKFM_u7.mjs → login-pWQHYVu2.mjs} +12 -10
  54. package/dist/{logs-CUZ6t9t3.mjs → logs-DnxVX7TR.mjs} +11 -13
  55. package/dist/migrate-CEu2X5DB.mjs +2 -0
  56. package/dist/{migrate-DHul7PRV.mjs → migrate-CV1on-yJ.mjs} +2 -4
  57. package/dist/{operator-args-CLgKGlwU.mjs → operator-args-CAVcmwUt.mjs} +12 -5
  58. package/dist/{operator-auth-8KnOVXVd.mjs → operator-auth-CkmTE3rt.mjs} +2 -2
  59. package/dist/{operator-client-DUwumHpQ.mjs → operator-client-LmwjxT6q.mjs} +3 -3
  60. package/dist/{operator-cmd-DBA6dl0m.mjs → operator-cmd-d-IEKgNk.mjs} +6 -6
  61. package/dist/{output-Dm_A4Tbv.mjs → output-BBsUwdyT.mjs} +22 -14
  62. package/dist/pages/client.d.mts +3 -0
  63. package/dist/pages/client.mjs +120 -29
  64. package/dist/pages/index.mjs +1 -1
  65. package/dist/{platform-args-BJdRtlLq.mjs → platform-args-Bzf8JPc2.mjs} +11 -3
  66. package/dist/platform-args-Cq6EjQro.mjs +2 -0
  67. package/dist/{platform-auth-config-B56E9YP1.mjs → platform-auth-config-0V0lA3pF.mjs} +7 -7
  68. package/dist/{platform-auth-protection-BDWO_aER.mjs → platform-auth-protection-DFeJ-JkK.mjs} +9 -9
  69. package/dist/{platform-auth-recovery-1gg4CSRe.mjs → platform-auth-recovery-ICy4muq6.mjs} +7 -7
  70. package/dist/{platform-cmd-Bt-1w6pY.mjs → platform-cmd-BPySFOew.mjs} +1 -1
  71. package/dist/{platform-cmd-DMcQStSc.mjs → platform-cmd-D7vSWMvV.mjs} +38 -28
  72. package/dist/platform-discovery-DDDUvnqp.mjs +27 -0
  73. package/dist/{platform-domain-BNkcz0OB.mjs → platform-domain-CUdY064e.mjs} +5 -5
  74. package/dist/{platform-lifecycle-BE6C_jxh.mjs → platform-lifecycle-BaUdTRPU.mjs} +1 -1
  75. package/dist/{platform-lifecycle-9OyBALhH.mjs → platform-lifecycle-Dm09JNkn.mjs} +4404 -3297
  76. package/dist/{platform-management-CjwLVQwN.mjs → platform-management-BSEc_ZeG.mjs} +48 -11
  77. package/dist/platform-management-Bp6aoH2C.mjs +2 -0
  78. package/dist/{platform-plans-config-BNGKGr4P.mjs → platform-plans-config-B0pOVQyW.mjs} +3 -3
  79. package/dist/{platform-recovery-D6KSpuFm.mjs → platform-recovery-WOZ95Uze.mjs} +4 -4
  80. package/dist/{platform-registry-QBa4DK32.mjs → platform-registry-KfNEF84O.mjs} +3 -3
  81. package/dist/{prepare-B5Mkic5u.mjs → prepare-39EvOhI6.mjs} +2 -4
  82. package/dist/prepare-CnjcTV2s.mjs +2 -0
  83. package/dist/{prepare-DOsL0CC9.mjs → prepare-DnaKBi--.mjs} +1 -1
  84. package/dist/{project-C0Fqu05O.mjs → project-BkbfDs0V.mjs} +15 -82
  85. package/dist/project-IOjBU8R6.mjs +2 -0
  86. package/dist/{project-cmd-CNzrqvBv.mjs → project-cmd-Bs5A392E.mjs} +21 -22
  87. package/dist/{project-team-DQOWPfQT.mjs → project-team-ohAWWaew.mjs} +8 -9
  88. package/dist/{project-token-CTDYU0Cc.mjs → project-token-CP01Jna6.mjs} +6 -9
  89. package/dist/{project-zero-trust-BNAkW-_0.mjs → project-zero-trust-BzkVgx35.mjs} +5 -6
  90. package/dist/prompts-6OSVA7DJ.mjs +2087 -0
  91. package/dist/prompts-ZAuJlyCj.mjs +2 -0
  92. package/dist/{provision-C4ORE7G7.mjs → provision-BEv0k-qz.mjs} +1 -1
  93. package/dist/{provision-CJFgTZY8.mjs → provision-Btj1jppf.mjs} +5 -7
  94. package/dist/{requests-MhxYnau8.mjs → requests-B3PBuGlX.mjs} +5 -6
  95. package/dist/{rollback-CJ6iSDoU.mjs → rollback-DDub9GsO.mjs} +9 -10
  96. package/dist/runtime/ai.mjs +3 -5
  97. package/dist/runtime/email/testing.mjs +2 -2
  98. package/dist/runtime/email.mjs +36 -18
  99. package/dist/runtime/remote/index.mjs +2 -2
  100. package/dist/runtime/routing.mjs +1 -1
  101. package/dist/{secret-Dli5fP0B.mjs → secret-3c72lY1U.mjs} +15 -16
  102. package/dist/{skills-D1II1Juz.mjs → skills-BPQUGClu.mjs} +1 -1
  103. package/dist/{subcommand-prompt-CY1C4fvl.mjs → subcommand-prompt-Dhom39bd.mjs} +40 -32
  104. package/dist/sveltekit.d.mts +1 -1
  105. package/dist/sveltekit.mjs +4 -9
  106. package/dist/{wrangler-7K-bW_DL.mjs → wrangler-DhUerFkW.mjs} +10 -15
  107. package/package.json +22 -23
  108. package/sandbox.Dockerfile +1 -1
  109. package/skills/void/SKILL.md +6 -1
  110. package/skills/void/docs/guide/ai.md +24 -86
  111. package/skills/void/docs/guide/auth.md +0 -2
  112. package/skills/void/docs/guide/database/d1.md +7 -7
  113. package/skills/void/docs/guide/deployment.md +58 -102
  114. package/skills/void/docs/guide/edge/headers.md +1 -1
  115. package/skills/void/docs/guide/email/domains.md +5 -1
  116. package/skills/void/docs/guide/email/sending.md +1 -1
  117. package/skills/void/docs/guide/env-vars.md +1 -5
  118. package/skills/void/docs/guide/index.md +19 -18
  119. package/skills/void/docs/guide/kv.md +0 -2
  120. package/skills/void/docs/guide/pages-routing/actions-and-forms.md +49 -47
  121. package/skills/void/docs/guide/pages-routing/overview.md +2 -2
  122. package/skills/void/docs/guide/platform/administration/email.md +0 -2
  123. package/skills/void/docs/guide/platform/administration/operations.md +11 -22
  124. package/skills/void/docs/guide/platform/administration/plans.md +1 -5
  125. package/skills/void/docs/guide/platform/administration/zero-trust.md +24 -9
  126. package/skills/void/docs/guide/platform/development/schema-ci.md +7 -1
  127. package/skills/void/docs/guide/platform/installation/ci.md +1 -1
  128. package/skills/void/docs/guide/platform/installation/credentials.md +10 -3
  129. package/skills/void/docs/guide/platform/installation/domains.md +8 -3
  130. package/skills/void/docs/guide/platform/installation/first-deployment.md +2 -2
  131. package/skills/void/docs/guide/platform/installation/maintenance.md +37 -5
  132. package/skills/void/docs/guide/platform/installation/prerequisites.md +87 -14
  133. package/skills/void/docs/guide/platform/installation/setup.md +80 -10
  134. package/skills/void/docs/guide/quickstart.md +37 -80
  135. package/skills/void/docs/guide/remote-dev.md +1 -1
  136. package/skills/void/docs/guide/sandboxes.md +36 -46
  137. package/skills/void/docs/guide/self-hosted-platform.md +20 -0
  138. package/skills/void/docs/guide/websockets.md +0 -2
  139. package/skills/void/docs/integrations/frameworks/overview.md +2 -2
  140. package/skills/void/docs/integrations/frameworks/sveltekit.md +40 -25
  141. package/skills/void/docs/integrations/nodejs-bun-deno.md +7 -2
  142. package/skills/void/docs/reference/api/resources.md +27 -0
  143. package/skills/void/docs/reference/api.md +1 -1
  144. package/skills/void/docs/reference/cli/auth.md +4 -3
  145. package/skills/void/docs/reference/cli/database.md +1 -1
  146. package/skills/void/docs/reference/cli/deploy.md +21 -1
  147. package/skills/void/docs/reference/cli/platform-installation.md +42 -27
  148. package/skills/void/docs/reference/cli/platform-operations.md +4 -8
  149. package/skills/void/docs/reference/cli/platform-zero-trust.md +14 -0
  150. package/skills/void/docs/reference/cli/platform.md +5 -0
  151. package/skills/void/docs/reference/config.md +1 -1
  152. package/skills/void/docs/reference/resource-inference.md +11 -8
  153. package/dist/auth-CCjt0hcq.mjs +0 -2
  154. package/dist/cf-build-output-_0HNWysu.mjs +0 -2
  155. package/dist/client-Cu7jWiF1.mjs +0 -2
  156. package/dist/deploy-bjXdFCtn.mjs +0 -2
  157. package/dist/dist-BuDuKZJv.mjs +0 -2
  158. package/dist/dist-CTBk70IR.mjs +0 -1310
  159. package/dist/gen-BVaUUumi.mjs +0 -2
  160. package/dist/help-DofyZuY7.mjs +0 -2
  161. package/dist/log-ChfPKsVd.mjs +0 -26
  162. package/dist/login-DYt_An22.mjs +0 -2
  163. package/dist/migrate-8_2u55MD.mjs +0 -2
  164. package/dist/platform-args-D3RXyR6h.mjs +0 -2
  165. package/dist/platform-management-CnyTdcWX.mjs +0 -2
  166. package/dist/prepare-cgvDMtSb.mjs +0 -2
  167. package/dist/project-BuUwfj6f.mjs +0 -2
  168. package/skills/void/docs/guide/env-migration.md +0 -109
  169. package/dist/{cf-build-output-BPqOT964.mjs → cf-build-output-U8o1Gl6X.mjs} +1 -1
@@ -1,6 +1,6 @@
1
1
  ## Void
2
2
 
3
3
  - This project uses [Void](https://void.cloud), a full-stack Vite framework for Cloudflare Workers with file-based API routing, server-rendered pages, and typed backend services.
4
- - Deploy to your Cloudflare account with `void deploy --platform cloudflare`, or connect to a Void platform with `void connect <url>` and deploy with `void deploy --platform void`. `void deploy` uses the saved destination.
4
+ - Deploy to your Cloudflare account with `void deploy --platform cloudflare`, or explicitly connect to your team’s Void platform with `void connect <url>` before deploying with `void deploy --platform void`. `void deploy` uses the saved destination.
5
5
  - Use Void's CLI and typed APIs for development and infrastructure. Void infers Cloudflare bindings from your imports; use Void commands to manage them.
6
6
  - Before working with Void, read the relevant Markdown docs in `node_modules/void/skills/void/docs/`. Start with `guide/quickstart.md` for setup and `reference/cli.md` for commands; consult the other guides and references for any Void feature.
package/README.md CHANGED
@@ -1,124 +1,37 @@
1
1
  # void
2
2
 
3
- Vite plugin and CLI for building and deploying apps on Void.
3
+ Build and deploy full-stack Vite apps on Cloudflare Workers. Void provides server routes, server-rendered pages, and typed access to databases, storage, and AI.
4
4
 
5
- You can also administer a team platform with the same CLI. Sign in with
6
- `void platform auth login`, then manage users, signup access, projects, and logs.
7
- Commands show a preview before applying changes and support `--json` for scripts.
8
- See [Platform Administration](../../docs/guide/platform-administration.md) for a
9
- walkthrough and the [CLI reference](../../docs/reference/cli/platform.md#operator-commands)
10
- for every command.
5
+ ## Getting Started
11
6
 
12
- Use `void platform config auth` to manage login methods and company signup.
13
- Use `void platform config plans` to manage account plans, enforced limits, and the default for new accounts. See [Plans and Limits](../../docs/guide/platform/administration/plans.md).
14
- Cloudflare Access protection has separate create/connect controls. Users can
15
- link another enabled login to their account with `void account link`.
7
+ Use Node.js 24.21.0 or later. In an empty directory, run:
16
8
 
17
- ## What It Covers
18
-
19
- - file-based API routes from `routes/`
20
- - Pages mode from `pages/`
21
- - typed Drizzle access via `void/db`
22
- - `crons/` and `queues/`
23
- - URL redirects, rewrites, and fallbacks (`void.config.ts` / `public/_redirects`, plus `c.rewrite()` from middleware)
24
- - binding inference for D1, KV, R2, AI, auth, queues, and typed Durable Objects
25
- - remote bindings for local development
26
- - one target-aware deploy path for Void-hosted and direct Cloudflare apps
27
- - automatic Cloudflare provisioning, verified Worker Version activation, and operational commands
28
-
29
- ## Quick Start
30
-
31
- Install the Void CLI:
32
-
33
- ```bash
9
+ ```sh
34
10
  npm install -D void
11
+ npx void init
12
+ npm run dev
35
13
  ```
36
14
 
37
- If you run `void init` in an empty directory, the scaffold flow adds the matching Pages adapter and Vite+ by default.
38
-
39
- Init offers to initialize Git and suggests an optional initial commit command. Use `--git` or `--no-git` to choose without the Git prompt. Existing repositories are preserved; Void does not commit automatically.
40
-
41
- To install a team platform, use `void platform install`. A domain is recommended; the visible workers.dev testing option is also available as `--workers-dev`. Add a domain later with `void platform domain set example.com`, preserving projects, deployments, and API connections. See the [platform setup guide](../../docs/guide/self-hosted-platform.md).
15
+ Choose a UI framework, starter, and deployment target. Then deploy:
42
16
 
43
- Init always writes brief coding-agent instructions to `AGENTS.md`, pointing to `node_modules/void/skills/void/docs/`, and links skills for detected agents. Run `void init --agents` to add or refresh just this setup without choosing an agent.
44
-
45
- Then run `npx void init`. In an empty directory, the full interactive flow can scaffold a starter and configure local project files. It then asks where to deploy: Cloudflare (the default) writes `void.config.ts`, handles secure browser sign-in through Void's bundled tooling, and saves the selected account; Void asks for the API URL of an explicitly connected company platform (`void connect <url>` or `void platform install`). Existing `void.json` and root Wrangler JSON/JSONC files are migrated automatically; commit `void.config.ts` and `void.lock.json` when created. Back up `~/.void/platforms/` after installing a company platform because its owner-only recovery material contains runtime keys that Cloudflare cannot return. The next app step is just `npx void deploy`. Auth-enabled deploys preserve an existing `BETTER_AUTH_SECRET` or create a persistent encrypted secret when missing on either platform. Root `.env` is local-only; production server keys declared in `env.ts` use encrypted remote secret storage and are rejected as plaintext Worker vars. In an existing app, init configures Void in place by adding missing Vite scripts and creating or patching `vite.config.*` with `voidPlugin()`.
46
-
47
- ```ts
48
- // vite.config.ts
49
- import { defineConfig } from 'vite';
50
- import { voidPlugin } from 'void';
51
-
52
- export default defineConfig({
53
- plugins: [voidPlugin()],
54
- });
17
+ ```sh
18
+ npx void deploy
55
19
  ```
56
20
 
57
- ## Core Surfaces
58
-
59
- - `voidPlugin()` — Vite integration, routing, pages mode, codegen, migrations, packaging
60
- - `void prepare` — generate `.void` artifacts for CI, editors, and fresh clones
61
- - `void info [--json]` — discover persistent resource names before moving definitions
62
- - `void auth login` — sign in to the project's saved Cloudflare or Void destination
63
- - `void account login` — platform auth
64
- - `void connect [url]` — choose Cloudflare or a Void platform, sign in, and save the deployment destination
65
- - `void platform *` — list, select, inspect, install, recover, repair, upgrade, disable, and safely uninstall a company platform
66
- - `void deploy` — build and deploy to the saved Cloudflare or Void target
67
- - `void db *` — local DB and migration commands
68
- - `void project *` — target-aware status, logs, rollback, managed-project operations, and scoped CI deploy credentials
69
- - `void secret *` / `void domain *` — target-aware Worker secrets and custom domains
70
-
71
- Runtime helpers include:
21
+ Void builds your app, provisions its resources, applies migrations, and prints the deployed URL.
72
22
 
73
- - `defineHandler`
74
- - `defineMiddleware`
75
- - `basicAuth`
76
- - `defineScheduled`
77
- - `defineQueue`
78
- - `void/db`
79
- - `void/kv`
80
- - `void/storage`
81
- - `void/durable`
82
- - `void/ai`
83
- - `void/isr`
84
- - `void/client`
85
- - `void/auth`
86
-
87
- ## Supported App Shapes
88
-
89
- - native Void apps (`routes/`, `pages/`, `middleware/`, `crons/`, `queues/`)
90
- - supported meta-framework deploy targets:
91
- - TanStack Start
92
- - React Router
93
- - vinext App Router and Pages Router
94
- - SvelteKit
95
- - Nuxt
96
- - Analog
97
- - Astro
98
- - static and SPA deploys
99
- - non-Cloudflare server targets (`node`, `bun`, `deno`)
100
-
101
- Direct Cloudflare deployments also support D1, KV, R2, Queues, Hyperdrive, auth, cron jobs, AI, ISR, typed SQLite Durable Objects, and WebSocket rooms. They upload an immutable Worker Version, probe it before activation (using a 0%-traffic version override when Durable Objects disable preview URLs), and retain version metadata for migration-aware rollback.
102
-
103
- Durable State and WebSocket definitions accept optional `name` to preserve their resource identity when files move. Run `void info` and pin the displayed name before moving deployed code. See [Durable State](../../docs/guide/durable-state.md#rename-a-file-while-keeping-its-state) and [WebSockets](../../docs/guide/websockets.md#move-a-route-while-keeping-its-state), including how to preserve room instances when renaming route parameters.
104
-
105
- Self-hosted platform upgrades verify every packaged PostgreSQL migration and require the live Drizzle history to be an exact prefix. Pending SQL is allowed only for an explicitly attested old-version/schema compatibility edge, runs in one transaction, and leaves the old Worker version authoritative until the target runtime passes discovery and health checks.
106
-
107
- An upgrade that changes the authenticated usage protocol briefly gates application traffic while it verifies the complete Worker set. An interruption leaves the gate closed for the next resumable upgrade instead of enabling an unsigned compatibility path.
108
-
109
- ## Database Model
110
-
111
- `void/db` is Drizzle-first.
112
-
113
- - D1 is the default managed database target; development and local database commands share the configured binding ID and persistence directory
114
- - apps can opt into PostgreSQL or MySQL mode
115
- - route types, DB types, and queue types are generated into `.void/*.d.ts`
116
-
117
- Node.js, Bun, and Deno Pages builds include production hydration assets. Deploy `dist/ssr` together with `dist/client`; the server loads its manifest and assets relative to the emitted module.
23
+ Follow the [Quickstart](https://void.cloud/guide/quickstart) for your first app or to add Void to an existing project.
118
24
 
119
25
  ## Documentation
120
26
 
121
- Full docs live at [void.cloud/guide](https://void.cloud/guide).
27
+ - [Introduction](https://void.cloud/guide/)
28
+ - [Server routing](https://void.cloud/guide/server-routing) and [Pages routing](https://void.cloud/guide/pages-routing/overview)
29
+ - [Database](https://void.cloud/guide/database) and [type safety](https://void.cloud/guide/type-safety)
30
+ - [Deployment](https://void.cloud/guide/deployment)
31
+ - [Framework integrations](https://void.cloud/integrations/frameworks/overview)
32
+ - [API](https://void.cloud/reference/api) and [CLI](https://void.cloud/reference/cli) reference
33
+
34
+ To share a deployment platform with your team, see [Install a Void Platform](https://void.cloud/guide/self-hosted-platform).
122
35
 
123
36
  ## License
124
37
 
@@ -1,13 +1,13 @@
1
- import { c as getToken, p as removeToken } from "./auth-CSkdO2Bb.mjs";
2
- import { j as log } from "./dist-CTBk70IR.mjs";
3
- import { n as PlatformClient } from "./client-RV8NVeB8.mjs";
4
- import { n as runLoginCommand } from "./login-UZKFM_u7.mjs";
1
+ import { c as getToken, f as removeToken } from "./auth-7wuZ5ob8.mjs";
2
+ import { L as log } from "./prompts-6OSVA7DJ.mjs";
3
+ import { r as PlatformClient } from "./client-RsPo8wsP.mjs";
4
+ import { n as runLoginCommand } from "./login-pWQHYVu2.mjs";
5
5
  import { execSync } from "node:child_process";
6
6
  //#region src/cli/account-cmd.ts
7
7
  async function runAccountCommand(root, args) {
8
8
  switch (args.subcommand) {
9
9
  case "login": return runLoginCommand(root);
10
- case "link": return import("./auth-link-CioEg6uY.mjs").then(({ runAuthLink }) => runAuthLink(root, args.connectionId));
10
+ case "link": return import("./auth-link-Z6E5DYvM.mjs").then(({ runAuthLink }) => runAuthLink(root, args.connectionId));
11
11
  case "logout":
12
12
  if (removeToken(root)) log.success("Logged out.");
13
13
  else log.info("Not logged in.");
@@ -1,15 +1,11 @@
1
1
  import { a as join } from "./dist-BVqXeR_h.mjs";
2
- import { t as cfAccessHeaders } from "./cf-access-DRsQRe6k.mjs";
3
- import { S as writeKeyringPassword, b as deleteKeyringPassword, c as platformCredentialAccount, o as listPlatformConnections, r as getActivePlatformConnection, s as normalizePlatformApiUrl, x as readKeyringPassword } from "./platform-registry-QBa4DK32.mjs";
4
- import { t as ensureCloudflaredToken } from "./cf-access-P0iZnu0q.mjs";
5
- import { a as readProjectApplicationDomain, f as VOID_CLOUD_PLATFORM, m as readLegacyHostedPlatformSelection, n as isLegacyVoidCloudProject, p as VOID_CLOUD_STAGING_PLATFORM, r as isVoidInternalStaging, s as readProjectPlatformUrl } from "./project-C0Fqu05O.mjs";
2
+ import { C as writeKeyringPassword, S as readKeyringPassword, c as platformCredentialAccount, o as listPlatformConnections, r as getActivePlatformConnection, s as normalizePlatformApiUrl, x as deleteKeyringPassword } from "./platform-registry-KfNEF84O.mjs";
3
+ import { i as readProjectPlatformUrl, r as readProjectConfig } from "./project-BkbfDs0V.mjs";
4
+ import { t as cfAccessHeaders } from "./cf-access-TWNzXltp.mjs";
5
+ import { t as ensureCloudflaredToken } from "./cf-access-AHKBzmuu.mjs";
6
6
  import { mkdirSync, readFileSync, writeFileSync } from "node:fs";
7
7
  import { createHash, randomBytes } from "node:crypto";
8
8
  import { homedir } from "node:os";
9
- //#region src/shared/proxy.ts
10
- const DEFAULT_PROXY_URL = "https://proxy.void.cloud";
11
- const STAGING_PROXY_URL = "https://proxy.staging.void.cloud";
12
- //#endregion
13
9
  //#region src/cli/auth.ts
14
10
  const CONFIG_DIR = join(homedir(), ".void");
15
11
  const CONFIG_PATH = join(CONFIG_DIR, "config.json");
@@ -50,19 +46,22 @@ function readOriginScopedToken(apiUrl, config) {
50
46
  }
51
47
  return fileToken;
52
48
  }
53
- function isStagingMode(root = process.cwd()) {
54
- return isVoidInternalStaging(root);
49
+ function connectedPlatform(apiUrl) {
50
+ if (!apiUrl) throw new Error("platform: No Void platform connected. Run `void connect <url>` first.");
51
+ const origin = normalizePlatformApiUrl(apiUrl);
52
+ const connection = listPlatformConnections().find((entry) => entry.apiUrl === origin);
53
+ if (!connection) throw new Error(`platform: No connection to ${origin}. Run \`void connect ${origin}\` first.`);
54
+ return connection;
55
55
  }
56
56
  function getSiteDomain(root = process.cwd()) {
57
- const legacySelection = readLegacyHostedPlatformSelection();
58
- const domain = readProjectApplicationDomain(root) ?? (isStagingMode(root) ? VOID_CLOUD_STAGING_PLATFORM.applicationDomain : void 0) ?? (isLegacyVoidCloudProject(root) || process.env.VOID_TOKEN && process.env.VOID_API_URL === void 0 ? VOID_CLOUD_PLATFORM.applicationDomain : void 0) ?? getActivePlatformConnection()?.applicationDomain ?? legacySelection?.applicationDomain;
59
- if (!domain) throw new Error("platform: No Void platform selected. Run `void connect <url>` or `void platform install` first.");
60
- return domain;
57
+ const connection = connectedPlatform(getApiUrl(root));
58
+ if (!connection.applicationDomain) throw new Error(`platform: Missing application domain. Run \`void connect ${connection.apiUrl}\` to refresh the connection.`);
59
+ return connection.applicationDomain;
61
60
  }
62
61
  /**
63
62
  * Read the deploy token.
64
63
  * Priority: origin-bound VOID_TOKEN > system keychain > migrated config.
65
- * An unscoped environment token retains its historical Void Cloud destination.
64
+ * Environment tokens must name their recipient with VOID_API_URL.
66
65
  */
67
66
  function getToken(root = process.cwd()) {
68
67
  const envToken = process.env.VOID_TOKEN;
@@ -79,7 +78,7 @@ function getToken(root = process.cwd()) {
79
78
  /** Account actions follow the selected connection, independently of application metadata. */
80
79
  function getAccountCredential() {
81
80
  const config = readConfig();
82
- const apiUrl = normalizePlatformApiUrl(process.env.VOID_API_URL || (process.env.VOID_TOKEN ? DEFAULT_API_URL : getActivePlatformConnection()?.apiUrl ?? config.api ?? readLegacyHostedPlatformSelection()?.apiUrl ?? (keyringGet("token") ? DEFAULT_API_URL : keyringGet("stagingToken") ? STAGING_API_URL : DEFAULT_API_URL)));
81
+ const apiUrl = connectedPlatform(process.env.VOID_API_URL || getActivePlatformConnection()?.apiUrl).apiUrl;
83
82
  return {
84
83
  apiUrl,
85
84
  token: readTokenForOrigin(apiUrl, config)
@@ -88,7 +87,8 @@ function getAccountCredential() {
88
87
  function readTokenForOrigin(apiUrl, config) {
89
88
  const envToken = process.env.VOID_TOKEN;
90
89
  if (envToken) {
91
- if (apiUrl !== (process.env.VOID_API_URL ? normalizePlatformApiUrl(process.env.VOID_API_URL) : DEFAULT_API_URL)) throw new Error(`auth: VOID_TOKEN is not bound to ${apiUrl}. Set VOID_API_URL to this platform's URL with its matching token, or unset VOID_TOKEN to use the saved login.`);
90
+ if (!process.env.VOID_API_URL) throw new Error("auth: Set VOID_API_URL alongside VOID_TOKEN to identify the connected platform that issued it.");
91
+ if (apiUrl !== normalizePlatformApiUrl(process.env.VOID_API_URL)) throw new Error(`auth: VOID_TOKEN is not bound to ${apiUrl}. Set VOID_API_URL to this platform's URL with its matching token, or unset VOID_TOKEN to use the saved login.`);
92
92
  return envToken;
93
93
  }
94
94
  return readOriginScopedToken(apiUrl, config);
@@ -126,8 +126,6 @@ function removeToken(root = process.cwd()) {
126
126
  } catch {}
127
127
  return removed;
128
128
  }
129
- const DEFAULT_API_URL = VOID_CLOUD_PLATFORM.apiUrl;
130
- const STAGING_API_URL = VOID_CLOUD_STAGING_PLATFORM.apiUrl;
131
129
  function base64Url(buffer) {
132
130
  return buffer.toString("base64").replaceAll("+", "-").replaceAll("/", "_").replaceAll("=", "");
133
131
  }
@@ -163,40 +161,15 @@ async function exchangeLoginCode(apiUrl, code, state, codeVerifier) {
163
161
  if (!body || typeof body !== "object" || !("token" in body) || typeof body.token !== "string" || body.token.length === 0) throw new Error("auth: Login code exchange did not return a token.");
164
162
  return body.token;
165
163
  }
166
- /**
167
- * Read the API URL from environment or config file.
168
- * Priority: VOID_API_URL env var > ~/.void/config.json > default
169
- */
164
+ /** Environment and project selections must refer to a verified local connection. */
170
165
  function getApiUrl(root = process.cwd()) {
171
- if (process.env.VOID_API_URL) return normalizePlatformApiUrl(process.env.VOID_API_URL);
172
- if (isStagingMode(root)) return STAGING_API_URL;
173
166
  const projectApiUrl = readProjectPlatformUrl(root);
174
- if (projectApiUrl) {
175
- if (projectApiUrl === DEFAULT_API_URL || projectApiUrl === STAGING_API_URL) return projectApiUrl;
176
- if (listPlatformConnections().some((connection) => connection.apiUrl === projectApiUrl)) return projectApiUrl;
177
- throw new Error(`platform: Project metadata selected unverified platform ${projectApiUrl}. Connect to it explicitly with \`void connect ${projectApiUrl}\` before forwarding credentials.`);
178
- }
179
- const config = readConfig();
180
- const legacySelection = readLegacyHostedPlatformSelection();
181
- let apiUrl = (isLegacyVoidCloudProject(root) ? DEFAULT_API_URL : void 0) ?? getActivePlatformConnection()?.apiUrl ?? config.api ?? legacySelection?.apiUrl;
182
- apiUrl ??= process.env.VOID_TOKEN ? DEFAULT_API_URL : void 0;
183
- if (!apiUrl) {
184
- apiUrl = keyringGet("token") ? DEFAULT_API_URL : keyringGet("stagingToken") ? STAGING_API_URL : void 0;
185
- if (apiUrl) try {
186
- writeConfig({
187
- ...config,
188
- api: apiUrl
189
- });
190
- } catch {}
191
- }
192
- if (!apiUrl) throw new Error("platform: No Void platform selected. Run `void connect <url>` or `void platform install` first.");
193
- return normalizePlatformApiUrl(apiUrl);
167
+ if (readProjectConfig(root) && !projectApiUrl) throw new Error("platform: This project link has no platform URL. Run `void connect <url>`, then `void project link` to choose its destination.");
168
+ return connectedPlatform(process.env.VOID_API_URL || projectApiUrl || getActivePlatformConnection()?.apiUrl).apiUrl;
194
169
  }
195
170
  function getProxyUrl(root = process.cwd()) {
171
+ const apiUrl = getApiUrl(root);
196
172
  if (process.env.VOID_PROXY_URL) return normalizePlatformApiUrl(process.env.VOID_PROXY_URL);
197
- const apiUrl = normalizePlatformApiUrl(getApiUrl(root));
198
- if (apiUrl === STAGING_API_URL) return STAGING_PROXY_URL;
199
- if (apiUrl === DEFAULT_API_URL) return DEFAULT_PROXY_URL;
200
173
  const proxyUrl = listPlatformConnections().find((connection) => connection.apiUrl === apiUrl)?.proxyUrl;
201
174
  if (proxyUrl === null || proxyUrl === void 0) throw new Error(`platform: No verified proxy is registered for ${apiUrl}. Reconnect with \`void connect ${apiUrl}\` or set VOID_PROXY_URL explicitly.`);
202
175
  return proxyUrl;
@@ -369,4 +342,4 @@ async function runPlatformLogin(origin, provider = "github", onUrl) {
369
342
  });
370
343
  }
371
344
  //#endregion
372
- export { saveToken as _, getApiUrl as a, getToken as c, openBrowser as d, readPlatformToken as f, savePlatformToken as g, runPlatformLogin as h, getAccountCredential as i, getTokenSource as l, runLogin as m, createCodeChallenge as n, getProxyUrl as o, removeToken as p, createCodeVerifier as r, getSiteDomain as s, awaitBrowserCallback as t, isStagingMode as u, DEFAULT_PROXY_URL as v, STAGING_PROXY_URL as y };
345
+ export { getApiUrl as a, getToken as c, readPlatformToken as d, removeToken as f, saveToken as g, savePlatformToken as h, getAccountCredential as i, getTokenSource as l, runPlatformLogin as m, createCodeChallenge as n, getProxyUrl as o, runLogin as p, createCodeVerifier as r, getSiteDomain as s, awaitBrowserCallback as t, openBrowser as u };
@@ -0,0 +1,2 @@
1
+ import { a as getApiUrl, m as runPlatformLogin, s as getSiteDomain } from "./auth-7wuZ5ob8.mjs";
2
+ export { getApiUrl, getSiteDomain, runPlatformLogin };
@@ -1,8 +1,8 @@
1
- import { a as getApiUrl, c as getToken, d as openBrowser, g as savePlatformToken, h as runPlatformLogin } from "./auth-CSkdO2Bb.mjs";
2
- import { j as log } from "./dist-CTBk70IR.mjs";
3
- import { n as PlatformClient } from "./client-RV8NVeB8.mjs";
4
- import { r as selectPlatformLoginMethod } from "./login-UZKFM_u7.mjs";
5
- import { t as discoverPlatform } from "./platform-cmd-DMcQStSc.mjs";
1
+ import { a as getApiUrl, c as getToken, h as savePlatformToken, m as runPlatformLogin, u as openBrowser } from "./auth-7wuZ5ob8.mjs";
2
+ import { L as log } from "./prompts-6OSVA7DJ.mjs";
3
+ import { r as PlatformClient } from "./client-RsPo8wsP.mjs";
4
+ import { r as selectPlatformLoginMethod } from "./login-pWQHYVu2.mjs";
5
+ import { t as discoverPlatform } from "./platform-cmd-D7vSWMvV.mjs";
6
6
  import { execFile } from "node:child_process";
7
7
  //#region src/cli/auth-link.ts
8
8
  async function runAuthLink(root, connectionId) {
@@ -13,7 +13,6 @@ async function runAuthLink(root, connectionId) {
13
13
  if (!platform.authentication) throw new Error("auth: This platform must be upgraded before linking login methods.");
14
14
  const target = await selectPlatformLoginMethod(platform, connectionId);
15
15
  const existing = await new PlatformClient(token, apiUrl).whoami();
16
- if (!existing.id) throw new Error("auth: This platform does not support account linking.");
17
16
  log.info(`Sign in again to ${existing.login} using an already linked login method.`);
18
17
  const source = await selectPlatformLoginMethod(platform);
19
18
  const freshToken = await runPlatformLogin(apiUrl, source.id, (url) => log.info(`Sign in: ${url}`));
@@ -1,6 +1,6 @@
1
- import { o as listPlatformConnections } from "./platform-registry-QBa4DK32.mjs";
2
- import { i as readDeploymentPlatform } from "./project-C0Fqu05O.mjs";
3
- import { I as select, W as isCancel } from "./dist-CTBk70IR.mjs";
1
+ import { o as listPlatformConnections } from "./platform-registry-KfNEF84O.mjs";
2
+ import { n as readDeploymentPlatform } from "./project-BkbfDs0V.mjs";
3
+ import { K as select, tt as isCancel } from "./prompts-6OSVA7DJ.mjs";
4
4
  //#region src/cli/auth-router.ts
5
5
  async function chooseDestination(root, args, interactive) {
6
6
  const saved = readDeploymentPlatform(root);
@@ -37,7 +37,7 @@ async function chooseDestination(root, args, interactive) {
37
37
  }
38
38
  async function runAuthRouter(root, args, interactive = Boolean(process.stdin.isTTY)) {
39
39
  if (args.subcommand === "link") {
40
- const { runAccountCommand } = await import("./account-cmd-C84Ee8cO.mjs");
40
+ const { runAccountCommand } = await import("./account-cmd-DcR1ywt8.mjs");
41
41
  await runAccountCommand(root, {
42
42
  subcommand: "link",
43
43
  ...args.connectionId ? { connectionId: args.connectionId } : {}
@@ -45,17 +45,17 @@ async function runAuthRouter(root, args, interactive = Boolean(process.stdin.isT
45
45
  return;
46
46
  }
47
47
  if (args.subcommand === "token") {
48
- const { runAccountCommand } = await import("./account-cmd-C84Ee8cO.mjs");
48
+ const { runAccountCommand } = await import("./account-cmd-DcR1ywt8.mjs");
49
49
  await runAccountCommand(root, { subcommand: "token" });
50
50
  return;
51
51
  }
52
52
  const destination = await chooseDestination(root, args, interactive);
53
53
  if (destination.platform === "cloudflare") {
54
- const { runCloudflareCommand } = await import("./cloudflare-cmd-BcrVyTmJ.mjs");
54
+ const { runCloudflareCommand } = await import("./cloudflare-cmd-bhwCxAN6.mjs");
55
55
  await runCloudflareCommand(root, { subcommand: args.subcommand === "whoami" || args.subcommand === "status" ? "status" : args.subcommand });
56
56
  return;
57
57
  }
58
- const { runAccountCommand } = await import("./account-cmd-C84Ee8cO.mjs");
58
+ const { runAccountCommand } = await import("./account-cmd-DcR1ywt8.mjs");
59
59
  const subcommand = args.subcommand === "status" ? "whoami" : args.subcommand;
60
60
  if (!destination.apiUrl) {
61
61
  await runAccountCommand(root, { subcommand });
@@ -1,8 +1,8 @@
1
- import { c as getToken } from "./auth-CSkdO2Bb.mjs";
2
- import { o as readProjectConfig } from "./project-C0Fqu05O.mjs";
3
- import { O as intro, P as outro, j as log } from "./dist-CTBk70IR.mjs";
4
- import { n as PlatformClient, t as PlatformApiError } from "./client-RV8NVeB8.mjs";
5
- import { a as dim, c as import_picocolors, r as cliTitle } from "./output-Dm_A4Tbv.mjs";
1
+ import { r as readProjectConfig } from "./project-BkbfDs0V.mjs";
2
+ import { c as getToken } from "./auth-7wuZ5ob8.mjs";
3
+ import { H as outro, L as log } from "./prompts-6OSVA7DJ.mjs";
4
+ import { n as PlatformApiError, r as PlatformClient } from "./client-RsPo8wsP.mjs";
5
+ import { c as import_picocolors, i as dim } from "./output-BBsUwdyT.mjs";
6
6
  import { r as resolveProjectBySlug, t as getRequestedProjectSlug } from "./resolve-project-BG5ORGID.mjs";
7
7
  import { appendFileSync, writeFileSync } from "node:fs";
8
8
  //#region src/cli/build-cmd.ts
@@ -10,7 +10,7 @@ const POLL_MS = 1e3;
10
10
  const BUILD_LOG_DRAIN_TIMEOUT_MS = 12e4;
11
11
  function isBuildLogComplete(page) {
12
12
  if (!page.terminal) return false;
13
- if (page.logsComplete === null || page.logsComplete === void 0) throw new Error("This platform cannot confirm that the final build logs were captured. Ask its administrator to upgrade the platform runtime, or read the retained logs without --follow.");
13
+ if (page.logsComplete === null) throw new Error("This platform cannot confirm that the final build logs were captured. Ask its administrator to upgrade the platform runtime, or read the retained logs without --follow.");
14
14
  return page.logsComplete === true;
15
15
  }
16
16
  function sleep(ms) {
@@ -74,7 +74,6 @@ async function runBuildCommand(root, args) {
74
74
  }
75
75
  async function runBuildLogsCommand(root, args) {
76
76
  console.log();
77
- intro(cliTitle("build logs"));
78
77
  const token = getToken(root);
79
78
  if (!token) {
80
79
  log.error("Not logged in. Run `void account login` first.");
@@ -128,7 +127,7 @@ async function runBuildLogsCommand(root, args) {
128
127
  await sleep(POLL_MS);
129
128
  }
130
129
  if (first.external) {
131
- log.message(`This build ran on GitHub Actions. View logs:\n${import_picocolors.default.cyan(first.external)}`);
130
+ log.message(`This build ran on GitHub Actions. View logs:\n${import_picocolors.default.blue(first.external)}`);
132
131
  return;
133
132
  }
134
133
  if (args.output) writeFileSync(args.output, "");
@@ -1,13 +1,12 @@
1
- import { c as getToken } from "./auth-CSkdO2Bb.mjs";
2
- import { o as readProjectConfig } from "./project-C0Fqu05O.mjs";
3
- import { O as intro, P as outro, j as log } from "./dist-CTBk70IR.mjs";
4
- import { n as PlatformClient } from "./client-RV8NVeB8.mjs";
5
- import { a as dim, i as createSpinner, r as cliTitle } from "./output-Dm_A4Tbv.mjs";
1
+ import { r as readProjectConfig } from "./project-BkbfDs0V.mjs";
2
+ import { c as getToken } from "./auth-7wuZ5ob8.mjs";
3
+ import { H as outro, L as log } from "./prompts-6OSVA7DJ.mjs";
4
+ import { r as PlatformClient } from "./client-RsPo8wsP.mjs";
5
+ import { i as dim, o as formatCount, r as createSpinner } from "./output-BBsUwdyT.mjs";
6
6
  import { r as resolveProjectBySlug, t as getRequestedProjectSlug } from "./resolve-project-BG5ORGID.mjs";
7
7
  //#region src/cli/cache.ts
8
8
  async function runPurgeCacheCommand(root, projectSlug) {
9
9
  console.log();
10
- intro(cliTitle("project purge-cache"));
11
10
  const token = getToken(root);
12
11
  if (!token) {
13
12
  log.error("Not logged in. Run `void account login` first.");
@@ -39,7 +38,7 @@ async function runPurgeCacheCommand(root, projectSlug) {
39
38
  try {
40
39
  const result = await client.purgeCache(projectId);
41
40
  s.stop("Cache purged.");
42
- log.success(`Purged ${result.purged} cached page(s).`);
41
+ log.success(`Purged ${formatCount(result.purged, "cached page")}.`);
43
42
  } catch (err) {
44
43
  s.stop("Cache purge failed.");
45
44
  log.error(err instanceof Error ? err.message : String(err));
@@ -1,8 +1,7 @@
1
- import { c as getToken } from "./auth-CSkdO2Bb.mjs";
2
- import { o as readProjectConfig } from "./project-C0Fqu05O.mjs";
3
- import { E as confirm, O as intro, P as outro, W as isCancel, j as log } from "./dist-CTBk70IR.mjs";
4
- import { n as PlatformClient } from "./client-RV8NVeB8.mjs";
5
- import { r as cliTitle } from "./output-Dm_A4Tbv.mjs";
1
+ import { r as readProjectConfig } from "./project-BkbfDs0V.mjs";
2
+ import { c as getToken } from "./auth-7wuZ5ob8.mjs";
3
+ import { A as confirm, H as outro, L as log, tt as isCancel } from "./prompts-6OSVA7DJ.mjs";
4
+ import { r as PlatformClient } from "./client-RsPo8wsP.mjs";
6
5
  //#region src/cli/cancel-deploy.ts
7
6
  const ACTIVE_STATUSES = /* @__PURE__ */ new Set([
8
7
  "pending",
@@ -12,7 +11,6 @@ const ACTIVE_STATUSES = /* @__PURE__ */ new Set([
12
11
  ]);
13
12
  async function runCancelDeployCommand(root, deployId) {
14
13
  console.log();
15
- intro(cliTitle("project cancel"));
16
14
  const token = getToken(root);
17
15
  if (!token) {
18
16
  log.error("Not logged in. Run `void account login` first.");
@@ -1,5 +1,5 @@
1
- import { n as isVoidAccessGatedUrl, t as cfAccessHeaders } from "./cf-access-DRsQRe6k.mjs";
2
- import { S as writeKeyringPassword, c as platformCredentialAccount, s as normalizePlatformApiUrl, x as readKeyringPassword } from "./platform-registry-QBa4DK32.mjs";
1
+ import { C as writeKeyringPassword, S as readKeyringPassword, c as platformCredentialAccount, s as normalizePlatformApiUrl } from "./platform-registry-KfNEF84O.mjs";
2
+ import { t as cfAccessHeaders } from "./cf-access-TWNzXltp.mjs";
3
3
  import { spawnSync } from "node:child_process";
4
4
  //#region src/cli/cf-access.ts
5
5
  const ACCESS_KEYRING_SERVICE = "dev.void.cli.access";
@@ -106,53 +106,9 @@ function ensurePlatformAccessToken(apiUrl, challenged = false, required = false,
106
106
  keyringTokens.set(origin, token);
107
107
  writeKeyringPassword(ACCESS_KEYRING_SERVICE, account, token);
108
108
  }
109
- const probedHosts = /* @__PURE__ */ new Set();
110
- /**
111
- * If the CLI is about to talk to a Cloudflare-Access-gated staging host,
112
- * probe the locally-installed `cloudflared` binary for a cached user JWT
113
- * and export it as `CF_ACCESS_TOKEN`. On interactive shells with no cached
114
- * token, open a browser login flow to populate the cache, then re-read it.
115
- *
116
- * Cached per-host so that an early non-gated call (e.g. prod) does not
117
- * permanently disable the probe for a later gated call (e.g. staging) in
118
- * the same process. Noop when:
119
- * - a service-token pair is already set (CI path)
120
- * - `CF_ACCESS_TOKEN` is already set (manual override or prior probe)
121
- * - the target host is not gated
122
- * - `cloudflared` is not installed
123
- */
109
+ /** Restore only credentials scoped to this explicitly selected platform origin. */
124
110
  function ensureCloudflaredToken(apiUrl) {
125
- if (!isVoidAccessGatedUrl(apiUrl) || process.env.VOID_ACCESS_ORIGIN || process.env.VOID_ACCESS_CREDENTIALS) {
126
- ensurePlatformAccessToken(apiUrl);
127
- return;
128
- }
129
- if (process.env.CF_ACCESS_CLIENT_ID && process.env.CF_ACCESS_CLIENT_SECRET) return;
130
- if (process.env.CF_ACCESS_TOKEN) return;
131
- if (!isVoidAccessGatedUrl(apiUrl)) return;
132
- const host = new URL(apiUrl).hostname;
133
- if (probedHosts.has(host)) return;
134
- probedHosts.add(host);
135
- let token = runCloudflared([
136
- "access",
137
- "token",
138
- `-app=${apiUrl}`
139
- ]);
140
- if (!token && process.stdin.isTTY && process.stdout.isTTY) {
141
- runCloudflared([
142
- "access",
143
- "login",
144
- apiUrl
145
- ], {
146
- inherit: true,
147
- timeoutMs: 12e4
148
- });
149
- token = runCloudflared([
150
- "access",
151
- "token",
152
- `-app=${apiUrl}`
153
- ]);
154
- }
155
- if (token) process.env.CF_ACCESS_TOKEN = token;
111
+ ensurePlatformAccessToken(apiUrl);
156
112
  }
157
113
  function runCloudflared(args, opts) {
158
114
  try {
@@ -7,14 +7,6 @@
7
7
  * 2. User JWT (`CF_ACCESS_TOKEN`) — dev path, typically populated via `cloudflared access token`
8
8
  * 3. No headers — prod, or unprotected hostnames
9
9
  */
10
- function isVoidAccessGatedUrl(targetUrl) {
11
- try {
12
- const url = new URL(targetUrl);
13
- return url.protocol === "https:" && (url.hostname.endsWith(".staging.void.cloud") || url.hostname.endsWith(".staging.void.app"));
14
- } catch {
15
- return false;
16
- }
17
- }
18
10
  function accessHeaders(env) {
19
11
  const id = env.CF_ACCESS_CLIENT_ID;
20
12
  const secret = env.CF_ACCESS_CLIENT_SECRET;
@@ -26,7 +18,7 @@ function accessHeaders(env) {
26
18
  if (typeof token === "string" && token.length > 0) return { "cf-access-token": token };
27
19
  return {};
28
20
  }
29
- /** Attach shared Void Access credentials only to known hosted staging origins. */
21
+ /** Attach Access credentials only to their explicitly scoped origin. */
30
22
  function cfAccessHeaders(env, targetUrl) {
31
23
  let origin;
32
24
  try {
@@ -52,7 +44,7 @@ function cfAccessHeaders(env, targetUrl) {
52
44
  } catch {
53
45
  return {};
54
46
  }
55
- return isVoidAccessGatedUrl(targetUrl) ? accessHeaders(env) : {};
47
+ return {};
56
48
  }
57
49
  /**
58
50
  * Capture credentials for a Cloudflare Worker readiness request whose target
@@ -72,4 +64,4 @@ function scopedAccessCredentials(env, targetUrl) {
72
64
  } : { CF_ACCESS_TOKEN: headers["cf-access-token"] } });
73
65
  }
74
66
  //#endregion
75
- export { trustedCloudflareWorkerAccessHeaders as i, isVoidAccessGatedUrl as n, scopedAccessCredentials as r, cfAccessHeaders as t };
67
+ export { scopedAccessCredentials as n, trustedCloudflareWorkerAccessHeaders as r, cfAccessHeaders as t };
@@ -0,0 +1,2 @@
1
+ import { t as prepareCfBuildOutput } from "./cf-build-output-U8o1Gl6X.mjs";
2
+ export { prepareCfBuildOutput };