void 0.9.2 → 0.10.1
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/README.md +1 -0
- package/dist/{auth-cmd-CPkWrQR9.mjs → auth-cmd-DBnbrX9Y.mjs} +2 -2
- package/dist/{better-auth-shared-ChVbrq52.mjs → better-auth-shared-D0Mbmx5V.mjs} +1 -1
- package/dist/{better-auth-shared-CmEQZs1T.d.mts → better-auth-shared-a7H3wk9J.d.mts} +2 -2
- package/dist/{cache-1SVxZ7BK.mjs → cache-DNX0hLsO.mjs} +1 -1
- package/dist/{cancel-deploy-JaFClLr7.mjs → cancel-deploy-CDzkVaYZ.mjs} +1 -1
- package/dist/cli/cli.mjs +205 -36
- package/dist/{client-DIfOFf1W.mjs → client-D4awzTnj.mjs} +149 -45
- package/dist/{config-BVEC0lti.mjs → config-8dLIngKW.mjs} +1 -1
- package/dist/{create-project-DCUrFJxa.mjs → create-project-CGodxfzH.mjs} +1 -1
- package/dist/{db-DiddQC2v.mjs → db-ERzz4oly.mjs} +16 -16
- package/dist/{delete-CYknzwXU.mjs → delete-CJZGDLBR.mjs} +1 -1
- package/dist/{deploy-CRU9fGjE.mjs → deploy-Cwa5sooV.mjs} +97 -108
- package/dist/{domain-B7RntQ1r.mjs → domain-WvoAHE6w.mjs} +1 -1
- package/dist/{drizzle-2fs1qTgy.mjs → drizzle-DqstQTGq.mjs} +1 -1
- package/dist/{env-Bvw0wMTI.mjs → env-Cx4czPsR.mjs} +3 -3
- package/dist/{env-helpers-Bd2wVdxz.d.mts → env-helpers-ZatKyjen.d.mts} +1 -1
- package/dist/{env-types-D6qI1ThV.mjs → env-types-CaJaIRXU.mjs} +1 -1
- package/dist/{env-validation-DBJsxZLz.mjs → env-validation-LH6eoyW-.mjs} +3 -3
- package/dist/{gen-CZdNWIaA.mjs → gen-Dgi4D7GC.mjs} +3 -3
- package/dist/git-metadata-Ce0AtSZL.mjs +82 -0
- package/dist/github-cmd-CUB041gj.mjs +308 -0
- package/dist/{handler-xflsMwWM.d.mts → handler-DczZlaXR.d.mts} +24 -4
- package/dist/{headers-Y0jshugF.mjs → headers-BNWymgnH.mjs} +2 -2
- package/dist/index.d.mts +4 -4
- package/dist/index.mjs +60 -55
- package/dist/{init-BHupO7Fm.mjs → init-DvaRDMIc.mjs} +125 -80
- package/dist/{link-7MoXUMaI.mjs → link-CpbWJY3P.mjs} +2 -2
- package/dist/{list-N2mCHv8q.mjs → list-BkwE5vH4.mjs} +1 -1
- package/dist/{login-tt1OmNVg.mjs → login-Ca6mhQVI.mjs} +1 -1
- package/dist/{logs-Cl7q2CjZ.mjs → logs-ArQzZquo.mjs} +1 -1
- package/dist/{mcp-BXD35N2J.mjs → mcp-Cc2MMXdQ.mjs} +1 -1
- package/dist/{node-CHWVVjO6.mjs → node-B07cZs0d.mjs} +4 -4
- package/dist/pages/client.d.mts +1 -1
- package/dist/pages/client.mjs +1 -0
- package/dist/pages/head-client.d.mts +1 -1
- package/dist/pages/head.d.mts +1 -1
- package/dist/pages/index.d.mts +8 -6
- package/dist/pages/index.mjs +3 -3
- package/dist/pages/islands-plugin.d.mts +1 -1
- package/dist/pages/islands-plugin.mjs +1 -1
- package/dist/pages/protocol.d.mts +2 -2
- package/dist/pages/protocol.mjs +30 -12
- package/dist/{plugin-inference-BUBhHt_1.mjs → plugin-inference-C3fLzFvP.mjs} +3 -1
- package/dist/{prepare-CrlAVbWS.mjs → prepare-DH2WnEpD.mjs} +14 -19
- package/dist/{preset-CIJG2O7a.mjs → preset-B7ZQZn0u.mjs} +2 -2
- package/dist/{project-cmd-CLrqSbqj.mjs → project-cmd-CWZeawuN.mjs} +8 -8
- package/dist/{project-tsconfig-HAGjfY6w.mjs → project-tsconfig-BTNuNoJ0.mjs} +18 -4
- package/dist/{protocol-DYca39yJ.d.mts → protocol-63PHtCHS.d.mts} +8 -5
- package/dist/{rollback-CEbAwbHK.mjs → rollback-BJ60ktsW.mjs} +1 -1
- package/dist/{route-types-jxRfWuCb.mjs → route-types-D03ryMXz.mjs} +3 -2
- package/dist/{runner-DLZ9E_cX.mjs → runner-BQyKUqAL.mjs} +1 -1
- package/dist/runtime/ai.mjs +1 -1
- package/dist/runtime/auth.d.mts +1 -1
- package/dist/runtime/better-auth-pg.d.mts +1 -1
- package/dist/runtime/better-auth-pg.mjs +3 -3
- package/dist/runtime/better-auth.d.mts +1 -1
- package/dist/runtime/better-auth.mjs +2 -2
- package/dist/runtime/client-react.d.mts +2 -2
- package/dist/runtime/client-react.mjs +1 -1
- package/dist/runtime/client-solid.d.mts +2 -2
- package/dist/runtime/client-solid.mjs +1 -1
- package/dist/runtime/client-svelte.d.mts +2 -2
- package/dist/runtime/client-svelte.mjs +1 -1
- package/dist/runtime/client-vue.d.mts +2 -2
- package/dist/runtime/client-vue.mjs +1 -1
- package/dist/runtime/client.d.mts +2 -2
- package/dist/runtime/client.mjs +1 -1
- package/dist/runtime/env-helpers.d.mts +1 -1
- package/dist/runtime/env-public-client.d.mts +1 -1
- package/dist/runtime/env-public.d.mts +2 -2
- package/dist/runtime/env-public.mjs +1 -1
- package/dist/runtime/env.mjs +1 -1
- package/dist/runtime/fetch-stream.d.mts +1 -1
- package/dist/runtime/fetch-stream.mjs +1 -1
- package/dist/runtime/fetch.d.mts +1 -1
- package/dist/runtime/fetch.mjs +1 -1
- package/dist/runtime/handler.d.mts +2 -2
- package/dist/runtime/handler.mjs +68 -2
- package/dist/runtime/isr.mjs +1 -1
- package/dist/runtime/live.d.mts +2 -2
- package/dist/runtime/live.mjs +1 -1
- package/dist/runtime/migration-handler-pg.mjs +1 -1
- package/dist/runtime/sandbox.mjs +1 -1
- package/dist/runtime/validator.d.mts +1 -1
- package/dist/runtime/ws-server.d.mts +2 -2
- package/dist/runtime/ws.d.mts +3 -3
- package/dist/{scan-BNC_1OsY.mjs → scan-DGEp1-1Q.mjs} +19 -11
- package/dist/{scan-2YmJkYAf.mjs → scan-VCAM1oh3.mjs} +55 -29
- package/dist/{secret-C_uTY7xx.mjs → secret-BRbXyu7E.mjs} +1 -1
- package/dist/{types-Dm9kep2X.d.mts → types-BnHMXezo.d.mts} +12 -3
- package/package.json +2 -2
- package/schema.json +3 -3
- package/skills/void/docs/guide/deployment.md +37 -11
- package/skills/void/docs/guide/edge/headers.md +10 -3
- package/skills/void/docs/guide/edge/rewrites.md +5 -5
- package/skills/void/docs/guide/pages-routing/layouts.md +8 -7
- package/skills/void/docs/guide/pages-routing/loaders.md +1 -1
- package/skills/void/docs/guide/pages-routing/overview.md +32 -5
- package/skills/void/docs/guide/server-routing.md +28 -0
- package/skills/void/docs/node_modules/void/AGENTS.md +15 -14
- package/skills/void/docs/node_modules/void/README.md +1 -0
- package/skills/void/docs/reference/api.md +44 -1
- package/skills/void/docs/reference/cli.md +65 -2
- package/skills/void/docs/reference/config.md +1 -1
- /package/dist/{auth-migrations-CuQkjjWE.mjs → auth-migrations-BP-hMzYl.mjs} +0 -0
- /package/dist/{auth-CDeb2XAl.d.mts → auth-nEUVHuFI.d.mts} +0 -0
- /package/dist/{defer-CouVukrf.mjs → defer-C-bdSM_b.mjs} +0 -0
- /package/dist/{dist-DR9sIMbM.mjs → dist-5cGIJHQQ.mjs} +0 -0
- /package/dist/{dotenv-Bkoqyq9r.mjs → dotenv-lS94ymhM.mjs} +0 -0
- /package/dist/{env-raw-RDkMnSTC.mjs → env-raw-Dtj1UAoK.mjs} +0 -0
- /package/dist/{fetch-error-CimrygMq.d.mts → fetch-error-BQMdPvge.d.mts} +0 -0
- /package/dist/{fetch-error-BFIoojjf.mjs → fetch-error-C6qffTl2.mjs} +0 -0
- /package/dist/{head-BsSTGnIe.d.mts → head-JAH2l3fg.d.mts} +0 -0
- /package/dist/{log-CWWZV4V1.mjs → log-BdD_Fpms.mjs} +0 -0
- /package/dist/{package-json-B2TD0JLu.mjs → package-json-Bg_GJdJB.mjs} +0 -0
- /package/dist/{pg-CMZ_5wsC.mjs → pg-CempqvEJ.mjs} +0 -0
- /package/dist/{providers-3Kkv63Ha.d.mts → providers-BkiAlEad.d.mts} +0 -0
- /package/dist/{providers-uC0PJg1c.mjs → providers-BwPbdHdi.mjs} +0 -0
- /package/dist/{runner-pg-Cv9V7ydr.mjs → runner-pg-BAheiT6v.mjs} +0 -0
- /package/dist/{skills-BRKc--As.mjs → skills--OMgLmXW.mjs} +0 -0
- /package/dist/{standard-schema-Dnsh2vnl.d.mts → standard-schema-BCBv-QaP.d.mts} +0 -0
- /package/dist/{subcommand-prompt-OD-x_Tsm.mjs → subcommand-prompt-ClwpLlKD.mjs} +0 -0
- /package/dist/{yarn-pnp-0SwYgQxx.mjs → yarn-pnp-DhCHHLAz.mjs} +0 -0
package/dist/runtime/client.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as FetchError } from "../fetch-error-
|
|
1
|
+
import { t as FetchError } from "../fetch-error-C6qffTl2.mjs";
|
|
2
2
|
import { fetch } from "./fetch.mjs";
|
|
3
3
|
import { fetchStream } from "./fetch-stream.mjs";
|
|
4
4
|
import { auth, createAuthClient } from "./auth-client.mjs";
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as getSecretOverride, c as oneOf, i as email, l as string, n as SECRET_OVERRIDE_SYMBOL, o as json, r as boolean, s as number, t as EnvSchema, u as url } from "../env-helpers-
|
|
1
|
+
import { a as getSecretOverride, c as oneOf, i as email, l as string, n as SECRET_OVERRIDE_SYMBOL, o as json, r as boolean, s as number, t as EnvSchema, u as url } from "../env-helpers-ZatKyjen.mjs";
|
|
2
2
|
export { EnvSchema, SECRET_OVERRIDE_SYMBOL, boolean, email, getSecretOverride, json, number, oneOf, string, url };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { c as oneOf, i as email, l as string, o as json, r as boolean, s as number, t as EnvSchema, u as url } from "../env-helpers-
|
|
1
|
+
import { c as oneOf, i as email, l as string, o as json, r as boolean, s as number, t as EnvSchema, u as url } from "../env-helpers-ZatKyjen.mjs";
|
|
2
2
|
|
|
3
3
|
//#region src/runtime/env-public-client.d.ts
|
|
4
4
|
declare const env: Record<string, unknown>;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/// <reference types="@cloudflare/workers-types" />
|
|
2
|
-
import { t as StandardSchemaV1 } from "../standard-schema-
|
|
3
|
-
import { c as oneOf, i as email, l as string, o as json, r as boolean, s as number, t as EnvSchema, u as url } from "../env-helpers-
|
|
2
|
+
import { t as StandardSchemaV1 } from "../standard-schema-BCBv-QaP.mjs";
|
|
3
|
+
import { c as oneOf, i as email, l as string, o as json, r as boolean, s as number, t as EnvSchema, u as url } from "../env-helpers-ZatKyjen.mjs";
|
|
4
4
|
import * as _$_cloudflare_sandbox0 from "@cloudflare/sandbox";
|
|
5
5
|
|
|
6
6
|
//#region src/runtime/env-public.d.ts
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { i as getRawRuntimeEnv } from "../env-raw-
|
|
1
|
+
import { i as getRawRuntimeEnv } from "../env-raw-Dtj1UAoK.mjs";
|
|
2
2
|
import { getRuntimeEnv } from "./env.mjs";
|
|
3
3
|
import { boolean, email, getSecretOverride, json, number, oneOf, string, url } from "./env-helpers.mjs";
|
|
4
4
|
//#region src/shared/env-mask.ts
|
package/dist/runtime/env.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { i as getRawRuntimeEnv, n as asEnv, r as envContext, t as INTERNAL_BINDING_PREFIXES } from "../env-raw-
|
|
1
|
+
import { i as getRawRuntimeEnv, n as asEnv, r as envContext, t as INTERNAL_BINDING_PREFIXES } from "../env-raw-Dtj1UAoK.mjs";
|
|
2
2
|
//#region src/runtime/env.ts
|
|
3
3
|
/**
|
|
4
4
|
* Public runtime env API — exposed via "void/_env".
|
package/dist/runtime/fetch.d.mts
CHANGED
package/dist/runtime/fetch.mjs
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
/// <reference types="@cloudflare/workers-types" />
|
|
2
|
-
import { C as
|
|
3
|
-
export { CloudBindings, CloudContext, CloudContextVariables, CloudEnv, Deferred, HandlerInput, InferProps, QueueBatch, QueueMessage, QueueRetryOptions, RenderAssetTags, TypedHandler, TypedQueueHandler, ValidationError, ValidatorSlots, VoidAssetRewriteError, defer, defineHandler, defineHead, defineMiddleware, defineQueue, defineRender, defineScheduled };
|
|
2
|
+
import { C as defer, E as ValidatorSlots, S as InferProps, T as HandlerInput, _ as defineQueue, a as CloudEnv, b as Deferred, c as QueueRetryOptions, d as TypedQueueHandler, f as VoidAssetRewriteError, g as defineMiddleware, h as defineHead, i as CloudContextVariables, l as RenderAssetTags, m as defineHandler, n as CloudBindings, o as QueueBatch, p as basicAuth, r as CloudContext, s as QueueMessage, t as BasicAuthOptions, u as TypedHandler, v as defineRender, w as ValidationError, y as defineScheduled } from "../handler-DczZlaXR.mjs";
|
|
3
|
+
export { BasicAuthOptions, CloudBindings, CloudContext, CloudContextVariables, CloudEnv, Deferred, HandlerInput, InferProps, QueueBatch, QueueMessage, QueueRetryOptions, RenderAssetTags, TypedHandler, TypedQueueHandler, ValidationError, ValidatorSlots, VoidAssetRewriteError, basicAuth, defer, defineHandler, defineHead, defineMiddleware, defineQueue, defineRender, defineScheduled };
|
package/dist/runtime/handler.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { convertReturnValue } from "./response.mjs";
|
|
2
2
|
import { runValidation } from "./validator.mjs";
|
|
3
|
-
import { i as ValidationError, n as defer } from "../defer-
|
|
3
|
+
import { i as ValidationError, n as defer } from "../defer-C-bdSM_b.mjs";
|
|
4
4
|
//#region src/runtime/handler.ts
|
|
5
5
|
/**
|
|
6
6
|
* Thrown when `c.rewrite()` is called with a destination whose final path
|
|
@@ -53,6 +53,72 @@ function defineHandler(...args) {
|
|
|
53
53
|
function defineMiddleware(handler) {
|
|
54
54
|
return handler;
|
|
55
55
|
}
|
|
56
|
+
const basicAuthEncoder = new TextEncoder();
|
|
57
|
+
const basicAuthDecoder = new TextDecoder("utf-8", { fatal: true });
|
|
58
|
+
function parseBasicAuthHeader(authorization) {
|
|
59
|
+
if (!authorization?.toLowerCase().startsWith("basic ")) return null;
|
|
60
|
+
try {
|
|
61
|
+
const encoded = authorization.slice(6).trim();
|
|
62
|
+
const binary = atob(encoded);
|
|
63
|
+
const bytes = Uint8Array.from(binary, (char) => char.charCodeAt(0));
|
|
64
|
+
const decoded = basicAuthDecoder.decode(bytes);
|
|
65
|
+
const separator = decoded.indexOf(":");
|
|
66
|
+
if (separator === -1) return null;
|
|
67
|
+
return {
|
|
68
|
+
username: decoded.slice(0, separator),
|
|
69
|
+
password: decoded.slice(separator + 1)
|
|
70
|
+
};
|
|
71
|
+
} catch {
|
|
72
|
+
return null;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
function timingSafeStringEqual(actual, expected) {
|
|
76
|
+
const actualBytes = basicAuthEncoder.encode(actual);
|
|
77
|
+
const expectedBytes = basicAuthEncoder.encode(expected);
|
|
78
|
+
let difference = actualBytes.length ^ expectedBytes.length;
|
|
79
|
+
for (let i = 0; i < expectedBytes.length; i++) difference |= (actualBytes[i] ?? 0) ^ expectedBytes[i];
|
|
80
|
+
return difference === 0;
|
|
81
|
+
}
|
|
82
|
+
function isVoidInternalPath(pathname) {
|
|
83
|
+
return pathname === "/__void" || pathname.startsWith("/__void/");
|
|
84
|
+
}
|
|
85
|
+
function basicAuthChallenge(realm, message) {
|
|
86
|
+
const escapedRealm = realm.replace(/["\\]/g, "\\$&");
|
|
87
|
+
return new Response(message, {
|
|
88
|
+
status: 401,
|
|
89
|
+
headers: {
|
|
90
|
+
"Cache-Control": "no-store",
|
|
91
|
+
"WWW-Authenticate": `Basic realm="${escapedRealm}", charset="UTF-8"`
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
function resolveBasicAuthOption(value, fallback) {
|
|
96
|
+
if (value === void 0) return fallback;
|
|
97
|
+
return typeof value === "function" ? value() : value;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Create Basic authentication middleware for temporary site gates and
|
|
101
|
+
* pre-launch protection.
|
|
102
|
+
*
|
|
103
|
+
* Void internal endpoints under `/__void` are always excluded so deploy-time
|
|
104
|
+
* migrations, prerendering, cron/queue dispatch, and remote binding helpers
|
|
105
|
+
* continue to reach Void's own internal-token checks.
|
|
106
|
+
*/
|
|
107
|
+
function basicAuth(options) {
|
|
108
|
+
return defineMiddleware(async (c, next) => {
|
|
109
|
+
if (isVoidInternalPath(c.req.path)) {
|
|
110
|
+
await next();
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
const username = resolveBasicAuthOption(options.username, "");
|
|
114
|
+
const password = resolveBasicAuthOption(options.password, "");
|
|
115
|
+
const credentials = parseBasicAuthHeader(c.req.raw.headers.get("Authorization"));
|
|
116
|
+
const usernameMatches = credentials && timingSafeStringEqual(credentials.username, username);
|
|
117
|
+
const passwordMatches = credentials && timingSafeStringEqual(credentials.password, password);
|
|
118
|
+
if (!usernameMatches || !passwordMatches) return basicAuthChallenge(resolveBasicAuthOption(options.realm, "Restricted"), resolveBasicAuthOption(options.message, "Authentication required"));
|
|
119
|
+
await next();
|
|
120
|
+
});
|
|
121
|
+
}
|
|
56
122
|
/**
|
|
57
123
|
* Identity function that provides type inference for scheduled jobs.
|
|
58
124
|
* At runtime it simply returns the function passed to it.
|
|
@@ -82,4 +148,4 @@ function defineQueue(handler) {
|
|
|
82
148
|
return handler;
|
|
83
149
|
}
|
|
84
150
|
//#endregion
|
|
85
|
-
export { ValidationError, VoidAssetRewriteError, defer, defineHandler, defineHead, defineMiddleware, defineQueue, defineRender, defineScheduled };
|
|
151
|
+
export { ValidationError, VoidAssetRewriteError, basicAuth, defer, defineHandler, defineHead, defineMiddleware, defineQueue, defineRender, defineScheduled };
|
package/dist/runtime/isr.mjs
CHANGED
package/dist/runtime/live.d.mts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/// <reference types="@cloudflare/workers-types" />
|
|
2
|
-
import { r as AuthUser } from "../auth-
|
|
3
|
-
import {
|
|
2
|
+
import { r as AuthUser } from "../auth-nEUVHuFI.mjs";
|
|
3
|
+
import { a as CloudEnv, r as CloudContext } from "../handler-DczZlaXR.mjs";
|
|
4
4
|
|
|
5
5
|
//#region src/runtime/live.d.ts
|
|
6
6
|
type MaybePromise<T> = T | Promise<T>;
|
package/dist/runtime/live.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as disablePgPassFallback } from "../pg-
|
|
1
|
+
import { t as disablePgPassFallback } from "../pg-CempqvEJ.mjs";
|
|
2
2
|
//#region src/runtime/migration-handler-pg.ts
|
|
3
3
|
function createMigrationHandler(env, migrations, _dialect, runAuthMigrations) {
|
|
4
4
|
return async (request) => {
|
package/dist/runtime/sandbox.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { i as getRawRuntimeEnv } from "../env-raw-
|
|
1
|
+
import { i as getRawRuntimeEnv } from "../env-raw-Dtj1UAoK.mjs";
|
|
2
2
|
import { requireRuntimeBinding } from "./env.mjs";
|
|
3
3
|
import { Sandbox, getSandbox as getSandbox$1 } from "@cloudflare/sandbox";
|
|
4
4
|
//#region src/runtime/sandbox.ts
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { D as runValidation, E as ValidatorSlots, T as HandlerInput } from "../handler-DczZlaXR.mjs";
|
|
2
2
|
export { HandlerInput, ValidatorSlots, runValidation };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { n as AuthState } from "../auth-
|
|
2
|
-
import { i as VoidAuthRuntimeOptions, n as VoidAuthEnv } from "../better-auth-shared-
|
|
1
|
+
import { n as AuthState } from "../auth-nEUVHuFI.mjs";
|
|
2
|
+
import { i as VoidAuthRuntimeOptions, n as VoidAuthEnv } from "../better-auth-shared-a7H3wk9J.mjs";
|
|
3
3
|
import { AnyWebSocketDefinition } from "./ws.mjs";
|
|
4
4
|
|
|
5
5
|
//#region src/runtime/ws-server.d.ts
|
package/dist/runtime/ws.d.mts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { r as AuthUser } from "../auth-
|
|
2
|
-
import { t as StandardSchemaV1 } from "../standard-schema-
|
|
3
|
-
import {
|
|
1
|
+
import { r as AuthUser } from "../auth-nEUVHuFI.mjs";
|
|
2
|
+
import { t as StandardSchemaV1 } from "../standard-schema-BCBv-QaP.mjs";
|
|
3
|
+
import { a as CloudEnv } from "../handler-DczZlaXR.mjs";
|
|
4
4
|
import { WebSocketRouteMap } from "void/routes";
|
|
5
5
|
|
|
6
6
|
//#region src/runtime/ws.d.ts
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { a as join, i as isAbsolute, t as basename } from "./pathe.M-eThtNZ-BrPhGF_K.mjs";
|
|
2
2
|
import { n as readProjectPaths } from "./project-paths-CCMrHYQm.mjs";
|
|
3
|
-
import { n as globSync, t as glob } from "./dist-
|
|
4
|
-
import { d as isCallExpression, f as isIdentifier, h as isObjectExpression, p as isLiteral } from "./plugin-inference-
|
|
5
|
-
import { o as parseRouteFilename, s as parseWebSocketFilename, t as scanPages } from "./scan-
|
|
3
|
+
import { n as globSync, t as glob } from "./dist-5cGIJHQQ.mjs";
|
|
4
|
+
import { d as isCallExpression, f as isIdentifier, h as isObjectExpression, p as isLiteral } from "./plugin-inference-C3fLzFvP.mjs";
|
|
5
|
+
import { o as parseRouteFilename, s as parseWebSocketFilename, t as scanPages } from "./scan-VCAM1oh3.mjs";
|
|
6
6
|
import { readFileSync } from "node:fs";
|
|
7
7
|
import { parseSync } from "vite";
|
|
8
8
|
//#region src/crons/scan.ts
|
|
@@ -147,6 +147,7 @@ function detectHttpExports(absPath) {
|
|
|
147
147
|
const program = parsed.program;
|
|
148
148
|
for (const node of program.body ?? []) if (node.type === "ExportNamedDeclaration") {
|
|
149
149
|
const declarationNode = node;
|
|
150
|
+
if (declarationNode.exportKind === "type") continue;
|
|
150
151
|
const decl = declarationNode.declaration;
|
|
151
152
|
if (decl) {
|
|
152
153
|
if (decl.type === "VariableDeclaration") {
|
|
@@ -157,6 +158,7 @@ function detectHttpExports(absPath) {
|
|
|
157
158
|
}
|
|
158
159
|
}
|
|
159
160
|
if (declarationNode.specifiers) for (const spec of declarationNode.specifiers) {
|
|
161
|
+
if (spec.exportKind === "type") continue;
|
|
160
162
|
const exported = isIdentifier(spec.exported) ? spec.exported.name : isIdentifier(spec.local) ? spec.local.name : void 0;
|
|
161
163
|
if (exported && HTTP_METHODS.has(exported)) methods.push(exported);
|
|
162
164
|
}
|
|
@@ -286,6 +288,18 @@ function parseMiddlewareDefinitions(files) {
|
|
|
286
288
|
};
|
|
287
289
|
}).sort((a, b) => a.order - b.order);
|
|
288
290
|
}
|
|
291
|
+
function compareRouteSpecificity(a, b) {
|
|
292
|
+
if (a.catchAll !== b.catchAll) return a.catchAll ? 1 : -1;
|
|
293
|
+
const aSegments = a.pattern.split("/");
|
|
294
|
+
const bSegments = b.pattern.split("/");
|
|
295
|
+
const shared = Math.min(aSegments.length, bSegments.length);
|
|
296
|
+
for (let i = 0; i < shared; i++) {
|
|
297
|
+
const aDynamic = aSegments[i].startsWith(":") || aSegments[i] === "*";
|
|
298
|
+
if (aDynamic !== (bSegments[i].startsWith(":") || bSegments[i] === "*")) return aDynamic ? 1 : -1;
|
|
299
|
+
if (aSegments[i] !== bSegments[i]) return aSegments[i].localeCompare(bSegments[i]);
|
|
300
|
+
}
|
|
301
|
+
return aSegments.length - bSegments.length;
|
|
302
|
+
}
|
|
289
303
|
/**
|
|
290
304
|
* Scan routes/ and middleware/ directories and return a structured manifest.
|
|
291
305
|
* Files starting with _ are ignored.
|
|
@@ -315,10 +329,7 @@ async function scanRoutes(root, options) {
|
|
|
315
329
|
const route = parseRouteFilename(f);
|
|
316
330
|
route.methods = detectHttpExports(join(routesDir, f));
|
|
317
331
|
return route;
|
|
318
|
-
}).sort(
|
|
319
|
-
if (a.catchAll !== b.catchAll) return a.catchAll ? 1 : -1;
|
|
320
|
-
return a.pattern.localeCompare(b.pattern);
|
|
321
|
-
}),
|
|
332
|
+
}).sort(compareRouteSpecificity),
|
|
322
333
|
websockets,
|
|
323
334
|
middleware: parseMiddlewareDefinitions(middlewareFiles),
|
|
324
335
|
jobs,
|
|
@@ -348,10 +359,7 @@ function scanRoutePatternsSync(root, paths = readProjectPaths(root)) {
|
|
|
348
359
|
} catch {
|
|
349
360
|
routeFiles = [];
|
|
350
361
|
}
|
|
351
|
-
return routeFiles.filter((f) => !isWebSocketPatternFile(f)).filter((f) => !f.split("/").some((s) => s.startsWith("_"))).map((f) => parseRouteFilename(f)).sort(
|
|
352
|
-
if (a.catchAll !== b.catchAll) return a.catchAll ? 1 : -1;
|
|
353
|
-
return a.pattern.localeCompare(b.pattern);
|
|
354
|
-
});
|
|
362
|
+
return routeFiles.filter((f) => !isWebSocketPatternFile(f)).filter((f) => !f.split("/").some((s) => s.startsWith("_"))).map((f) => parseRouteFilename(f)).sort(compareRouteSpecificity);
|
|
355
363
|
}
|
|
356
364
|
//#endregion
|
|
357
365
|
export { scanQueuesSync as a, scanWebSocketRoutesSync as i, scanRoutePatternsSync as n, scanJobsSync as o, scanRoutes as r, scanMiddlewareSync as t };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { a as join, n as dirname, r as extname, t as basename } from "./pathe.M-eThtNZ-BrPhGF_K.mjs";
|
|
2
2
|
import { n as readProjectPaths } from "./project-paths-CCMrHYQm.mjs";
|
|
3
|
-
import { t as glob } from "./dist-
|
|
3
|
+
import { t as glob } from "./dist-5cGIJHQQ.mjs";
|
|
4
4
|
import { existsSync, readFileSync } from "node:fs";
|
|
5
5
|
//#region src/router/parse-filename.ts
|
|
6
6
|
const EXTENSIONS = [
|
|
@@ -83,30 +83,29 @@ function toLayoutId(layout) {
|
|
|
83
83
|
if (isNamedLayout(layout)) return layout.directory ? `${layout.directory}/_layouts/${layout.name}` : `_layouts/${layout.name}`;
|
|
84
84
|
return layout.directory ? `${layout.directory}/layout` : "layout";
|
|
85
85
|
}
|
|
86
|
-
|
|
87
|
-
|
|
86
|
+
function resolveLayoutDirectories(componentId, componentPath) {
|
|
87
|
+
if (componentPath) {
|
|
88
|
+
const segments = componentPath.split("/");
|
|
89
|
+
segments.pop();
|
|
90
|
+
return segments.map((_, index) => segments.slice(0, index + 1).join("/"));
|
|
91
|
+
}
|
|
88
92
|
const parts = componentId.split("/");
|
|
93
|
+
return parts.slice(0, -1).map((_, index) => parts.slice(0, index + 1).join("/"));
|
|
94
|
+
}
|
|
95
|
+
/** Resolve the layout chain for a component (innermost last) */
|
|
96
|
+
function resolveLayoutChain(componentId, layouts, componentPath) {
|
|
89
97
|
const chain = [];
|
|
90
98
|
const root = layouts.find((layout) => layout.directory === "");
|
|
91
99
|
if (root) chain.push(root);
|
|
92
|
-
|
|
93
|
-
for (let partIndex = 0; partIndex < parts.length - 1; partIndex++) {
|
|
94
|
-
dir = dir ? `${dir}/${parts[partIndex]}` : parts[partIndex];
|
|
100
|
+
for (const dir of resolveLayoutDirectories(componentId, componentPath)) {
|
|
95
101
|
const layout = layouts.find((candidate) => candidate.directory === dir);
|
|
96
102
|
if (layout) chain.push(layout);
|
|
97
103
|
}
|
|
98
104
|
return chain;
|
|
99
105
|
}
|
|
100
106
|
/** Walk up directory tree to find closest _layouts/<name> */
|
|
101
|
-
function resolveNamedLayout(name, componentId, namedLayouts) {
|
|
102
|
-
const
|
|
103
|
-
const dirs = [];
|
|
104
|
-
let dir = "";
|
|
105
|
-
for (let partIndex = 0; partIndex < parts.length - 1; partIndex++) {
|
|
106
|
-
dir = dir ? `${dir}/${parts[partIndex]}` : parts[partIndex];
|
|
107
|
-
dirs.push(dir);
|
|
108
|
-
}
|
|
109
|
-
dirs.reverse();
|
|
107
|
+
function resolveNamedLayout(name, componentId, namedLayouts, componentPath) {
|
|
108
|
+
const dirs = resolveLayoutDirectories(componentId, componentPath).reverse();
|
|
110
109
|
dirs.push("");
|
|
111
110
|
for (const directory of dirs) {
|
|
112
111
|
const found = namedLayouts.find((namedLayout) => namedLayout.name === name && namedLayout.directory === directory);
|
|
@@ -116,7 +115,7 @@ function resolveNamedLayout(name, componentId, namedLayouts) {
|
|
|
116
115
|
}
|
|
117
116
|
function resolveEffectiveLayoutEntries(page, layouts, namedLayouts) {
|
|
118
117
|
if (page.layout === false) return [];
|
|
119
|
-
const defaultChain = resolveLayoutChain(page.componentId, layouts).map((layout) => ({
|
|
118
|
+
const defaultChain = resolveLayoutChain(page.componentId, layouts, page.componentPath).map((layout) => ({
|
|
120
119
|
id: toLayoutId(layout),
|
|
121
120
|
definition: layout
|
|
122
121
|
}));
|
|
@@ -124,7 +123,7 @@ function resolveEffectiveLayoutEntries(page, layouts, namedLayouts) {
|
|
|
124
123
|
const isExclusive = page.layout.startsWith("!");
|
|
125
124
|
const name = isExclusive ? page.layout.slice(1) : page.layout;
|
|
126
125
|
if (name.startsWith(".") || name.startsWith("/")) return defaultChain;
|
|
127
|
-
const resolved = resolveNamedLayout(name, page.componentId, namedLayouts);
|
|
126
|
+
const resolved = resolveNamedLayout(name, page.componentId, namedLayouts, page.componentPath);
|
|
128
127
|
if (!resolved) return defaultChain;
|
|
129
128
|
const namedEntry = {
|
|
130
129
|
id: toLayoutId(resolved),
|
|
@@ -160,13 +159,31 @@ const SERVER_EXTENSIONS = [
|
|
|
160
159
|
"mts"
|
|
161
160
|
];
|
|
162
161
|
const PAGES_EXPORT_RE = /export\s+(?:const|function|async\s+function)\s+(loader|actions?)\b/g;
|
|
163
|
-
const REVALIDATE_RE = /export\s+const\s+revalidate\s*=\s*(\d+)\s
|
|
164
|
-
const PRERENDER_RE = /export\s+const\s+prerender\s*=\s*true\s
|
|
165
|
-
const PRERENDER_FALSE_RE = /export\s+const\s+prerender\s*=\s*false\s
|
|
162
|
+
const REVALIDATE_RE = /export\s+const\s+revalidate\s*=\s*(\d+)\s*;?/;
|
|
163
|
+
const PRERENDER_RE = /export\s+const\s+prerender\s*=\s*true\s*;?/;
|
|
164
|
+
const PRERENDER_FALSE_RE = /export\s+const\s+prerender\s*=\s*false\s*;?/;
|
|
165
|
+
const SSR_TRUE_RE = /export\s+const\s+ssr\s*=\s*true\s*;?/;
|
|
166
|
+
const SSR_FALSE_RE = /export\s+const\s+ssr\s*=\s*false\s*;?/;
|
|
166
167
|
const GET_PRERENDER_PATHS_RE = /export\s+(?:async\s+)?function\s+getPrerenderPaths\b/;
|
|
167
168
|
const LAYOUT_STRING_RE = /export\s+const\s+layout\s*=\s*["']([^"']+)["']\s*;?/;
|
|
168
169
|
const LAYOUT_FALSE_RE = /export\s+const\s+layout\s*=\s*false\s*;?/;
|
|
169
170
|
const MAX_REVALIDATE = 31536e3;
|
|
171
|
+
function inferAutoPrerender(page, options) {
|
|
172
|
+
const isDynamic = page.params.length > 0 || page.catchAll;
|
|
173
|
+
if (options?.output === "static") return !isDynamic || page.hasGetPrerenderPaths === true;
|
|
174
|
+
return page.island === true && !page.methods.includes("loader") && !isDynamic;
|
|
175
|
+
}
|
|
176
|
+
function resolvePageRendering(page, options) {
|
|
177
|
+
if (page.island && page.ssr === false) throw new Error(`pages: ssr = false is not valid for island page '${page.componentPath}'.`);
|
|
178
|
+
const ssrMode = page.ssr === true ? "server" : page.ssr === false ? "client" : "auto";
|
|
179
|
+
const prerenderMode = page.prerender === true ? "force" : page.prerender === false ? "disabled" : "auto";
|
|
180
|
+
return {
|
|
181
|
+
ssrMode,
|
|
182
|
+
prerenderMode,
|
|
183
|
+
renderMode: page.island === true ? "island" : ssrMode === "client" ? "client" : "server",
|
|
184
|
+
shouldPrerender: prerenderMode === "force" || prerenderMode === "auto" && inferAutoPrerender(page, options)
|
|
185
|
+
};
|
|
186
|
+
}
|
|
170
187
|
async function scanPages(root, options) {
|
|
171
188
|
const pagesDir = options?.pagesDir ?? options?.paths?.pagesDir ?? readProjectPaths(root).pagesDir;
|
|
172
189
|
if (!existsSync(pagesDir)) return {
|
|
@@ -219,7 +236,7 @@ async function scanPages(root, options) {
|
|
|
219
236
|
const methods = [];
|
|
220
237
|
let revalidate;
|
|
221
238
|
let prerender;
|
|
222
|
-
let
|
|
239
|
+
let ssr;
|
|
223
240
|
let hasGetPrerenderPaths;
|
|
224
241
|
const serverBase = hasIslandSuffix ? file.replace(`.island${ext}`, "") : file.replace(ext, "");
|
|
225
242
|
for (const serverExt of SERVER_EXTENSIONS) {
|
|
@@ -231,17 +248,24 @@ async function scanPages(root, options) {
|
|
|
231
248
|
const revalidateMatch = content.match(REVALIDATE_RE);
|
|
232
249
|
if (revalidateMatch) revalidate = Number(revalidateMatch[1]);
|
|
233
250
|
if (PRERENDER_RE.test(content)) prerender = true;
|
|
234
|
-
if (PRERENDER_FALSE_RE.test(content))
|
|
251
|
+
else if (PRERENDER_FALSE_RE.test(content)) prerender = false;
|
|
252
|
+
if (SSR_TRUE_RE.test(content)) ssr = true;
|
|
253
|
+
else if (SSR_FALSE_RE.test(content)) ssr = false;
|
|
235
254
|
if (GET_PRERENDER_PATHS_RE.test(content)) hasGetPrerenderPaths = true;
|
|
236
255
|
break;
|
|
237
256
|
}
|
|
238
257
|
}
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
258
|
+
const rendering = resolvePageRendering({
|
|
259
|
+
componentPath: file,
|
|
260
|
+
island,
|
|
261
|
+
ssr,
|
|
262
|
+
prerender,
|
|
263
|
+
methods,
|
|
264
|
+
params: route.params,
|
|
265
|
+
catchAll: route.catchAll,
|
|
266
|
+
hasGetPrerenderPaths
|
|
267
|
+
}, options);
|
|
268
|
+
if (rendering.shouldPrerender && revalidate === void 0) revalidate = MAX_REVALIDATE;
|
|
245
269
|
let metadata;
|
|
246
270
|
let layout;
|
|
247
271
|
if (ext === ".md") {
|
|
@@ -264,6 +288,8 @@ async function scanPages(root, options) {
|
|
|
264
288
|
componentId,
|
|
265
289
|
revalidate,
|
|
266
290
|
prerender,
|
|
291
|
+
ssr,
|
|
292
|
+
...rendering,
|
|
267
293
|
hasGetPrerenderPaths,
|
|
268
294
|
island,
|
|
269
295
|
metadata,
|
|
@@ -291,7 +317,7 @@ async function scanPages(root, options) {
|
|
|
291
317
|
if (page.layout === void 0 || page.layout === false) continue;
|
|
292
318
|
const name = page.layout.startsWith("!") ? page.layout.slice(1) : page.layout;
|
|
293
319
|
if (name.startsWith(".") || name.startsWith("/")) continue;
|
|
294
|
-
if (!resolveNamedLayout(name, page.componentId, namedLayouts)) throw new Error(`pages: Page '${page.componentPath}' specifies layout '${page.layout}', but _layouts/${name}.vue was not found in any ancestor directory.`);
|
|
320
|
+
if (!resolveNamedLayout(name, page.componentId, namedLayouts, page.componentPath)) throw new Error(`pages: Page '${page.componentPath}' specifies layout '${page.layout}', but _layouts/${name}.vue was not found in any ancestor directory.`);
|
|
295
321
|
}
|
|
296
322
|
return {
|
|
297
323
|
pages,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { n as cliTitle } from "./output-DeiS4oEX.mjs";
|
|
2
|
-
import {
|
|
2
|
+
import { d as getToken, n as PlatformClient } from "./client-D4awzTnj.mjs";
|
|
3
3
|
import { _ as me, c as R, g as ge, n as Ce, u as Se, v as ue, x as q, y as ye } from "./dist-abzUneor.mjs";
|
|
4
4
|
import { r as readProjectConfig } from "./project-CH9pdo16.mjs";
|
|
5
5
|
import { r as resolveProjectBySlug, t as getRequestedProjectSlug } from "./resolve-project-D4O1_fZz.mjs";
|
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
//#region src/pages/types.d.ts
|
|
2
|
+
type ExplicitBoolean = true | false | undefined;
|
|
3
|
+
type SsrMode = "auto" | "server" | "client";
|
|
4
|
+
type PrerenderMode = "auto" | "force" | "disabled";
|
|
5
|
+
type PageRenderMode = "server" | "client" | "island";
|
|
2
6
|
type PageDefinition = {
|
|
3
7
|
/** URL pattern, e.g. "/users/:id" */pattern: string; /** Route params, e.g. ["id"] */
|
|
4
8
|
params: Array<string>; /** Whether this is a catch-all route */
|
|
@@ -7,8 +11,13 @@ type PageDefinition = {
|
|
|
7
11
|
serverPath: string | null; /** HTTP methods exported by server handler */
|
|
8
12
|
methods: Array<string>; /** Component ID used in page object, e.g. "users/[id]" */
|
|
9
13
|
componentId: string; /** Edge caching revalidate TTL in seconds, from .server.ts export */
|
|
10
|
-
revalidate?: number; /** Whether `export const prerender = true` is set in server handler */
|
|
11
|
-
prerender?:
|
|
14
|
+
revalidate?: number; /** Whether `export const prerender = true/false` is set in server handler */
|
|
15
|
+
prerender?: ExplicitBoolean; /** Whether `export const ssr = true/false` is set in server handler */
|
|
16
|
+
ssr?: ExplicitBoolean; /** Normalized SSR mode from the public `ssr` export */
|
|
17
|
+
ssrMode: SsrMode; /** Normalized prerender mode from the public `prerender` export */
|
|
18
|
+
prerenderMode: PrerenderMode; /** Normalized page render mode */
|
|
19
|
+
renderMode: PageRenderMode; /** Whether this page should participate in prerender collection */
|
|
20
|
+
shouldPrerender: boolean; /** Whether `export function getPrerenderPaths` is defined in server handler */
|
|
12
21
|
hasGetPrerenderPaths?: boolean; /** Whether this is an island page (.island.tsx/.island.vue) */
|
|
13
22
|
island?: boolean; /** Frontmatter metadata extracted from .md files (title, description) */
|
|
14
23
|
metadata?: {
|
|
@@ -39,4 +48,4 @@ type DevCssAsset = {
|
|
|
39
48
|
css: string;
|
|
40
49
|
};
|
|
41
50
|
//#endregion
|
|
42
|
-
export {
|
|
51
|
+
export { PageRenderMode as a, PageDefinition as i, LayoutDefinition as n, PageScanResult as o, NamedLayoutDefinition as r, DevCssAsset as t };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "void",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.1",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "git+https://github.com/voidzero-dev/void.git",
|
|
@@ -353,7 +353,7 @@
|
|
|
353
353
|
"valibot": ">=1.0.0-beta.7",
|
|
354
354
|
"vite": "^8.0.0",
|
|
355
355
|
"zod": "^3.25.0 || ^4.0.0",
|
|
356
|
-
"@void/md": "0.
|
|
356
|
+
"@void/md": "0.10.1"
|
|
357
357
|
},
|
|
358
358
|
"peerDependenciesMeta": {
|
|
359
359
|
"@void/md": {
|
package/schema.json
CHANGED
|
@@ -154,7 +154,7 @@
|
|
|
154
154
|
{
|
|
155
155
|
"type": "object",
|
|
156
156
|
"patternProperties": {
|
|
157
|
-
"^(
|
|
157
|
+
"^(\\/|\\*$)": {
|
|
158
158
|
"type": "number",
|
|
159
159
|
"minimum": 0
|
|
160
160
|
}
|
|
@@ -216,7 +216,7 @@
|
|
|
216
216
|
"type": "object",
|
|
217
217
|
"description": "URL rewrites. Keys are source URL patterns (path-only `/path` or host-scoped `https://host/path`); values are destination paths. Serves content from the destination without changing the browser URL. Destinations must start with \"/\" and must not contain \"?\" — the incoming request's query string is preserved automatically.",
|
|
218
218
|
"patternProperties": {
|
|
219
|
-
"^(/|https://)": { "type": "string", "pattern": "^/[^?]*$" }
|
|
219
|
+
"^(/|https://)": { "type": "string", "pattern": "^/(?!/)[^?]*$" }
|
|
220
220
|
},
|
|
221
221
|
"additionalProperties": false
|
|
222
222
|
},
|
|
@@ -224,7 +224,7 @@
|
|
|
224
224
|
"type": "object",
|
|
225
225
|
"description": "Fallback rewrites. Same shape as `rewrites`, but only fire when no static asset matched the request. Useful for SPA shells or default-locale catch-alls without pre-empting real routes. Destinations must start with \"/\" and must not contain \"?\".",
|
|
226
226
|
"patternProperties": {
|
|
227
|
-
"^(/|https://)": { "type": "string", "pattern": "^/[^?]*$" }
|
|
227
|
+
"^(/|https://)": { "type": "string", "pattern": "^/(?!/)[^?]*$" }
|
|
228
228
|
},
|
|
229
229
|
"additionalProperties": false
|
|
230
230
|
}
|
|
@@ -64,30 +64,56 @@ If your CI pipeline runs typechecking or other static analysis before deploy, ru
|
|
|
64
64
|
|
|
65
65
|
## GitHub Actions
|
|
66
66
|
|
|
67
|
-
You can deploy from a GitHub repo
|
|
67
|
+
You can deploy from a GitHub repo on every push to `main`. Running `void init --github` generates `.github/workflows/void-deploy.yml` in your project.
|
|
68
|
+
|
|
69
|
+
The workflow authenticates with [GitHub OIDC](https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/about-security-hardening-with-openid-connect) — there is **no long-lived `VOID_TOKEN` secret to store or rotate**. The job requests a short-lived OIDC token from GitHub, exchanges it at `POST $VOID_API_URL/auth/github-oidc` for a short-lived project-scoped deploy token (about 15 minutes on the free tier; longer on higher plans, capped at ~60 minutes), then runs `void deploy --project <slug>`:
|
|
68
70
|
|
|
69
71
|
```yaml
|
|
70
|
-
name: Deploy
|
|
72
|
+
name: Deploy to Void
|
|
71
73
|
on:
|
|
72
74
|
push:
|
|
73
75
|
branches: [main]
|
|
74
76
|
|
|
77
|
+
# Latest push wins: a newer commit cancels an in-flight deploy for the same
|
|
78
|
+
# repo + branch, so an older commit can never overtake a newer one.
|
|
79
|
+
concurrency:
|
|
80
|
+
group: void-deploy-${{ github.repository }}-${{ github.ref }}
|
|
81
|
+
cancel-in-progress: true
|
|
82
|
+
|
|
83
|
+
permissions:
|
|
84
|
+
id-token: write
|
|
85
|
+
contents: read
|
|
86
|
+
|
|
87
|
+
env:
|
|
88
|
+
VOID_API_URL: ${{ vars.VOID_API_URL || 'https://api.void.cloud' }}
|
|
89
|
+
VOID_PROJECT: my-app
|
|
90
|
+
|
|
75
91
|
jobs:
|
|
76
92
|
deploy:
|
|
77
93
|
runs-on: ubuntu-latest
|
|
78
94
|
steps:
|
|
79
|
-
- uses: actions/checkout@
|
|
80
|
-
- uses:
|
|
95
|
+
- uses: actions/checkout@v6
|
|
96
|
+
- uses: actions/setup-node@v6
|
|
81
97
|
with:
|
|
82
|
-
node-version:
|
|
83
|
-
cache:
|
|
84
|
-
- run:
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
98
|
+
node-version: lts/*
|
|
99
|
+
cache: npm
|
|
100
|
+
- run: npm ci
|
|
101
|
+
- name: Exchange GitHub OIDC token for a Void deploy token
|
|
102
|
+
run: |
|
|
103
|
+
OIDC_TOKEN="$(curl -sf \
|
|
104
|
+
-H "Authorization: Bearer $ACTIONS_ID_TOKEN_REQUEST_TOKEN" \
|
|
105
|
+
"$ACTIONS_ID_TOKEN_REQUEST_URL&audience=void" | jq -r '.value')"
|
|
106
|
+
VOID_TOKEN="$(curl -sf \
|
|
107
|
+
-H 'Content-Type: application/json' \
|
|
108
|
+
-d "$(jq -n --arg t "$OIDC_TOKEN" --arg p "$VOID_PROJECT" '{oidcToken: $t, project: $p}')" \
|
|
109
|
+
"$VOID_API_URL/auth/github-oidc" | jq -r '.token')"
|
|
110
|
+
echo "::add-mask::$VOID_TOKEN"
|
|
111
|
+
echo "VOID_TOKEN=$VOID_TOKEN" >> "$GITHUB_ENV"
|
|
112
|
+
- name: Deploy
|
|
113
|
+
run: npx void deploy --project "$VOID_PROJECT"
|
|
88
114
|
```
|
|
89
115
|
|
|
90
|
-
|
|
116
|
+
Connect the repository to your project once with `void github connect <project> --repo <owner/repo> --executor github_actions` to authorize it. This GitHub Actions path requires the `github_actions` build executor — the default `container` executor will not work with this workflow. The exact steps vary by package manager (the scaffold detects pnpm, yarn, bun, or npm). The `VOID_PROJECT` value is baked in from your linked project when known; otherwise the workflow reads a `VOID_PROJECT` repository variable. To target staging, set a `VOID_API_URL` repository variable to `https://api.staging.void.cloud`.
|
|
91
117
|
|
|
92
118
|
## Other Targets
|
|
93
119
|
|