@vinext/cloudflare 1.0.0-beta.1 → 1.0.0-beta.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. package/README.md +193 -1
  2. package/dist/cache/cdn-adapter-config.d.ts +31 -0
  3. package/dist/cache/cdn-adapter-config.js +95 -0
  4. package/dist/cache/cdn-adapter.d.ts +48 -15
  5. package/dist/cache/cdn-adapter.js +50 -13
  6. package/dist/cache/cdn-adapter.runtime.d.ts +26 -4
  7. package/dist/cache/cdn-adapter.runtime.js +150 -37
  8. package/dist/cache/cdn-adapter.worker.d.ts +31 -0
  9. package/dist/cache/cdn-adapter.worker.js +373 -0
  10. package/dist/cache/cdn-build-id.d.ts +6 -0
  11. package/dist/cache/cdn-build-id.js +9 -0
  12. package/dist/cache/config.d.ts +137 -0
  13. package/dist/cache/config.js +87 -0
  14. package/dist/cache/kv-data-adapter.d.ts +32 -8
  15. package/dist/cache/kv-data-adapter.js +5 -1
  16. package/dist/cache/kv-data-adapter.runtime.d.ts +45 -13
  17. package/dist/cache/kv-data-adapter.runtime.js +132 -52
  18. package/dist/cache/kv-key.d.ts +15 -0
  19. package/dist/cache/kv-key.js +43 -0
  20. package/dist/cache/response-store-adapter.d.ts +73 -0
  21. package/dist/cache/response-store-adapter.js +64 -0
  22. package/dist/cache/response-store-adapter.self-contained.worker.d.ts +18 -0
  23. package/dist/cache/response-store-adapter.self-contained.worker.js +12 -0
  24. package/dist/cache/response-store-adapter.service-binding.worker.d.ts +16 -0
  25. package/dist/cache/response-store-adapter.service-binding.worker.js +11 -0
  26. package/dist/cache/response-store-adapter.worker.d.ts +14 -0
  27. package/dist/cache/response-store-adapter.worker.js +278 -0
  28. package/dist/cache/response-store-cdn.runtime.d.ts +5 -0
  29. package/dist/cache/response-store-cdn.runtime.js +41 -0
  30. package/dist/cache/response-store-data.runtime.d.ts +34 -0
  31. package/dist/cache/response-store-data.runtime.js +300 -0
  32. package/dist/cacheability-artifact.d.ts +10 -0
  33. package/dist/cacheability-artifact.js +215 -0
  34. package/dist/cacheability-manifest-limits.d.ts +4 -0
  35. package/dist/cacheability-manifest-limits.js +7 -0
  36. package/dist/cacheability-probe.d.ts +49 -0
  37. package/dist/cacheability-probe.js +660 -0
  38. package/dist/cdn-warm.d.ts +110 -12
  39. package/dist/cdn-warm.js +880 -82
  40. package/dist/cli.d.ts +1 -1
  41. package/dist/cli.js +15 -1
  42. package/dist/deploy-config.d.ts +14 -11
  43. package/dist/deploy-config.js +24 -5
  44. package/dist/deploy-help.d.ts +3 -4
  45. package/dist/deploy-help.js +65 -22
  46. package/dist/deploy.d.ts +139 -42
  47. package/dist/deploy.js +946 -132
  48. package/dist/images/images-optimizer.d.ts +5 -5
  49. package/dist/images/images-optimizer.runtime.d.ts +1 -5
  50. package/dist/prerender-kv-populate.d.ts +3 -4
  51. package/dist/prerender-kv-populate.js +51 -18
  52. package/dist/tpr.d.ts +34 -70
  53. package/dist/tpr.js +50 -603
  54. package/dist/utils/cache-control-metadata.d.ts +3 -4
  55. package/dist/version-deploy.d.ts +46 -17
  56. package/dist/version-deploy.js +151 -14
  57. package/dist/version-headers.d.ts +2 -0
  58. package/dist/version-headers.js +2 -0
  59. package/dist/worker-deployment-url.d.ts +9 -0
  60. package/dist/worker-deployment-url.js +45 -0
  61. package/dist/workers-dev-url.d.ts +2 -3
  62. package/dist/wrangler-config.d.ts +19 -0
  63. package/dist/wrangler-config.js +294 -0
  64. package/dist/wrangler-version-metadata.d.ts +7 -0
  65. package/dist/wrangler-version-metadata.js +9 -0
  66. package/package.json +21 -11
package/dist/cli.d.ts CHANGED
@@ -1 +1 @@
1
- export { };
1
+ export {}
package/dist/cli.js CHANGED
@@ -38,16 +38,30 @@ async function deployCommand() {
38
38
  root: process.cwd(),
39
39
  preview: parsed.preview,
40
40
  env: parsed.env,
41
+ config: parsed.config,
41
42
  skipBuild: parsed.skipBuild,
42
43
  dryRun: parsed.dryRun,
44
+ verbose: parsed.verbose,
43
45
  name: parsed.name,
44
46
  prerenderAll: parsed.prerenderAll,
45
47
  prerenderConcurrency: parsed.prerenderConcurrency,
46
48
  warmCdnCache: parsed.warmCdnCache,
49
+ warmCdnTarget: parsed.warmCdnTarget,
47
50
  warmCdnConcurrency: parsed.warmCdnConcurrency,
48
51
  warmCdnTimeout: parsed.warmCdnTimeout,
49
52
  warmCdnRetries: parsed.warmCdnRetries,
50
- warmCdnStrict: parsed.warmCdnStrict,
53
+ warmCdnDiscoveryTimeout: parsed.warmCdnDiscoveryTimeout,
54
+ warmCdnDiscoveryRetries: parsed.warmCdnDiscoveryRetries,
55
+ warmCdnProbeTimeout: parsed.warmCdnProbeTimeout,
56
+ warmCdnProbeRetries: parsed.warmCdnProbeRetries,
57
+ warmCdnCertify: parsed.warmCdnCertify,
58
+ warmCdnReadinessTimeout: parsed.warmCdnReadinessTimeout,
59
+ warmCdnReadinessRetries: parsed.warmCdnReadinessRetries,
60
+ warmCdnReadinessProbes: parsed.warmCdnReadinessProbes,
61
+ warmCdnReadinessProbeDelay: parsed.warmCdnReadinessProbeDelay,
62
+ dangerouslyPromoteOnCdnWarmError: parsed.dangerouslyPromoteOnCdnWarmError,
63
+ warmCdnPromote: parsed.warmCdnPromote,
64
+ warmCdnPromotionDelay: parsed.warmCdnPromotionDelay,
51
65
  warmCdnIncludeFallbacks: parsed.warmCdnIncludeFallbacks,
52
66
  experimentalTPR: parsed.experimentalTPR,
53
67
  tprCoverage: parsed.tprCoverage,
@@ -1,5 +1,4 @@
1
1
  import { VinextCacheConfig } from "vinext/internal/cache-adapters";
2
-
3
2
  //#region src/deploy-config.d.ts
4
3
  /**
5
4
  * Check whether an existing vite.config file already imports and uses the
@@ -9,7 +8,7 @@ import { VinextCacheConfig } from "vinext/internal/cache-adapters";
9
8
  * Returns true when the config both imports the package and invokes
10
9
  * `cloudflare(...)` in the plugin list.
11
10
  */
12
- declare function viteConfigHasCloudflarePlugin(root: string): boolean;
11
+ export declare function viteConfigHasCloudflarePlugin(root: string): boolean;
13
12
  /**
14
13
  * Detect whether the Vite config assigns a CDN or data cache adapter — i.e. the
15
14
  * `cdn` or `data` field of the `vinext({ cache })` option is given a value.
@@ -18,14 +17,18 @@ declare function viteConfigHasCloudflarePlugin(root: string): boolean;
18
17
  * an unreadable or absent config is treated as configured so a deploy is never
19
18
  * blocked on a false negative.
20
19
  */
21
- declare function viteConfigHasCacheAdapter(root: string): boolean;
22
- type ResolvedKvDataAdapterConfig = {
20
+ export declare function viteConfigHasCacheAdapter(root: string): boolean;
21
+ export type ResolvedKvDataAdapterConfig = {
23
22
  binding: string;
24
23
  appPrefix?: string;
25
24
  ttlSeconds?: number;
26
25
  };
27
- declare function resolveKvDataAdapterConfig(cache: VinextCacheConfig | null | undefined): ResolvedKvDataAdapterConfig | null;
28
- declare function viteConfigHasImageAdapter(root: string): boolean;
26
+ export type ResolvedCdnAdapterConfig = {
27
+ versionMetadataBinding: string;
28
+ };
29
+ export declare function resolveCdnAdapterConfig(cache: VinextCacheConfig | null | undefined): ResolvedCdnAdapterConfig | null;
30
+ export declare function resolveKvDataAdapterConfig(cache: VinextCacheConfig | null | undefined): ResolvedKvDataAdapterConfig | null;
31
+ export declare function viteConfigHasImageAdapter(root: string): boolean;
29
32
  /**
30
33
  * Detect whether an existing user-authored Worker entry wires up a cache
31
34
  * backend imperatively via one of the `setCacheHandler` / `setDataCacheHandler`
@@ -40,16 +43,16 @@ declare function viteConfigHasImageAdapter(root: string): boolean;
40
43
  * missing Worker entry returns false (nothing to inspect — defer to other
41
44
  * checks).
42
45
  */
43
- declare function workerEntryHasCacheHandler(root: string): boolean;
46
+ export declare function workerEntryHasCacheHandler(root: string): boolean;
44
47
  /**
45
48
  * Build the error thrown when an ISR/cached app is deployed without a cache
46
49
  * adapter configured in the Vite config. Production deployments need a
47
50
  * persistent cache backend; vinext no longer scaffolds one into the Worker
48
51
  * entry, so it must be declared via `vinext({ cache })`.
49
52
  */
50
- declare function formatMissingCacheAdapterError(options: {
53
+ export declare function formatMissingCacheAdapterError(options: {
51
54
  configFile?: string;
55
+ typedConfig?: boolean;
52
56
  }): string;
53
- declare function formatImageOptimizationHint(): string;
54
- //#endregion
55
- export { ResolvedKvDataAdapterConfig, formatImageOptimizationHint, formatMissingCacheAdapterError, resolveKvDataAdapterConfig, viteConfigHasCacheAdapter, viteConfigHasCloudflarePlugin, viteConfigHasImageAdapter, workerEntryHasCacheHandler };
57
+ export declare function formatImageOptimizationHint(typedConfig?: boolean): string;
58
+ //#endregion
@@ -1,6 +1,8 @@
1
1
  import { DEFAULT_KV_DATA_CACHE_BINDING } from "./cache/kv-data-adapter.js";
2
- import path from "node:path";
2
+ import { DEFAULT_CDN_VERSION_METADATA_BINDING } from "./cache/cdn-adapter.js";
3
3
  import fs from "node:fs";
4
+ import path from "node:path";
5
+ import { fileURLToPath } from "node:url";
4
6
  import { findViteConfigPath } from "vinext/internal/utils/project";
5
7
  //#region src/deploy-config.ts
6
8
  function escapeRegExp(value) {
@@ -84,9 +86,25 @@ function viteConfigHasCacheAdapter(root) {
84
86
  return true;
85
87
  }
86
88
  const block = extractCacheBlock(content);
87
- if (!block) return false;
89
+ if (!block) {
90
+ const assigned = /\bcache\s*:\s*([^,}\n]+)/.exec(content)?.[1].trim();
91
+ return Boolean(assigned && assigned !== "undefined" && assigned !== "null");
92
+ }
88
93
  return cacheFieldAssigned(block, "cdn") || cacheFieldAssigned(block, "data");
89
94
  }
95
+ function isCloudflareCdnAdapterPath(adapter) {
96
+ const normalized = adapter.replace(/\\/g, "/");
97
+ return ["cdn-adapter.runtime", "response-store-cdn.runtime"].some((runtime) => {
98
+ const bundledRuntime = fileURLToPath(new URL(`./cache/${runtime}.js`, import.meta.url)).replace(/\\/g, "/");
99
+ return normalized === `@vinext/cloudflare/cache/${runtime}` || normalized === `@vinext/cloudflare/cache/${runtime}.js` || normalized === bundledRuntime;
100
+ });
101
+ }
102
+ function resolveCdnAdapterConfig(cache) {
103
+ const cdn = cache?.cdn;
104
+ if (!cdn?.adapter || !isCloudflareCdnAdapterPath(cdn.adapter)) return null;
105
+ const options = cdn.options;
106
+ return { versionMetadataBinding: typeof options?.versionMetadataBinding === "string" && options.versionMetadataBinding.length > 0 ? options.versionMetadataBinding : DEFAULT_CDN_VERSION_METADATA_BINDING };
107
+ }
90
108
  function isCloudflareKvDataAdapterPath(adapter) {
91
109
  const normalized = adapter.replace(/\\/g, "/");
92
110
  return normalized === "@vinext/cloudflare/cache/kv-data-adapter.runtime" || normalized === "@vinext/cloudflare/cache/kv-data-adapter.runtime.js" || normalized.endsWith("/cache/kv-data-adapter.runtime.js");
@@ -160,10 +178,11 @@ function workerEntryHasCacheHandler(root) {
160
178
  */
161
179
  function formatMissingCacheAdapterError(options) {
162
180
  const configRef = options.configFile ? options.configFile : "your Vite config";
163
- return `[vinext] This app uses ISR / caching but no cache adapter is configured in ${configRef}.\n\n Production deployments need a persistent cache backend. Declare one on the\n vinext() plugin in ${configRef}:\n\n import { kvDataAdapter } from "@vinext/cloudflare/cache/kv-data-adapter";\n\n export default defineConfig({\n plugins: [\n vinext({\n cache: {\n data: kvDataAdapter(), // KV-backed data cache (binding: VINEXT_KV_CACHE)\n },\n }),\n cloudflare(),\n ],\n });\n\n The VINEXT_KV_CACHE namespace binding is added to wrangler.jsonc for you.\n Create the namespace with:\n\n npx wrangler kv namespace create VINEXT_KV_CACHE`;
181
+ return `[vinext] This app uses ISR / caching but no cache adapter is configured in ${configRef}.\n\n Production deployments need a persistent cache backend. Declare one on the\n vinext() plugin in ${configRef}:\n\n import { kvDataAdapter } from "@vinext/cloudflare/cache/kv-data-adapter";\n\n export default defineConfig({\n plugins: [\n vinext({\n cache: {\n data: kvDataAdapter(), // KV-backed data cache (binding: VINEXT_KV_CACHE)\n },\n }),\n cloudflare(),\n ],\n });\n\n` + (options.typedConfig ? ` Configure the VINEXT_KV_CACHE namespace binding in cloudflare.config.ts.` : " The VINEXT_KV_CACHE namespace binding is added to wrangler.jsonc for you.\n Create the namespace with:\n\n npx wrangler kv namespace create VINEXT_KV_CACHE");
164
182
  }
165
- function formatImageOptimizationHint() {
183
+ function formatImageOptimizationHint(typedConfig = false) {
184
+ if (typedConfig) return " [vinext] next/image is served unoptimized. To enable edge image\n optimization via Cloudflare Images, configure imagesOptimizer() in your\n Vite config and the IMAGES binding in cloudflare.config.ts.";
166
185
  return " [vinext] next/image is served unoptimized. To enable edge image\n optimization via Cloudflare Images, run:\n\n vinext init --platform=cloudflare --image-optimization=cloudflare-images\n\n This adds the imagesOptimizer() option to your Vite config and the matching\n IMAGES binding to your Wrangler config without replacing existing settings.";
167
186
  }
168
187
  //#endregion
169
- export { formatImageOptimizationHint, formatMissingCacheAdapterError, resolveKvDataAdapterConfig, viteConfigHasCacheAdapter, viteConfigHasCloudflarePlugin, viteConfigHasImageAdapter, workerEntryHasCacheHandler };
188
+ export { formatImageOptimizationHint, formatMissingCacheAdapterError, resolveCdnAdapterConfig, resolveKvDataAdapterConfig, viteConfigHasCacheAdapter, viteConfigHasCloudflarePlugin, viteConfigHasImageAdapter, workerEntryHasCacheHandler };
@@ -1,5 +1,4 @@
1
1
  //#region src/deploy-help.d.ts
2
- declare function formatDeployHelp(): string;
3
- declare function printDeployHelp(): void;
4
- //#endregion
5
- export { formatDeployHelp, printDeployHelp };
2
+ export declare function formatDeployHelp(): string;
3
+ export declare function printDeployHelp(): void;
4
+ //#endregion
@@ -9,15 +9,18 @@ function formatDeployHelp() {
9
9
  - Detects App Router or Pages Router
10
10
  - Validates setup from vinext init --platform=cloudflare
11
11
  - Builds the project with Vite
12
- - Deploys via wrangler
12
+ - Deploys with cf for typed Cloudflare config projects, or Wrangler otherwise
13
13
 
14
14
  Options:
15
15
  --preview Deploy to preview environment (same as --env preview)
16
- --env <name> Deploy using wrangler env.<name>
17
- --name <name> Custom Worker name (default: from package.json)
16
+ --env <name> Cloudflare mode for typed config; Wrangler environment otherwise
17
+ --name <name> Custom Worker name for Wrangler config projects
18
18
  --config <path> Wrangler config path (default: wrangler.jsonc/json/toml)
19
19
  --skip-build Skip the build step (use existing dist/)
20
20
  --dry-run Validate setup without building or deploying
21
+ --verbose Print raw output from internal Cloudflare CLI commands
22
+ --no-promote Do not promote the uploaded Worker version to 100%
23
+ traffic
21
24
  --prerender-all Pre-render discovered routes after building (future
22
25
  releases will auto-populate the remote cache)
23
26
  --prerender-concurrency <count>
@@ -25,43 +28,83 @@ function formatDeployHelp() {
25
28
  --experimental-warm-cdn-cache
26
29
  Upload a Worker version, warm build-discovered paths
27
30
  through the production URL, then promote it (experimental)
31
+ --warm-cdn-target <origin>
32
+ HTTPS origin to use for discovery, probing, and warming
33
+ (overrides URLs inferred from Wrangler output)
28
34
  --warm-cdn-concurrency <count>
29
- Maximum number of CDN warmup requests in parallel
30
- --warm-cdn-timeout <ms> Per-request CDN warmup timeout (default: 5000)
31
- --warm-cdn-retries <n> Retries for transient CDN warmup failures (default: 1)
32
- --warm-cdn-strict Fail deploy when any CDN warmup request fails
35
+ Maximum number of CDN warmup requests in parallel (default: 25)
36
+ --warm-cdn-timeout <ms> Per-request CDN warmup timeout (default: 10000)
37
+ --warm-cdn-retries <n> Retries per failed CDN warmup request (default: 1;
38
+ staged-version propagation default: 60)
39
+ --warm-cdn-discovery-timeout <ms>
40
+ Total staged path-discovery deadline (default: 120000)
41
+ --warm-cdn-discovery-retries <n>
42
+ Optional staged path-discovery retry limit
43
+ (default: derived from the discovery deadline)
44
+ --warm-cdn-probe-timeout <ms>
45
+ Abort when cacheability probing makes no progress for
46
+ this duration (default: 120000)
47
+ --warm-cdn-probe-retries <n>
48
+ Cacheability-probe retries (default: 2)
49
+ --warm-cdn-certify With --experimental-warm-cdn-cache, re-request warmed
50
+ entries using headers only and require every planned
51
+ entry to be reusable before promotion
52
+ --warm-cdn-readiness-timeout <ms>
53
+ Explicit total staged-readiness deadline (default:
54
+ 120000)
55
+ --warm-cdn-readiness-retries <n>
56
+ Staged-readiness retries (default: 60)
57
+ --warm-cdn-readiness-probes <count>
58
+ Consecutive successful staged-readiness probes
59
+ required before warming (default: 6)
60
+ --warm-cdn-readiness-probe-delay <ms>
61
+ Delay between staged-readiness probes (default: 1000)
62
+ --dangerously-promote-on-cdn-warm-error
63
+ Promote even when ordinary staged warmup cannot be
64
+ verified (never bypasses --warm-cdn-certify)
65
+ --warm-cdn-promotion-delay <ms>
66
+ Delay before promotion after warmup (default: 15000)
33
67
  --warm-cdn-include-fallbacks
34
68
  Also warm PPR fallback-shell placeholder paths
35
69
  -h, --help Show this help
36
70
 
37
71
  Experimental:
38
- --experimental-tpr Enable Traffic-aware Pre-Rendering
39
- --tpr-coverage <pct> Traffic coverage target, 0-100 (default: 90)
40
- --tpr-limit <count> Hard cap on pages to pre-render (default: 1000)
41
- --tpr-window <hours> Analytics lookback window in hours (default: 24)
72
+ --experimental-traffic-aware-warm-cache
73
+ Select CDN pre-warm routes from traffic
74
+ --traffic-aware-coverage <pct> Traffic coverage target, 0-100 (default: 90)
75
+ --traffic-aware-limit <count> Hard cap on selected routes (default: 1000)
76
+ --traffic-aware-window <hours> Analytics lookback window in hours (default: 24)
42
77
 
43
- TPR (Traffic-aware Pre-Rendering) uses Cloudflare zone analytics to determine
44
- which pages get the most traffic and pre-renders them into KV cache during
45
- deploy. This feature is experimental and must be explicitly enabled. Requires
46
- a custom domain (zone analytics are unavailable on *.workers.dev) and the
47
- CLOUDFLARE_API_TOKEN environment variable with Zone.Analytics read permission.
78
+ Traffic-aware warming uses Cloudflare zone analytics to select the
79
+ highest-traffic routes, then feeds those routes into the same staged CDN
80
+ pre-warming flow used by --experimental-warm-cdn-cache. It requires a custom
81
+ domain and a CLOUDFLARE_API_TOKEN with Zone Analytics read permission.
48
82
 
49
- CDN warmup requests populate the edge cache only in the Cloudflare data centers
50
- reached by the warmup run; they do not globally prefill every edge location.
83
+ Legacy --experimental-tpr and --tpr-* aliases remain supported.
84
+
85
+ Workers Cache automatically uses tiered caching. Warmed entries can therefore
86
+ be reused outside the data center reached by the warmup request after cache
87
+ propagation, but the deploy does not wait for every edge location to fill.
51
88
 
52
89
  Examples:
53
90
  npx @vinext/cloudflare deploy Build and deploy to production
54
91
  vpx @vinext/cloudflare deploy Build and deploy with Vite+
55
92
  vp exec vinext-cloudflare deploy Run the locally installed Vite+ bin
56
93
  vinext-cloudflare deploy --preview Deploy to a preview URL
57
- vinext-cloudflare deploy --env staging Deploy using wrangler env.staging
94
+ vinext-cloudflare deploy --env staging Deploy using Cloudflare mode/environment staging
58
95
  vinext-cloudflare deploy --config dist/server/wrangler.json Deploy using a generated Wrangler config
59
96
  vinext-cloudflare deploy --dry-run Validate setup without building or deploying
60
97
  vinext-cloudflare deploy --name my-app Deploy with a custom Worker name
98
+ vinext-cloudflare deploy --no-promote Upload a version without changing deployment traffic
61
99
  vinext-cloudflare deploy --experimental-warm-cdn-cache Warm build-discovered paths during version deploy (experimental)
62
- vinext-cloudflare deploy --experimental-tpr Enable TPR during deploy
63
- vinext-cloudflare deploy --experimental-tpr --tpr-coverage 95 Cover 95% of traffic
64
- vinext-cloudflare deploy --experimental-tpr --tpr-limit 500 Cap at 500 pages
100
+ vinext-cloudflare deploy --experimental-warm-cdn-cache --warm-cdn-target https://example.com
101
+ Warm an explicit production origin
102
+ vinext-cloudflare deploy --experimental-traffic-aware-warm-cache
103
+ Enable traffic-aware warming
104
+ vinext-cloudflare deploy --experimental-traffic-aware-warm-cache --traffic-aware-coverage 95
105
+ Cover 95% of traffic
106
+ vinext-cloudflare deploy --experimental-traffic-aware-warm-cache --traffic-aware-limit 500
107
+ Cap at 500 routes
65
108
  `;
66
109
  }
67
110
  function printDeployHelp() {
package/dist/deploy.d.ts CHANGED
@@ -1,31 +1,81 @@
1
- import { parseWranglerConfig } from "./tpr.js";
2
- import { WranglerDeploymentStatus, WranglerVersionTraffic } from "./version-deploy.js";
1
+ import { CdnWarmOptions, CdnWarmRequestPlan, PrerenderWarmPlan } from "./cdn-warm.js";
2
+ import { parseWranglerConfig } from "./wrangler-config.js";
3
+ import { TrafficEntry } from "./tpr.js";
4
+ import { WranglerDeploymentStatus, WranglerVersionTraffic, WranglerVersionUploadResult } from "./version-deploy.js";
3
5
  import { KVBulkPair } from "./prerender-kv-populate.js";
4
6
  import { spawn } from "node:child_process";
5
-
7
+ import { VinextCacheConfig } from "vinext/internal/config/prerender";
8
+ import { ProjectInfo } from "vinext/internal/utils/project";
6
9
  //#region src/deploy.d.ts
7
- type DeployOptions = {
8
- /** Project root directory */root: string; /** Deploy to preview environment (default: production) */
9
- preview?: boolean; /** Wrangler environment name from wrangler.jsonc env.<name> */
10
- env?: string; /** Custom project name for the Worker */
11
- name?: string; /** Wrangler config path, relative to root unless absolute */
12
- config?: string; /** Skip the build step (assume already built) */
13
- skipBuild?: boolean; /** Dry run — validate setup but don't build or deploy */
14
- dryRun?: boolean; /** Pre-render all discovered routes into the dist output after building */
15
- prerenderAll?: boolean; /** Maximum number of routes to prerender in parallel */
16
- prerenderConcurrency?: number; /** Warm Cloudflare's CDN cache by requesting build-discovered paths for the uploaded version */
17
- warmCdnCache?: boolean; /** Maximum number of CDN warmup requests to issue in parallel */
18
- warmCdnConcurrency?: number; /** Per-request CDN warmup timeout in milliseconds */
19
- warmCdnTimeout?: number; /** Number of CDN warmup retries for transient failures */
20
- warmCdnRetries?: number; /** Fail deployment if any CDN warmup request fails */
21
- warmCdnStrict?: boolean; /** Include PPR fallback-shell placeholder paths during CDN warmup */
22
- warmCdnIncludeFallbacks?: boolean; /** Enable experimental TPR (Traffic-aware Pre-Rendering) */
23
- experimentalTPR?: boolean; /** TPR: traffic coverage percentage target (0–100, default: 90) */
24
- tprCoverage?: number; /** TPR: hard cap on number of pages to pre-render (default: 1000) */
25
- tprLimit?: number; /** TPR: analytics lookback window in hours (default: 24) */
10
+ export declare const DEFAULT_CDN_WARM_PROMOTION_DELAY_MS = 15000;
11
+ export type DeployOptions = {
12
+ /** Project root directory */
13
+ root: string;
14
+ /** Deploy to preview environment (default: production) */
15
+ preview?: boolean;
16
+ /** Wrangler environment name from wrangler.jsonc env.<name> */
17
+ env?: string;
18
+ /** Custom project name for the Worker */
19
+ name?: string;
20
+ /** Wrangler config path, relative to root unless absolute */
21
+ config?: string;
22
+ /** Skip the build step (assume already built) */
23
+ skipBuild?: boolean;
24
+ /** Dry run — validate setup but don't build or deploy */
25
+ dryRun?: boolean;
26
+ /** Print raw output from internal Wrangler commands. */
27
+ verbose?: boolean;
28
+ /** Pre-render all discovered routes into the dist output after building */
29
+ prerenderAll?: boolean;
30
+ /** Maximum number of routes to prerender in parallel */
31
+ prerenderConcurrency?: number;
32
+ /** Warm Cloudflare's CDN cache by requesting build-discovered paths for the uploaded version */
33
+ warmCdnCache?: boolean;
34
+ /** Explicit production origin to use for CDN discovery, probing, and warming */
35
+ warmCdnTarget?: string;
36
+ /** Maximum number of CDN warmup requests to issue in parallel */
37
+ warmCdnConcurrency?: number;
38
+ /** Per-request CDN warmup timeout in milliseconds */
39
+ warmCdnTimeout?: number;
40
+ /** Number of CDN warmup retries for transient failures */
41
+ warmCdnRetries?: number;
42
+ /** Maximum duration of staged Worker path discovery */
43
+ warmCdnDiscoveryTimeout?: number;
44
+ /** Number of transient staged Worker path discovery retries */
45
+ warmCdnDiscoveryRetries?: number;
46
+ /** Abort after this duration without a completed cacheability probe */
47
+ warmCdnProbeTimeout?: number;
48
+ /** Number of transient staged Worker cacheability probe retries */
49
+ warmCdnProbeRetries?: number;
50
+ /** Re-request warmed identities and require reusable CDN hits before promotion */
51
+ warmCdnCertify?: boolean;
52
+ /** Maximum duration of staged Worker readiness verification */
53
+ warmCdnReadinessTimeout?: number;
54
+ /** Number of staged Worker readiness retries */
55
+ warmCdnReadinessRetries?: number;
56
+ /** Consecutive successful probes required before warming the staged Worker */
57
+ warmCdnReadinessProbes?: number;
58
+ /** Delay between staged Worker readiness probes in milliseconds */
59
+ warmCdnReadinessProbeDelay?: number;
60
+ /** Promote even when staged CDN warmup cannot be completed */
61
+ dangerouslyPromoteOnCdnWarmError?: boolean;
62
+ /** Promote the uploaded Worker version to 100% traffic (default: true) */
63
+ warmCdnPromote?: boolean;
64
+ /** Delay between successful warmup and promotion in milliseconds */
65
+ warmCdnPromotionDelay?: number;
66
+ /** Include PPR fallback-shell placeholder paths during CDN warmup */
67
+ warmCdnIncludeFallbacks?: boolean;
68
+ /** Select CDN pre-warm routes using traffic analytics */
69
+ experimentalTPR?: boolean;
70
+ /** TPR: traffic coverage percentage target (0–100, default: 90) */
71
+ tprCoverage?: number;
72
+ /** TPR: hard cap on selected routes (default: 1000) */
73
+ tprLimit?: number;
74
+ /** TPR: analytics lookback window in hours (default: 24) */
26
75
  tprWindow?: number;
27
76
  };
28
- declare function parseDeployArgs(args: string[]): {
77
+ export type DeploymentTool = "cf" | "wrangler";
78
+ export declare function parseDeployArgs(args: string[]): {
29
79
  help: boolean;
30
80
  preview: boolean;
31
81
  env: string | undefined;
@@ -33,13 +83,26 @@ declare function parseDeployArgs(args: string[]): {
33
83
  config: string | undefined;
34
84
  skipBuild: boolean;
35
85
  dryRun: boolean;
86
+ verbose: boolean;
36
87
  prerenderAll: boolean;
37
88
  prerenderConcurrency: number | undefined;
38
89
  warmCdnCache: boolean;
90
+ warmCdnTarget: string | undefined;
39
91
  warmCdnConcurrency: number | undefined;
40
92
  warmCdnTimeout: number | undefined;
41
93
  warmCdnRetries: number | undefined;
42
- warmCdnStrict: boolean;
94
+ warmCdnDiscoveryTimeout: number | undefined;
95
+ warmCdnDiscoveryRetries: number | undefined;
96
+ warmCdnProbeTimeout: number | undefined;
97
+ warmCdnProbeRetries: number | undefined;
98
+ warmCdnCertify: boolean;
99
+ warmCdnReadinessTimeout: number | undefined;
100
+ warmCdnReadinessRetries: number | undefined;
101
+ warmCdnReadinessProbes: number | undefined;
102
+ warmCdnReadinessProbeDelay: number | undefined;
103
+ dangerouslyPromoteOnCdnWarmError: boolean;
104
+ warmCdnPromote: boolean;
105
+ warmCdnPromotionDelay: number | undefined;
43
106
  warmCdnIncludeFallbacks: boolean;
44
107
  experimentalTPR: boolean;
45
108
  tprCoverage: number | undefined;
@@ -58,18 +121,26 @@ declare function parseDeployArgs(args: string[]): {
58
121
  *
59
122
  * Passing `undefined` is a no-op; the callback runs with `process.env` untouched.
60
123
  */
61
- declare function withCloudflareEnv<T>(env: string | undefined, fn: () => Promise<T>): Promise<T>;
124
+ export declare function withCloudflareEnv<T>(env: string | undefined, fn: () => Promise<T>): Promise<T>;
125
+ export declare function resolveViteBuildMode(deploymentTool: DeploymentTool, env: string | undefined): string;
62
126
  type WranglerDeployArgs = {
63
127
  args: string[];
64
128
  env: string | undefined;
65
129
  };
130
+ type CfDeployArgs = {
131
+ args: string[];
132
+ mode: string | undefined;
133
+ };
66
134
  type WranglerKVBulkPutArgs = {
67
135
  args: string[];
68
136
  env: string | undefined;
69
137
  };
70
- declare function validateWranglerEnvName(env: string): string;
71
- declare function buildWranglerDeployArgs(options: Pick<DeployOptions, "preview" | "env" | "name" | "config">): WranglerDeployArgs;
72
- declare function buildWranglerKVBulkPutArgs(options: {
138
+ export declare function validateWranglerEnvName(env: string): string;
139
+ export declare function buildWranglerDeployArgs(options: Pick<DeployOptions, "preview" | "env" | "name" | "config">): WranglerDeployArgs;
140
+ export declare function resolveDeploymentTool(root: string): DeploymentTool;
141
+ export declare function isCfCliInstalled(root: string, resolvePackageJson?: (root: string) => string | null): boolean;
142
+ export declare function buildCfDeployArgs(options: Pick<DeployOptions, "preview" | "env">): CfDeployArgs;
143
+ export declare function buildWranglerKVBulkPutArgs(options: {
73
144
  binding: string;
74
145
  env?: string;
75
146
  filePath: string;
@@ -80,30 +151,56 @@ declare function buildWranglerKVBulkPutArgs(options: {
80
151
  * Invoking the JavaScript file through `process.execPath` avoids the `.cmd`
81
152
  * shim and command shell that package managers create on Windows.
82
153
  */
83
- declare function resolveWranglerBin(root: string, resolvePackageJson?: (root: string) => string | null): string;
84
- declare function buildNodeCliInvocation(scriptPath: string, args: string[], nodeExecutable?: string): {
154
+ export declare function resolveWranglerBin(root: string, resolvePackageJson?: (root: string) => string | null): string;
155
+ export declare function resolveCfBin(root: string, resolvePackageJson?: (root: string) => string | null): string;
156
+ export declare function buildNodeCliInvocation(scriptPath: string, args: string[], nodeExecutable?: string): {
85
157
  file: string;
86
158
  args: string[];
87
159
  };
88
- declare function buildWranglerInvocation(root: string, options: Pick<DeployOptions, "preview" | "env" | "name" | "config">, nodeExecutable?: string): {
160
+ export declare function buildWranglerInvocation(root: string, options: Pick<DeployOptions, "preview" | "env" | "name" | "config">, nodeExecutable?: string): {
89
161
  file: string;
90
162
  args: string[];
91
163
  env: string | undefined;
92
164
  };
93
- declare function runWranglerKVBulkPut(root: string, options: {
165
+ export declare function runKVBulkPut(root: string, options: {
94
166
  binding: string;
167
+ deploymentTool: DeploymentTool;
95
168
  env?: string;
96
169
  pairs: KVBulkPair[];
97
170
  tempDir?: string;
98
171
  }, execute?: typeof spawn, nodeExecutable?: string): Promise<void>;
99
- declare function runWranglerDeploy(root: string, options: Pick<DeployOptions, "preview" | "env" | "name" | "config">, execute?: typeof spawn): Promise<string>;
100
- declare function deployWithCdnWarmup(root: string, paths: readonly string[], options: Pick<DeployOptions, "preview" | "env" | "name" | "config" | "warmCdnConcurrency" | "warmCdnTimeout" | "warmCdnRetries" | "warmCdnStrict">): Promise<string>;
101
- declare function resolveCdnWarmupTargetUrl(root: string, deployedUrl: string | null): string | null;
102
- declare function resolveCdnWarmupTargetUrl(root: string, deployedUrl: string | null, options: Pick<DeployOptions, "preview" | "env" | "config">): string | null;
103
- declare function getZeroPercentStagingTraffic(deployment: WranglerDeploymentStatus | null, versionId: string): WranglerVersionTraffic[] | null;
172
+ export declare function runWranglerDeploy(root: string, options: Pick<DeployOptions, "preview" | "env" | "name" | "config" | "verbose"> & {
173
+ promote?: boolean;
174
+ }, execute?: typeof spawn): Promise<string>;
175
+ export declare function runCfDeploy(root: string, options: Pick<DeployOptions, "preview" | "env">, execute?: typeof spawn): Promise<string>;
176
+ export declare function hasCdnWarmRequests(plan: Omit<CdnWarmRequestPlan, "pagesDataPaths"> & {
177
+ pagesDataPaths?: readonly string[];
178
+ }): boolean;
179
+ export declare function selectTPRWarmPlan(plan: PrerenderWarmPlan, traffic: readonly TrafficEntry[], coverage: number, limit: number): PrerenderWarmPlan;
180
+ export declare function projectRequiresRouteCacheabilityProbeManifest(project: Pick<ProjectInfo, "isAppRouter" | "isPagesRouter">, cacheConfig: VinextCacheConfig | null): boolean;
181
+ type CdnWarmDeployOptions = Pick<DeployOptions, "preview" | "env" | "name" | "config" | "verbose" | "warmCdnTarget" | "warmCdnConcurrency" | "warmCdnTimeout" | "warmCdnRetries" | "warmCdnDiscoveryTimeout" | "warmCdnDiscoveryRetries" | "warmCdnProbeTimeout" | "warmCdnProbeRetries" | "warmCdnCertify" | "warmCdnReadinessTimeout" | "warmCdnReadinessRetries" | "warmCdnReadinessProbes" | "warmCdnReadinessProbeDelay" | "dangerouslyPromoteOnCdnWarmError" | "warmCdnPromote" | "warmCdnPromotionDelay"> & Pick<CdnWarmOptions, "deploymentId" | "expectedBuildId" | "expectedRscBuildId" | "loadingShellPaths" | "pagesDataPaths" | "routeHandlerPaths" | "routePatterns" | "rscPaths" | "statusSource"> & {
182
+ deploymentTool?: DeploymentTool;
183
+ /** Allow optional route selection to discover no warmable requests. */
184
+ allowEmptyWarmPlan?: boolean;
185
+ /** Probe a staged Worker and upload the resulting manifest as a second version. */
186
+ cacheabilityProbe?: boolean;
187
+ discoverWarmPlan?: (target: {
188
+ headers?: HeadersInit;
189
+ targetUrl: string;
190
+ }) => Promise<PrerenderWarmPlan>;
191
+ /** Narrow the final warm requests without changing discovery or probe metadata. */
192
+ selectWarmPlan?: (plan: PrerenderWarmPlan) => PrerenderWarmPlan;
193
+ };
194
+ type DeploymentControlPlaneOptions = Pick<DeployOptions, "preview" | "env" | "name" | "config" | "verbose"> & {
195
+ deploymentTool?: DeploymentTool;
196
+ };
197
+ export declare function deployWithCdnWarmup(root: string, paths: readonly string[], options: CdnWarmDeployOptions): Promise<string>;
198
+ export declare function resolveCdnWarmupTargetUrl(root: string, deployedUrl: string | null): string | null;
199
+ export declare function resolveCdnWarmupTargetUrl(root: string, deployedUrl: string | null, options: Pick<DeployOptions, "preview" | "env" | "config" | "warmCdnTarget">): string | null;
200
+ export declare function getZeroPercentStagingTraffic(deployment: WranglerDeploymentStatus | null, versionId: string): WranglerVersionTraffic[] | null;
104
201
  type ParsedWranglerConfig = NonNullable<ReturnType<typeof parseWranglerConfig>>;
105
- declare function resolveWorkerNameForVersionOverride(config: ParsedWranglerConfig | null, options: Pick<DeployOptions, "preview" | "env" | "name">): string | undefined;
106
- declare function buildVersionOverrideHeaders(workerName: string | undefined, versionId: string): HeadersInit | undefined;
107
- declare function deploy(options: DeployOptions): Promise<void>;
108
- //#endregion
109
- export { DeployOptions, buildNodeCliInvocation, buildVersionOverrideHeaders, buildWranglerDeployArgs, buildWranglerInvocation, buildWranglerKVBulkPutArgs, deploy, deployWithCdnWarmup, getZeroPercentStagingTraffic, parseDeployArgs, resolveCdnWarmupTargetUrl, resolveWorkerNameForVersionOverride, resolveWranglerBin, runWranglerDeploy, runWranglerKVBulkPut, validateWranglerEnvName, withCloudflareEnv };
202
+ export declare function resolveDeploymentControlPlaneOptions(options: DeploymentControlPlaneOptions, upload: Pick<WranglerVersionUploadResult, "workerName">): DeploymentControlPlaneOptions;
203
+ export declare function resolveWorkerNameForVersionOverride(config: ParsedWranglerConfig | null, options: Pick<DeployOptions, "preview" | "env" | "name">): string | undefined;
204
+ export declare function buildVersionOverrideHeaders(workerName: string | undefined, versionId: string): HeadersInit | undefined;
205
+ export declare function deploy(options: DeployOptions): Promise<void>;
206
+ //#endregion