void 0.10.10 → 0.10.11

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 (103) hide show
  1. package/AGENT_PROMPT.md +4 -0
  2. package/README.md +1 -1
  3. package/dist/{agents-Bmr5tFFb.mjs → agents-CtgBYqld.mjs} +1 -1
  4. package/dist/{auth-cmd-Cw1edJdZ.mjs → auth-cmd-BqsdZJp5.mjs} +3 -3
  5. package/dist/{better-auth-shared-BvnM9px6.d.mts → better-auth-shared-DealXecJ.d.mts} +1 -1
  6. package/dist/{build-cmd-C6kNDJBv.mjs → build-cmd-Bujrv5q-.mjs} +3 -3
  7. package/dist/{cache-DIUSnIjJ.mjs → cache-C11V8Fxq.mjs} +3 -3
  8. package/dist/{cancel-deploy-BosnzEHC.mjs → cancel-deploy-fwFYF04b.mjs} +2 -2
  9. package/dist/cli/cli.mjs +124 -41
  10. package/dist/cli/env-schema-probe.d.mts +96 -0
  11. package/dist/cli/env-schema-probe.mjs +272 -0
  12. package/dist/{client-C9FG6Vzc.mjs → client-Gb71-XkG.mjs} +12 -2
  13. package/dist/{config-BdUctCZD.mjs → config-CutEMNGJ.mjs} +3 -3
  14. package/dist/{config-BcAeIPe3.mjs → config-E03l1C_h.mjs} +2 -2
  15. package/dist/{create-project-CjYX23M_.mjs → create-project-DsYvl3TB.mjs} +3 -3
  16. package/dist/{db-BvKV34IK.mjs → db-PZBsLSGb.mjs} +27 -27
  17. package/dist/{delete-CThKLXfi.mjs → delete-mh6p-zkQ.mjs} +3 -3
  18. package/dist/deploy-DT8wsPZd.mjs +6990 -0
  19. package/dist/{discover-BuVVSAum.mjs → discover-CJHyvYfR.mjs} +2 -2
  20. package/dist/dist-DaKKDf8D.mjs +41 -0
  21. package/dist/{domain-DMrBabBQ.mjs → domain-DiaNQbrl.mjs} +2 -2
  22. package/dist/entry-D7yy4xVH.mjs +100 -0
  23. package/dist/{env-BfG7O71F.mjs → env-AAHU02L6.mjs} +5 -5
  24. package/dist/env-mask-Dd47NbR6.mjs +90 -0
  25. package/dist/env-public-BfiLcMBk.d.mts +140 -0
  26. package/dist/{env-types-D51bnR-c.mjs → env-types-QBj-ndax.mjs} +2 -2
  27. package/dist/env-validation-BdDlGhbN.mjs +1069 -0
  28. package/dist/{gen-Bee261SV.mjs → gen-oup1xBN0.mjs} +8 -8
  29. package/dist/{github-cmd-DfeFEasr.mjs → github-cmd-BdNaOVNa.mjs} +3 -3
  30. package/dist/{handler-imD0UVDT.d.mts → handler-Cjh8uM3Y.d.mts} +1 -1
  31. package/dist/{headers-CTAjX-UO.mjs → headers-BQknpzkn.mjs} +2 -2
  32. package/dist/index.d.mts +1 -1
  33. package/dist/index.mjs +41 -33
  34. package/dist/{init-xfwW7cLp.mjs → init-Dl2PKuQn.mjs} +13 -14
  35. package/dist/{link-Co136MEs.mjs → link-CdGHSIy-.mjs} +4 -4
  36. package/dist/{list-BKDjA3M5.mjs → list-CPwFDZ_c.mjs} +3 -3
  37. package/dist/{login-CrOTnR_6.mjs → login-BT3H8PN3.mjs} +2 -2
  38. package/dist/{logs-DlAg25ww.mjs → logs-Bt313ax7.mjs} +3 -2
  39. package/dist/{mcp-BNjMGMB0.mjs → mcp-DoM3_nhd.mjs} +7 -2
  40. package/dist/{node-CnE-SZCk.mjs → node-BDx8pmhq.mjs} +5 -5
  41. package/dist/{package-json-B0NuUWGd.mjs → package-json-Cx1osYo6.mjs} +1 -1
  42. package/dist/pages/client.d.mts +1 -1
  43. package/dist/pages/index.d.mts +1 -23
  44. package/dist/pages/index.mjs +5 -5
  45. package/dist/pages/islands-plugin.mjs +2 -2
  46. package/dist/pages/protocol.d.mts +2 -2
  47. package/dist/{plugin-inference-CJxi_fWI.mjs → plugin-inference-DMeavIJ6.mjs} +4 -98
  48. package/dist/{prepare-BRyC4TCC.mjs → prepare-DOBTY0o4.mjs} +10 -10
  49. package/dist/preset-BGrvB4Bl.mjs +539 -0
  50. package/dist/{project-cmd-B2bcKefD.mjs → project-cmd-D_w-4w5B.mjs} +13 -9
  51. package/dist/{project-paths-tpdR1mJR.mjs → project-paths-BQd7OmIo.mjs} +1 -1
  52. package/dist/project-paths-GpziKeQQ.d.mts +25 -0
  53. package/dist/{project-tsconfig-D9uSVVpA.mjs → project-tsconfig-B-QtXjLQ.mjs} +2 -2
  54. package/dist/{protocol-6hTJ04T1.d.mts → protocol-Bnb0LFp3.d.mts} +1 -1
  55. package/dist/provision-BLrCEBbI.mjs +2557 -0
  56. package/dist/requests-B8sZxaFM.mjs +50 -0
  57. package/dist/{resolve-project-D2HI3TrG.mjs → resolve-project-BBMtLLV9.mjs} +1 -1
  58. package/dist/{rollback-9dfmB-YZ.mjs → rollback-CkvTFXx5.mjs} +2 -2
  59. package/dist/{route-types-CfKfhbIg.mjs → route-types-COI2DsZv.mjs} +2 -2
  60. package/dist/{runner-h272wcPj.mjs → runner-kapo9aPs.mjs} +3 -3
  61. package/dist/{runner-pg-waxJOnBb.mjs → runner-pg-CHM76xuC.mjs} +1 -1
  62. package/dist/runtime/better-auth-pg.d.mts +1 -1
  63. package/dist/runtime/better-auth.d.mts +1 -1
  64. package/dist/runtime/env-public.d.mts +1 -139
  65. package/dist/runtime/env-public.mjs +2 -90
  66. package/dist/runtime/handler.d.mts +1 -1
  67. package/dist/runtime/live.d.mts +1 -1
  68. package/dist/runtime/validator.d.mts +1 -1
  69. package/dist/runtime/ws-server.d.mts +1 -1
  70. package/dist/runtime/ws.d.mts +2 -2
  71. package/dist/{scan-Dp_Gyzs3.mjs → scan-DEwlM_Xy.mjs} +2 -2
  72. package/dist/{scan-i7Yz54fv.mjs → scan-DYXkrasO.mjs} +4 -4
  73. package/dist/{secret-DeMnMcV0.mjs → secret-Dt32J6RI.mjs} +3 -3
  74. package/dist/{skills-DsdNDtX3.mjs → skills-CLjN0uUO.mjs} +2 -2
  75. package/dist/{subcommand-prompt-DtES-oP6.mjs → subcommand-prompt-BzV8iQZo.mjs} +1 -1
  76. package/dist/sveltekit.mjs +1 -1
  77. package/dist/{validate-DT7nFMlf.mjs → validate-Cw_RLeTj.mjs} +1 -1
  78. package/dist/{yarn-pnp-CW8LB6g_.mjs → yarn-pnp-DJn3SAHF.mjs} +1 -1
  79. package/getting-started-prompt.txt +3 -1
  80. package/package.json +5 -3
  81. package/skills/void/SKILL.md +34 -33
  82. package/skills/void/docs/guide/auth.md +8 -0
  83. package/skills/void/docs/guide/deployment.md +1 -1
  84. package/skills/void/docs/guide/env-vars.md +14 -6
  85. package/skills/void/docs/guide/queues.md +4 -0
  86. package/skills/void/docs/integrations/cloudflare.md +64 -5
  87. package/skills/void/docs/node_modules/void/AGENT_PROMPT.md +4 -0
  88. package/skills/void/docs/node_modules/void/README.md +1 -1
  89. package/skills/void/docs/node_modules/void/node_modules/@types/proper-lockfile/README.md +51 -0
  90. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/pathslash/README.md +64 -0
  91. package/skills/void/docs/node_modules/void/node_modules/pathslash/README.md +64 -0
  92. package/skills/void/docs/node_modules/void/node_modules/proper-lockfile/CHANGELOG.md +108 -0
  93. package/skills/void/docs/node_modules/void/node_modules/proper-lockfile/README.md +183 -0
  94. package/skills/void/docs/node_modules/void/skills/void/SKILL.md +34 -33
  95. package/skills/void/docs/node_modules/void/test/e2e/README.md +85 -0
  96. package/skills/void/docs/reference/cli.md +74 -14
  97. package/dist/deploy-B02JyKP9.mjs +0 -3748
  98. package/dist/dotenv-D_UbC_vc.mjs +0 -173
  99. package/dist/env-validation-CeC2FL66.mjs +0 -163
  100. package/dist/pathe.M-eThtNZ-CQzLbt4c.mjs +0 -150
  101. package/dist/preset-CVvwCeIy.mjs +0 -208
  102. package/skills/void/docs/node_modules/void/node_modules/@void/md/node_modules/pathe/README.md +0 -73
  103. package/skills/void/docs/node_modules/void/node_modules/pathe/README.md +0 -73
@@ -0,0 +1,183 @@
1
+ # proper-lockfile
2
+
3
+ [![NPM version][npm-image]][npm-url] [![Downloads][downloads-image]][npm-url] [![Build Status][travis-image]][travis-url] [![Coverage Status][codecov-image]][codecov-url] [![Dependency status][david-dm-image]][david-dm-url] [![Dev Dependency status][david-dm-dev-image]][david-dm-dev-url]
4
+
5
+ [npm-url]:https://npmjs.org/package/proper-lockfile
6
+ [downloads-image]:https://img.shields.io/npm/dm/proper-lockfile.svg
7
+ [npm-image]:https://img.shields.io/npm/v/proper-lockfile.svg
8
+ [travis-url]:https://travis-ci.org/moxystudio/node-proper-lockfile
9
+ [travis-image]:https://img.shields.io/travis/moxystudio/node-proper-lockfile/master.svg
10
+ [codecov-url]:https://codecov.io/gh/moxystudio/node-proper-lockfile
11
+ [codecov-image]:https://img.shields.io/codecov/c/github/moxystudio/node-proper-lockfile/master.svg
12
+ [david-dm-url]:https://david-dm.org/moxystudio/node-proper-lockfile
13
+ [david-dm-image]:https://img.shields.io/david/moxystudio/node-proper-lockfile.svg
14
+ [david-dm-dev-url]:https://david-dm.org/moxystudio/node-proper-lockfile?type=dev
15
+ [david-dm-dev-image]:https://img.shields.io/david/dev/moxystudio/node-proper-lockfile.svg
16
+
17
+ An inter-process and inter-machine lockfile utility that works on a local or network file system.
18
+
19
+
20
+ ## Installation
21
+
22
+ `$ npm install proper-lockfile`
23
+
24
+
25
+ ## Design
26
+
27
+ There are various ways to achieve [file locking](http://en.wikipedia.org/wiki/File_locking).
28
+
29
+ This library utilizes the `mkdir` strategy which works atomically on any kind of file system, even network based ones.
30
+ The lockfile path is based on the file path you are trying to lock by suffixing it with `.lock`.
31
+
32
+ When a lock is successfully acquired, the lockfile's `mtime` (modified time) is periodically updated to prevent staleness. This allows to effectively check if a lock is stale by checking its `mtime` against a stale threshold. If the update of the mtime fails several times, the lock might be compromised. The `mtime` is [supported](http://en.wikipedia.org/wiki/Comparison_of_file_systems) in almost every `filesystem`.
33
+
34
+
35
+ ### Comparison
36
+
37
+ This library is similar to [lockfile](https://github.com/isaacs/lockfile) but the latter has some drawbacks:
38
+
39
+ - It relies on `open` with `O_EXCL` flag which has problems in network file systems. `proper-lockfile` uses `mkdir` which doesn't have this issue.
40
+
41
+ > O_EXCL is broken on NFS file systems; programs which rely on it for performing locking tasks will contain a race condition.
42
+
43
+ - The lockfile staleness check is done via `ctime` (creation time) which is unsuitable for long running processes. `proper-lockfile` constantly updates lockfiles `mtime` to do proper staleness check.
44
+
45
+ - It does not check if the lockfile was compromised which can lead to undesirable situations. `proper-lockfile` checks the lockfile when updating the `mtime`.
46
+
47
+ - It has a default value of `0` for the stale option which isn't good because any crash or process kill that the package can't handle gracefully will leave the lock active forever.
48
+
49
+
50
+ ### Compromised
51
+
52
+ `proper-lockfile` does not detect cases in which:
53
+
54
+ - A `lockfile` is manually removed and someone else acquires the lock right after
55
+ - Different `stale`/`update` values are being used for the same file, possibly causing two locks to be acquired on the same file
56
+
57
+ `proper-lockfile` detects cases in which:
58
+
59
+ - Updates to the `lockfile` fail
60
+ - Updates take longer than expected, possibly causing the lock to become stale for a certain amount of time
61
+
62
+
63
+ As you see, the first two are a consequence of bad usage. Technically, it was possible to detect the first two but it would introduce complexity and eventual race conditions.
64
+
65
+
66
+ ## Usage
67
+
68
+ ### .lock(file, [options])
69
+
70
+ Tries to acquire a lock on `file` or rejects the promise on error.
71
+
72
+ If the lock succeeds, a `release` function is provided that should be called when you want to release the lock. The `release` function also rejects the promise on error (e.g. when the lock was already compromised).
73
+
74
+ Available options:
75
+
76
+ - `stale`: Duration in milliseconds in which the lock is considered stale, defaults to `10000` (minimum value is `5000`)
77
+ - `update`: The interval in milliseconds in which the lockfile's `mtime` will be updated, defaults to `stale/2` (minimum value is `1000`, maximum value is `stale/2`)
78
+ - `retries`: The number of retries or a [retry](https://www.npmjs.org/package/retry) options object, defaults to `0`
79
+ - `realpath`: Resolve symlinks using realpath, defaults to `true` (note that if `true`, the `file` must exist previously)
80
+ - `fs`: A custom fs to use, defaults to `graceful-fs`
81
+ - `onCompromised`: Called if the lock gets compromised, defaults to a function that simply throws the error which will probably cause the process to die
82
+ - `lockfilePath`: Custom lockfile path. e.g.: If you want to lock a directory and create the lock file inside it, you can pass `file` as `<dir path>` and `options.lockfilePath` as `<dir path>/dir.lock`
83
+
84
+
85
+ ```js
86
+ const lockfile = require('proper-lockfile');
87
+
88
+ lockfile.lock('some/file')
89
+ .then((release) => {
90
+ // Do something while the file is locked
91
+
92
+ // Call the provided release function when you're done,
93
+ // which will also return a promise
94
+ return release();
95
+ })
96
+ .catch((e) => {
97
+ // either lock could not be acquired
98
+ // or releasing it failed
99
+ console.error(e)
100
+ });
101
+
102
+ // Alternatively, you may use lockfile('some/file') directly.
103
+ ```
104
+
105
+
106
+ ### .unlock(file, [options])
107
+
108
+ Releases a previously acquired lock on `file` or rejects the promise on error.
109
+
110
+ Whenever possible you should use the `release` function instead (as exemplified above). Still there are cases in which it's hard to keep a reference to it around code. In those cases `unlock()` might be handy.
111
+
112
+ Available options:
113
+
114
+ - `realpath`: Resolve symlinks using realpath, defaults to `true` (note that if `true`, the `file` must exist previously)
115
+ - `fs`: A custom fs to use, defaults to `graceful-fs`
116
+ - `lockfilePath`: Custom lockfile path. e.g.: If you want to lock a directory and create the lock file inside it, you can pass `file` as `<dir path>` and `options.lockfilePath` as `<dir path>/dir.lock`
117
+
118
+
119
+ ```js
120
+ const lockfile = require('proper-lockfile');
121
+
122
+ lockfile.lock('some/file')
123
+ .then(() => {
124
+ // Do something while the file is locked
125
+
126
+ // Later..
127
+ return lockfile.unlock('some/file');
128
+ });
129
+ ```
130
+
131
+ ### .check(file, [options])
132
+
133
+ Check if the file is locked and its lockfile is not stale, rejects the promise on error.
134
+
135
+ Available options:
136
+
137
+ - `stale`: Duration in milliseconds in which the lock is considered stale, defaults to `10000` (minimum value is `5000`)
138
+ - `realpath`: Resolve symlinks using realpath, defaults to `true` (note that if `true`, the `file` must exist previously)
139
+ - `fs`: A custom fs to use, defaults to `graceful-fs`
140
+ - `lockfilePath`: Custom lockfile path. e.g.: If you want to lock a directory and create the lock file inside it, you can pass `file` as `<dir path>` and `options.lockfilePath` as `<dir path>/dir.lock`
141
+
142
+
143
+ ```js
144
+ const lockfile = require('proper-lockfile');
145
+
146
+ lockfile.check('some/file')
147
+ .then((isLocked) => {
148
+ // isLocked will be true if 'some/file' is locked, false otherwise
149
+ });
150
+ ```
151
+
152
+ ### .lockSync(file, [options])
153
+
154
+ Sync version of `.lock()`.
155
+ Returns the `release` function or throws on error.
156
+
157
+ ### .unlockSync(file, [options])
158
+
159
+ Sync version of `.unlock()`.
160
+ Throws on error.
161
+
162
+ ### .checkSync(file, [options])
163
+
164
+ Sync version of `.check()`.
165
+ Returns a boolean or throws on error.
166
+
167
+
168
+ ## Graceful exit
169
+
170
+ `proper-lockfile` automatically removes locks if the process exits, except if the process is killed with SIGKILL or it crashes due to a VM fatal error (e.g.: out of memory).
171
+
172
+
173
+ ## Tests
174
+
175
+ `$ npm test`
176
+ `$ npm test -- --watch` during development
177
+
178
+ The test suite is very extensive. There's even a stress test to guarantee exclusiveness of locks.
179
+
180
+
181
+ ## License
182
+
183
+ Released under the [MIT License](https://www.opensource.org/licenses/mit-license.php).
@@ -32,39 +32,40 @@ Then ask what to do next.
32
32
 
33
33
  ## Task Routing
34
34
 
35
- | User intent | Docs file(s) |
36
- | ----------------------------------------- | ----------------------------------------------------------------------------------------- |
37
- | CLI command syntax, flags, env vars | `docs/reference/cli.md` |
38
- | Initial setup, onboarding, first app | `docs/guide/quickstart.md`, `docs/reference/cli.md` |
39
- | App type detection and mode behavior | `docs/guide/app-types.md`, `docs/reference/config.md` |
40
- | Server/API routing and middleware | `docs/guide/server-routing.md`, `docs/integrations/hono.md` |
41
- | Pages mode, loader/action, forms, layouts | `docs/guide/pages-routing/*.md`, `docs/guide/type-safety.md` |
42
- | Database and migrations | `docs/guide/database.md`, `docs/guide/type-safety.md` |
43
- | Typed fetch and end-to-end typing | `docs/guide/typed-fetch.md`, `docs/guide/type-safety.md` |
44
- | Authentication | `docs/guide/auth.md`, `docs/guide/env-vars.md` |
45
- | Cloudflare runtime bindings and config | `docs/integrations/cloudflare.md`, `docs/reference/config.md`, `docs/guide/env-vars.md` |
46
- | AI inference (Workers AI, providers) | `docs/guide/ai.md` |
47
- | KV / storage / queues / cron jobs | `docs/guide/kv.md`, `docs/guide/storage.md`, `docs/guide/queues.md`, `docs/guide/jobs.md` |
48
- | SSR and caching | `docs/guide/ssr.md`, `docs/guide/edge/*.md` |
49
- | Rewrites, redirects, fallbacks | `docs/guide/edge/rewrites.md`, `docs/guide/edge/redirects.md`, `docs/reference/config.md` |
50
- | Static site generation | `docs/guide/ssg.md` |
51
- | Deployment and CI | `docs/guide/deployment.md`, `docs/reference/cli.md` |
52
- | Project status, deployment history | `docs/reference/cli.md` |
53
- | Cache purging | `docs/reference/cli.md` |
54
- | Project logs, runtime errors | `docs/reference/cli.md` |
55
- | Secrets management (put/sync/delete) | `docs/reference/cli.md`, `docs/guide/env-vars.md` |
56
- | Typed env vars (`defineEnv`, `env.ts`) | `docs/guide/env-vars.md` |
57
- | Custom domain setup | `docs/reference/cli.md` |
58
- | Database status, reset, seed, export | `docs/reference/cli.md`, `docs/guide/database.md` |
59
- | Auth login/logout/whoami | `docs/reference/cli.md` |
60
- | Overview / introduction | `docs/guide/index.md` |
61
- | API surface details | `docs/reference/api.md` |
62
- | Meta framework integration | `docs/integrations/frameworks/*.md` |
63
- | Coding agent setup | `docs/integrations/agents.md` |
64
- | Node.js / Bun / Deno targets | `docs/integrations/nodejs-bun-deno.md` |
65
- | ORMs and external databases | `docs/integrations/orms-and-external-dbs.md` |
66
- | Project structure and conventions | `docs/reference/structure.md` |
67
- | Resource/binding inference | `docs/reference/resource-inference.md` |
35
+ | User intent | Docs file(s) |
36
+ | ------------------------------------------ | ----------------------------------------------------------------------------------------- |
37
+ | CLI command syntax, flags, env vars | `docs/reference/cli.md` |
38
+ | Initial setup, onboarding, first app | `docs/guide/quickstart.md`, `docs/reference/cli.md` |
39
+ | App type detection and mode behavior | `docs/guide/app-types.md`, `docs/reference/config.md` |
40
+ | Server/API routing and middleware | `docs/guide/server-routing.md`, `docs/integrations/hono.md` |
41
+ | Pages mode, loader/action, forms, layouts | `docs/guide/pages-routing/*.md`, `docs/guide/type-safety.md` |
42
+ | Database and migrations | `docs/guide/database.md`, `docs/guide/type-safety.md` |
43
+ | Typed fetch and end-to-end typing | `docs/guide/typed-fetch.md`, `docs/guide/type-safety.md` |
44
+ | Authentication | `docs/guide/auth.md`, `docs/guide/env-vars.md` |
45
+ | Cloudflare runtime bindings and config | `docs/integrations/cloudflare.md`, `docs/reference/config.md`, `docs/guide/env-vars.md` |
46
+ | AI inference (Workers AI, providers) | `docs/guide/ai.md` |
47
+ | KV / storage / queues / cron jobs | `docs/guide/kv.md`, `docs/guide/storage.md`, `docs/guide/queues.md`, `docs/guide/jobs.md` |
48
+ | SSR and caching | `docs/guide/ssr.md`, `docs/guide/edge/*.md` |
49
+ | Rewrites, redirects, fallbacks | `docs/guide/edge/rewrites.md`, `docs/guide/edge/redirects.md`, `docs/reference/config.md` |
50
+ | Static site generation | `docs/guide/ssg.md` |
51
+ | Deployment and CI | `docs/guide/deployment.md`, `docs/reference/cli.md` |
52
+ | Self-host deploy to own Cloudflare account | `docs/integrations/cloudflare.md`, `docs/reference/cli.md` |
53
+ | Project status, deployment history | `docs/reference/cli.md` |
54
+ | Cache purging | `docs/reference/cli.md` |
55
+ | Project logs, runtime errors | `docs/reference/cli.md` |
56
+ | Secrets management (put/sync/delete) | `docs/reference/cli.md`, `docs/guide/env-vars.md` |
57
+ | Typed env vars (`defineEnv`, `env.ts`) | `docs/guide/env-vars.md` |
58
+ | Custom domain setup | `docs/reference/cli.md` |
59
+ | Database status, reset, seed, export | `docs/reference/cli.md`, `docs/guide/database.md` |
60
+ | Auth login/logout/whoami | `docs/reference/cli.md` |
61
+ | Overview / introduction | `docs/guide/index.md` |
62
+ | API surface details | `docs/reference/api.md` |
63
+ | Meta framework integration | `docs/integrations/frameworks/*.md` |
64
+ | Coding agent setup | `docs/integrations/agents.md` |
65
+ | Node.js / Bun / Deno targets | `docs/integrations/nodejs-bun-deno.md` |
66
+ | ORMs and external databases | `docs/integrations/orms-and-external-dbs.md` |
67
+ | Project structure and conventions | `docs/reference/structure.md` |
68
+ | Resource/binding inference | `docs/reference/resource-inference.md` |
68
69
 
69
70
  ## Working Rules
70
71
 
@@ -0,0 +1,85 @@
1
+ # `packages/void/test/e2e`
2
+
3
+ Gated live-account end-to-end tests. These run REAL Cloudflare operations against a REAL account, so
4
+ they **skip unless credentials are present**. Locally that means exporting the env vars below; in CI
5
+ they run on **pushes to `main`** (see [In CI](#in-ci)).
6
+
7
+ ## `cloudflare-deploy-live.test.ts`
8
+
9
+ Deploys `playground/spa` (D1 + KV + cron) to the target account via `void deploy --backend cloudflare`,
10
+ verifies the live worker answers HTTP 200, then deletes the worker and every resource it created.
11
+
12
+ It does **not** drive `--provision`: that path fails closed in non-interactive shells by design (a
13
+ spawned CLI has no TTY, and CI cannot commit back the ids a create would mint). So the test plays the
14
+ provisioner's role itself — it creates the id-bearing D1 + KV directly with `wrangler … create`,
15
+ writes their real ids into the app's root config exactly as `--provision` would, then runs the
16
+ CI-safe `void deploy --backend cloudflare` (no `--provision`). That exercises the real
17
+ build → tamper-guard → remote-migrations → `wrangler deploy` pipeline end to end.
18
+
19
+ ### Prerequisites
20
+
21
+ The suite is skipped unless BOTH env vars are set:
22
+
23
+ | Env var | Purpose |
24
+ | ------------------------ | -------------------------------------------------------------------------- |
25
+ | `VOID_E2E_CF_TOKEN` | Cloudflare API token that can create + delete Workers Scripts, D1, and KV. |
26
+ | `VOID_E2E_CF_ACCOUNT_ID` | Cloudflare account id to deploy into. |
27
+
28
+ The token needs, on that account, **Workers Scripts: Edit**, **D1: Edit**, and **Workers KV Storage:
29
+ Edit** (Edit implies read, covering the ownership/teardown list calls). Cron triggers ride along with
30
+ the worker deploy — no extra permission.
31
+
32
+ The account must also have a **workers.dev subdomain** already registered (with its wildcard TLS cert
33
+ provisioned). Without one, `wrangler deploy` uploads the worker but cannot publish a public URL, and
34
+ the HTTP-200 assertion has nothing to hit. Opening the Workers & Pages dashboard once registers a
35
+ subdomain automatically; a freshly-registered subdomain takes a few minutes for its cert to go live,
36
+ during which the first run may see a TLS handshake failure — rerun once the cert is ready.
37
+
38
+ With no env vars the suite SKIPS cleanly (0 run, N skipped).
39
+
40
+ ### Running it
41
+
42
+ ```sh
43
+ # Ensure the CLI is built first (dist/cli/cli.mjs):
44
+ vp run build:core
45
+
46
+ VOID_E2E_CF_TOKEN=... VOID_E2E_CF_ACCOUNT_ID=... vp test run packages/void/test/e2e
47
+ ```
48
+
49
+ ### In CI
50
+
51
+ `VOID_E2E_CF_TOKEN` and `VOID_E2E_CF_ACCOUNT_ID` are **environment secrets** on the `cloudflare-e2e`
52
+ GitHub Environment (not repo secrets), and a dedicated `live-e2e` job in `.github/workflows/ci.yml`
53
+ consumes them — the main `test` job carries no creds at all. Two layers keep the account token off
54
+ untrusted code:
55
+
56
+ - The `live-e2e` job runs only on a direct push to `main` (`github.event_name == 'push' && github.ref
57
+ == 'refs/heads/main'`), so `pull_request` runs, tag pushes, and `workflow_call` (release) skip it.
58
+ - The `cloudflare-e2e` environment's deployment branch policy allows `main` **only**, enforced by
59
+ GitHub server-side on the run's ref. A `pull_request` run's ref is `refs/pull/<n>/merge`, so it can
60
+ never reach the secret **even if a PR edits this workflow** — the expression-level gate alone would
61
+ be bypassable that way; the environment ref-check is the real boundary.
62
+
63
+ So the credentialed live deploy runs on every merge to `main`; everywhere else the creds are empty and
64
+ the suite SKIPS (the `test` job still imports the file and skips it). The `live-e2e` job itself is
65
+ fail-closed — a preflight step errors if either credential is empty (a missing, deleted, or
66
+ not-yet-rotated secret), so a misconfigured gate is loud instead of a silent green skip. Each
67
+ `live-e2e` run also gets `VOID_E2E_RUN_ID = <run-id>-<attempt>` for the unique per-run resource names
68
+ below.
69
+
70
+ ### Resource naming & cleanup
71
+
72
+ Each run derives a UNIQUE resource name — `void-e2e-cf-deploy-<suffix>` — so overlapping runs never
73
+ collide on remote resources. The suffix is `VOID_E2E_RUN_ID` (CI: `<run-id>-<attempt>`) or, locally, a
74
+ timestamp + random. Derived names mirror the provisioner: `<name>-db` (D1), `<name>-kv` (KV). The
75
+ shared `void-e2e-cf-deploy-` prefix keeps every resource greppable, so an orphan from a hard-killed run
76
+ is easy to find and `wrangler delete`. A pre-run ownership gate refuses to start if the run's names
77
+ already exist (failing closed on any lookup it cannot confirm), so the test never adopts or deletes a
78
+ resource it does not own. Teardown runs even when the deploy or an assertion fails.
79
+
80
+ > **Local concurrency:** unique names isolate _remote_ resources, but a run also snapshots and
81
+ > overwrites the shared `playground/spa/wrangler.jsonc` and builds in place. Do **not** run two live
82
+ > e2e invocations against the same checkout at once — they would race that file. CI is unaffected (each
83
+ > runner is an isolated checkout, and only the single `main`-push `live-e2e` job deploys). The deploy
84
+ > test also asserts the returned host's worker label equals this run's `WORKER_NAME`, so a clobbered
85
+ > overlay fails loudly instead of validating another run's worker.
@@ -32,6 +32,7 @@ Use this page as a command reference. If you are setting up a project for the fi
32
32
  | `void auth login` | Authenticate with Void |
33
33
  | `void project link` | Link directory to a project |
34
34
  | `void project logs` | Show runtime logs from deployed project |
35
+ | `void project requests` | Show request-level traffic (status, method, timing) |
35
36
  | `void project rollback` | Roll back to a previous deployment |
36
37
  | `void project cancel` | Cancel an active deployment |
37
38
  | `void project purge-cache` | Purge all cached pages |
@@ -162,12 +163,12 @@ void project logs [--level <level>] [--filter <text>] [--range <duration>] [--de
162
163
 
163
164
  Show runtime logs from the deployed project. Uses the linked project from `.void/project.json`.
164
165
 
165
- | Flag | Purpose | Default |
166
- | -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- |
167
- | `--range <duration>` | How far back to look. Format: `<number><unit>` (m/h/d). Max 7d. | `1h` |
168
- | `--level <level>` | Filter by log level. One of `error`, `warn`, `info`, `log`, `debug`, `all`. `error` also includes uncaught exceptions and non-`ok` requests. | `all` |
169
- | `--filter <text>` | Case-insensitive **substring** match against log message text and exception name/message — not a level filter. Shows the full request entry on any hit. | none |
170
- | `--deployment <id>` | Filter logs to a specific deployment ID. | none |
166
+ | Flag | Purpose | Default |
167
+ | -------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- |
168
+ | `--range <duration>` | How far back to look. Format: `<number><unit>` (m/h/d). Max 7d. | `1h` |
169
+ | `--level <level>` | Filter by log level. One of `error`, `warn`, `info`, `log`, `debug`, `all`. `error` also includes uncaught exceptions, non-`ok` outcomes, and any 5xx response — even when the worker neither threw nor logged. | `all` |
170
+ | `--filter <text>` | Case-insensitive **substring** match against log message text and exception name/message — not a level filter. Shows the full request entry on any hit. | none |
171
+ | `--deployment <id>` | Filter logs to a specific deployment ID. | none |
171
172
 
172
173
  Output shows one line per request (`HH:MM:SS METHOD URL STATUS`) with indented console log and exception lines beneath. Errors and exceptions are colored red, warnings yellow.
173
174
 
@@ -178,7 +179,32 @@ void project logs --level error --range 12h
178
179
  void project logs --level error --filter websocket
179
180
  ```
180
181
 
181
- Tip: `void project logs` only sees what Cloudflare Tail captures — top-level `console.*` calls and uncaught throws. Application errors caught and persisted to your own DB are invisible to tail. Surface them via `console.error(...)` or `void/log`'s `logger.error(...)` so they show up under `--level error`.
182
+ Tip: `void project logs` only sees what Cloudflare Tail captures — top-level `console.*` calls and uncaught throws. Application errors caught and persisted to your own DB are invisible to tail. Surface them via `console.error(...)` or `void/log`'s `logger.error(...)` so they show up under `--level error`. For 5xx that never reach your worker at all (edge-router errors, static/SPA projects), use `void project requests --status 5xx`.
183
+
184
+ ### `void project requests`
185
+
186
+ ```
187
+ void project requests [--status <filter>] [--range <duration>]
188
+ ```
189
+
190
+ Show request-level traffic recorded at the edge for the linked project: one line per request with time, method, HTTP status, request type, and server timing. Unlike `void project logs` (which only has rows for invoked user workers), this reads the edge request-metering data, so it also surfaces:
191
+
192
+ - **5xx the edge router generated itself** — missing deployment manifest, static-asset read timeouts, SSR dispatch timeouts — which never invoke your worker and so never appear in logs.
193
+ - **Requests to static/SPA projects**, which are served directly from storage and never run a worker.
194
+
195
+ | Flag | Purpose | Default |
196
+ | -------------------- | --------------------------------------------------------------------------------------------- | ------- |
197
+ | `--status <filter>` | Filter by status: a class (`2xx`, `3xx`, `4xx`, `5xx`) or an exact 3-digit code (e.g. `500`). | none |
198
+ | `--range <duration>` | How far back to look. Format: `<number><unit>` (m/h/d). Max 7d. | `1h` |
199
+
200
+ Output shows one line per request (`HH:MM:SS METHOD STATUS TYPE DURATION`). 5xx are colored red, 4xx yellow. Note: request paths are not recorded, so this view shows status and type rather than URLs — use `void project logs` for per-URL, per-log detail on requests that do reach your worker.
201
+
202
+ Examples:
203
+
204
+ ```
205
+ void project requests --status 5xx
206
+ void project requests --range 24h
207
+ ```
182
208
 
183
209
  ### `void project rollback [deployId]`
184
210
 
@@ -226,19 +252,22 @@ If `--project` is provided, purges that project's cache instead of the linked pr
226
252
 
227
253
  ```
228
254
  void deploy [--project <name>] [--dir <path>] [--spa] [--skip-build] [--debug]
255
+ void deploy --backend cloudflare [--provision]
229
256
  ```
230
257
 
231
258
  Auto-detects your project type and chooses the right pipeline. See [Supported App Types](../guide/app-types.md) and [Deployment](../guide/deployment.md) for details.
232
259
 
233
260
  For Drizzle projects, deploy performs a read-only schema drift check. If a new migration would be generated, deploy stops and tells you to run `void db generate`, review the migration, commit it yourself, and rerun `void deploy`.
234
261
 
235
- | Flag | Purpose |
236
- | ------------------ | ---------------------------------------------------------------------------- |
237
- | `--project <name>` | Target a specific project by slug |
238
- | `--dir <path>` | Deploy a pre-built static directory (skips build) |
239
- | `--spa` | Use SPA mode instead of SSG for static deploys |
240
- | `--skip-build` | Skip the build step (use existing build output) |
241
- | `--debug` | Mirror the structured deploy log to stderr (also written to `~/.void/logs/`) |
262
+ | Flag | Purpose |
263
+ | ---------------------- | -------------------------------------------------------------------------------------------- |
264
+ | `--project <name>` | Target a specific project by slug; not supported with `--backend cloudflare` |
265
+ | `--dir <path>` | Deploy a pre-built static directory (skips build); not supported with `--backend cloudflare` |
266
+ | `--spa` | Use SPA mode instead of SSG for static deploys; not supported with `--backend cloudflare` |
267
+ | `--skip-build` | Skip the build step (use existing build output); not supported with `--backend cloudflare` |
268
+ | `--backend cloudflare` | Deploy to your own Cloudflare account instead of the Void platform |
269
+ | `--provision` | Create missing bindings (D1/KV/R2/Queues/Hyperdrive); requires `--backend cloudflare` |
270
+ | `--debug` | Mirror the structured deploy log to stderr (also written to `~/.void/logs/`) |
242
271
 
243
272
  Every deploy writes a structured JSONL trace to `~/.void/logs/deploy-<timestamp>.jsonl` regardless of `--debug`. On failure the path is printed at the end of the error message so you can attach it when reporting platform issues. `VOID_DEPLOY_DEBUG=1` is accepted as an alternate trigger for stderr mirroring.
244
273
 
@@ -252,6 +281,37 @@ If no project is linked and no override is provided, CLI prompts to link or crea
252
281
 
253
282
  That fallback is mainly for projects that skipped Void project setup during `void init`.
254
283
 
284
+ ### `void deploy --backend cloudflare`
285
+
286
+ Deploy the built worker straight to **your own** Cloudflare account instead of the Void platform. This path uses your local `wrangler` auth and your root `wrangler.jsonc` — no Void login or linked project is involved.
287
+
288
+ ```
289
+ void deploy --backend cloudflare # deploy using resources already in wrangler.jsonc
290
+ void deploy --backend cloudflare --provision # create any missing resources first, then deploy
291
+ ```
292
+
293
+ Prerequisites:
294
+
295
+ - A Cloudflare account must be **pinned**: set `account_id` in your root `wrangler.jsonc`, or export `CLOUDFLARE_ACCOUNT_ID`. A multi-account token otherwise makes wrangler prompt (or error in CI), which Void cannot intercept.
296
+ - Authenticate wrangler (`wrangler login`, or set `CLOUDFLARE_API_TOKEN`). Deploy needs a token with `Workers Scripts:Edit` plus read on the resources you bind; `--provision` additionally needs per-product `*:Edit` (D1, KV, R2, Queues, Hyperdrive).
297
+ - `CLOUDFLARE_API_TOKEN` is **required** to provision a Hyperdrive config for the first time — `wrangler login` covers every other resource, but wrangler exposes no machine-readable Hyperdrive list, so Void checks for an existing config over the Cloudflare REST API, which OAuth cannot authenticate. Without a token, `--provision` stops before touching your account. Alternatively create the Hyperdrive config yourself and put its id in `wrangler.jsonc` — deploying an already-provisioned Hyperdrive app needs no token.
298
+ - `--skip-build` is **not supported** with `--backend cloudflare`: this backend validates the artifact the build emits (worker `vars` in `dist/ssr/wrangler.json`, the generated auth schema), so there is nothing to check without a fresh build.
299
+ - `--project`, `--dir` and `--spa` are **not supported** with `--backend cloudflare` either, and are rejected rather than ignored: no Void project is resolved on this path, and it uploads the worker your build emits rather than a static directory.
300
+ - Local Docker is required to build apps that use the sandbox.
301
+
302
+ What it does, in order: settles the app class before any account op (v1 supports **full Void apps on the Cloudflare Workers target** -- worker-bearing apps running Void's routing, with D1/KV/R2/Queues/Hyperdrive and, on D1/SQLite, auth + ISR; framework SSR of every kind, static/SPA/SSG apps, node/bun/deno targets, and PostgreSQL apps with auth or with checked-in migrations all fail closed with guidance), pins the account and checks auth, provisions or drift-checks resources, **builds**, then gates on the artifact the build emitted — production secrets checked against the build's effective mode/envDir, the auth schema, and migration validation — then applies remote D1 migrations for SQLite apps (verifying the applied set equals the validated set and none remain pending), and finally runs `wrangler deploy` on exactly the verified artifact. Auth apps must ship checked-in migrations that produce the Better Auth schema — the managed platform's runtime auth-migration step does not run on this backend.
303
+
304
+ The build deliberately comes **before** the secret, auth-schema, and migration gates, because those gates inspect the real emitted worker rather than a prediction of it. A missing secret or a bad migration surfaces after the build has run — relevant when a build is expensive or has side effects. Remote D1 migrations run only once every gate has passed, so a failed gate mutates nothing remote.
305
+
306
+ `--provision` creates any D1 database, KV namespace, R2 bucket, Queues, Hyperdrive config, and the ISR cache namespace your source needs, then lets wrangler write the real ids into your root `wrangler.jsonc`. It is **idempotent** — re-running creates nothing that already exists (it reads existing ids first). Notes:
307
+
308
+ - **Provision is a single-operator, dev-machine action.** The lock that guards it is per local config path only; it does not coordinate across machines. Two people provisioning the same account at once could create duplicate resources. `--provision` also **fails closed in CI / non-interactive shells** unless your committed `wrangler.jsonc` already covers every resource (a provable no-op). Provision locally, commit the updated `wrangler.jsonc`, then let CI run `void deploy --backend cloudflare`.
309
+ - **Your `wrangler.jsonc` is rewritten.** When wrangler writes the new ids, it preserves your comments but normalizes the whole file's indentation — expect that in the diff.
310
+ - **Your `.env*` values ship as plaintext.** All four of `.env`, `.env.local`, `.env.production` and `.env.production.local` are loaded by this backend and baked into the worker's `vars` — the `.local` files included, unlike managed `void deploy`. A value also present in the shell environment is stripped back out. Move real secrets to `wrangler secret put <NAME>` so they are not committed into `wrangler.json`. Deploy warns on likely-plaintext secrets and hard-blocks on missing required secrets.
311
+ - **First deploy of a not-yet-deployed worker:** its remote secrets can't be listed yet, so the secret gate prints the required key names and the `wrangler secret put <NAME>` commands to bootstrap them on the draft worker before deploying (or add a value to `.env` / `.env.production` and rerun).
312
+
313
+ See the [Cloudflare integration guide](../integrations/cloudflare.md#deploy-to-your-own-cloudflare-account) for the full walk-through.
314
+
255
315
  ## Database
256
316
 
257
317
  ### `void db push`