void 0.10.8 → 0.10.10

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 (47) hide show
  1. package/dist/{auth-cmd-DlgNwByu.mjs → auth-cmd-Cw1edJdZ.mjs} +2 -2
  2. package/dist/{build-cmd-Br8qL0rA.mjs → build-cmd-C6kNDJBv.mjs} +1 -1
  3. package/dist/{cache-wH-mP8UE.mjs → cache-DIUSnIjJ.mjs} +1 -1
  4. package/dist/{cancel-deploy-BEBOEgtu.mjs → cancel-deploy-BosnzEHC.mjs} +1 -1
  5. package/dist/cli/cli.mjs +77 -28
  6. package/dist/{client-Cj96iiBH.mjs → client-C9FG6Vzc.mjs} +8 -0
  7. package/dist/{config-1twldYCW.mjs → config-BcAeIPe3.mjs} +6 -0
  8. package/dist/{create-project-DD9n8Ho-.mjs → create-project-CjYX23M_.mjs} +1 -1
  9. package/dist/{db-DjKE2-A-.mjs → db-BvKV34IK.mjs} +4 -4
  10. package/dist/{delete-D2kr3Kmk.mjs → delete-CThKLXfi.mjs} +1 -1
  11. package/dist/{deploy-C4PbkFyE.mjs → deploy-B02JyKP9.mjs} +59 -16
  12. package/dist/{domain-_luIsM_B.mjs → domain-DMrBabBQ.mjs} +1 -1
  13. package/dist/{env-CO5XAS9t.mjs → env-BfG7O71F.mjs} +1 -1
  14. package/dist/env-raw-Cx8ElDdj.mjs +58 -0
  15. package/dist/{gen-Cf79J4aw.mjs → gen-Bee261SV.mjs} +1 -1
  16. package/dist/{github-cmd-B6OX9c7d.mjs → github-cmd-DfeFEasr.mjs} +101 -2
  17. package/dist/{headers-BwvFGhkx.mjs → headers-CTAjX-UO.mjs} +1 -1
  18. package/dist/index.d.mts +13 -1
  19. package/dist/index.mjs +70 -31
  20. package/dist/{init-KirOzVDs.mjs → init-xfwW7cLp.mjs} +4 -4
  21. package/dist/{link-CUmiosyb.mjs → link-Co136MEs.mjs} +2 -2
  22. package/dist/{list-3GEw7b6m.mjs → list-BKDjA3M5.mjs} +1 -1
  23. package/dist/{login-DJReaT_Q.mjs → login-CrOTnR_6.mjs} +1 -1
  24. package/dist/{logs-D-rQ56Lq.mjs → logs-DlAg25ww.mjs} +1 -1
  25. package/dist/{mcp-D7yc0dXY.mjs → mcp-BNjMGMB0.mjs} +1 -1
  26. package/dist/{node-yFFk626c.mjs → node-CnE-SZCk.mjs} +1 -1
  27. package/dist/pages/index.mjs +2 -2
  28. package/dist/{prepare-C_cVurhP.mjs → prepare-BRyC4TCC.mjs} +1 -1
  29. package/dist/{project-cmd-DnU7u9QF.mjs → project-cmd-B2bcKefD.mjs} +8 -8
  30. package/dist/{rollback-Yh7bCKob.mjs → rollback-9dfmB-YZ.mjs} +1 -1
  31. package/dist/runtime/ai.mjs +113 -15
  32. package/dist/runtime/env-public.mjs +9 -4
  33. package/dist/runtime/env.d.mts +14 -1
  34. package/dist/runtime/env.mjs +24 -10
  35. package/dist/runtime/isr-cache.d.mts +207 -0
  36. package/dist/runtime/isr-cache.mjs +523 -0
  37. package/dist/runtime/isr.d.mts +4 -3
  38. package/dist/runtime/isr.mjs +44 -5
  39. package/dist/runtime/live.mjs +1 -1
  40. package/dist/runtime/sandbox.mjs +1 -1
  41. package/dist/{secret-u7FRvg8d.mjs → secret-DeMnMcV0.mjs} +1 -1
  42. package/package.json +3 -2
  43. package/schema.json +11 -0
  44. package/skills/void/docs/integrations/cloudflare.md +107 -0
  45. package/skills/void/docs/node_modules/void/{AGENTS.md → CLAUDE.md} +14 -0
  46. package/skills/void/docs/reference/cli.md +23 -0
  47. package/dist/env-raw-CoS20LHP.mjs +0 -32
@@ -1,5 +1,5 @@
1
- import { i as getRawRuntimeEnv } from "../env-raw-CoS20LHP.mjs";
2
- import { getRuntimeEnv } from "./env.mjs";
1
+ import { a as getRawRuntimeEnv } from "../env-raw-Cx8ElDdj.mjs";
2
+ import { getRuntimeEnv, isInternalBinding } 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
5
5
  /**
@@ -177,7 +177,10 @@ async function _validateEnvOnce(envValues) {
177
177
  validatedCache.set(cacheKey, cache);
178
178
  cacheList.push(cache);
179
179
  }
180
- for (const [key, value] of report.values) if (!cache.has(key)) cache.set(key, value);
180
+ for (const [key, value] of report.values) {
181
+ if (isInternalBinding(key, cacheKey)) continue;
182
+ if (!cache.has(key)) cache.set(key, value);
183
+ }
181
184
  } catch {}
182
185
  bootValidationState = { ok: true };
183
186
  return;
@@ -254,11 +257,13 @@ var EnvValidationError = class extends Error {
254
257
  }
255
258
  };
256
259
  function readKey(key) {
260
+ const rawEnv = getRawRuntimeEnv();
261
+ if (isInternalBinding(key, rawEnv)) return;
257
262
  const rawValue = getRuntimeEnv()[key];
258
263
  if (!registeredSchema) return rawValue;
259
264
  const validator = registeredSchema[key];
260
265
  if (!validator) return rawValue;
261
- const cacheKey = getRawRuntimeEnv();
266
+ const cacheKey = rawEnv;
262
267
  let cache = validatedCache.get(cacheKey);
263
268
  if (!cache) {
264
269
  cache = /* @__PURE__ */ new Map();
@@ -5,9 +5,22 @@ type RuntimeEnv = Record<string, unknown>;
5
5
  //#endregion
6
6
  //#region src/runtime/env.d.ts
7
7
  declare function withRuntimeEnv<T>(env: unknown, fn: () => T): T;
8
+ /**
9
+ * Shared internal-binding predicate. A binding is framework-internal — and must
10
+ * never be exposed to user code — when it carries an internal prefix
11
+ * (`__VOID_`, `__PROJECT_`; always hidden) or is an exact-name internal (e.g.
12
+ * `ISR_CACHE`; hidden ONLY while ISR is active for the isolate). `rawEnv` is the
13
+ * unfiltered runtime env, consulted via {@link isIsrActive} to gate the
14
+ * exact-name check so a non-ISR app's own `ISR_CACHE` binding stays visible —
15
+ * matching the build-time `isr` gate on the generated `c.env` filter.
16
+ *
17
+ * Single source of truth for the runtime `env` filter here and the public
18
+ * `void/env` proxy (`env-public.ts`).
19
+ */
20
+ declare function isInternalBinding(name: string, rawEnv: RuntimeEnv): boolean;
8
21
  /** Returns the runtime env with internal platform bindings hidden. */
9
22
  declare function getRuntimeEnv(): RuntimeEnv;
10
23
  declare function getRuntimeBinding<T = unknown>(name: string): T | undefined;
11
24
  declare function requireRuntimeBinding<T = unknown>(name: string): T;
12
25
  //#endregion
13
- export { type RuntimeEnv, getRuntimeBinding, getRuntimeEnv, requireRuntimeBinding, withRuntimeEnv };
26
+ export { type RuntimeEnv, getRuntimeBinding, getRuntimeEnv, isInternalBinding, requireRuntimeBinding, withRuntimeEnv };
@@ -1,4 +1,4 @@
1
- import { i as getRawRuntimeEnv, n as asEnv, r as envContext, t as INTERNAL_BINDING_PREFIXES } from "../env-raw-CoS20LHP.mjs";
1
+ import { a as getRawRuntimeEnv, i as envContext, n as INTERNAL_BINDING_PREFIXES, o as isIsrActive, r as asEnv, t as INTERNAL_BINDING_EXACT_NAMES } from "../env-raw-Cx8ElDdj.mjs";
2
2
  //#region src/runtime/env.ts
3
3
  /**
4
4
  * Public runtime env API — exposed via "void/_env".
@@ -12,24 +12,37 @@ function withRuntimeEnv(env, fn) {
12
12
  if (!resolved) return fn();
13
13
  return envContext.run(resolved, fn);
14
14
  }
15
- function isInternalBinding(name) {
16
- return INTERNAL_BINDING_PREFIXES.some((p) => name.startsWith(p));
15
+ /**
16
+ * Shared internal-binding predicate. A binding is framework-internal — and must
17
+ * never be exposed to user code — when it carries an internal prefix
18
+ * (`__VOID_`, `__PROJECT_`; always hidden) or is an exact-name internal (e.g.
19
+ * `ISR_CACHE`; hidden ONLY while ISR is active for the isolate). `rawEnv` is the
20
+ * unfiltered runtime env, consulted via {@link isIsrActive} to gate the
21
+ * exact-name check so a non-ISR app's own `ISR_CACHE` binding stays visible —
22
+ * matching the build-time `isr` gate on the generated `c.env` filter.
23
+ *
24
+ * Single source of truth for the runtime `env` filter here and the public
25
+ * `void/env` proxy (`env-public.ts`).
26
+ */
27
+ function isInternalBinding(name, rawEnv) {
28
+ if (INTERNAL_BINDING_PREFIXES.some((p) => name.startsWith(p))) return true;
29
+ return isIsrActive(rawEnv) && INTERNAL_BINDING_EXACT_NAMES.includes(name);
17
30
  }
18
31
  function filterEnvProxy(env) {
19
32
  return new Proxy(env, {
20
33
  get(target, prop, receiver) {
21
- if (typeof prop === "string" && isInternalBinding(prop)) return;
34
+ if (typeof prop === "string" && isInternalBinding(prop, target)) return;
22
35
  return Reflect.get(target, prop, receiver);
23
36
  },
24
37
  has(target, prop) {
25
- if (typeof prop === "string" && isInternalBinding(prop)) return false;
38
+ if (typeof prop === "string" && isInternalBinding(prop, target)) return false;
26
39
  return Reflect.has(target, prop);
27
40
  },
28
41
  ownKeys(target) {
29
- return Reflect.ownKeys(target).filter((key) => typeof key !== "string" || !isInternalBinding(key));
42
+ return Reflect.ownKeys(target).filter((key) => typeof key !== "string" || !isInternalBinding(key, target));
30
43
  },
31
44
  getOwnPropertyDescriptor(target, prop) {
32
- if (typeof prop === "string" && isInternalBinding(prop)) return;
45
+ if (typeof prop === "string" && isInternalBinding(prop, target)) return;
33
46
  return Reflect.getOwnPropertyDescriptor(target, prop);
34
47
  }
35
48
  });
@@ -39,8 +52,9 @@ function getRuntimeEnv() {
39
52
  return filterEnvProxy(getRawRuntimeEnv());
40
53
  }
41
54
  function getRuntimeBinding(name) {
42
- if (isInternalBinding(name)) return;
43
- return getRawRuntimeEnv()[name];
55
+ const raw = getRawRuntimeEnv();
56
+ if (isInternalBinding(name, raw)) return;
57
+ return raw[name];
44
58
  }
45
59
  function requireRuntimeBinding(name) {
46
60
  const value = getRuntimeBinding(name);
@@ -48,4 +62,4 @@ function requireRuntimeBinding(name) {
48
62
  throw new Error(`env: Missing Cloudflare binding '${name}'.`);
49
63
  }
50
64
  //#endregion
51
- export { getRuntimeBinding, getRuntimeEnv, requireRuntimeBinding, withRuntimeEnv };
65
+ export { getRuntimeBinding, getRuntimeEnv, isInternalBinding, requireRuntimeBinding, withRuntimeEnv };
@@ -0,0 +1,207 @@
1
+ //#region src/runtime/isr-cache.d.ts
2
+ /**
3
+ * Single-tenant ISR (incremental static regeneration) cache ladder for the
4
+ * self-hosted Void worker (`vite build && wrangler deploy`).
5
+ *
6
+ * On managed Void, ISR lives in the dispatch worker that sits IN FRONT of the
7
+ * user worker. Self-host has no dispatch worker, so this module ports that
8
+ * caching ladder INTO the user worker, collapsed from multi-tenant to a single
9
+ * deployment:
10
+ *
11
+ * - No `projectId`, no cross-tenant metering.
12
+ * - No `#rw=` rewrite variant, no query-string variant fanout, no variant cap.
13
+ * - The deployment id is baked at build time as a compile-time literal and
14
+ * surfaced on `env.__VOID_ISR_DEPLOYMENT_ID` (Task 7). The KV helpers read
15
+ * it from `env` (matching the `revalidate()` purge path in `runtime/isr.ts`),
16
+ * while `handleIsr` uses the `deploymentId` option for the edge-cache keys —
17
+ * the two are the same value.
18
+ *
19
+ * Fail-open contract: every `env.ISR_CACHE` (KV) and `caches.default` operation
20
+ * is wrapped so a misconfigured or erroring cache degrades to a live render,
21
+ * never a 500. Read/hit-path failures bail (caller renders live); write-path
22
+ * failures are swallowed.
23
+ *
24
+ * Worker-only: no `lib.dom` types — globals come from `@cloudflare/workers-types`.
25
+ *
26
+ * Ported from `void-platform/packages/dispatch` (`isr.ts`, `index.ts`,
27
+ * `pattern.ts`) and `void-platform/packages/isr-shared`.
28
+ */
29
+ /**
30
+ * Minimal env surface this module needs. Both fields are optional so a worker
31
+ * with no ISR binding (or a caller that only knows the deployment id) still
32
+ * typechecks and fails open at runtime.
33
+ */
34
+ interface IsrCacheEnv {
35
+ ISR_CACHE?: KVNamespace;
36
+ __VOID_ISR_DEPLOYMENT_ID?: string;
37
+ }
38
+ type IsrCacheEntry = Readonly<{
39
+ body: ReadableStream;
40
+ status: number;
41
+ headers: Record<string, string>;
42
+ createdAt: number;
43
+ ttl: number;
44
+ }>;
45
+ type IsrCacheMetadata = Readonly<{
46
+ /** HTTP status code */s: number; /** createdAt (ms) */
47
+ c: number; /** TTL (seconds) */
48
+ t: number;
49
+ }>;
50
+ /** Renders a live response for a request (worker dispatch + asset serving). */
51
+ type RenderFn = (request: Request) => Promise<Response>;
52
+ type HandleIsrOptions = Readonly<{
53
+ revalidate: number | Record<string, number> | undefined;
54
+ deploymentId: string;
55
+ }>;
56
+ /**
57
+ * Build the normalized path segment for an ISR-cached page.
58
+ * Root path `/` maps to `__index__` to avoid trailing-slash ambiguity.
59
+ */
60
+ declare function normalizeIsrPath(pathname: string): string;
61
+ /**
62
+ * Inverse of `normalizeIsrPath`: turn a normalized segment back into a
63
+ * pathname starting with `/`.
64
+ */
65
+ declare function denormalizeIsrPath(normalized: string): string;
66
+ /**
67
+ * Canonicalize an inbound pathname to the form used inside edge cache URLs.
68
+ * Equivalent to `denormalizeIsrPath(normalizeIsrPath(pathname))` — strips any
69
+ * trailing slash except for root.
70
+ */
71
+ declare function canonicalIsrPathname(pathname: string): string;
72
+ /**
73
+ * KV cache key for an ISR-cached page. Deployment- AND host-scoped: cached HTML
74
+ * cannot outlive the hashed assets of the deployment that produced it (a fresh
75
+ * `wrangler deploy` mints a new deployment id → cold cache), and one host's
76
+ * cached content never bleeds into another host served by the same worker
77
+ * (custom domain + workers.dev, apex + www, etc.).
78
+ */
79
+ declare function isrKey(deploymentId: string, host: string, pathname: string): string;
80
+ /**
81
+ * Host-registry key. Every host that has written cached content registers itself
82
+ * under `void-isr-hosts/<id>/<host>` (value `''`) so a purge with no request host
83
+ * (cron / queue `revalidate({ paths })`) can enumerate the hosts to purge.
84
+ * Scoped by deployment id so registrations from an old deploy do not leak.
85
+ */
86
+ declare function hostRegistryKey(deploymentId: string, host: string): string;
87
+ /**
88
+ * Edge-cache (`caches.default`) key for the HTML variant. The public URL stays
89
+ * clean; this internal key carries the deployment id so a new deploy never
90
+ * reads HTML produced by an older deploy.
91
+ */
92
+ declare function htmlEdgeKey(host: string, pathname: string, id: string): string;
93
+ /**
94
+ * Edge-cache key for the JSON (pages-protocol) variant. Separated from HTML by
95
+ * the `&__void=json` marker.
96
+ */
97
+ declare function jsonEdgeKey(host: string, pathname: string, id: string): string;
98
+ /**
99
+ * Match a pattern against a pathname using LITERAL semantics — no named
100
+ * captures. Two wildcards are special: `*` matches any characters INCLUDING `/`
101
+ * (a splat), and a WHOLE-segment `:name` (preceded by `/` or start, followed by
102
+ * `/` or end) matches exactly ONE path segment (`[^/]+`). A mid-segment literal
103
+ * `:` (e.g. `/api/v1:health`) is left alone. This is a strict SUPERSET of the
104
+ * old `*`-only matcher (old `*`-only manifests match identically). Malformed
105
+ * patterns yield `false` rather than throwing.
106
+ */
107
+ declare function matchLiteralPattern(pattern: string, pathname: string): boolean;
108
+ /**
109
+ * Pack response headers + body into a single ArrayBuffer.
110
+ * Format: [4 bytes uint32 LE header length][UTF-8 header JSON][raw body]
111
+ */
112
+ declare function packIsrValue(headers: Record<string, string>, body: ArrayBuffer): ArrayBuffer;
113
+ /**
114
+ * Unpack headers + body from a packed ArrayBuffer.
115
+ * Returns null if the buffer is too small or malformed.
116
+ */
117
+ declare function unpackIsrValue(buffer: ArrayBuffer): {
118
+ headers: Record<string, string>;
119
+ body: ArrayBuffer;
120
+ } | null;
121
+ /**
122
+ * Read an ISR cache entry from KV. Returns null on cache miss, malformed
123
+ * metadata, or ANY KV error (fail-open → caller renders live). The KV key is
124
+ * deployment-scoped via `env.__VOID_ISR_DEPLOYMENT_ID` (see module header) and
125
+ * host-scoped via `host` so one host never reads another host's cached bytes.
126
+ */
127
+ declare function readIsrCache(env: IsrCacheEnv, host: string, pathname: string): Promise<IsrCacheEntry | null>;
128
+ /**
129
+ * Write an ISR cache entry to KV. The `response.clone()` is taken SYNCHRONOUSLY
130
+ * before any `await` so a caller that consumes `response.body` for the client
131
+ * response (after kicking us off via `ctx.waitUntil`) cannot race the body
132
+ * away. Any KV error is swallowed (fail-open on the write path).
133
+ */
134
+ declare function writeIsrCache(env: IsrCacheEnv, host: string, pathname: string, response: Response, ttl: number): Promise<void>;
135
+ /**
136
+ * List every host that has registered cached content for a deployment. Used by
137
+ * the on-demand `revalidate({ paths })` purge when there is no request host
138
+ * (cron / queue). Fail-open: a registry read error yields the hosts collected so
139
+ * far (or none) rather than throwing — degraded purge coverage, never a 500.
140
+ */
141
+ declare function listIsrHosts(kv: KVNamespace, deploymentId: string): Promise<Array<string>>;
142
+ /**
143
+ * Delete an ISR cache entry from KV. Used when a worker permanently opts out
144
+ * via `x-revalidate: 0`. Any KV error is swallowed (fail-open).
145
+ */
146
+ declare function deleteIsrCache(env: IsrCacheEnv, host: string, pathname: string): Promise<void>;
147
+ /** Check if a cached entry is stale. */
148
+ declare function isStale(entry: IsrCacheEntry): boolean;
149
+ /** Build a Response from an ISR cache entry. */
150
+ declare function isrCacheResponse(entry: IsrCacheEntry, stale: boolean): Response;
151
+ /**
152
+ * Read the `x-revalidate` header from a worker response.
153
+ * Returns the override TTL, or the default. A value of 0 means "do not cache".
154
+ */
155
+ declare function resolveRevalidateTtl(response: Response, defaultTtl: number): number;
156
+ /**
157
+ * ISR should be bypassed for requests with credentials and EventSource
158
+ * requests. Pages protocol navigation (X-VoidPages) uses a separate JSON edge
159
+ * cache.
160
+ */
161
+ declare function shouldBypassIsr(request: Request): boolean;
162
+ /**
163
+ * Resolve the ISR TTL for a given pathname.
164
+ * Accepts the `revalidate` config (number, object, or undefined). For the
165
+ * object form, the first matching pattern wins.
166
+ */
167
+ declare function resolvePathTtl(revalidate: number | Record<string, number> | undefined, pathname: string): number;
168
+ declare function serializeHeaders(response: Response): Record<string, string>;
169
+ declare function normalizePageDataForJsonCache(raw: string): string | null;
170
+ declare function extractPageDataFromHtml(html: string): string | null;
171
+ declare function clientRevalidateResponse(response: Response): Response;
172
+ declare function isEventStreamResponse(response: Response): boolean;
173
+ /**
174
+ * Populate the JSON edge cache from a response's embedded page data (the
175
+ * `x-void-page-data` header or the `__VOID_PAGE_DATA__` inline script). No-ops
176
+ * when there is no extractable page data. Any cache error is swallowed
177
+ * (fail-open) so this is always safe to fire inside `ctx.waitUntil`.
178
+ */
179
+ declare function populateJsonEdgeCache(cache: Cache | undefined, cacheKey: string, response: Response, ttl: number, state: "HIT" | "MISS"): Promise<void>;
180
+ /**
181
+ * Build a new Request with the `X-VoidPages` header removed. Headers on an
182
+ * existing Request are immutable, so we must clone into a fresh Request. ISR
183
+ * only runs for GET, so there is no body to preserve.
184
+ */
185
+ declare function cloneWithoutVoidPages(request: Request): Request;
186
+ /**
187
+ * Run the ISR caching ladder for a request.
188
+ *
189
+ * Returns a cached/rendered `Response` when ISR applies, or `null` when the
190
+ * caller should render live itself (request not ISR-eligible, or a read/hit
191
+ * cache op failed open).
192
+ *
193
+ * Ladder:
194
+ * - Bail (`null`) if not GET, a Range request, `shouldBypassIsr`, or the path
195
+ * has no ISR TTL. Range requests bail BEFORE any cache read/write so they
196
+ * render live (correct 206) and never touch the shared full-response entry.
197
+ * - JSON (X-VoidPages) path: edge match → hit serves `clientRevalidateResponse`;
198
+ * miss renders live JSON and returns it — the JSON path never writes the edge
199
+ * cache. The JSON edge variant is warmed only as a side-effect of the HTML
200
+ * render path (cold colo re-renders JSON).
201
+ * - HTML path: L1 edge match → L2 KV. Hit serves `isrCacheResponse`
202
+ * (stale hits also queue a background revalidation). Miss renders live and,
203
+ * when cacheable, writes KV + JSON edge + HTML edge in the background.
204
+ */
205
+ declare function handleIsr(request: Request, env: IsrCacheEnv, ctx: ExecutionContext, options: HandleIsrOptions, render: RenderFn): Promise<Response | null>;
206
+ //#endregion
207
+ export { HandleIsrOptions, IsrCacheEntry, IsrCacheEnv, IsrCacheMetadata, RenderFn, canonicalIsrPathname, clientRevalidateResponse, cloneWithoutVoidPages, deleteIsrCache, denormalizeIsrPath, extractPageDataFromHtml, handleIsr, hostRegistryKey, htmlEdgeKey, isEventStreamResponse, isStale, isrCacheResponse, isrKey, jsonEdgeKey, listIsrHosts, matchLiteralPattern, normalizeIsrPath, normalizePageDataForJsonCache, packIsrValue, populateJsonEdgeCache, readIsrCache, resolvePathTtl, resolveRevalidateTtl, serializeHeaders, shouldBypassIsr, unpackIsrValue, writeIsrCache };