void 1.2.1 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{account-cmd-CdUll_35.mjs → account-cmd-HP8bixYo.mjs} +3 -3
- package/dist/{application-analysis-fEqoSeMp.mjs → application-analysis-DDOQwiXk.mjs} +18 -12
- package/dist/{application-routing-DAhNP4u3.mjs → application-routing-4719u_kf.mjs} +3 -1
- package/dist/auth-g2TQbDLD.d.mts +70 -0
- package/dist/{auth-link-C87vGXM-.mjs → auth-link-CedYpDCy.mjs} +3 -3
- package/dist/{auth-router-6I81r-ix.mjs → auth-router-vafo7x8w.mjs} +11 -6
- package/dist/{better-auth-shared-D-6z0q0f.mjs → better-auth-shared-7FM3Uk2N.mjs} +48 -2
- package/dist/{better-auth-shared-DVk2DkTW.d.mts → better-auth-shared-BHB8kiTE.d.mts} +1 -1
- package/dist/{build-cmd-ex1g-j_e.mjs → build-cmd-9vUAQ1_V.mjs} +1 -1
- package/dist/{cache-oHzrnY3z.mjs → cache-jvwLNb0h.mjs} +1 -1
- package/dist/{cancel-deploy-viAMD0Q_.mjs → cancel-deploy-Dw0UmWKO.mjs} +1 -1
- package/dist/{cf-build-output-BhVxldCw.mjs → cf-build-output-XpNR9zoh.mjs} +122 -5
- package/dist/cf-build-output-bd8Uwv1P.mjs +1 -0
- package/dist/{cf-worker-settings-BECvvTVd.mjs → cf-worker-settings-Dg27RzyT.mjs} +11 -5
- package/dist/cli/cli.mjs +41 -32
- package/dist/cli/cloudflare-operation-process.mjs +35 -8
- package/dist/cli/env-schema-probe.mjs +2 -2
- package/dist/{client-BEkdj1kx.mjs → client-B3LnB_bE.mjs} +8 -1
- package/dist/client-BZb9j66F.mjs +1 -0
- package/dist/{cloudflare-auth-Byo_0_N9.mjs → cloudflare-auth-DyD_kVFr.mjs} +1 -1
- package/dist/{cloudflare-cmd-DMzCv12s.mjs → cloudflare-cmd-D-b_u3T4.mjs} +2 -2
- package/dist/{cloudflare-config-DchHxPTo.mjs → cloudflare-config-CH1AylZT.mjs} +14 -3
- package/dist/{cloudflare-connect-CCRTVg-I.mjs → cloudflare-connect-zTJh8UnN.mjs} +2 -2
- package/dist/{cloudflare-operations-Dh9dEHJj.mjs → cloudflare-operations-Bc-7fN44.mjs} +4 -4
- package/dist/{cloudflare-operations-DsSaw2BT.mjs → cloudflare-operations-BtulCNOg.mjs} +1 -1
- package/dist/{config-BU6hMu1W.mjs → config-BV2ASlpn.mjs} +1 -1
- package/dist/{config-DQfHOKh9.d.mts → config-CAdZVTLN.d.mts} +4 -1
- package/dist/config-D-6q7EBH.mjs +87 -0
- package/dist/{config-DHgSEWT7.mjs → config-OFOAimzt.mjs} +5 -3
- package/dist/config-entry.d.mts +1 -1
- package/dist/{config-BIaXIkkv.mjs → config-tqMM6DwY.mjs} +1 -1
- package/dist/{connect-k7R2rPVA.mjs → connect-BOM6zvFX.mjs} +4 -4
- package/dist/{create-project-DV71ol5d.mjs → create-project-Bxd02EHN.mjs} +1 -1
- package/dist/{create-project-DTuy-l0z.mjs → create-project-C2K0DN2O.mjs} +1 -1
- package/dist/{db-DVOkLH5X.mjs → db-Cdvr3zwG.mjs} +18 -18
- package/dist/{db-types-NGxPwnlt.mjs → db-types-0eCiqYb1.mjs} +1 -1
- package/dist/{delete-BbP5eopu.mjs → delete-lETE6Tpt.mjs} +1 -1
- package/dist/deploy-CX94CmKa.mjs +2 -0
- package/dist/{deploy-7H32EnUs.mjs → deploy-CdM-LAxX.mjs} +473 -148
- package/dist/{deploy-managed-static-DlvcvnQT.mjs → deploy-managed-static-DjeBFG2c.mjs} +43 -20
- package/dist/{deploy-transport-BzGEj0Ge.mjs → deploy-transport-DIq_gFTP.mjs} +14 -13
- package/dist/deploy.d.mts +2 -0
- package/dist/deploy.mjs +8 -5
- package/dist/{dispatch-DoUnxTNo.mjs → dispatch-CLa2LThw.mjs} +76 -7
- package/dist/{domain-CA2wBgra.mjs → domain-DyhNtdYf.mjs} +2 -2
- package/dist/{email-DXpCc77w.mjs → email-DM2wDcBN.mjs} +59 -10
- package/dist/{email-cloudflare-D03g2TkS.mjs → email-cloudflare-PMbAev9Q.mjs} +124 -10
- package/dist/{env-DgOQ9_8S.mjs → env-78hbN-oI.mjs} +3 -3
- package/dist/{env-BJjULvL0.mjs → env-BaMz0j7H.mjs} +6 -1
- package/dist/{env-validation-Dwq3PJzK.mjs → env-validation-B3VobvXm.mjs} +2 -1
- package/dist/{env-validation-BmsdCZEk.mjs → env-validation-BUfFZ6bt.mjs} +1 -1
- package/dist/error-pages-CLIJ7aYq.mjs +37 -0
- package/dist/gen-BhWBT4iu.mjs +1 -0
- package/dist/{gen-BfmcIi2g.mjs → gen-CFmsUsW1.mjs} +3 -3
- package/dist/{github-cmd-CY9LUqLh.mjs → github-cmd-De-_IWbM.mjs} +1 -1
- package/dist/{handler-BbkSPzGF.d.mts → handler-BHktmuTL.d.mts} +4 -2
- package/dist/{headers-D522zd0A.mjs → headers--vaK_chu.mjs} +1 -1
- package/dist/{help-CxSlPpzJ.mjs → help-CKbrhZha.mjs} +16 -1
- package/dist/help-qOZr3wng.mjs +1 -0
- package/dist/index.d.mts +3 -5
- package/dist/index.mjs +370 -140
- package/dist/{info-7VDlhtyy.mjs → info-Yg0-V5Rs.mjs} +4 -4
- package/dist/{init-DxYyOs4-.mjs → init-CDiJQycf.mjs} +241 -206
- package/dist/{link-Ddmod1dZ.mjs → link-Dllip08S.mjs} +2 -2
- package/dist/{list-MogaugiO.mjs → list-BYRP6am0.mjs} +2 -2
- package/dist/{live-Bt8Y_0bg.d.mts → live-BllfDuzA.d.mts} +2 -2
- package/dist/{local-d1-BHBnKWRb.mjs → local-d1-CAwAs9GH.mjs} +1 -1
- package/dist/login-BAPmYnb7.mjs +1 -0
- package/dist/{login-Cttnagmm.mjs → login-PcFy5mlC.mjs} +2 -2
- package/dist/{logs-CAszUWZI.mjs → logs-DmJTBhed.mjs} +2 -2
- package/dist/{migrate-DyT2jJ8y.mjs → migrate-B8S2xTcb.mjs} +5 -66
- package/dist/migrate-BIYTPQE6.mjs +1 -0
- package/dist/nitro.mjs +4 -4
- package/dist/{node-WB7c2N4L.mjs → node-CDOPrGSl.mjs} +5 -5
- package/dist/{operator-args-UnE8Y2eK.mjs → operator-args-BsJIYXaT.mjs} +8 -1
- package/dist/operator-cmd-CjazwOyb.mjs +1 -0
- package/dist/{operator-cmd-skshjMGl.mjs → operator-cmd-DmkmS2wL.mjs} +4 -3
- package/dist/pages/client.d.mts +32 -4
- package/dist/pages/client.mjs +186 -29
- package/dist/pages/index.d.mts +34 -2
- package/dist/pages/index.mjs +96 -55
- package/dist/pages/islands-plugin.d.mts +1 -1
- package/dist/pages/islands-plugin.mjs +9 -3
- package/dist/pages/protocol.d.mts +2 -2
- package/dist/platform-args-BC8_hsDj.mjs +1 -0
- package/dist/{platform-args-DVbVClZl.mjs → platform-args-BMD2gjc_.mjs} +1 -1
- package/dist/{platform-auth-config-C-pm5Qzx.mjs → platform-auth-config-CImnfohz.mjs} +3 -3
- package/dist/{platform-auth-protection-SHhvim1L.mjs → platform-auth-protection-BogLhtHi.mjs} +2 -2
- package/dist/{platform-auth-recovery-DXVWs-wA.mjs → platform-auth-recovery-B-mEaWEi.mjs} +2 -2
- package/dist/{platform-cmd-PiNRkopU.mjs → platform-cmd-CV8NxIIn.mjs} +1 -1
- package/dist/{platform-cmd-D5I1beUX.mjs → platform-cmd-DZK2ixMl.mjs} +4 -4
- package/dist/{platform-domain-jpmBfZeb.mjs → platform-domain-CRvelPGE.mjs} +2 -2
- package/dist/{platform-lifecycle-DyKmuNY6.mjs → platform-lifecycle-CPYY7E9B.mjs} +103 -41
- package/dist/{platform-lifecycle-DH3Yr1qQ.mjs → platform-lifecycle-DwXq7kZt.mjs} +1 -1
- package/dist/{platform-management--vDwSn35.mjs → platform-management-BOnGbMSM.mjs} +1 -1
- package/dist/{platform-management-7m-PLaPJ.mjs → platform-management-lXdgGgAM.mjs} +1 -1
- package/dist/{platform-recovery-BiNpZZab.mjs → platform-recovery-noaALXnE.mjs} +2 -2
- package/dist/{plugin-inference-DUjCd55H.mjs → plugin-inference-CeiB6BG5.mjs} +53 -18
- package/dist/{prepare-BcAE5Sdj.mjs → prepare-BuOS18AM.mjs} +1 -1
- package/dist/{prepare-DA-17DhO.mjs → prepare-D604Yiyr.mjs} +12 -8
- package/dist/prepare-DU-tOpS5.mjs +1 -0
- package/dist/{prerender-render-Cijv7UFo.mjs → prerender-render-CaShbHJ3.mjs} +13 -1
- package/dist/prerender-render.d.mts +1 -0
- package/dist/prerender-render.mjs +1 -1
- package/dist/{project-cmd-DA4K5faU.mjs → project-cmd-DBYqAIbe.mjs} +15 -15
- package/dist/{project-team-CQBNveX3.mjs → project-team-BjCLgTRC.mjs} +1 -1
- package/dist/{project-token-CCalFyQf.mjs → project-token-BB6PwaA9.mjs} +1 -1
- package/dist/{project-tsconfig-Itv1f4WC.mjs → project-tsconfig-CVvk6Z_e.mjs} +24 -2
- package/dist/{project-zero-trust-DPnkiEuT.mjs → project-zero-trust-CWDh1P_t.mjs} +1 -1
- package/dist/{protocol-BBDpJz3G.d.mts → protocol-D5XDySYu.d.mts} +2 -2
- package/dist/{provision-BFLCrnUp.mjs → provision-DfxLCg-d.mjs} +1 -1
- package/dist/{provision-DtROpNNI.mjs → provision-DztLJ97X.mjs} +24 -8
- package/dist/{requests-BpH0kImL.mjs → requests-D_pbzDyz.mjs} +1 -1
- package/dist/{rollback-CXS1tAa-.mjs → rollback-CjfIYsJx.mjs} +2 -2
- package/dist/{route-types-BZi26DVS.mjs → route-types-DvEGmPif.mjs} +109 -30
- package/dist/routes-stub.d.mts +22 -13
- package/dist/runtime/auth.d.mts +2 -2
- package/dist/runtime/better-auth-mysql.d.mts +1 -1
- package/dist/runtime/better-auth-mysql.mjs +1 -1
- package/dist/runtime/better-auth-pg.d.mts +1 -1
- package/dist/runtime/better-auth-pg.mjs +1 -1
- package/dist/runtime/better-auth.d.mts +1 -1
- package/dist/runtime/better-auth.mjs +1 -1
- package/dist/runtime/client-react.d.mts +1 -1
- package/dist/runtime/client-solid.d.mts +1 -1
- package/dist/runtime/client-svelte.d.mts +1 -1
- package/dist/runtime/client-vue.d.mts +1 -1
- package/dist/runtime/client.d.mts +1 -1
- package/dist/runtime/handler.d.mts +1 -1
- package/dist/runtime/live-client.d.mts +1 -1
- package/dist/runtime/live.d.mts +1 -1
- package/dist/runtime/log.mjs +19 -1
- package/dist/runtime/routing.d.mts +5 -4
- package/dist/runtime/routing.mjs +14 -73
- package/dist/runtime/validator.d.mts +1 -1
- package/dist/runtime/ws-server.d.mts +3 -3
- package/dist/runtime/ws.d.mts +1 -1
- package/dist/runtime/ws.mjs +4 -2
- package/dist/{scan-8IzYXiU_.mjs → scan-N9WzdcAl.mjs} +302 -23
- package/dist/{secret-BbXHfLAt.mjs → secret-3X0PxmuX.mjs} +9 -12
- package/dist/static-asset-marker-Btf-6oCD.mjs +32 -0
- package/dist/{types-7AIz0OZu.d.mts → types-w72dljaA.d.mts} +6 -1
- package/dist/{version-metadata-tS39iW09.mjs → version-metadata-D2vfMQzv.mjs} +2 -1
- package/dist/worker-conditions-AWFRcFxR.mjs +11 -0
- package/dist/{wrangler-F96NnLyb.mjs → wrangler-I-scB_1t.mjs} +82 -13
- package/dist/wrangler-UnwdISay.mjs +1 -0
- package/dist/{wrapper-D3sZyh2C.mjs → wrapper-BBl1rC32.mjs} +8 -12
- package/dist/{ws-BH-im_tX.d.mts → ws-B3ClMVDh.d.mts} +3 -2
- package/docs/guide/auth.md +4 -2
- package/docs/guide/edge/redirects.md +22 -0
- package/docs/guide/edge/static-assets.md +10 -0
- package/docs/guide/email/domains.md +1 -1
- package/docs/guide/email/receiving.md +2 -0
- package/docs/guide/email/sending.md +1 -1
- package/docs/guide/pages-routing/actions-and-forms.md +43 -13
- package/docs/guide/pages-routing/markdown.md +2 -0
- package/docs/guide/pages-routing/overview.md +33 -2
- package/docs/guide/platform/administration/email.md +18 -0
- package/docs/guide/platform/installation/maintenance.md +3 -1
- package/docs/guide/platform/installation/prerequisites.md +9 -4
- package/docs/guide/platform/installation/uninstall.md +2 -0
- package/docs/guide/queues.md +13 -1
- package/docs/guide/server-routing.md +40 -2
- package/docs/guide/ssg.md +8 -0
- package/docs/guide/type-safety.md +7 -7
- package/docs/guide/websockets.md +4 -2
- package/docs/integrations/cloudflare.md +16 -7
- package/docs/reference/api/auth.md +6 -2
- package/docs/reference/api/deploy.md +9 -5
- package/docs/reference/api/pages.md +6 -4
- package/docs/reference/cli/deploy.md +10 -9
- package/docs/reference/cli/email.md +13 -0
- package/docs/reference/cli/platform-email.md +2 -2
- package/docs/reference/cli.md +1 -0
- package/docs/reference/config.md +11 -1
- package/docs/reference/structure.md +3 -1
- package/package.json +9 -7
- package/schema.json +4 -0
- package/skills/void/SKILL.md +1 -1
- package/templates/assets/icons.svg +49 -0
- package/templates/assets/react.svg +1 -0
- package/templates/assets/solid.svg +1 -0
- package/templates/assets/stack.svg +35 -0
- package/templates/assets/svelte.svg +1 -0
- package/templates/assets/void.svg +5 -0
- package/templates/assets/vue.svg +1 -0
- package/dist/auth-DkcFflXV.d.mts +0 -42
- package/dist/cf-build-output-BJHuSsVN.mjs +0 -1
- package/dist/client-BiRDZTSd.mjs +0 -1
- package/dist/config-CyUJzi3q.mjs +0 -32
- package/dist/deploy-CE0Ev0Ob.mjs +0 -2
- package/dist/gen-NrOlWZaG.mjs +0 -1
- package/dist/help-BeAFFE5C.mjs +0 -1
- package/dist/login-DgDwlKc_.mjs +0 -1
- package/dist/migrate-n49ZeS1X.mjs +0 -1
- package/dist/operator-cmd-d2MvJOrl.mjs +0 -1
- package/dist/parse-filename-DioPHiR9.mjs +0 -77
- package/dist/platform-args-kQrgxScY.mjs +0 -1
- package/dist/prepare-C4I0f--h.mjs +0 -1
- package/dist/wrangler-BLb3_luP.mjs +0 -1
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { a as join, s as relative } from "./dist-ipQi0Q8y.mjs";
|
|
2
|
-
import { a as deriveWebSocketClassNameFromName, o as inferWebSocketResourceName } from "./plugin-inference-
|
|
3
|
-
import { p as readConfig } from "./config-
|
|
4
|
-
import { d as deriveDurableResourceIdentity, f as inferDurableResourceName, t as analyzeApplicationSync } from "./application-analysis-
|
|
5
|
-
import { n as VOID_LOCK_FILE } from "./cloudflare-config-
|
|
2
|
+
import { a as deriveWebSocketClassNameFromName, o as inferWebSocketResourceName } from "./plugin-inference-CeiB6BG5.mjs";
|
|
3
|
+
import { p as readConfig } from "./config-OFOAimzt.mjs";
|
|
4
|
+
import { d as deriveDurableResourceIdentity, f as inferDurableResourceName, t as analyzeApplicationSync } from "./application-analysis-DDOQwiXk.mjs";
|
|
5
|
+
import { n as VOID_LOCK_FILE } from "./cloudflare-config-CH1AylZT.mjs";
|
|
6
6
|
import { existsSync, readFileSync } from "node:fs";
|
|
7
7
|
import { isRecord } from "@void/deploy-core";
|
|
8
8
|
//#region src/cli/info.ts
|
|
@@ -1,28 +1,28 @@
|
|
|
1
1
|
import { a as join, c as resolve, i as isAbsolute, n as dirname, s as relative, t as basename } from "./dist-ipQi0Q8y.mjs";
|
|
2
|
-
import { r as detectFramework } from "./plugin-inference-
|
|
2
|
+
import { r as detectFramework } from "./plugin-inference-CeiB6BG5.mjs";
|
|
3
3
|
import { n as readProjectPaths, o as TYPED_CONFIG_FILE } from "./project-paths-DGu_QZ_Q.mjs";
|
|
4
|
-
import { c as getDatabaseCasing, l as getDatabaseDialect, p as readConfig, s as databaseConfigValue } from "./config-
|
|
4
|
+
import { c as getDatabaseCasing, l as getDatabaseDialect, p as readConfig, s as databaseConfigValue } from "./config-OFOAimzt.mjs";
|
|
5
5
|
import { t as MagicString } from "./dist-Cegxq8gs.mjs";
|
|
6
6
|
import { c as writeDeploymentPlatform, n as readDeploymentPlatform, r as readProjectConfig, t as attachSelectedPlatform, u as writeProjectConfig } from "./project-rqDnVsJN.mjs";
|
|
7
|
-
import {
|
|
8
|
-
import { M as writeProvisionedWranglerConfig, i as LATEST_KNOWN_COMPAT_DATE } from "./wrangler-
|
|
7
|
+
import { i as materializeCloudflareConfig } from "./cloudflare-config-CH1AylZT.mjs";
|
|
8
|
+
import { F as canRewriteVoidProjectConfig, L as writeVoidProjectConfig, M as writeProvisionedWranglerConfig, i as LATEST_KNOWN_COMPAT_DATE } from "./wrangler-I-scB_1t.mjs";
|
|
9
9
|
import { i as readPackageJson, n as hasPackageDependency } from "./package-json-BjYqR-So.mjs";
|
|
10
10
|
import { c as getToken } from "./auth-B6iOCjKI.mjs";
|
|
11
|
-
import { n as ensureProjectTsconfig, t as createProjectTsconfig } from "./project-tsconfig-
|
|
11
|
+
import { n as ensureProjectTsconfig, t as createProjectTsconfig } from "./project-tsconfig-CVvk6Z_e.mjs";
|
|
12
12
|
import { t as parseDotenvFile } from "./dotenv-CNazY3-w.mjs";
|
|
13
|
-
import { r as writeDrizzleConfig, t as PLACEHOLDER_DB_URL } from "./config-
|
|
13
|
+
import { r as writeDrizzleConfig, t as PLACEHOLDER_DB_URL } from "./config-tqMM6DwY.mjs";
|
|
14
14
|
import { A as confirm, K as select, L as log, O as cancel, X as text, tt as isCancel } from "./dist-Cor9XGoz.mjs";
|
|
15
15
|
import { n as getOwnVersion, r as getPackageDir, t as detectAgents } from "./agents-CuNtT0D_.mjs";
|
|
16
|
-
import { r as PlatformClient } from "./client-
|
|
16
|
+
import { r as PlatformClient } from "./client-B3LnB_bE.mjs";
|
|
17
17
|
import { l as formatUrl, m as printSuccess, p as note } from "./output-BpgYODYx.mjs";
|
|
18
|
-
import { a as promptProjectSelection, r as promptAndCreateProject } from "./create-project-
|
|
18
|
+
import { a as promptProjectSelection, r as promptAndCreateProject } from "./create-project-Bxd02EHN.mjs";
|
|
19
19
|
import { s as formatProjectCommand } from "./cloudflare-process-8jEYIeim.mjs";
|
|
20
20
|
import { i as hasLocalLockfile, n as drizzleKitBin, r as findInstalledYarnPnpRuntime, t as buildDrizzleKitSpawnEnv } from "./yarn-pnp-DLbEFMT0.mjs";
|
|
21
|
-
import { t as promptForLoginToken } from "./login-
|
|
22
|
-
import { i as saveDiscoveredPlatform, t as discoverPlatform } from "./platform-cmd-
|
|
23
|
-
import { t as connectCloudflare } from "./cloudflare-connect-
|
|
21
|
+
import { t as promptForLoginToken } from "./login-PcFy5mlC.mjs";
|
|
22
|
+
import { i as saveDiscoveredPlatform, t as discoverPlatform } from "./platform-cmd-DZK2ixMl.mjs";
|
|
23
|
+
import { t as connectCloudflare } from "./cloudflare-connect-zTJh8UnN.mjs";
|
|
24
24
|
import { n as snapshotDrizzleOutputs } from "./generate-B1m4Cm4n.mjs";
|
|
25
|
-
import { i as
|
|
25
|
+
import { i as migrateFrameworkAdapterPaths, t as migrateLegacyVoidConfig } from "./migrate-B8S2xTcb.mjs";
|
|
26
26
|
import { createRequire } from "node:module";
|
|
27
27
|
import { existsSync, mkdirSync, readFileSync, readdirSync, writeFileSync } from "node:fs";
|
|
28
28
|
import { parseSync } from "vite";
|
|
@@ -211,6 +211,9 @@ function initialCommitCommand(root) {
|
|
|
211
211
|
return `${git} add -A && ${git} commit -m "chore: initial commit"`;
|
|
212
212
|
}
|
|
213
213
|
//#endregion
|
|
214
|
+
//#region src/cli/starter-ui.css?raw
|
|
215
|
+
var starter_ui_default = ":root {\n --text: rgb(22 23 29 / 70%);\n --text-h: #16171d;\n --bg: #fff;\n --border: #e5e4e7;\n --code-bg: #f2f1f4;\n --accent: #6c3bff;\n --error: #b42318;\n --social-bg: #f2f1f4;\n --radius-inner: 4px;\n --radius-element: 6px;\n --shadow: rgba(0, 0, 0, 0.1) 0 10px 15px -3px, rgba(0, 0, 0, 0.05) 0 4px 6px -2px;\n\n --sans: system-ui, 'Segoe UI', Roboto, sans-serif;\n --heading: system-ui, 'Segoe UI', Roboto, sans-serif;\n --mono: ui-monospace, Consolas, monospace;\n\n font: 18px/145% var(--sans);\n letter-spacing: 0.18px;\n color-scheme: light dark;\n color: var(--text);\n background: var(--bg);\n font-synthesis: none;\n text-rendering: optimizeLegibility;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n\n @media (max-width: 1024px) {\n font-size: 16px;\n }\n}\n\n@supports (corner-shape: squircle) {\n :root {\n /* Squircle curves need about twice the radius to read as rounded. */\n --radius-inner: 8px;\n --radius-element: 12px;\n }\n\n :where(.starter, .starter *),\n .starter *::before,\n .starter *::after {\n corner-shape: squircle;\n }\n}\n\n@media (prefers-color-scheme: dark) {\n :root {\n --text: rgb(255 255 255 / 70%);\n --text-h: #fff;\n --bg: #16171d;\n --border: #3b3440;\n --code-bg: #3b3440;\n --accent: #b39aff;\n --error: #fda29b;\n --social-bg: #3b3440;\n --shadow: rgba(0, 0, 0, 0.4) 0 10px 15px -3px, rgba(0, 0, 0, 0.25) 0 4px 6px -2px;\n }\n}\n\n.starter {\n width: 1126px;\n max-width: 100%;\n margin: 0 auto;\n text-align: center;\n border-inline: 1px solid var(--border);\n min-height: 100svh;\n display: flex;\n flex-direction: column;\n box-sizing: border-box;\n}\n\nbody {\n margin: 0;\n}\n\nh1,\nh2 {\n font-family: var(--heading);\n font-weight: 500;\n color: var(--text-h);\n}\n\nh1 {\n font-size: 56px;\n letter-spacing: -1.68px;\n margin: 32px 0;\n @media (max-width: 1024px) {\n font-size: 36px;\n margin: 20px 0;\n }\n}\nh2 {\n font-size: 24px;\n line-height: 118%;\n letter-spacing: -0.24px;\n margin: 0 0 8px;\n @media (max-width: 1024px) {\n font-size: 20px;\n }\n}\np {\n margin: 0;\n}\n\ncode {\n font-family: var(--mono);\n display: inline-flex;\n border-radius: var(--radius-inner);\n color: var(--text-h);\n font-size: 15px;\n line-height: 135%;\n padding: 4px 8px;\n background: var(--code-bg);\n}\n\n.hero {\n position: relative;\n\n .base,\n .framework,\n .void {\n inset-inline: 0;\n margin: 0 auto;\n }\n\n .base {\n width: 170px;\n position: relative;\n z-index: 0;\n }\n\n .framework,\n .void {\n position: absolute;\n }\n\n .framework {\n z-index: 1;\n top: 34px;\n height: 28px;\n transform: perspective(2000px) rotateZ(300deg) rotateX(44deg) rotateY(39deg) scale(1.4);\n }\n\n .void {\n z-index: 0;\n top: 107px;\n height: 22px;\n width: auto;\n transform: perspective(2000px) rotateZ(300deg) rotateX(40deg) rotateY(39deg) scale(0.8);\n }\n}\n\n#center {\n display: flex;\n flex-direction: column;\n gap: 25px;\n padding-bottom: 24px;\n place-content: center;\n place-items: center;\n flex-grow: 1;\n\n @media (max-width: 1024px) {\n padding: 32px 20px 24px;\n gap: 18px;\n }\n}\n\n.starter-intro {\n width: min(720px, 100%);\n padding-inline: 20px;\n box-sizing: border-box;\n\n a {\n color: var(--accent);\n }\n\n @media (max-width: 1024px) {\n padding-inline: 0;\n }\n}\n\n.starter-description {\n display: grid;\n gap: 12px;\n\n > p:nth-child(2) {\n text-wrap: balance;\n }\n}\n\n.starter-demo {\n border-top: 1px solid var(--border);\n padding: 32px;\n text-align: left;\n\n @media (max-width: 1024px) {\n padding: 24px 20px;\n }\n}\n\n.demo-content {\n max-width: 640px;\n margin: 0 auto;\n display: grid;\n gap: 24px;\n\n h2 {\n margin: 0;\n }\n}\n\n.messages {\n list-style: none;\n margin: 0;\n padding: 0;\n display: grid;\n gap: 12px;\n\n li {\n padding: 12px 16px;\n border: 1px solid var(--border);\n border-radius: var(--radius-element);\n overflow-wrap: anywhere;\n }\n\n strong {\n display: block;\n color: var(--text-h);\n font-weight: 500;\n }\n\n small {\n font-size: 14px;\n }\n}\n\n.message-form {\n display: grid;\n gap: 12px;\n\n label {\n color: var(--text-h);\n }\n\n input,\n button {\n font: inherit;\n color: var(--text-h);\n background: var(--social-bg);\n border: 1px solid var(--border);\n border-radius: var(--radius-element);\n padding: 10px 12px;\n\n &:focus-visible {\n outline: 2px solid var(--accent);\n outline-offset: 2px;\n }\n }\n\n input {\n flex: 1;\n min-width: 0;\n }\n\n button {\n cursor: pointer;\n\n &:hover {\n border-color: var(--accent);\n }\n\n &:disabled {\n cursor: wait;\n opacity: 0.6;\n }\n }\n}\n\n.message-fields {\n display: flex;\n gap: 8px;\n\n @media (max-width: 480px) {\n flex-direction: column;\n }\n}\n\n.message-form [data-void-form-error] {\n color: var(--error);\n font-size: 14px;\n}\n\n#next-steps {\n display: flex;\n border-top: 1px solid var(--border);\n text-align: left;\n\n & > div {\n flex: 1 1 0;\n padding: 32px;\n @media (max-width: 1024px) {\n padding: 24px 20px;\n }\n }\n\n .icon {\n color: var(--accent);\n margin-bottom: 16px;\n width: 22px;\n height: 22px;\n }\n\n @media (max-width: 1024px) {\n flex-direction: column;\n text-align: center;\n }\n}\n\n#docs {\n border-right: 1px solid var(--border);\n\n @media (max-width: 1024px) {\n border-right: none;\n border-bottom: 1px solid var(--border);\n }\n}\n\n#next-steps ul {\n list-style: none;\n padding: 0;\n display: flex;\n gap: 8px;\n margin: 32px 0 0;\n\n a {\n color: var(--text-h);\n font-size: 16px;\n border-radius: var(--radius-element);\n background: var(--social-bg);\n display: flex;\n padding: 6px 12px;\n align-items: center;\n gap: 8px;\n text-decoration: none;\n transition: box-shadow 0.3s;\n\n &:hover {\n box-shadow: var(--shadow);\n }\n .button-icon {\n height: 18px;\n width: 18px;\n }\n }\n\n @media (max-width: 1024px) {\n margin-top: 20px;\n flex-wrap: wrap;\n justify-content: center;\n\n li {\n flex: 1 1 calc(50% - 8px);\n }\n\n a {\n width: 100%;\n justify-content: center;\n box-sizing: border-box;\n }\n }\n}\n\n#spacer {\n height: 88px;\n border-top: 1px solid var(--border);\n @media (max-width: 1024px) {\n height: 48px;\n }\n}\n\n.ticks {\n position: relative;\n width: 100%;\n\n &::before,\n &::after {\n content: '';\n position: absolute;\n top: -4.5px;\n border: 5px solid transparent;\n }\n\n &::before {\n left: 0;\n border-left-color: var(--border);\n }\n &::after {\n right: 0;\n border-right-color: var(--border);\n }\n}\n";
|
|
216
|
+
//#endregion
|
|
214
217
|
//#region src/cli/template.ts
|
|
215
218
|
const SCAFFOLD_GITIGNORE_LINES = [
|
|
216
219
|
"node_modules",
|
|
@@ -242,7 +245,7 @@ const SCAFFOLD_TOOLCHAIN_OPTIONS = [{
|
|
|
242
245
|
label: "Vite",
|
|
243
246
|
hint: "Uses plain Vite commands without Vite+."
|
|
244
247
|
}];
|
|
245
|
-
const REACT_SCAFFOLD_COMPILER_DEV_DEPENDENCIES = { "oxc-transform-react": "^0.
|
|
248
|
+
const REACT_SCAFFOLD_COMPILER_DEV_DEPENDENCIES = { "oxc-transform-react": "^0.152.0" };
|
|
246
249
|
const SCAFFOLD_FRAMEWORK_OPTIONS = [
|
|
247
250
|
{
|
|
248
251
|
value: "react",
|
|
@@ -268,6 +271,7 @@ const SCAFFOLD_FRAMEWORK_OPTIONS = [
|
|
|
268
271
|
const SCAFFOLD_FRAMEWORKS = {
|
|
269
272
|
react: {
|
|
270
273
|
label: "React",
|
|
274
|
+
docsUrl: "https://react.dev/",
|
|
271
275
|
adapterPackage: "@void/react",
|
|
272
276
|
adapterImport: "voidReact",
|
|
273
277
|
adapterPlugin: "@void/react/plugin",
|
|
@@ -285,6 +289,7 @@ const SCAFFOLD_FRAMEWORKS = {
|
|
|
285
289
|
},
|
|
286
290
|
vue: {
|
|
287
291
|
label: "Vue",
|
|
292
|
+
docsUrl: "https://vuejs.org/",
|
|
288
293
|
adapterPackage: "@void/vue",
|
|
289
294
|
adapterImport: "voidVue",
|
|
290
295
|
adapterPlugin: "@void/vue/plugin",
|
|
@@ -295,6 +300,7 @@ const SCAFFOLD_FRAMEWORKS = {
|
|
|
295
300
|
},
|
|
296
301
|
svelte: {
|
|
297
302
|
label: "Svelte",
|
|
303
|
+
docsUrl: "https://svelte.dev/",
|
|
298
304
|
adapterPackage: "@void/svelte",
|
|
299
305
|
adapterImport: "voidSvelte",
|
|
300
306
|
adapterPlugin: "@void/svelte/plugin",
|
|
@@ -305,6 +311,7 @@ const SCAFFOLD_FRAMEWORKS = {
|
|
|
305
311
|
},
|
|
306
312
|
solid: {
|
|
307
313
|
label: "Solid",
|
|
314
|
+
docsUrl: "https://www.solidjs.com/",
|
|
308
315
|
adapterPackage: "@void/solid",
|
|
309
316
|
adapterImport: "voidSolid",
|
|
310
317
|
adapterPlugin: "@void/solid/plugin",
|
|
@@ -326,9 +333,16 @@ function getScaffoldTsconfigCompilerOptions(framework) {
|
|
|
326
333
|
function createPagesStarterTemplate(options) {
|
|
327
334
|
const { framework, starterMode, toolchain = "vite", voidPackageSpec, adapterPackageSpec } = options;
|
|
328
335
|
const config = SCAFFOLD_FRAMEWORKS[framework];
|
|
336
|
+
const assets = join(getPackageDir(), "templates", "assets");
|
|
329
337
|
const files = {
|
|
330
338
|
"vite.config.ts": getViteConfig(framework, config),
|
|
331
|
-
[`pages/index.${config.pageExtension}`]: getIndexPage(framework, starterMode)
|
|
339
|
+
[`pages/index.${config.pageExtension}`]: getIndexPage(framework, starterMode),
|
|
340
|
+
"pages/style.css": starter_ui_default,
|
|
341
|
+
"pages/vite-env.d.ts": "/// <reference types=\"vite/client\" />\n",
|
|
342
|
+
"public/stack.svg": readFileSync(join(assets, "stack.svg"), "utf8"),
|
|
343
|
+
"public/void.svg": readFileSync(join(assets, "void.svg"), "utf8"),
|
|
344
|
+
[`public/${framework}.svg`]: readFileSync(join(assets, `${framework}.svg`), "utf8"),
|
|
345
|
+
"public/icons.svg": readFileSync(join(assets, "icons.svg"), "utf8")
|
|
332
346
|
};
|
|
333
347
|
if (starterMode !== "static") {
|
|
334
348
|
files["pages/index.server.ts"] = getIndexServer();
|
|
@@ -452,210 +466,216 @@ export default defineSeed<typeof import("./schema")>(async ({ db, schema }) => {
|
|
|
452
466
|
`;
|
|
453
467
|
}
|
|
454
468
|
function getIndexPage(framework, starterMode) {
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
<
|
|
461
|
-
<
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
</
|
|
477
|
-
</
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
469
|
+
const { label, docsUrl } = SCAFFOLD_FRAMEWORKS[framework];
|
|
470
|
+
const hasDatabase = starterMode !== "static";
|
|
471
|
+
const body = `<main class="starter">
|
|
472
|
+
<section id="center" aria-labelledby="welcome-title">
|
|
473
|
+
<div class="hero">
|
|
474
|
+
<img class="base" src="/stack.svg" width="170" height="179" alt="" />
|
|
475
|
+
<img class="framework" src="/${framework}.svg" alt="${label} logo" />
|
|
476
|
+
<img class="void" src="/void.svg" alt="Void logo" />
|
|
477
|
+
</div>
|
|
478
|
+
<div class="starter-intro">
|
|
479
|
+
<h1 id="welcome-title">Welcome to Void</h1>
|
|
480
|
+
<div class="starter-description">
|
|
481
|
+
${indent(starterMode === "static" ? `<p>This starter is running in Pages mode with no database or server code yet.</p>
|
|
482
|
+
<p>
|
|
483
|
+
Add <code>pages/*.server.ts</code>, <code>routes/</code>, or <code>void/db</code> when
|
|
484
|
+
you want to grow into full-stack features.
|
|
485
|
+
</p>` : `<p>
|
|
486
|
+
This starter is running in Pages mode. The list below is loaded from your database in <code>pages/index.server.ts</code>.
|
|
487
|
+
</p>
|
|
488
|
+
<p>API example: <a href="/api/hello">/api/hello</a></p>`, 8)}
|
|
489
|
+
</div>
|
|
490
|
+
</div>
|
|
491
|
+
</section>${hasDatabase ? `\n <div class="ticks" aria-hidden="true"></div>\n${indent(getMessagesDemo(framework), 2)}` : ""}
|
|
492
|
+
<div class="ticks" aria-hidden="true"></div>
|
|
493
|
+
<section id="next-steps" aria-label="Resources">
|
|
494
|
+
<div id="docs">
|
|
495
|
+
<svg class="icon" role="presentation" aria-hidden="true">
|
|
496
|
+
<use href="/icons.svg#documentation-icon"></use>
|
|
497
|
+
</svg>
|
|
498
|
+
<h2>Documentation</h2>
|
|
499
|
+
<p>Your questions, answered</p>
|
|
500
|
+
<ul>
|
|
501
|
+
<li>
|
|
502
|
+
<a href="https://void.cloud/guide/quickstart" target="_blank" rel="noreferrer">
|
|
503
|
+
Quickstart
|
|
504
|
+
</a>
|
|
505
|
+
</li>
|
|
506
|
+
<li>
|
|
507
|
+
<a href="${docsUrl}" target="_blank" rel="noreferrer">
|
|
508
|
+
<img class="button-icon" src="/${framework}.svg" alt="" />
|
|
509
|
+
Learn more
|
|
510
|
+
</a>
|
|
511
|
+
</li>
|
|
512
|
+
</ul>
|
|
513
|
+
</div>
|
|
514
|
+
<div id="social">
|
|
515
|
+
<svg class="icon" role="presentation" aria-hidden="true">
|
|
516
|
+
<use href="/icons.svg#social-icon"></use>
|
|
517
|
+
</svg>
|
|
518
|
+
<h2>Connect with us</h2>
|
|
519
|
+
<p>Join the Void community</p>
|
|
520
|
+
<ul>
|
|
521
|
+
<li>
|
|
522
|
+
<a href="https://github.com/voidzero-dev/void" target="_blank" rel="noreferrer">
|
|
523
|
+
<svg class="button-icon" role="presentation" aria-hidden="true">
|
|
524
|
+
<use href="/icons.svg#github-icon"></use>
|
|
525
|
+
</svg>
|
|
526
|
+
GitHub
|
|
527
|
+
</a>
|
|
528
|
+
</li>
|
|
529
|
+
<li>
|
|
530
|
+
<a href="https://discord.gg/cC6TEVFKSx" target="_blank" rel="noreferrer">
|
|
531
|
+
<svg class="button-icon" role="presentation" aria-hidden="true">
|
|
532
|
+
<use href="/icons.svg#discord-icon"></use>
|
|
533
|
+
</svg>
|
|
534
|
+
Discord
|
|
535
|
+
</a>
|
|
536
|
+
</li>
|
|
537
|
+
<li>
|
|
538
|
+
<a href="https://x.com/deploytovoid" target="_blank" rel="noreferrer">
|
|
539
|
+
<svg class="button-icon" role="presentation" aria-hidden="true">
|
|
540
|
+
<use href="/icons.svg#x-icon"></use>
|
|
541
|
+
</svg>
|
|
542
|
+
X.com
|
|
543
|
+
</a>
|
|
544
|
+
</li>
|
|
545
|
+
<li>
|
|
546
|
+
<a href="https://bsky.app/profile/voidzero.dev" target="_blank" rel="noreferrer">
|
|
547
|
+
<svg class="button-icon" role="presentation" aria-hidden="true">
|
|
548
|
+
<use href="/icons.svg#bluesky-icon"></use>
|
|
549
|
+
</svg>
|
|
550
|
+
Bluesky
|
|
551
|
+
</a>
|
|
552
|
+
</li>
|
|
553
|
+
</ul>
|
|
554
|
+
</div>
|
|
555
|
+
</section>
|
|
556
|
+
<div class="ticks" aria-hidden="true"></div>
|
|
557
|
+
<div id="spacer" aria-hidden="true"></div>
|
|
558
|
+
</main>`;
|
|
503
559
|
switch (framework) {
|
|
504
|
-
case "react":
|
|
560
|
+
case "react":
|
|
561
|
+
case "solid": {
|
|
562
|
+
const jsx = framework === "react" ? body.replaceAll("class=", "className=") : body;
|
|
563
|
+
return `${hasDatabase ? `${framework === "solid" ? "import { For, Show } from \"solid-js\";\n" : ""}import { Form, useForm } from "${SCAFFOLD_FRAMEWORKS[framework].adapterPackage}";
|
|
505
564
|
import type { Props } from "./index.server";
|
|
565
|
+
` : ""}import "./style.css";
|
|
506
566
|
|
|
507
|
-
export default function HomePage({ messages }: Props) {
|
|
508
|
-
const form = useForm("
|
|
509
|
-
|
|
510
|
-
<main>
|
|
511
|
-
<h1>Welcome to Void</h1>
|
|
512
|
-
<p>
|
|
513
|
-
This starter is running in Pages mode. The list below is loaded from your database in
|
|
514
|
-
<code> pages/index.server.ts</code>.
|
|
515
|
-
</p>
|
|
516
|
-
<p>
|
|
517
|
-
API example: <a href="/api/hello">/api/hello</a>
|
|
518
|
-
</p>
|
|
519
|
-
{messages.length === 0 ? (
|
|
520
|
-
<p>
|
|
521
|
-
No messages yet. Run <code>void db seed</code> to load the sample row from
|
|
522
|
-
<code> db/seed.ts</code>.
|
|
523
|
-
</p>
|
|
524
|
-
) : (
|
|
525
|
-
<ul>
|
|
526
|
-
{messages.map((message) => (
|
|
527
|
-
<li key={message.id}>
|
|
528
|
-
<strong>{message.text}</strong>
|
|
529
|
-
<br />
|
|
530
|
-
<small>{String(message.createdAt)}</small>
|
|
531
|
-
</li>
|
|
532
|
-
))}
|
|
533
|
-
</ul>
|
|
534
|
-
)}
|
|
535
|
-
<Form form={form}>
|
|
536
|
-
<label>Message <input value={form.data.text} onChange={event => form.setData("text", event.target.value)} /></label>
|
|
537
|
-
<button disabled={form.pending}>Add message</button>
|
|
538
|
-
</Form>
|
|
539
|
-
</main>
|
|
567
|
+
export default function HomePage(${hasDatabase ? framework === "react" ? "{ messages }: Props" : "props: Props" : ""}) {
|
|
568
|
+
${hasDatabase ? " const form = useForm(\"/\", { text: \"\" });\n\n" : ""} return (
|
|
569
|
+
${indent(jsx, 4)}
|
|
540
570
|
);
|
|
541
571
|
}
|
|
542
572
|
`;
|
|
573
|
+
}
|
|
543
574
|
case "vue": return `<script setup lang="ts">
|
|
544
|
-
import type { Props } from "./index.server";
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
defineProps<Props>();
|
|
548
|
-
const form = useForm("/", { text: "" });
|
|
549
|
-
<\/script>
|
|
575
|
+
${hasDatabase ? "import { Form, useForm } from \"@void/vue\";\nimport type { Props } from \"./index.server\";\n" : ""}import "./style.css";
|
|
576
|
+
${hasDatabase ? "\ndefineProps<Props>();\nconst form = useForm(\"/\", { text: \"\" });\n" : ""}<\/script>
|
|
550
577
|
|
|
551
578
|
<template>
|
|
552
|
-
|
|
553
|
-
<h1>Welcome to Void</h1>
|
|
554
|
-
<p>
|
|
555
|
-
This starter is running in Pages mode. The list below is loaded from your database in
|
|
556
|
-
<code>pages/index.server.ts</code>.
|
|
557
|
-
</p>
|
|
558
|
-
<p>
|
|
559
|
-
API example: <a href="/api/hello">/api/hello</a>
|
|
560
|
-
</p>
|
|
561
|
-
<p v-if="messages.length === 0">
|
|
562
|
-
No messages yet. Run <code>void db seed</code> to load the sample row from
|
|
563
|
-
<code>db/seed.ts</code>.
|
|
564
|
-
</p>
|
|
565
|
-
<ul v-else>
|
|
566
|
-
<li v-for="message in messages" :key="message.id">
|
|
567
|
-
<strong>{{ message.text }}</strong>
|
|
568
|
-
<br />
|
|
569
|
-
<small>{{ String(message.createdAt) }}</small>
|
|
570
|
-
</li>
|
|
571
|
-
</ul>
|
|
572
|
-
<Form :form="form">
|
|
573
|
-
<label>Message <input v-model="form.data.text" /></label>
|
|
574
|
-
<button :disabled="form.pending">Add message</button>
|
|
575
|
-
</Form>
|
|
576
|
-
</main>
|
|
579
|
+
${indent(body, 2)}
|
|
577
580
|
</template>
|
|
578
581
|
`;
|
|
579
582
|
case "svelte": return `<script lang="ts">
|
|
580
|
-
import type { Props } from "./index.server";
|
|
581
|
-
|
|
582
|
-
const form = useForm("/", { text: "" });
|
|
583
|
-
|
|
584
|
-
let { messages }: Props = $props();
|
|
585
|
-
<\/script>
|
|
586
|
-
|
|
587
|
-
<main>
|
|
588
|
-
<h1>Welcome to Void</h1>
|
|
589
|
-
<p>
|
|
590
|
-
This starter is running in Pages mode. The list below is loaded from your database in
|
|
591
|
-
<code>pages/index.server.ts</code>.
|
|
592
|
-
</p>
|
|
593
|
-
<p>
|
|
594
|
-
API example: <a href="/api/hello">/api/hello</a>
|
|
595
|
-
</p>
|
|
596
|
-
{#if messages.length === 0}
|
|
597
|
-
<p>
|
|
598
|
-
No messages yet. Run <code>void db seed</code> to load the sample row from
|
|
599
|
-
<code>db/seed.ts</code>.
|
|
600
|
-
</p>
|
|
601
|
-
{:else}
|
|
602
|
-
<ul>
|
|
603
|
-
{#each messages as message (message.id)}
|
|
604
|
-
<li>
|
|
605
|
-
<strong>{message.text}</strong>
|
|
606
|
-
<br />
|
|
607
|
-
<small>{String(message.createdAt)}</small>
|
|
608
|
-
</li>
|
|
609
|
-
{/each}
|
|
610
|
-
</ul>
|
|
611
|
-
{/if}
|
|
612
|
-
<Form {form}>
|
|
613
|
-
<label>Message <input bind:value={form.data.text} /></label>
|
|
614
|
-
<button disabled={form.pending}>Add message</button>
|
|
615
|
-
</Form>
|
|
616
|
-
</main>
|
|
617
|
-
`;
|
|
618
|
-
case "solid": return `import { Form, useForm } from "${SCAFFOLD_FRAMEWORKS[framework].adapterPackage}";
|
|
619
|
-
import type { Props } from "./index.server";
|
|
583
|
+
${hasDatabase ? " import { Form, useForm } from \"@void/svelte\";\n import type { Props } from \"./index.server\";\n" : ""} import "./style.css";
|
|
584
|
+
${hasDatabase ? "\n let { messages }: Props = $props();\n const form = useForm(\"/\", { text: \"\" });\n" : ""}<\/script>
|
|
620
585
|
|
|
621
|
-
|
|
622
|
-
const form = useForm("/", { text: "" });
|
|
623
|
-
return (
|
|
624
|
-
<main>
|
|
625
|
-
<h1>Welcome to Void</h1>
|
|
626
|
-
<p>
|
|
627
|
-
This starter is running in Pages mode. The list below is loaded from your database in
|
|
628
|
-
<code> pages/index.server.ts</code>.
|
|
629
|
-
</p>
|
|
630
|
-
<p>
|
|
631
|
-
API example: <a href="/api/hello">/api/hello</a>
|
|
632
|
-
</p>
|
|
633
|
-
{props.messages.length === 0 ? (
|
|
634
|
-
<p>
|
|
635
|
-
No messages yet. Run <code>void db seed</code> to load the sample row from
|
|
636
|
-
<code> db/seed.ts</code>.
|
|
637
|
-
</p>
|
|
638
|
-
) : (
|
|
639
|
-
<ul>
|
|
640
|
-
{props.messages.map((message) => (
|
|
641
|
-
<li>
|
|
642
|
-
<strong>{message.text}</strong>
|
|
643
|
-
<br />
|
|
644
|
-
<small>{String(message.createdAt)}</small>
|
|
645
|
-
</li>
|
|
646
|
-
))}
|
|
647
|
-
</ul>
|
|
648
|
-
)}
|
|
649
|
-
<Form form={form}>
|
|
650
|
-
<label>Message <input value={form.data.text} onInput={event => form.setData("text", event.target.value)} /></label>
|
|
651
|
-
<button disabled={form.pending}>Add message</button>
|
|
652
|
-
</Form>
|
|
653
|
-
</main>
|
|
654
|
-
);
|
|
655
|
-
}
|
|
586
|
+
${body}
|
|
656
587
|
`;
|
|
657
588
|
}
|
|
658
589
|
}
|
|
590
|
+
function getMessagesDemo(framework) {
|
|
591
|
+
const empty = `<p class="empty-state">
|
|
592
|
+
No messages yet. Run <code>void db seed</code> to load the sample row from <code>db/seed.ts</code>.
|
|
593
|
+
</p>`;
|
|
594
|
+
const content = {
|
|
595
|
+
react: `{messages.length === 0 ? (
|
|
596
|
+
${indent(empty, 2)}
|
|
597
|
+
) : (
|
|
598
|
+
<ul class="messages">
|
|
599
|
+
{messages.map((message) => (
|
|
600
|
+
<li key={message.id}>
|
|
601
|
+
<strong>{message.text}</strong>
|
|
602
|
+
<small>{String(message.createdAt)}</small>
|
|
603
|
+
</li>
|
|
604
|
+
))}
|
|
605
|
+
</ul>
|
|
606
|
+
)}
|
|
607
|
+
<Form form={form} className="message-form">
|
|
608
|
+
<label htmlFor="message-text">Message</label>
|
|
609
|
+
<div class="message-fields">
|
|
610
|
+
<input id="message-text" name="text" value={form.data.text} onChange={(event) => form.setData("text", event.target.value)} required maxLength={1000} />
|
|
611
|
+
<button type="submit" disabled={form.pending}>Add message</button>
|
|
612
|
+
</div>
|
|
613
|
+
</Form>`,
|
|
614
|
+
vue: `<template v-if="messages.length === 0">
|
|
615
|
+
${indent(empty, 2)}
|
|
616
|
+
</template>
|
|
617
|
+
<ul v-else class="messages">
|
|
618
|
+
<li v-for="message in messages" :key="message.id">
|
|
619
|
+
<strong>{{ message.text }}</strong>
|
|
620
|
+
<small>{{ String(message.createdAt) }}</small>
|
|
621
|
+
</li>
|
|
622
|
+
</ul>
|
|
623
|
+
<Form :form="form" class="message-form">
|
|
624
|
+
<label for="message-text">Message</label>
|
|
625
|
+
<div class="message-fields">
|
|
626
|
+
<input id="message-text" name="text" v-model="form.data.text" required maxlength="1000" />
|
|
627
|
+
<button type="submit" :disabled="form.pending">Add message</button>
|
|
628
|
+
</div>
|
|
629
|
+
</Form>`,
|
|
630
|
+
svelte: `{#if messages.length === 0}
|
|
631
|
+
${indent(empty, 2)}
|
|
632
|
+
{:else}
|
|
633
|
+
<ul class="messages">
|
|
634
|
+
{#each messages as message (message.id)}
|
|
635
|
+
<li>
|
|
636
|
+
<strong>{message.text}</strong>
|
|
637
|
+
<small>{String(message.createdAt)}</small>
|
|
638
|
+
</li>
|
|
639
|
+
{/each}
|
|
640
|
+
</ul>
|
|
641
|
+
{/if}
|
|
642
|
+
<Form {form} class="message-form">
|
|
643
|
+
<label for="message-text">Message</label>
|
|
644
|
+
<div class="message-fields">
|
|
645
|
+
<input id="message-text" name="text" bind:value={form.data.text} required maxlength={1000} />
|
|
646
|
+
<button type="submit" disabled={form.pending}>Add message</button>
|
|
647
|
+
</div>
|
|
648
|
+
</Form>`,
|
|
649
|
+
solid: `<Show when={props.messages.length > 0} fallback={
|
|
650
|
+
${indent(empty, 2)}
|
|
651
|
+
}>
|
|
652
|
+
<ul class="messages">
|
|
653
|
+
<For each={props.messages}>{(message) => (
|
|
654
|
+
<li>
|
|
655
|
+
<strong>{message.text}</strong>
|
|
656
|
+
<small>{String(message.createdAt)}</small>
|
|
657
|
+
</li>
|
|
658
|
+
)}</For>
|
|
659
|
+
</ul>
|
|
660
|
+
</Show>
|
|
661
|
+
<Form form={form} class="message-form">
|
|
662
|
+
<label for="message-text">Message</label>
|
|
663
|
+
<div class="message-fields">
|
|
664
|
+
<input id="message-text" name="text" value={form.data.text} onInput={(event) => form.setData("text", event.currentTarget.value)} required maxLength={1000} />
|
|
665
|
+
<button type="submit" disabled={form.pending}>Add message</button>
|
|
666
|
+
</div>
|
|
667
|
+
</Form>`
|
|
668
|
+
}[framework];
|
|
669
|
+
return `<section class="starter-demo" aria-labelledby="messages-title">
|
|
670
|
+
<div class="demo-content">
|
|
671
|
+
<h2 id="messages-title">Messages</h2>
|
|
672
|
+
${indent(content, 4)}
|
|
673
|
+
</div>
|
|
674
|
+
</section>`;
|
|
675
|
+
}
|
|
676
|
+
function indent(source, spaces) {
|
|
677
|
+
return source.split("\n").map((line) => " ".repeat(spaces) + line).join("\n");
|
|
678
|
+
}
|
|
659
679
|
//#endregion
|
|
660
680
|
//#region src/cli/init-vite-plus.ts
|
|
661
681
|
/** Keep every Vite consumer on the core used by the selected Vite+ toolchain. */
|
|
@@ -2408,18 +2428,28 @@ export const posts = sqliteTable("posts", {
|
|
|
2408
2428
|
});
|
|
2409
2429
|
`;
|
|
2410
2430
|
}
|
|
2431
|
+
function demoFiles(root) {
|
|
2432
|
+
const paths = readProjectPaths(root);
|
|
2433
|
+
return {
|
|
2434
|
+
schema: paths.schemaFile,
|
|
2435
|
+
route: join(paths.routesDir, "api", "posts.ts"),
|
|
2436
|
+
client: join(paths.ssrDir, "demo.ts")
|
|
2437
|
+
};
|
|
2438
|
+
}
|
|
2411
2439
|
/**
|
|
2412
2440
|
* Scaffolds the "SQL → types → handler → fetch" demo into an existing project.
|
|
2413
2441
|
* `setupExistingProject` has already declared `void` in `package.json`.
|
|
2442
|
+
* The caller skips the demo when any of its files exists, so these writes never replace user code.
|
|
2414
2443
|
*/
|
|
2415
2444
|
function scaffoldDemo(root, dialect) {
|
|
2416
2445
|
const devCommand = getDevCommand(root);
|
|
2417
2446
|
const paths = readProjectPaths(root);
|
|
2447
|
+
const files = demoFiles(root);
|
|
2418
2448
|
mkdirSync(paths.dbDir, { recursive: true });
|
|
2419
|
-
writeFileSync(
|
|
2449
|
+
writeFileSync(files.schema, demoSchemaSource(dialect));
|
|
2420
2450
|
log.step("Created db/schema.ts");
|
|
2421
2451
|
mkdirSync(join(paths.routesDir, "api"), { recursive: true });
|
|
2422
|
-
writeFileSync(
|
|
2452
|
+
writeFileSync(files.route, `import { defineHandler } from "void";
|
|
2423
2453
|
import { db } from "void/db";
|
|
2424
2454
|
import { posts } from "@schema";
|
|
2425
2455
|
|
|
@@ -2431,7 +2461,7 @@ export const GET = defineHandler(async () => {
|
|
|
2431
2461
|
log.step("Created routes/api/posts.ts");
|
|
2432
2462
|
ensureProjectTsconfig(root, void 0, true, true, { paths });
|
|
2433
2463
|
mkdirSync(paths.ssrDir, { recursive: true });
|
|
2434
|
-
writeFileSync(
|
|
2464
|
+
writeFileSync(files.client, `import { fetch } from "void/client";
|
|
2435
2465
|
|
|
2436
2466
|
// Fully typed: response type is inferred from the GET handler's return type,
|
|
2437
2467
|
// which is derived from the migration schema. No manual types needed.
|
|
@@ -2569,8 +2599,13 @@ async function runInitCommand(root, initArgs) {
|
|
|
2569
2599
|
linkSkillsForSpecificAgents(root, agents);
|
|
2570
2600
|
} else log.info("Bundled Void docs: node_modules/void/docs/");
|
|
2571
2601
|
if (!targeted && !framework) {
|
|
2602
|
+
const existingDemoFiles = Object.values(demoFiles(root)).filter((file) => existsSync(file));
|
|
2572
2603
|
if (didScaffoldStarter || state.hasRoutes || state.hasMigrations || state.hasPages) log.info("Project already has pages, routes, or migrations, skipping demo");
|
|
2573
|
-
else
|
|
2604
|
+
else if (hasDrizzleSchema(root)) log.info("Project already has a database schema, skipping demo");
|
|
2605
|
+
else if (existingDemoFiles.length > 0) {
|
|
2606
|
+
const names = existingDemoFiles.map((file) => relative(root, file)).join(", ");
|
|
2607
|
+
log.info(`Project already has ${names}, skipping demo`);
|
|
2608
|
+
} else {
|
|
2574
2609
|
const scaffold = await confirm({ message: "Scaffold demo code? (migration + API route + frontend fetch)" });
|
|
2575
2610
|
if (isCancel(scaffold)) {
|
|
2576
2611
|
cancel("Setup cancelled.");
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { r as readProjectConfig, t as attachSelectedPlatform, u as writeProjectConfig } from "./project-rqDnVsJN.mjs";
|
|
2
2
|
import { c as getToken, s as getSiteDomain } from "./auth-B6iOCjKI.mjs";
|
|
3
3
|
import { H as outro, L as log, O as cancel } from "./dist-Cor9XGoz.mjs";
|
|
4
|
-
import { r as PlatformClient } from "./client-
|
|
4
|
+
import { r as PlatformClient } from "./client-B3LnB_bE.mjs";
|
|
5
5
|
import { f as import_picocolors, m as printSuccess } from "./output-BpgYODYx.mjs";
|
|
6
|
-
import { a as promptProjectSelection, r as promptAndCreateProject } from "./create-project-
|
|
6
|
+
import { a as promptProjectSelection, r as promptAndCreateProject } from "./create-project-Bxd02EHN.mjs";
|
|
7
7
|
import { a as resolveProjectBySlug } from "./resolve-project-Xoi6eTWY.mjs";
|
|
8
8
|
//#region src/cli/link.ts
|
|
9
9
|
function projectLabel(slug, root, url) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { n as readDeploymentPlatform, r as readProjectConfig } from "./project-rqDnVsJN.mjs";
|
|
2
2
|
import { c as getToken } from "./auth-B6iOCjKI.mjs";
|
|
3
3
|
import { H as outro, L as log } from "./dist-Cor9XGoz.mjs";
|
|
4
|
-
import { r as PlatformClient } from "./client-
|
|
4
|
+
import { r as PlatformClient } from "./client-B3LnB_bE.mjs";
|
|
5
5
|
import { _ as tablePrefix, c as formatRelativeTime, f as import_picocolors, h as sanitizeTerminalText, i as dim, o as formatCount } from "./output-BpgYODYx.mjs";
|
|
6
6
|
import { a as resolveProjectBySlug } from "./resolve-project-Xoi6eTWY.mjs";
|
|
7
7
|
//#region src/cli/list.ts
|
|
@@ -42,7 +42,7 @@ async function runListCommand(root, slug) {
|
|
|
42
42
|
}
|
|
43
43
|
async function showCloudflareDeployments(root, slug) {
|
|
44
44
|
if (slug) throw new Error("project: A project name selects a Void platform project and is not used for direct Cloudflare apps.");
|
|
45
|
-
const { readCloudflareWorkerStatus, resolveCloudflareOperationContext } = await import("./cloudflare-operations-
|
|
45
|
+
const { readCloudflareWorkerStatus, resolveCloudflareOperationContext } = await import("./cloudflare-operations-BtulCNOg.mjs");
|
|
46
46
|
const status = await readCloudflareWorkerStatus(resolveCloudflareOperationContext(root));
|
|
47
47
|
if (status.versions.length === 0) {
|
|
48
48
|
outro(`No deployments for ${status.workerName}.`);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { r as AuthUser } from "./auth-
|
|
2
|
-
import { a as CloudEnv, r as CloudContext } from "./handler-
|
|
1
|
+
import { r as AuthUser } from "./auth-g2TQbDLD.mjs";
|
|
2
|
+
import { a as CloudEnv, r as CloudContext } from "./handler-BHktmuTL.mjs";
|
|
3
3
|
//#region src/runtime/live.d.ts
|
|
4
4
|
type MaybePromise<T> = T | Promise<T>;
|
|
5
5
|
type LiveControlRequest = {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { a as join, c as resolve, i as isAbsolute } from "./dist-ipQi0Q8y.mjs";
|
|
2
|
-
import { b as readRootWranglerConfig } from "./wrangler-
|
|
2
|
+
import { b as readRootWranglerConfig } from "./wrangler-I-scB_1t.mjs";
|
|
3
3
|
import { r as getMiniflareDatabasePath } from "./runner-3uGC-oLF.mjs";
|
|
4
4
|
import { existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from "node:fs";
|
|
5
5
|
import { createHash } from "node:crypto";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { r as selectPlatformLoginMethod } from "./login-PcFy5mlC.mjs";
|