void 0.7.12 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (142) hide show
  1. package/AGENT_PROMPT.md +1 -1
  2. package/README.md +2 -2
  3. package/dist/{agents-DqkFfc2c.mjs → agents-Dkgafwfr.mjs} +1 -1
  4. package/dist/{auth-cmd-bS88H4Lb.mjs → auth-cmd-B1-7r6ng.mjs} +3 -3
  5. package/dist/{better-auth-shared-D2JaoCs4.mjs → better-auth-shared-CbAF6sOM.mjs} +1 -1
  6. package/dist/{better-auth-shared-HXlHRw02.d.mts → better-auth-shared-Fzyk5yS1.d.mts} +2 -7
  7. package/dist/{cache-DUDCNty6.mjs → cache-CGYC-2LW.mjs} +5 -5
  8. package/dist/{cancel-deploy-DOuSbPwX.mjs → cancel-deploy-B4j31z7d.mjs} +4 -4
  9. package/dist/canonical-json-CEyQaVDa.mjs +13 -0
  10. package/dist/cli/cli.mjs +44 -31
  11. package/dist/{client-C_DYiXeu.mjs → client-C-nH6yz3.mjs} +5 -5
  12. package/dist/{collect-HqAuilH6.mjs → collect-9rO3JFNM.mjs} +1 -1
  13. package/dist/{config-DyUSwbeX.mjs → config--wXmVOoe.mjs} +10 -8
  14. package/dist/{config-CeRQg3Lz.mjs → config-BVEC0lti.mjs} +11 -2
  15. package/dist/{config-CvHtTM0q.mjs → config-hhMYPVRT.mjs} +3 -12
  16. package/dist/{create-project-hvFe6rbI.mjs → create-project-BGnQMy5N.mjs} +44 -18
  17. package/dist/{db-YEYSTfGw.mjs → db-CT5Xg6ds.mjs} +42 -37
  18. package/dist/{delete-XyM_VD9o.mjs → delete-eMGTHHB9.mjs} +5 -5
  19. package/dist/{deploy-CPAEgVQm.mjs → deploy-7EA_lKq9.mjs} +169 -99
  20. package/dist/{discover-CKGQpis8.mjs → discover-C8N1I4tK.mjs} +9 -6
  21. package/dist/{domain-Dvj7u8tr.mjs → domain-UfLrp2vc.mjs} +64 -22
  22. package/dist/{drizzle-Cx7cVwrE.mjs → drizzle-DmaANP4-.mjs} +1 -1
  23. package/dist/{env-Bjl0rzuf.mjs → env-Cvdbbm_N.mjs} +7 -7
  24. package/dist/{env-helpers-Dw95CU8e.d.mts → env-helpers-Bt9yYg5I.d.mts} +1 -1
  25. package/dist/{env-types-BSQghXbx.mjs → env-types-D6qI1ThV.mjs} +8 -19
  26. package/dist/{env-validation-Buy5pe3u.mjs → env-validation-DBJsxZLz.mjs} +4 -4
  27. package/dist/{gen-DU8NIdrH.mjs → gen-Cn2hZ8RR.mjs} +37 -31
  28. package/dist/{handler-DJTuxB10.d.mts → handler-BPhL8AmU.d.mts} +3 -3
  29. package/dist/{headers-CuVHn6Kl.mjs → headers-wAPJigtE.mjs} +3 -3
  30. package/dist/index.d.mts +3 -3
  31. package/dist/index.mjs +273 -104
  32. package/dist/{init-iIiQWzyB.mjs → init-DL6syXuF.mjs} +124 -38
  33. package/dist/{link-DdXqlUiJ.mjs → link-C5x1E-XZ.mjs} +5 -5
  34. package/dist/{list-9Bxa5Odn.mjs → list-ezL7hqDV.mjs} +5 -5
  35. package/dist/{login-C_MfDjhu.mjs → login-CkLr-AaI.mjs} +3 -3
  36. package/dist/{logs-DjqCpEER.mjs → logs-MnGILmLz.mjs} +4 -4
  37. package/dist/{mcp-vA0880_K.mjs → mcp-B84MmVAW.mjs} +3 -3
  38. package/dist/{node-gxRQXIRT.mjs → node-fpywdcbN.mjs} +6 -6
  39. package/dist/{output-D3g5otMC.mjs → output-DeiS4oEX.mjs} +1 -1
  40. package/dist/pages/client.d.mts +1 -1
  41. package/dist/pages/head-client.d.mts +1 -1
  42. package/dist/pages/head.d.mts +1 -1
  43. package/dist/pages/index.d.mts +28 -3
  44. package/dist/pages/index.mjs +6 -5
  45. package/dist/pages/islands-plugin.d.mts +1 -1
  46. package/dist/pages/islands-plugin.mjs +15 -14
  47. package/dist/pages/protocol.d.mts +2 -2
  48. package/dist/pages/protocol.mjs +1 -1
  49. package/dist/{pathe.M-eThtNZ-D-kmWkCS.mjs → pathe.M-eThtNZ-BrPhGF_K.mjs} +1 -1
  50. package/dist/plan-aD3wRDqF.mjs +271 -0
  51. package/dist/{plugin-inference-BexV6LL3.mjs → plugin-inference-Ba1uGdIy.mjs} +26 -20
  52. package/dist/{prepare-BEkH89oX.mjs → prepare-BrAISonG.mjs} +29 -19
  53. package/dist/{preset-CYQh93UF.mjs → preset-BRsCi8ZB.mjs} +10 -8
  54. package/dist/{project-DhB4A8_g.mjs → project-CH9pdo16.mjs} +1 -1
  55. package/dist/{project-cmd-CeXO06hG.mjs → project-cmd-JQUzv3qF.mjs} +10 -10
  56. package/dist/project-paths-CCMrHYQm.mjs +100 -0
  57. package/dist/{project-slug-KRvHQEQI.mjs → project-slug-De4UjtD9.mjs} +0 -1
  58. package/dist/{project-tsconfig-Bfy55qvs.mjs → project-tsconfig-HAGjfY6w.mjs} +10 -5
  59. package/dist/{protocol-D7r_deVZ.d.mts → protocol-mcSsdMij.d.mts} +3 -3
  60. package/dist/providers--_pvxpNN.d.mts +7 -0
  61. package/dist/{resolve-project-DdjLQ2tB.mjs → resolve-project-CNpUbUHd.mjs} +1 -1
  62. package/dist/{rollback-C8OSMxmq.mjs → rollback-CoAAvC18.mjs} +4 -4
  63. package/dist/{route-types-qVL-v-CB.mjs → route-types-jxRfWuCb.mjs} +1 -1
  64. package/dist/{runner-C0d3lJo1.mjs → runner-BkGBfr4e.mjs} +4 -2
  65. package/dist/{runner-pg-Bd_172vF.mjs → runner-pg-BXP0JpHW.mjs} +1 -1
  66. package/dist/runtime/ai.mjs +2 -2
  67. package/dist/runtime/auth.d.mts +1 -1
  68. package/dist/runtime/better-auth-pg.d.mts +1 -1
  69. package/dist/runtime/better-auth-pg.mjs +2 -2
  70. package/dist/runtime/better-auth.d.mts +1 -1
  71. package/dist/runtime/better-auth.mjs +2 -2
  72. package/dist/runtime/client.d.mts +2 -2
  73. package/dist/runtime/client.mjs +1 -1
  74. package/dist/runtime/env-helpers.d.mts +1 -1
  75. package/dist/runtime/env-public-client.d.mts +1 -1
  76. package/dist/runtime/env-public.d.mts +2 -2
  77. package/dist/runtime/env-public.mjs +1 -1
  78. package/dist/runtime/env.mjs +1 -1
  79. package/dist/runtime/fetch-stream.d.mts +1 -1
  80. package/dist/runtime/fetch-stream.mjs +1 -1
  81. package/dist/runtime/fetch.d.mts +1 -1
  82. package/dist/runtime/fetch.mjs +1 -1
  83. package/dist/runtime/handler.d.mts +1 -1
  84. package/dist/runtime/handler.mjs +1 -1
  85. package/dist/runtime/isr.mjs +1 -1
  86. package/dist/runtime/live.d.mts +2 -2
  87. package/dist/runtime/live.mjs +1 -1
  88. package/dist/runtime/migration-handler.d.mts +33 -1
  89. package/dist/runtime/migration-handler.mjs +398 -23
  90. package/dist/runtime/remote/index.mjs +1 -1
  91. package/dist/runtime/sandbox.d.mts +73 -3
  92. package/dist/runtime/sandbox.mjs +239 -3
  93. package/dist/runtime/validator.d.mts +1 -1
  94. package/dist/runtime/ws-server.d.mts +2 -2
  95. package/dist/runtime/ws.d.mts +3 -3
  96. package/dist/{scan-CKpylFj9.mjs → scan-2YmJkYAf.mjs} +4 -3
  97. package/dist/{scan-CkK1Hzpa.mjs → scan-DzzHqtiT.mjs} +82 -43
  98. package/dist/{secret-NDvlqAN2.mjs → secret-mz8t_CML.mjs} +5 -5
  99. package/dist/{skills-SAG0WyVn.mjs → skills-B_ynF4lA.mjs} +3 -3
  100. package/dist/{subcommand-prompt-q9T06dpg.mjs → subcommand-prompt-CPuV7tPW.mjs} +2 -2
  101. package/dist/sveltekit.mjs +1 -1
  102. package/dist/{validate-DW3ViKTA.mjs → validate-CNWm-PsL.mjs} +49 -9
  103. package/dist/{yarn-pnp-6LD6_3Ej.mjs → yarn-pnp-QgEYVC3V.mjs} +1 -1
  104. package/getting-started-prompt.txt +2 -2
  105. package/package.json +3 -2
  106. package/schema.json +5 -0
  107. package/skills/void/SKILL.md +1 -1
  108. package/skills/void/docs/guide/ai.md +1 -1
  109. package/skills/void/docs/guide/app-types.md +1 -1
  110. package/skills/void/docs/guide/database/postgresql.md +1 -1
  111. package/skills/void/docs/guide/edge/headers.md +1 -1
  112. package/skills/void/docs/guide/edge/static-assets.md +34 -0
  113. package/skills/void/docs/guide/pages-routing/overview.md +1 -1
  114. package/skills/void/docs/guide/quickstart.md +2 -2
  115. package/skills/void/docs/guide/sandboxes.md +3 -2
  116. package/skills/void/docs/guide/ssr.md +25 -2
  117. package/skills/void/docs/integrations/cloudflare.md +5 -3
  118. package/skills/void/docs/integrations/frameworks/overview.md +1 -1
  119. package/skills/void/docs/integrations/nodejs-bun-deno.md +10 -9
  120. package/skills/void/docs/node_modules/void/AGENT_PROMPT.md +1 -1
  121. package/skills/void/docs/node_modules/void/README.md +2 -2
  122. package/skills/void/docs/node_modules/void/skills/void/SKILL.md +1 -1
  123. package/skills/void/docs/reference/api.md +204 -13
  124. package/skills/void/docs/reference/cli.md +55 -7
  125. package/skills/void/docs/reference/config.md +27 -4
  126. package/skills/void/docs/reference/resource-inference.md +1 -1
  127. /package/dist/{auth-DmuALf16.d.mts → auth-SfRBhXan.d.mts} +0 -0
  128. /package/dist/{auth-migrations-BwLPwRgH.mjs → auth-migrations-BqJoGqGQ.mjs} +0 -0
  129. /package/dist/{cf-access-BW8K93Fm.mjs → cf-access-DKDsgwOU.mjs} +0 -0
  130. /package/dist/{defer-2ARBu8Et.mjs → defer-DkoEwda-.mjs} +0 -0
  131. /package/dist/{dist-q8b2Mjgb.mjs → dist-DR9sIMbM.mjs} +0 -0
  132. /package/dist/{dist-D2L3_KTK.mjs → dist-abzUneor.mjs} +0 -0
  133. /package/dist/{dotenv-HQNhRalS.mjs → dotenv-Bkoqyq9r.mjs} +0 -0
  134. /package/dist/{env-raw-DtfQ9E31.mjs → env-raw-zk5JQKZe.mjs} +0 -0
  135. /package/dist/{fetch-error-DZ868Xq4.d.mts → fetch-error-BbixZ9vW.d.mts} +0 -0
  136. /package/dist/{fetch-error-CEr0ACTl.mjs → fetch-error-rXermVU3.mjs} +0 -0
  137. /package/dist/{head-C7QW7UY1.d.mts → head-CZs8dMxG.d.mts} +0 -0
  138. /package/dist/{log-7ChR5Fbc.mjs → log-CWWZV4V1.mjs} +0 -0
  139. /package/dist/{magic-string.es-DS_lmuBe.mjs → magic-string.es-C1Fb0uxq.mjs} +0 -0
  140. /package/dist/{providers-BlFNPYen.mjs → providers-uC0PJg1c.mjs} +0 -0
  141. /package/dist/{standard-schema-D2qvCEYV.d.mts → standard-schema-WhHcCaqJ.d.mts} +0 -0
  142. /package/dist/{types-DG_Ynnyd.d.mts → types-C8wsi1hv.d.mts} +0 -0
@@ -4,7 +4,7 @@ outline: deep
4
4
 
5
5
  # API Reference
6
6
 
7
- This page is the source of truth for public `void` exports. Use it when you already know what feature you want and need the exact import, signature, or return type.
7
+ This page is the source of truth for user-facing `void` exports. Use it when you already know what feature you want and need the exact import, signature, or return type. Some exported subpaths are implementation support for adapters, generated workers, or internal runtime wiring and are intentionally not listed as app APIs.
8
8
 
9
9
  ## Plugin
10
10
 
@@ -193,7 +193,8 @@ function defineRender(
193
193
 
194
194
  ```ts
195
195
  interface RenderAssetTags {
196
- head: string; // Script and style tags for <head>
196
+ css: string; // Stylesheet links for <head>
197
+ preloads: string; // Modulepreload and dev client tags for <head>
197
198
  body: string; // Script tags for before </body>
198
199
  }
199
200
  ```
@@ -533,11 +534,11 @@ The typed client is built on [ofetch](https://github.com/unjs/ofetch) with a typ
533
534
 
534
535
  ## Database
535
536
 
536
- Imported from `"void/db"`. The `db` export is a [Drizzle ORM](https://orm.drizzle.team) instance for [Cloudflare D1](https://developers.cloudflare.com/d1/). See the [Database guide](../guide/database.md) for usage and the [Drizzle docs](https://orm.drizzle.team/docs/select) for the full query API.
537
+ Imported from `"void/db"`. The `db` export is a [Drizzle ORM](https://orm.drizzle.team) instance for the configured database dialect: [Cloudflare D1](https://developers.cloudflare.com/d1/) by default, or PostgreSQL when `void.json` sets `"database": "pg"` / `"postgresql"`. See the [Database guide](../guide/database.md) for usage and the [Drizzle docs](https://orm.drizzle.team/docs/select) for the full query API.
537
538
 
538
539
  ### `db`
539
540
 
540
- Default Drizzle D1 instance, pre-wired with the `env.DB` binding and your schema from `db/schema.ts`.
541
+ Default Drizzle instance, pre-wired with your schema from `db/schema.ts`.
541
542
 
542
543
  ```ts
543
544
  import { db } from 'void/db';
@@ -546,11 +547,18 @@ import { users } from '@schema';
546
547
  const allUsers = await db.select().from(users).all();
547
548
  ```
548
549
 
549
- When the Void plugin is active, `void/db` is served as a virtual module that auto-wires the D1 binding with your schema. The published npm fallback uses a lazy proxy that resolves the `DB` binding at first access.
550
+ When the Void plugin is active, `void/db` is served as a virtual module that auto-wires the active database with your schema.
551
+
552
+ - D1 projects resolve the `DB` binding and expose `DrizzleD1Database<Schema>`.
553
+ - PostgreSQL projects use `DATABASE_URL` during local development and Hyperdrive's `connectionString` in production, exposing `NodePgDatabase<Schema>`.
554
+
555
+ The published npm fallback uses a lazy D1 proxy that resolves the `DB` binding at first access.
550
556
 
551
557
  ### `createDb(database)`
552
558
 
553
- Creates a Drizzle D1 instance from a specific D1 binding. Use this when you have multiple D1 databases or need a non-default binding.
559
+ Creates a Drizzle instance for the active dialect.
560
+
561
+ For D1 projects, pass a specific D1 binding. Use this when you have multiple D1 databases or need a non-default binding.
554
562
 
555
563
  ```ts
556
564
  import { createDb } from 'void/db';
@@ -559,10 +567,22 @@ import { env } from 'cloudflare:workers';
559
567
  const db = createDb(env.MY_OTHER_DB);
560
568
  ```
561
569
 
570
+ For PostgreSQL projects, pass a connection string.
571
+
572
+ ```ts
573
+ import { createDb } from 'void/db';
574
+
575
+ const db = createDb('postgres://user:password@host:5432/app');
576
+ ```
577
+
562
578
  **Signature:**
563
579
 
564
580
  ```ts
565
- function createDb(d1: D1Database): DrizzleD1Database;
581
+ // D1
582
+ function createDb(d1: D1Database): DrizzleD1Database<Schema>;
583
+
584
+ // PostgreSQL
585
+ function createDb(connectionString: string): NodePgDatabase<Schema>;
566
586
  ```
567
587
 
568
588
  ### Query Operators
@@ -602,6 +622,98 @@ The callback receives:
602
622
 
603
623
  Seed modules can export either `default` or a named `seed` function.
604
624
 
625
+ ## KV
626
+
627
+ Imported from `"void/kv"`.
628
+
629
+ ### `kv`
630
+
631
+ Typed JSON-aware client for the inferred `KV` binding.
632
+
633
+ ```ts
634
+ import { kv } from 'void/kv';
635
+
636
+ await kv.put('settings', { theme: 'dark' });
637
+ const settings = await kv.get<{ theme: string }>('settings');
638
+ ```
639
+
640
+ **Key exports:** `kv`, `createKV(namespace)`, `KVClient`, `KVMap`, `PutOptions`, `ListOptions`.
641
+
642
+ `kv.map(prefix)` creates a typed namespaced view where every key is stored under `prefix:`.
643
+
644
+ ## Storage
645
+
646
+ Imported from `"void/storage"`.
647
+
648
+ ### `storage`
649
+
650
+ Default [R2 bucket](https://developers.cloudflare.com/r2/) proxy for the inferred `STORAGE` binding.
651
+
652
+ ```ts
653
+ import { storage } from 'void/storage';
654
+
655
+ await storage.put('avatars/alice.png', file);
656
+ const object = await storage.get('avatars/alice.png');
657
+ ```
658
+
659
+ **Key exports:** `storage`, `createStorage(bucket)`.
660
+
661
+ ## AI
662
+
663
+ Imported from `"void/ai"`.
664
+
665
+ ### `ai`
666
+
667
+ Typed AI client for Workers AI models and AI Gateway-backed third-party providers.
668
+
669
+ ```ts
670
+ import { ai } from 'void/ai';
671
+
672
+ const result = await ai.run('@cf/meta/llama-3.1-8b-instruct', {
673
+ messages: [{ role: 'user', content: 'Summarize this release note.' }],
674
+ });
675
+ ```
676
+
677
+ **Key exports:** `ai`, `VoidAi`, model input/response types. See [AI](../guide/ai.md) for provider setup and streaming examples.
678
+
679
+ ## ISR
680
+
681
+ Imported from `"void/isr"`.
682
+
683
+ ### `revalidate(options)`
684
+
685
+ Revalidate ISR-cached pages on demand. In local development this is a no-op because there is no edge ISR cache.
686
+
687
+ ```ts
688
+ import { revalidate } from 'void/isr';
689
+
690
+ await revalidate({ paths: ['/', '/blog/hello'] });
691
+ await revalidate({ all: true });
692
+ ```
693
+
694
+ **Signature:**
695
+
696
+ ```ts
697
+ function revalidate(options: { paths?: string[]; all?: boolean }): Promise<void>;
698
+ ```
699
+
700
+ ## Logging
701
+
702
+ Imported from `"void/log"`.
703
+
704
+ ### `logger`
705
+
706
+ Structured logger that emits one JSON line per call so deployed logs can be filtered by message and fields.
707
+
708
+ ```ts
709
+ import { logger } from 'void/log';
710
+
711
+ logger.info('checkout completed', { orderId, userId });
712
+ logger.error('webhook failed', { provider: 'stripe', attempt: 3 });
713
+ ```
714
+
715
+ **Methods:** `logger.error(message, fields?)`, `logger.warn(message, fields?)`, `logger.info(message, fields?)`.
716
+
605
717
  ## Types
606
718
 
607
719
  ### `CloudContext`
@@ -691,9 +803,42 @@ Empty stub interface augmented at build time by the generated `.void/routes.d.ts
691
803
  import type { RouteMap } from 'void/routes';
692
804
  ```
693
805
 
694
- ## Environment Types
806
+ ## Environment
807
+
808
+ Imported from `"void/env"`.
809
+
810
+ ### `defineEnv(schema)`
695
811
 
696
- Importing `"void/env"` provides global Cloudflare environment types:
812
+ Register an env schema and return the typed [`env`](#env) proxy. Void auto-discovers `env.ts`, imports it during dev/build/deploy, generates `.void/env.d.ts`, validates production secrets before deploy, and validates values at worker boot.
813
+
814
+ ```ts
815
+ import { defineEnv, string, number, oneOf, url } from 'void/env';
816
+
817
+ export default defineEnv({
818
+ STRIPE_KEY: string().secret(),
819
+ PORT: number().default(3000),
820
+ NODE_ENV: oneOf(['development', 'production']),
821
+ VITE_PUBLIC_URL: url().public(),
822
+ });
823
+ ```
824
+
825
+ ### `env`
826
+
827
+ Typed runtime proxy for declared env keys. Unknown keys and bindings pass through as `unknown`.
828
+
829
+ ```ts
830
+ import { env } from 'void/env';
831
+
832
+ const port = env.PORT;
833
+ ```
834
+
835
+ ### Schema helpers
836
+
837
+ `void/env` includes Standard Schema-compatible helpers: `string()`, `number()`, `boolean()`, `url()`, `email()`, `oneOf([...])`, and `json<T>()`. Each helper supports `.optional()`, `.default(value)`, `.secret()`, and `.public()`.
838
+
839
+ ### Types
840
+
841
+ `void/env` also provides global Cloudflare environment types:
697
842
 
698
843
  ```ts
699
844
  /// <reference types="void/env" />
@@ -732,6 +877,7 @@ function voidVue(options?: VoidVueOptions): Plugin[];
732
877
  ```ts
733
878
  interface VoidVueOptions {
734
879
  vue?: VuePluginOptions; // passed through to @vitejs/plugin-vue
880
+ viewTransitions?: boolean; // enable View Transitions API for navigations
735
881
  }
736
882
  ```
737
883
 
@@ -746,6 +892,8 @@ Imported from `"@void/vue"`.
746
892
  | `useParams()` | Returns dynamic route params for the page currently being rendered. |
747
893
  | `useNavigation()` | Returns pending navigation state: `{ state, location, method }`, where `state` is `"idle"`, `"loading"`, or `"submitting"` and `location` is the pending destination. |
748
894
  | `useForm(url, defaults, options?)` | Typed reactive form helper bound to a page action URL. Returns `{ data, post, put, patch, delete, pending, errors, error, hasChanges, wasSuccessful, recentlySuccessful, reset, clearErrors, clearError }`. |
895
+ | `useIslandForm(defaults)` | Form helper for island components where the action URL is inferred from the current island request. Returns the same form state and submit helpers as `useForm()`. |
896
+ | `action(url, options?)` | Awaitable one-shot page action helper. Uses `POST` by default and accepts `{ data, method, params }`, where `method` can be `"PUT"`, `"PATCH"`, or `"DELETE"`. Returns an `ActionResult`. |
749
897
  | `useShared()` | Returns shared data injected by middleware via `c.set("shared", {...})`. |
750
898
 
751
899
  Vue `Link` GET `data` is merged into the rendered `href` query string. Primitive values are serialized with `String(value)`, arrays become repeated keys, `null` and `undefined` are omitted, and nested objects throw. `prefetch` and `reloadDocument` are GET-only and throw for mutation links.
@@ -794,6 +942,7 @@ Imported from `"@void/react"`.
794
942
  | `useParams()` | Returns dynamic route params for the page currently being rendered. |
795
943
  | `useNavigation()` | Returns pending navigation state: `{ state, location, method }`, where `state` is `"idle"`, `"loading"`, or `"submitting"` and `location` is the pending destination. |
796
944
  | `useForm(url, defaults, options?)` | Form helper hook. Returns `{ data, setData, post, put, patch, delete, pending, errors, error, hasChanges, wasSuccessful, recentlySuccessful, reset, clearErrors, clearError }`. |
945
+ | `useIslandForm(defaults)` | Form helper hook for island components where the action URL is inferred from the current island request. Returns the same form state and submit helpers as `useForm()`. |
797
946
  | `action(url, options?)` | Awaitable one-shot page action helper. Uses `POST` by default and accepts `{ data, method, params }`, where `method` can be `"PUT"`, `"PATCH"`, or `"DELETE"`. Returns an `ActionResult`. |
798
947
  | `useShared()` | Returns shared data injected by middleware via `c.set("shared", {...})`. |
799
948
  | `Deferred<T>` | React-only prop type for `defer()` results. It is `Promise<T>` and is consumed with React `use()`. |
@@ -835,6 +984,10 @@ function voidSvelte(options?: VoidSvelteOptions): Plugin[];
835
984
  interface VoidSvelteOptions {
836
985
  svelte?: SveltePluginOptions; // passed through to @sveltejs/vite-plugin-svelte
837
986
  viewTransitions?: boolean; // enable View Transitions API
987
+ prefetch?: {
988
+ hoverDelay?: number;
989
+ cacheFor?: number | string | [string, string];
990
+ };
838
991
  }
839
992
  ```
840
993
 
@@ -846,6 +999,8 @@ Imported from `"@void/svelte"`.
846
999
  | ---------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
847
1000
  | `Link` | Svelte component for SPA navigation. Renders `<a>` for GET, `<button>` for non-GET methods. Props: `href`, `method`, `data`, `prefetch`, `cacheFor`, `preserveScroll`, `preserveState`, `replace`, `reloadDocument`, `viewTransition`, `onNavigate`. |
848
1001
  | `useForm(url, defaults, options?)` | Form helper using Svelte 5 runes. Returns `{ data, post, put, patch, delete, pending, errors, error, hasChanges, wasSuccessful, recentlySuccessful, reset, clearErrors, clearError }`. |
1002
+ | `useIslandForm(defaults)` | Form helper for island components where the action URL is inferred from the current island request. Returns the same form state and submit helpers as `useForm()`. |
1003
+ | `action(url, options?)` | Awaitable one-shot page action helper. Uses `POST` by default and accepts `{ data, method, params }`, where `method` can be `"PUT"`, `"PATCH"`, or `"DELETE"`. Returns an `ActionResult`. |
849
1004
  | `useShared()` | Returns shared data injected by middleware via `c.set("shared", {...})`. |
850
1005
  | `useRouter()` | Returns the Void Router with current route state (`url`, `path`, `query`, `params`) and navigation methods: `visit`, `refresh`, awaitable `prefetch`, `flush`, `flushAll`. |
851
1006
  | `useParams()` | Returns dynamic route params for the page currently being rendered. |
@@ -879,6 +1034,10 @@ function voidSolid(options?: VoidSolidOptions): Plugin[];
879
1034
  interface VoidSolidOptions {
880
1035
  solid?: SolidPluginOptions; // passed through to vite-plugin-solid
881
1036
  viewTransitions?: boolean; // enable View Transitions API
1037
+ prefetch?: {
1038
+ hoverDelay?: number;
1039
+ cacheFor?: number | string | [string, string];
1040
+ };
882
1041
  }
883
1042
  ```
884
1043
 
@@ -890,6 +1049,8 @@ Imported from `"@void/solid"`.
890
1049
  | ---------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
891
1050
  | `Link` | Solid component for SPA navigation. Renders `<a>` for GET, `<button>` for non-GET methods. Props: `href`, `method`, `data`, `prefetch`, `cacheFor`, `preserveScroll`, `preserveState`, `replace`, `reloadDocument`, `viewTransition`, `onNavigate`. |
892
1051
  | `useForm(url, defaults, options?)` | Form helper using Solid stores. Returns `{ data, setData, post, put, patch, delete, pending, errors, error, hasChanges, wasSuccessful, recentlySuccessful, reset, clearErrors, clearError }`. |
1052
+ | `useIslandForm(defaults)` | Form helper for island components where the action URL is inferred from the current island request. Returns the same form state and submit helpers as `useForm()`. |
1053
+ | `action(url, options?)` | Awaitable one-shot page action helper. Uses `POST` by default and accepts `{ data, method, params }`, where `method` can be `"PUT"`, `"PATCH"`, or `"DELETE"`. Returns an `ActionResult`. |
893
1054
  | `useShared()` | Returns shared data injected by middleware via `c.set("shared", {...})`. |
894
1055
  | `useRouter()` | Returns the Void Router with current route state (`url`, `path`, `query`, `params`) and navigation methods: `visit`, `refresh`, awaitable `prefetch`, `flush`, `flushAll`. |
895
1056
  | `useParams()` | Returns dynamic route params for the page currently being rendered. |
@@ -897,11 +1058,35 @@ Imported from `"@void/solid"`.
897
1058
 
898
1059
  Solid `Link` GET `data` is merged into the rendered `href` query string. Primitive values are serialized with `String(value)`, arrays become repeated keys, `null` and `undefined` are omitted, and nested objects throw. `prefetch` and `reloadDocument` are GET-only and throw for mutation links.
899
1060
 
900
- ## Subpath Exports
1061
+ ## Markdown Package
1062
+
1063
+ The optional `@void/md` package adds Markdown pages to Pages Routing. Install it alongside a Pages adapter and add `voidMarkdown()` to your Vite plugins.
1064
+
1065
+ ```ts
1066
+ import { voidMarkdown } from '@void/md/plugin';
1067
+
1068
+ export default defineConfig({
1069
+ plugins: [voidPlugin(), voidReact(), voidMarkdown()],
1070
+ });
1071
+ ```
1072
+
1073
+ | Import path | Contents |
1074
+ | ---------------------------- | ---------------------------------------------------------------------------------------- |
1075
+ | `@void/md/plugin` | `voidMarkdown(options?)`, `MarkdownOptions`, `MdPage` |
1076
+ | `@void/md` | `useFrontmatter()`, `FrontmatterContext`, `setFrontmatter()`, `MdPage` |
1077
+ | `@void/md/pages` | Generated metadata for Markdown pages, used for navigation, sidebars, and search indexes |
1078
+ | `@void/md/theme.css` | Full Markdown theme styles |
1079
+ | `@void/md/theme-content.css` | Content-only Markdown styles for apps that provide their own shell/layout |
1080
+
1081
+ See [Markdown Pages](../guide/pages-routing/markdown.md) for setup and framework-specific examples.
1082
+
1083
+ ## User-Facing Imports
1084
+
1085
+ This table lists app-facing imports. Exported implementation subpaths such as `void/pages*`, `void/runtime/*`, and `void/remote*` are used by adapters, generated entries, or internal runtime wiring and are not documented as application APIs.
901
1086
 
902
1087
  | Import path | Contents |
903
1088
  | ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
904
- | `void` | `voidPlugin` named export + all handler/type re-exports |
1089
+ | `void` | `voidPlugin`, handler/type re-exports, `defer`, `Deferred`, `DeferredState`, `InferProps`, `HeadDescriptor` |
905
1090
  | `void/handler` | `defineHandler`, `defineMiddleware`, `defineScheduled`, `defineQueue`, `defineRender`, `defineHead`, types |
906
1091
  | `void/auth` | `defineAuth`, `getUser`, `getSession`, `requireAuth`, `AuthUser`, `AuthSession`, `AuthState` |
907
1092
  | `void/client` | `fetch`, `fetchStream`, `FetchError`, `auth`, `createAuthClient`, `AuthUser`, `AuthSession`, `AuthState` |
@@ -917,9 +1102,15 @@ Solid `Link` GET `data` is merged into the rendered `href` query string. Primiti
917
1102
  | `void/drizzle-arktype` | Re-exports [`drizzle-arktype`](https://orm.drizzle.team/docs/arktype) for schema-derived ArkType validators for Drizzle tables |
918
1103
  | `void/schema-d1` | Re-exports [`drizzle-orm/sqlite-core`](https://orm.drizzle.team/docs/column-types/sqlite) for D1 table and column builders |
919
1104
  | `void/schema-pg` | Re-exports [`drizzle-orm/pg-core`](https://orm.drizzle.team/docs/column-types/pg) for PostgreSQL table and column builders |
920
- | `void/db` | `db` ([Drizzle D1](https://orm.drizzle.team/docs/get-started/d1-new) instance), `createDb`, query operators (`eq`, `and`, `or`, `desc`, `like`, `inArray`, etc.) |
1105
+ | `void/db` | `db` (Drizzle D1 or PostgreSQL instance for the active dialect), `createDb`, query operators (`eq`, `and`, `or`, `desc`, `like`, `inArray`, etc.) |
921
1106
  | `void/seed` | `defineSeed`, `SeedContext`, `SeedFn` for programmatic `void db seed` modules |
1107
+ | `void/kv` | `kv`, `createKV`, typed KV client/map types |
1108
+ | `void/storage` | `storage`, `createStorage` for the inferred R2 binding or a specific `R2Bucket` |
1109
+ | `void/ai` | `ai`, `VoidAi`, model input and response types |
1110
+ | `void/isr` | `revalidate(options)` for on-demand ISR cache invalidation |
1111
+ | `void/log` | `logger` structured logging helper |
922
1112
  | `void/routes` | `RouteMap` and `WebSocketRouteMap` stubs (types only) |
923
1113
  | `void/queues` | `queues` proxy for sending messages to typed queues |
924
1114
  | `void/sandbox` | `getSandbox`, `sandbox`, `Sandbox`, and sandbox option types from the Cloudflare Sandbox SDK. `getSandbox(id)` resolves to the same Durable Object instance for a given `id` across all deploys and rollbacks. DO-level storage (`ctx.storage`) is durable; the container filesystem, processes, and exposed ports are tied to a single container lifetime and are lost on idle (`sleepAfter`, default `10m`), crash, or platform restart. See [Sandboxes › State persistence](../guide/sandboxes.md#state-persistence). |
925
- | `void/env` | Global Cloudflare env types (types only) |
1115
+ | `void/env` | `defineEnv`, `env`, schema helpers (`string`, `number`, `boolean`, `url`, `email`, `oneOf`, `json`), and global Cloudflare env types |
1116
+ | `void/sveltekit` | SvelteKit integration helpers: `withVoidTSConfig()` and `mergeVoidSvelteKitTsconfig()` |
@@ -16,11 +16,14 @@ Use this page as a command reference. If you are setting up a project for the fi
16
16
  | `void prepare` | Generate `.void` artifacts without starting Vite |
17
17
  | `void gen model <name> [cols...]` | Scaffold migration + CRUD routes |
18
18
  | `void gen route <path>` | Create an API route |
19
+ | `void db push` | Apply schema directly without migration files |
20
+ | `void db generate` | Generate SQL migrations from schema changes |
19
21
  | `void db status` | Show local/remote migration status |
20
22
  | `void db reset` | Drop and re-apply all migrations |
21
23
  | `void db seed` | Reset + seed local database |
22
24
  | `void db studio` | Open Drizzle Studio for local database |
23
25
  | `void secret put <name=value>` | Set a production secret |
26
+ | `void secret list` | List production secrets |
24
27
  | `void secret sync .env.local` | Bulk upload secrets from dotenv file |
25
28
  | `void env check [--remote]` | Validate env.ts schema |
26
29
  | `void env types` | Regenerate .void/env.d.ts from env.ts |
@@ -29,7 +32,9 @@ Use this page as a command reference. If you are setting up a project for the fi
29
32
  | `void project link` | Link directory to a project |
30
33
  | `void project logs` | Show runtime logs from deployed project |
31
34
  | `void project rollback` | Roll back to a previous deployment |
35
+ | `void project cancel` | Cancel an active deployment |
32
36
  | `void project purge-cache` | Purge all cached pages |
37
+ | `void mcp` | Start the Void MCP server |
33
38
  | `void init` | Setup wizard for new or existing projects |
34
39
 
35
40
  ## Binary Invocation
@@ -66,7 +71,9 @@ void init [--tsconfig] [--github] [--agents]
66
71
 
67
72
  Setup wizard for Void projects (new or existing).
68
73
 
69
- If run in a scaffoldable empty directory, `void init` scaffolds a Pages starter. If a single Pages adapter is already installed, it reuses that framework; otherwise it asks which framework to scaffold (React, Vue, Svelte, or Solid). It then asks which starter you want: D1, PostgreSQL, or Static Pages. The D1 and PostgreSQL starters write a framework-specific `vite.config.ts`, a `pages/` home page plus `.server.ts` loader, `db/schema.ts`, `db/seed.ts`, a generated initial migration under `db/migrations/`, and `routes/api/hello.ts`. The Static Pages starter writes just the framework-specific `vite.config.ts` and a `pages/` home page so you can add server features later.
74
+ If run in a scaffoldable empty directory, `void init` scaffolds a Pages starter. It asks which scaffold toolchain to use, with Vite+ as the default top option and plain Vite as the alternative. If a single Pages adapter is already installed, it reuses that framework; otherwise it asks which framework to scaffold (React, Vue, Svelte, or Solid). It then asks which starter you want: D1, PostgreSQL, or Static Pages. The D1 and PostgreSQL starters write a framework-specific `vite.config.ts`, a `pages/` home page plus `.server.ts` loader, `db/schema.ts`, `db/seed.ts`, a generated initial migration under `db/migrations/`, and `routes/api/hello.ts`. The Static Pages starter writes just the framework-specific `vite.config.ts` and a `pages/` home page so you can add server features later. Vite+ starters add `vite-plus` and use `vp dev`, `vp build`, and `vp preview` scripts.
75
+
76
+ If run in a non-empty folder that does not look like an app yet, such as a parent `Projects/` folder with subdirectories but no `package.json`, `void init` asks whether to create a new subfolder or continue in the current folder. Creating a subfolder is the default selection.
70
77
 
71
78
  If run in an existing project, `void init` configures the project in place: it ensures `void` and `vite` are declared, adds missing `dev` (`vite`) and `build` (`vite build`) scripts without overwriting existing scripts, and creates or patches `vite.config.*` with `voidPlugin()` when the config shape is safe to edit. If the Vite config is too dynamic to patch confidently, it prints the manual snippet instead of rewriting it.
72
79
 
@@ -182,6 +189,17 @@ Roll back to a previous deployment. Traffic instantly switches to the target dep
182
189
 
183
190
  Only **retained** deployments can be rolled back to. The number of retained deployments depends on your plan (free: 1, solo: 5, pro: 25, unlimited for sponsored/custom).
184
191
 
192
+ ### `void project cancel [deployId]`
193
+
194
+ ```
195
+ void project cancel [deployId]
196
+ ```
197
+
198
+ Cancel an active deployment.
199
+
200
+ - If `[deployId]` is omitted, shows an interactive select menu of active deployments for the linked project
201
+ - If `[deployId]` is provided, cancels that deployment directly
202
+
185
203
  ### `void project delete [name]`
186
204
 
187
205
  Permanently delete a project and all its resources (databases, KV namespaces, R2 buckets, deployments). Requires typing the project slug to confirm.
@@ -232,6 +250,18 @@ That fallback is mainly for projects that skipped Void project setup during `voi
232
250
 
233
251
  ## Database
234
252
 
253
+ ### `void db push`
254
+
255
+ Apply your Drizzle schema directly to the development database without creating migration files. For D1 projects, this updates the local D1 database used by dev. For PostgreSQL projects, this uses `DATABASE_URL` from `.env.local`.
256
+
257
+ Use this for quick schema iteration while prototyping. Before deploying, generate and review migration files with `void db generate`.
258
+
259
+ ### `void db generate`
260
+
261
+ Generate SQL migration files from schema changes.
262
+
263
+ The command compares your current `db/schema.ts` or `db/schema/` modules against the last generated Drizzle snapshot and writes new migration artifacts under `db/migrations/`. Review and commit the generated files before deploying.
264
+
235
265
  ### `void db status`
236
266
 
237
267
  Show migration status. Displays which migrations are applied or pending locally. When logged in and linked to a project, also shows remote status.
@@ -416,6 +446,14 @@ void gen queue emails
416
446
 
417
447
  ## Secrets
418
448
 
449
+ ### `void secret list`
450
+
451
+ ```
452
+ void secret list [--project <name>]
453
+ ```
454
+
455
+ List the production secrets configured for the project. Secret values are never printed.
456
+
419
457
  ### `void secret put`
420
458
 
421
459
  ```
@@ -537,10 +575,12 @@ List all custom domains and their status (active/pending).
537
575
  ### `void domain status`
538
576
 
539
577
  ```
540
- void domain status <hostname> [--project <name>]
578
+ void domain status <hostname> [--project <name>] [--verbose]
541
579
  ```
542
580
 
543
- Check verification and SSL status for a specific domain. Shows hostname, status, SSL status, and any verification errors.
581
+ Check verification and SSL status for a specific domain. Prints a rolled-up state (`awaiting_dns`, `verifying_dns`, `issuing_cert`, `deploying_cert`, `awaiting_deployment`, `active`, `error`, or `pending`) with a one-line diagnostic explaining what Cloudflare is doing and any user action required. When DNS records are still pending, the command also prints the exact TXT records to add at your DNS provider.
582
+
583
+ Pass `--verbose` to additionally print the raw multi-line status breakdown (DB status, SSL status, ownership state, verification errors) underneath the rollup.
544
584
 
545
585
  Project resolution for domain commands follows the same order as deploy (`--project`, `VOID_PROJECT`, linked project).
546
586
 
@@ -556,9 +596,17 @@ Runs all agent setup steps:
556
596
 
557
597
  If no agent is detected, `void init --agents` asks you to choose from Claude Code, Cursor, Codex, Gemini CLI, or Generic.
558
598
 
599
+ ### `void mcp`
600
+
601
+ ```
602
+ void mcp
603
+ ```
604
+
605
+ Start the Void MCP server over stdio for supported coding agents.
606
+
559
607
  ## Environment variables
560
608
 
561
- | Variable | Purpose | Default |
562
- | -------------- | ------------------------------------------------------------ | ------- |
563
- | `VOID_TOKEN` | Auth token override instead of saved config | none |
564
- | `VOID_PROJECT` | Default project slug for deploy, secret, and delete commands | none |
609
+ | Variable | Purpose | Default |
610
+ | -------------- | ------------------------------------------------------------------------- | ------- |
611
+ | `VOID_TOKEN` | Auth token override instead of saved config | none |
612
+ | `VOID_PROJECT` | Default project slug for deploy, secret, domain, and cache purge commands | none |
@@ -13,6 +13,7 @@ Project-level configuration lives in a `void.json` file at the project root. Mos
13
13
  ```json
14
14
  {
15
15
  "$schema": "./node_modules/void/schema.json",
16
+ "sourceDir": "src",
16
17
  "target": "cloudflare",
17
18
  "auth": {
18
19
  "providers": ["email", "github", "google"]
@@ -36,10 +37,24 @@ Project-level configuration lives in a `void.json` file at the project root. Mos
36
37
  }
37
38
  ```
38
39
 
39
- Add the `$schema` field for autocomplete and validation in your editor.
40
+ Add the `$schema` field for autocomplete and validation in your editor. The schema ships with the `void` package at `node_modules/void/schema.json` and is also exposed as the `void/schema.json` package subpath.
40
41
 
41
42
  ## Fields
42
43
 
44
+ ### `sourceDir`
45
+
46
+ Directory containing Void source conventions, relative to the project root.
47
+
48
+ When omitted, Void uses the existing project-root conventions: `pages/`, `routes/`, `middleware/`, `crons/`, `queues/`, `db/`, `auth.ts`, and `env.ts`.
49
+
50
+ When set, those conventions move under the configured directory:
51
+
52
+ ```json
53
+ { "sourceDir": "src" }
54
+ ```
55
+
56
+ With that config, Void reads `src/pages`, `src/routes`, `src/db/schema.ts`, `src/db/migrations`, `src/auth.ts`, and `src/env.ts`. Project files such as `void.json`, `vite.config.ts`, `package.json`, `tsconfig.json`, `wrangler.json`, `public/`, and `.env*` stay at the project root. Void does not scan both locations; if source conventions exist in both places during dev/build, remove one copy so the active source tree is unambiguous.
57
+
43
58
  ### `auth`
44
59
 
45
60
  High-level Better Auth configuration.
@@ -222,7 +237,9 @@ Deploy target runtime. Defaults to `"cloudflare"`.
222
237
  | `"bun"` | Bun, using `Bun.serve()` |
223
238
  | `"deno"` | Deno, using `Deno.serve()` |
224
239
 
225
- Non-CF targets disable CF bindings (`void/db`, `void/kv`, `void/auth`, `void/storage`, `void/ai`, `void/sandbox`, `void/env`, `void/ws`). Importing any of these with a non-CF target produces a compile-time error. File-based routing, middleware, and `void/client` all work normally.
240
+ Non-CF targets disable CF binding imports (`void/db`, `void/kv`, `void/auth`, `void/storage`, `void/ai`, `void/sandbox`, `void/env`). Importing any of these with a non-CF target produces a compile-time error. File-based routing, middleware, and `void/client` all work normally.
241
+
242
+ Void-managed WebSocket route files (`*.ws.ts`) are Cloudflare-only because they compile to Durable Objects. The `void/ws` subpath itself is not blocked on non-CF targets so client-side `connect()` code can still be bundled where a browser-like `WebSocket` runtime is available.
226
243
 
227
244
  ```json
228
245
  { "target": "node" }
@@ -236,23 +253,29 @@ Curated Cloudflare Workers configuration. Cloudflare-targeted apps require an ex
236
253
  | --------------------- | ---------- | -------------------------------------- |
237
254
  | `compatibility_date` | `string` | Cloudflare Workers compatibility date |
238
255
  | `compatibility_flags` | `string[]` | Cloudflare Workers compatibility flags |
256
+ | `vars` | `object` | Plain-text worker variables |
239
257
 
240
258
  ```json
241
259
  {
242
260
  "worker": {
243
261
  "compatibility_date": "2025-12-01",
244
- "compatibility_flags": ["nodejs_compat"]
262
+ "compatibility_flags": ["nodejs_compat"],
263
+ "vars": {
264
+ "PUBLIC_API_BASE": "https://api.example.com"
265
+ }
245
266
  }
246
267
  }
247
268
  ```
248
269
 
270
+ `worker.vars` values must be strings. They are merged into Worker bindings before `.env` files are loaded, so project `.env` values override `worker.vars` for local dev/build. Do not put secrets here; use `env.ts` plus `void secret put` for production secrets.
271
+
249
272
  ### `routing`
250
273
 
251
274
  Routing and edge configuration for headers, redirects, rewrites, and caching.
252
275
 
253
276
  #### `routing.headers`
254
277
 
255
- Custom response headers for static assets. Keys are URL patterns, values are arrays of `"Name: value"` strings. See [Custom Headers](../guide/edge/headers) for details.
278
+ Custom response headers for dispatch-worker responses. Keys are URL patterns, values are arrays of `"Name: value"` strings. See [Custom Headers](../guide/edge/headers) for details.
256
279
 
257
280
  ```json
258
281
  {
@@ -26,7 +26,7 @@ This runs once before plugins initialize, so the results are available to config
26
26
  | `AI` | `Ai` | `import { ai } from "void/ai"` | `env.AI` or `c.env.AI` |
27
27
  | `SANDBOX` | `DurableObjectNamespace<Sandbox>` | `import { getSandbox } from "void/sandbox"` | `env.SANDBOX` or `c.env.SANDBOX` |
28
28
  | Auth | none | `import { ... } from "void/auth"` or `import { auth } from "void/client"` | none |
29
- | `QUEUE_*` | `Queue` | `import { ... } from "void/queue"` | `env.QUEUE_*` |
29
+ | `QUEUE_*` | `Queue` | `import { queues } from "void/queues"` | `env.QUEUE_*` |
30
30
 
31
31
  Auth detection also triggers when importing the `auth` specifier from `void/client` (but not when importing only `fetch`).
32
32
 
File without changes
File without changes
File without changes
File without changes