@vinext/cloudflare 1.0.0-beta.7 → 1.0.0-beta.9
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 +64 -22
- package/dist/cache/cdn-adapter-config.d.ts +16 -8
- package/dist/cache/cdn-adapter-config.js +57 -17
- package/dist/cache/cdn-adapter.d.ts +25 -24
- package/dist/cache/cdn-adapter.js +24 -20
- package/dist/cache/cdn-adapter.runtime.d.ts +9 -3
- package/dist/cache/cdn-adapter.runtime.js +63 -40
- package/dist/cache/cdn-adapter.worker.d.ts +31 -0
- package/dist/cache/cdn-adapter.worker.js +373 -0
- package/dist/cache/cdn-build-id.d.ts +4 -3
- package/dist/cache/cdn-build-id.js +5 -1
- package/dist/cache/kv-data-adapter.d.ts +25 -5
- package/dist/cache/kv-data-adapter.js +5 -1
- package/dist/cache/kv-data-adapter.runtime.d.ts +38 -4
- package/dist/cache/kv-data-adapter.runtime.js +115 -41
- package/dist/cache/kv-key.d.ts +4 -5
- package/dist/cache/response-store-adapter.d.ts +70 -0
- package/dist/cache/response-store-adapter.js +45 -0
- package/dist/cache/response-store-adapter.self-contained.worker.d.ts +18 -0
- package/dist/cache/response-store-adapter.self-contained.worker.js +12 -0
- package/dist/cache/response-store-adapter.service-binding.worker.d.ts +16 -0
- package/dist/cache/response-store-adapter.service-binding.worker.js +11 -0
- package/dist/cache/response-store-adapter.worker.d.ts +14 -0
- package/dist/cache/response-store-adapter.worker.js +264 -0
- package/dist/cache/response-store-cdn.runtime.d.ts +5 -0
- package/dist/cache/response-store-cdn.runtime.js +41 -0
- package/dist/cache/response-store-data.runtime.d.ts +34 -0
- package/dist/cache/response-store-data.runtime.js +289 -0
- package/dist/cacheability-artifact.d.ts +2 -3
- package/dist/cacheability-artifact.js +27 -1
- package/dist/cacheability-manifest-limits.d.ts +3 -4
- package/dist/cacheability-manifest-limits.js +1 -1
- package/dist/cacheability-probe.d.ts +8 -9
- package/dist/cacheability-probe.js +255 -91
- package/dist/cdn-warm.d.ts +31 -25
- package/dist/cdn-warm.js +228 -54
- package/dist/deploy-config.d.ts +11 -12
- package/dist/deploy-config.js +8 -3
- package/dist/deploy-help.d.ts +3 -4
- package/dist/deploy-help.js +20 -14
- package/dist/deploy.d.ts +35 -28
- package/dist/deploy.js +204 -95
- package/dist/images/images-optimizer.d.ts +3 -4
- package/dist/prerender-kv-populate.d.ts +3 -4
- package/dist/prerender-kv-populate.js +3 -2
- package/dist/tpr.d.ts +26 -74
- package/dist/tpr.js +45 -603
- package/dist/utils/cache-control-metadata.d.ts +3 -4
- package/dist/version-deploy.d.ts +17 -17
- package/dist/version-deploy.js +10 -5
- package/dist/worker-deployment-url.d.ts +3 -4
- package/dist/workers-dev-url.d.ts +2 -3
- package/dist/wrangler-config.d.ts +19 -0
- package/dist/wrangler-config.js +294 -0
- package/dist/wrangler-version-metadata.d.ts +2 -3
- package/package.json +13 -11
package/dist/deploy.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { writeCacheabilityManifestArtifact } from "./cacheability-artifact.js";
|
|
2
2
|
import { DEFAULT_CACHEABILITY_PROBE_RETRY_DELAY_MS, probeStagedWorkerCacheability, readPrerenderSecret } from "./cacheability-probe.js";
|
|
3
|
-
import { CdnOperationProgress, createCdnWarmTargets,
|
|
4
|
-
import { parseWranglerConfig
|
|
3
|
+
import { CdnOperationProgress, createCdnWarmTargets, createPrerenderWarmPlan, waitForCdnWarmTargetReadiness, warmCdnCache } from "./cdn-warm.js";
|
|
4
|
+
import { parseWranglerConfig } from "./wrangler-config.js";
|
|
5
|
+
import { resolveTPRRoutes, selectRoutes } from "./tpr.js";
|
|
5
6
|
import { VINEXT_EXPECTED_WORKER_VERSION_HEADER } from "./version-headers.js";
|
|
6
7
|
import { formatImageOptimizationHint, formatMissingCacheAdapterError, resolveCdnAdapterConfig, resolveKvDataAdapterConfig, viteConfigHasCacheAdapter, viteConfigHasCloudflarePlugin, viteConfigHasImageAdapter, workerEntryHasCacheHandler } from "./deploy-config.js";
|
|
7
8
|
import { assertCdnVersionMetadataConfig } from "./wrangler-version-metadata.js";
|
|
@@ -13,7 +14,8 @@ import fs from "node:fs";
|
|
|
13
14
|
import path from "node:path";
|
|
14
15
|
import { cacheabilityRoutePathname } from "vinext/internal/server/cacheability-manifest";
|
|
15
16
|
import { setTimeout } from "node:timers/promises";
|
|
16
|
-
import { DEFAULT_REMOTE_PATH_DISCOVERY_PHASE_TIMEOUT_MS, DEFAULT_REMOTE_PATH_DISCOVERY_RETRY_DELAY_MS, emitPrerenderPathManifest } from "vinext/internal/build/prerender-paths";
|
|
17
|
+
import { DEFAULT_REMOTE_PATH_DISCOVERY_PHASE_TIMEOUT_MS, DEFAULT_REMOTE_PATH_DISCOVERY_RETRY_DELAY_MS, discoverPrerenderPathManifest, emitPrerenderPathManifest } from "vinext/internal/build/prerender-paths";
|
|
18
|
+
import { normalizePathTrailingSlash } from "vinext/shims/url-utils";
|
|
17
19
|
import os from "node:os";
|
|
18
20
|
import { spawn } from "node:child_process";
|
|
19
21
|
import { parseArgs } from "node:util";
|
|
@@ -21,7 +23,7 @@ import { pathToFileURL } from "node:url";
|
|
|
21
23
|
import { runPrerender } from "vinext/internal/build/run-prerender";
|
|
22
24
|
import { loadDotenv } from "vinext/internal/config/dotenv";
|
|
23
25
|
import { findVinextNextConfigInPlugins, loadNextConfig, resolveNextConfig, resolveNextConfigInput } from "vinext/internal/config/next-config";
|
|
24
|
-
import { findVinextCacheConfigInPlugins, findVinextPrerenderConfigInPlugins, findVinextRouteRootConfigInPlugins, formatVinextPrerenderLabel, hasBuildIdentityResponseHeader, hasVerbatimResponseVary, requiresRouteCacheabilityProbeManifest, resolveVinextPrerenderDecision } from "vinext/internal/config/prerender";
|
|
26
|
+
import { cacheWarmupStatusSource, findVinextCacheConfigInPlugins, findVinextPrerenderConfigInPlugins, findVinextRouteRootConfigInPlugins, formatVinextPrerenderLabel, hasBuildIdentityResponseHeader, hasUncachedRequestRouting, hasVerbatimResponseVary, isConfiguredCdnResponsePolicyHeader, requiresRouteCacheabilityProbeManifest, resolveVinextPrerenderDecision, supportsCanonicalRscWarmup } from "vinext/internal/config/prerender";
|
|
25
27
|
import { detectProject, findInNodeModules, formatMissingCloudflarePluginError, getMissingDeps } from "vinext/internal/utils/project";
|
|
26
28
|
import { PHASE_PRODUCTION_BUILD } from "vinext/shims/constants";
|
|
27
29
|
//#region src/deploy.ts
|
|
@@ -71,6 +73,7 @@ function formatUnknownError(error) {
|
|
|
71
73
|
if (error instanceof Error && error.message) return error.message;
|
|
72
74
|
return String(error);
|
|
73
75
|
}
|
|
76
|
+
var StagedWarmupError = class extends Error {};
|
|
74
77
|
/** Deploy command flag definitions for util.parseArgs. */
|
|
75
78
|
const deployArgOptions = {
|
|
76
79
|
help: {
|
|
@@ -126,6 +129,10 @@ const deployArgOptions = {
|
|
|
126
129
|
type: "boolean",
|
|
127
130
|
default: false
|
|
128
131
|
},
|
|
132
|
+
"no-promote": {
|
|
133
|
+
type: "boolean",
|
|
134
|
+
default: false
|
|
135
|
+
},
|
|
129
136
|
"warm-cdn-no-promote": {
|
|
130
137
|
type: "boolean",
|
|
131
138
|
default: false
|
|
@@ -135,6 +142,13 @@ const deployArgOptions = {
|
|
|
135
142
|
type: "boolean",
|
|
136
143
|
default: false
|
|
137
144
|
},
|
|
145
|
+
"experimental-traffic-aware-warm-cache": {
|
|
146
|
+
type: "boolean",
|
|
147
|
+
default: false
|
|
148
|
+
},
|
|
149
|
+
"traffic-aware-coverage": { type: "string" },
|
|
150
|
+
"traffic-aware-limit": { type: "string" },
|
|
151
|
+
"traffic-aware-window": { type: "string" },
|
|
138
152
|
"experimental-tpr": {
|
|
139
153
|
type: "boolean",
|
|
140
154
|
default: false
|
|
@@ -186,13 +200,13 @@ function parseDeployArgs(args) {
|
|
|
186
200
|
warmCdnReadinessProbes: values["warm-cdn-readiness-probes"] === void 0 ? void 0 : parsePositiveIntegerArg(values["warm-cdn-readiness-probes"], "--warm-cdn-readiness-probes"),
|
|
187
201
|
warmCdnReadinessProbeDelay: values["warm-cdn-readiness-probe-delay"] === void 0 ? void 0 : validateTimerDelay(parseNonNegativeIntegerArg(values["warm-cdn-readiness-probe-delay"], "--warm-cdn-readiness-probe-delay"), "--warm-cdn-readiness-probe-delay", values["warm-cdn-readiness-probe-delay"]),
|
|
188
202
|
dangerouslyPromoteOnCdnWarmError: values["dangerously-promote-on-cdn-warm-error"],
|
|
189
|
-
warmCdnPromote: !values["warm-cdn-no-promote"],
|
|
203
|
+
warmCdnPromote: !values["no-promote"] && !values["warm-cdn-no-promote"],
|
|
190
204
|
warmCdnPromotionDelay: values["warm-cdn-promotion-delay"] === void 0 ? void 0 : validatePromotionDelay(parseNonNegativeIntegerArg(values["warm-cdn-promotion-delay"], "--warm-cdn-promotion-delay"), values["warm-cdn-promotion-delay"]),
|
|
191
205
|
warmCdnIncludeFallbacks: values["warm-cdn-include-fallbacks"],
|
|
192
|
-
experimentalTPR: values["experimental-tpr"],
|
|
193
|
-
tprCoverage: parseIntArg("
|
|
194
|
-
tprLimit: parseIntArg("
|
|
195
|
-
tprWindow: parseIntArg("
|
|
206
|
+
experimentalTPR: values["experimental-traffic-aware-warm-cache"] || values["experimental-tpr"],
|
|
207
|
+
tprCoverage: parseIntArg("traffic-aware-coverage", values["traffic-aware-coverage"] ?? values["tpr-coverage"]),
|
|
208
|
+
tprLimit: parseIntArg("traffic-aware-limit", values["traffic-aware-limit"] ?? values["tpr-limit"]),
|
|
209
|
+
tprWindow: parseIntArg("traffic-aware-window", values["traffic-aware-window"] ?? values["tpr-window"])
|
|
196
210
|
};
|
|
197
211
|
}
|
|
198
212
|
/**
|
|
@@ -234,7 +248,8 @@ async function loadProjectWranglerApi(root) {
|
|
|
234
248
|
try {
|
|
235
249
|
wranglerPath = req.resolve("wrangler");
|
|
236
250
|
} catch {
|
|
237
|
-
|
|
251
|
+
const cloudflarePluginPath = req.resolve("@cloudflare/vite-plugin");
|
|
252
|
+
wranglerPath = createRequire(cloudflarePluginPath).resolve("wrangler");
|
|
238
253
|
}
|
|
239
254
|
return await import(
|
|
240
255
|
/* @vite-ignore */
|
|
@@ -386,6 +401,7 @@ async function runWranglerKVBulkPut(root, options, execute = spawn, nodeExecutab
|
|
|
386
401
|
}
|
|
387
402
|
}
|
|
388
403
|
async function runWranglerDeploy(root, options, execute = spawn) {
|
|
404
|
+
if (options.promote === false) return runWranglerVersionUpload(root, options).previewUrl ?? "(Preview URL not detected in wrangler output)";
|
|
389
405
|
const spawnOptions = {
|
|
390
406
|
cwd: root,
|
|
391
407
|
stdio: [
|
|
@@ -426,12 +442,50 @@ async function runWranglerDeploy(root, options, execute = spawn) {
|
|
|
426
442
|
function hasCdnWarmRequests(plan) {
|
|
427
443
|
return plan.paths.length + (plan.pagesDataPaths?.length ?? 0) + (plan.routeHandlerPaths?.length ?? 0) + plan.rscPaths.length + plan.loadingShellPaths.length > 0;
|
|
428
444
|
}
|
|
445
|
+
function selectTPRWarmPlan(plan, traffic, coverage, limit) {
|
|
446
|
+
const canonical = (pathname) => normalizePathTrailingSlash(pathname, false);
|
|
447
|
+
const resolved = new Set(Object.entries(plan.routePatterns ?? {}).map(([pathname, route]) => canonical(route.cacheabilityProbe?.concretePathname ?? pathname)));
|
|
448
|
+
const requestsByPath = /* @__PURE__ */ new Map();
|
|
449
|
+
for (const { path, requests } of traffic) {
|
|
450
|
+
const pathname = canonical(path);
|
|
451
|
+
if (!resolved.has(pathname)) continue;
|
|
452
|
+
requestsByPath.set(pathname, (requestsByPath.get(pathname) ?? 0) + requests);
|
|
453
|
+
}
|
|
454
|
+
const selected = new Set(selectRoutes(Array.from(requestsByPath, ([path, requests]) => ({
|
|
455
|
+
path,
|
|
456
|
+
requests
|
|
457
|
+
})).sort((a, b) => b.requests - a.requests), coverage, limit).routes.map(({ path }) => path));
|
|
458
|
+
const includes = (pathname) => selected.has(canonical(plan.routePatterns?.[pathname]?.cacheabilityProbe?.concretePathname ?? pathname));
|
|
459
|
+
const filter = (pathnames) => pathnames?.filter(includes);
|
|
460
|
+
return {
|
|
461
|
+
...plan,
|
|
462
|
+
appPaths: filter(plan.appPaths),
|
|
463
|
+
loadingShellPaths: filter(plan.loadingShellPaths) ?? [],
|
|
464
|
+
pagesDataPaths: filter(plan.pagesDataPaths),
|
|
465
|
+
pagesPaths: filter(plan.pagesPaths),
|
|
466
|
+
paths: filter(plan.paths) ?? [],
|
|
467
|
+
routeHandlerPaths: filter(plan.routeHandlerPaths),
|
|
468
|
+
routePatterns: plan.routePatterns ? Object.fromEntries(Object.entries(plan.routePatterns).filter(([pathname]) => includes(pathname))) : void 0,
|
|
469
|
+
rscPaths: filter(plan.rscPaths) ?? []
|
|
470
|
+
};
|
|
471
|
+
}
|
|
429
472
|
function projectRequiresRouteCacheabilityProbeManifest(project, cacheConfig) {
|
|
430
473
|
return (project.isAppRouter || project.isPagesRouter) && requiresRouteCacheabilityProbeManifest(cacheConfig);
|
|
431
474
|
}
|
|
432
475
|
function cdnWarmTargetKey(target) {
|
|
433
476
|
return `${target.kind}\0${target.sourcePathname}`;
|
|
434
477
|
}
|
|
478
|
+
function requiredCdnWarmTargetKeys(plan, optionalTargetKeys) {
|
|
479
|
+
const keys = /* @__PURE__ */ new Set([
|
|
480
|
+
...plan.paths.map((pathname) => `html\0${pathname}`),
|
|
481
|
+
...plan.pagesDataPaths.map((pathname) => `pages-data\0${pathname}`),
|
|
482
|
+
...(plan.routeHandlerPaths ?? []).map((pathname) => `app-route\0${pathname}`),
|
|
483
|
+
...plan.rscPaths.map((pathname) => `rsc-full\0${pathname}`),
|
|
484
|
+
...plan.loadingShellPaths.map((pathname) => `rsc-loading-shell\0${pathname}`)
|
|
485
|
+
]);
|
|
486
|
+
if (optionalTargetKeys) for (const key of optionalTargetKeys) keys.delete(key);
|
|
487
|
+
return keys;
|
|
488
|
+
}
|
|
435
489
|
async function deployWithCdnWarmup(root, paths, options) {
|
|
436
490
|
if (options.warmCdnTarget !== void 0) options = {
|
|
437
491
|
...options,
|
|
@@ -481,10 +535,11 @@ async function deployUploadedVersionWithCdnWarmup(root, paths, options) {
|
|
|
481
535
|
};
|
|
482
536
|
const discoverWarmPlan = async (targetUrl, headers) => {
|
|
483
537
|
if (!options.discoverWarmPlan) return;
|
|
484
|
-
const
|
|
538
|
+
const discovered = await options.discoverWarmPlan({
|
|
485
539
|
headers,
|
|
486
540
|
targetUrl
|
|
487
541
|
});
|
|
542
|
+
const plan = options.selectWarmPlan?.(discovered) ?? discovered;
|
|
488
543
|
deploymentId = plan.deploymentId;
|
|
489
544
|
expectedBuildId = plan.buildIdentity;
|
|
490
545
|
expectedRscBuildId = plan.rscBuildId;
|
|
@@ -524,14 +579,22 @@ async function deployUploadedVersionWithCdnWarmup(root, paths, options) {
|
|
|
524
579
|
concurrency: options.warmCdnConcurrency,
|
|
525
580
|
timeoutMs: options.warmCdnTimeout,
|
|
526
581
|
retries: options.warmCdnRetries,
|
|
582
|
+
retrySkippedTargetKeys: propagatingTarget && hasPreparedWarmPlan ? requiredCdnWarmTargetKeys(plan, options.optionalWarmTargetKeys) : void 0,
|
|
527
583
|
requireCacheHit,
|
|
528
|
-
strict: requireCacheHit || !allowUnverifiedPromotion
|
|
584
|
+
strict: requireCacheHit || !allowUnverifiedPromotion,
|
|
585
|
+
statusSource: options.statusSource
|
|
529
586
|
});
|
|
530
587
|
const wranglerConfig = parseWranglerConfig(root, options.config);
|
|
531
|
-
|
|
532
|
-
|
|
588
|
+
let deploymentStatus;
|
|
589
|
+
try {
|
|
590
|
+
deploymentStatus = runWranglerDeploymentStatus(root, options);
|
|
591
|
+
} catch (error) {
|
|
592
|
+
if (!hasPreparedWarmPlan) throw error;
|
|
593
|
+
throw new StagedWarmupError(formatUnknownError(error), { cause: error });
|
|
594
|
+
}
|
|
595
|
+
if (options.expectedDeploymentState && !deploymentStateEquals(deploymentStatus, options.expectedDeploymentState)) throw new StagedWarmupError("Two-stage CDN warming stopped because Worker deployment traffic or deployment identity changed before the final version could be staged. No final version was promoted.");
|
|
533
596
|
const stagingTraffic = getZeroPercentStagingTraffic(deploymentStatus, upload.versionId);
|
|
534
|
-
if (hasPreparedWarmPlan && !stagingTraffic) throw new
|
|
597
|
+
if (hasPreparedWarmPlan && !stagingTraffic) throw new StagedWarmupError("Two-stage CDN warming stopped because Worker deployment traffic changed before the final version could be staged. No final version was promoted.");
|
|
535
598
|
let staged = null;
|
|
536
599
|
let triggersDeployedUrl = options.triggersDeployedUrl ?? null;
|
|
537
600
|
let stagedCacheFilled = false;
|
|
@@ -577,6 +640,7 @@ async function deployUploadedVersionWithCdnWarmup(root, paths, options) {
|
|
|
577
640
|
pagesDataPaths: remainingWarmPlan.pagesDataPaths,
|
|
578
641
|
paths: remainingWarmPlan.paths,
|
|
579
642
|
routeHandlerPaths: remainingWarmPlan.routeHandlerPaths,
|
|
643
|
+
routePatterns: remainingWarmPlan.routePatterns,
|
|
580
644
|
rscPaths: remainingWarmPlan.rscPaths
|
|
581
645
|
};
|
|
582
646
|
const stagedWarmRequests = stagedWarmPlan.paths.length + stagedWarmPlan.pagesDataPaths.length + (stagedWarmPlan.routeHandlerPaths?.length ?? 0) + stagedWarmPlan.rscPaths.length + stagedWarmPlan.loadingShellPaths.length;
|
|
@@ -622,7 +686,7 @@ async function deployUploadedVersionWithCdnWarmup(root, paths, options) {
|
|
|
622
686
|
routeHandlerPaths: warmResult.retryPlan.routeHandlerPaths,
|
|
623
687
|
rscPaths: warmResult.retryPlan.rscPaths
|
|
624
688
|
};
|
|
625
|
-
if (
|
|
689
|
+
if (options.warmCdnCertify && warmResult.warmed > 0) {
|
|
626
690
|
console.log(` CDN warmup: certifying ${warmResult.warmed} staged cache entr${warmResult.warmed === 1 ? "y" : "ies"} before promotion...`);
|
|
627
691
|
const certification = await warmUploadedVersion(targetUrl, headers, true, warmResult.warmedPlan, true);
|
|
628
692
|
if (certification.warmed !== warmResult.warmed) throw new Error(`CDN warmup certified ${certification.warmed}/${warmResult.warmed} staged cache entries as reusable.`);
|
|
@@ -635,7 +699,7 @@ async function deployUploadedVersionWithCdnWarmup(root, paths, options) {
|
|
|
635
699
|
}
|
|
636
700
|
else if (initialWarmRequests > 0) {
|
|
637
701
|
const message = "CDN warmup failed: pre-traffic warmup needs a production URL and Worker name for version overrides. Configure a route/custom domain and Worker name, or deploy without --experimental-warm-cdn-cache.";
|
|
638
|
-
if (!allowUnverifiedPromotion) throw new
|
|
702
|
+
if (!allowUnverifiedPromotion) throw new StagedWarmupError(`${message} ${getStagedVersionCleanupNote()}`);
|
|
639
703
|
console.warn(` ${message} Promoting because the dangerous override is enabled.`);
|
|
640
704
|
}
|
|
641
705
|
} else {
|
|
@@ -650,19 +714,18 @@ async function deployUploadedVersionWithCdnWarmup(root, paths, options) {
|
|
|
650
714
|
if (options.warmCdnPromote === false) {
|
|
651
715
|
if (!staged) throw new Error("CDN warmup cannot skip promotion because the uploaded Worker version could not be staged at 0% traffic. The current deployment must have exactly one version serving 100% traffic.");
|
|
652
716
|
const remainingWarmRequests = countRemainingWarmRequests();
|
|
653
|
-
if (!hasPreparedWarmPlan && options.discoverWarmPlan && discoveredWarmRequests === 0) throw withStagedVersionCleanupNote(/* @__PURE__ */ new Error("CDN warmup cannot skip promotion because no build-discovered requests were found to warm."));
|
|
717
|
+
if (!options.allowEmptyWarmPlan && !hasPreparedWarmPlan && options.discoverWarmPlan && discoveredWarmRequests === 0) throw withStagedVersionCleanupNote(/* @__PURE__ */ new Error("CDN warmup cannot skip promotion because no build-discovered requests were found to warm."));
|
|
654
718
|
if (remainingWarmRequests > 0) throw withStagedVersionCleanupNote(/* @__PURE__ */ new Error(`CDN warmup cannot skip promotion because ${remainingWarmRequests} request(s) remain unwarmed.`));
|
|
655
719
|
if (hasPreparedWarmPlan && stagedDeploymentState) {
|
|
656
720
|
let currentDeployment;
|
|
657
721
|
try {
|
|
658
722
|
currentDeployment = runWranglerDeploymentStatus(root, options);
|
|
659
723
|
} catch (error) {
|
|
660
|
-
|
|
661
|
-
throw new Error(`${message} CDN warmup cannot confirm that the uploaded Worker remains staged at 0% traffic; production Worker triggers/routes remain applied. Inspect \`wrangler deployments status\` before continuing.`, { cause: error });
|
|
724
|
+
throw new StagedWarmupError(`${error instanceof Error ? error.message : String(error)} CDN warmup cannot confirm that the uploaded Worker remains staged at 0% traffic; production Worker triggers/routes remain applied. Inspect \`wrangler deployments status\` before continuing.`, { cause: error });
|
|
662
725
|
}
|
|
663
|
-
if (!deploymentStateEquals(currentDeployment, stagedDeploymentState)) throw new
|
|
726
|
+
if (!deploymentStateEquals(currentDeployment, stagedDeploymentState)) throw new StagedWarmupError("Two-stage CDN warming stopped because Worker deployment traffic or deployment identity changed before the no-promote handoff. The uploaded Worker is not confirmed staged at 0% traffic; production Worker triggers/routes remain applied.");
|
|
664
727
|
}
|
|
665
|
-
console.log(
|
|
728
|
+
console.log(` CDN warmup: promotion disabled; uploaded Worker version ${upload.versionId} remains staged at 0% traffic and production Worker triggers/routes remain applied.`);
|
|
666
729
|
return staged.deployedUrl ?? triggersDeployedUrl ?? upload.previewUrl ?? "(URL not detected in wrangler output)";
|
|
667
730
|
}
|
|
668
731
|
let deployed;
|
|
@@ -673,7 +736,7 @@ async function deployUploadedVersionWithCdnWarmup(root, paths, options) {
|
|
|
673
736
|
}];
|
|
674
737
|
let promotionAttempted = false;
|
|
675
738
|
try {
|
|
676
|
-
if (stagedCacheFilled) {
|
|
739
|
+
if (stagedCacheFilled && options.statusSource !== "vinext") {
|
|
677
740
|
const promotionDelay = options.warmCdnPromotionDelay ?? 15e3;
|
|
678
741
|
if (promotionDelay > 0) {
|
|
679
742
|
console.log(` CDN warmup: waiting ${promotionDelay / 1e3} seconds for cache propagation before promotion...`);
|
|
@@ -737,15 +800,19 @@ function deploymentStateEquals(actual, expected) {
|
|
|
737
800
|
function reconcileVersionDeployFailure(root, options, error, expected) {
|
|
738
801
|
const message = error instanceof Error ? error.message : String(error);
|
|
739
802
|
let reconciliation;
|
|
803
|
+
let mayNeedCleanup = true;
|
|
740
804
|
try {
|
|
741
805
|
const current = runWranglerDeploymentStatus(root, options);
|
|
742
806
|
if (deploymentTrafficEquals(current.versions, expected.desiredTraffic)) reconciliation = expected.desiredDescription;
|
|
743
|
-
else if (deploymentStateEquals(current, expected.priorState))
|
|
744
|
-
|
|
807
|
+
else if (deploymentStateEquals(current, expected.priorState)) {
|
|
808
|
+
reconciliation = expected.priorDescription;
|
|
809
|
+
mayNeedCleanup = false;
|
|
810
|
+
} else reconciliation = "Worker deployment state differs from both the requested and prior state, so the deployment outcome is unknown or another deployment changed it.";
|
|
745
811
|
} catch (reconciliationError) {
|
|
746
812
|
reconciliation = `Worker deployment status could not be read after the command failed, so the deployment outcome is unknown (${reconciliationError instanceof Error ? reconciliationError.message : String(reconciliationError)}).`;
|
|
747
813
|
}
|
|
748
|
-
|
|
814
|
+
const detail = `${message} ${reconciliation}`;
|
|
815
|
+
return mayNeedCleanup ? new StagedWarmupError(detail, { cause: error }) : new Error(detail, { cause: error });
|
|
749
816
|
}
|
|
750
817
|
function assertDeploymentStateUnchanged(root, options, expected, message) {
|
|
751
818
|
if (!deploymentStateEquals(runWranglerDeploymentStatus(root, options), expected)) throw new Error(message);
|
|
@@ -773,8 +840,7 @@ async function deployWithCacheabilityProbe(root, options) {
|
|
|
773
840
|
stagedProbeDeployment = runWranglerDeploymentStatus(root, options);
|
|
774
841
|
if (!deploymentTrafficEquals(stagedProbeDeployment.versions, probeTraffic)) throw new Error("Two-stage CDN warming stopped because Worker deployment traffic changed immediately after the probe version was staged.");
|
|
775
842
|
} catch (error) {
|
|
776
|
-
|
|
777
|
-
throw new Error(`${message} The probe staging command completed, but its current deployment state could not be confirmed; production Worker triggers/routes were not changed. Inspect \`wrangler deployments status\` and remove the staged probe version if necessary.`, { cause: error });
|
|
843
|
+
throw new StagedWarmupError(`${error instanceof Error ? error.message : String(error)} The probe staging command completed, but its current deployment state could not be confirmed; production Worker triggers/routes were not changed. Inspect \`wrangler deployments status\` and remove the staged probe version if necessary.`, { cause: error });
|
|
778
844
|
}
|
|
779
845
|
let prepared;
|
|
780
846
|
try {
|
|
@@ -870,9 +936,11 @@ async function deployWithCacheabilityProbe(root, options) {
|
|
|
870
936
|
routeHandlerPaths: probe.cacheableTargets.filter((target) => target.kind === "app-route").map((target) => target.sourcePathname),
|
|
871
937
|
rscPaths: probe.cacheableTargets.filter((target) => target.kind === "rsc-full").map((target) => target.sourcePathname)
|
|
872
938
|
};
|
|
939
|
+
const selectedFinalPlan = options.selectWarmPlan?.(finalPlan) ?? finalPlan;
|
|
873
940
|
assertDeploymentStateUnchanged(root, options, stagedProbeDeployment, "Two-stage CDN warming stopped because Worker deployment traffic or deployment identity changed while cacheability was being probed. No final version was promoted.");
|
|
941
|
+
const finalConfig = writeCacheabilityManifestArtifact(root, options.config, probe.manifest);
|
|
874
942
|
const finalUpload = runWranglerVersionUpload(root, {
|
|
875
|
-
config:
|
|
943
|
+
config: finalConfig,
|
|
876
944
|
env: options.env,
|
|
877
945
|
name: options.name,
|
|
878
946
|
preview: options.preview,
|
|
@@ -881,7 +949,7 @@ async function deployWithCacheabilityProbe(root, options) {
|
|
|
881
949
|
prepared = {
|
|
882
950
|
optionalWarmTargetKeys: new Set(probe.speculativeTargets.map(cdnWarmTargetKey)),
|
|
883
951
|
prerenderSecret,
|
|
884
|
-
plan:
|
|
952
|
+
plan: selectedFinalPlan,
|
|
885
953
|
upload: finalUpload
|
|
886
954
|
};
|
|
887
955
|
} catch (error) {
|
|
@@ -936,12 +1004,10 @@ function buildVersionOverrideHeaders(workerName, versionId) {
|
|
|
936
1004
|
};
|
|
937
1005
|
}
|
|
938
1006
|
function withStagedVersionCleanupNote(error) {
|
|
939
|
-
|
|
940
|
-
return new Error(`${message} ${getStagedVersionCleanupNote()}`, { cause: error });
|
|
1007
|
+
return new StagedWarmupError(`${error instanceof Error ? error.message : String(error)} ${getStagedVersionCleanupNote()}`, { cause: error });
|
|
941
1008
|
}
|
|
942
1009
|
function withStagedProbeVersionCleanupNote(error) {
|
|
943
|
-
|
|
944
|
-
return new Error(`${message} The probe version may remain staged at 0% with the previous version still serving 100% traffic; production Worker triggers/routes were not changed.`, { cause: error });
|
|
1010
|
+
return new StagedWarmupError(`${error instanceof Error ? error.message : String(error)} The probe version may remain staged at 0% with the previous version still serving 100% traffic; production Worker triggers/routes were not changed.`, { cause: error });
|
|
945
1011
|
}
|
|
946
1012
|
function getStagedVersionCleanupNote() {
|
|
947
1013
|
return "The uploaded version may remain staged at 0% with the previous version still serving 100% traffic; Worker triggers/routes may also have changed because trigger deployment runs before warming. Rerun deploy to promote it or use `wrangler versions deploy` to choose the desired version split.";
|
|
@@ -994,7 +1060,8 @@ async function deploy(options) {
|
|
|
994
1060
|
const cdnAdapterConfig = resolveCdnAdapterConfig(viteConfigMetadata.cacheConfig);
|
|
995
1061
|
const nextConfig = await withCloudflareEnv(buildEnv, async () => {
|
|
996
1062
|
const inlineNextConfig = viteConfigMetadata.nextConfig;
|
|
997
|
-
|
|
1063
|
+
const rawNextConfig = inlineNextConfig ? await resolveNextConfigInput(inlineNextConfig, PHASE_PRODUCTION_BUILD) : await loadNextConfig(info.root, PHASE_PRODUCTION_BUILD);
|
|
1064
|
+
return resolveNextConfig(rawNextConfig, info.root);
|
|
998
1065
|
});
|
|
999
1066
|
const vinextPrerenderConfig = !options.prerenderAll && nextConfig.output !== "export" ? viteConfigMetadata.prerenderConfig : null;
|
|
1000
1067
|
const prerenderDecision = resolveVinextPrerenderDecision({
|
|
@@ -1003,12 +1070,46 @@ async function deploy(options) {
|
|
|
1003
1070
|
nextOutput: nextConfig.output
|
|
1004
1071
|
});
|
|
1005
1072
|
const hasStrictResponseVary = hasVerbatimResponseVary(viteConfigMetadata.cacheConfig);
|
|
1073
|
+
const warmupStatusSource = cacheWarmupStatusSource(viteConfigMetadata.cacheConfig);
|
|
1074
|
+
const hasStagedRequestRouting = hasUncachedRequestRouting(viteConfigMetadata.cacheConfig) || warmupStatusSource === "data-cache";
|
|
1006
1075
|
const hasBuildIdentityHeader = hasBuildIdentityResponseHeader(viteConfigMetadata.cacheConfig);
|
|
1076
|
+
const hasCanonicalRscWarmup = supportsCanonicalRscWarmup(viteConfigMetadata.cacheConfig);
|
|
1007
1077
|
const needsCacheabilityProbeManifest = projectRequiresRouteCacheabilityProbeManifest(info, viteConfigMetadata.cacheConfig);
|
|
1008
1078
|
const shouldEmitPrerenderPathManifest = !options.skipBuild && prerenderDecision;
|
|
1009
1079
|
if (!options.skipBuild) await runBuild(info, buildEnv);
|
|
1010
1080
|
else console.log("\n Skipping build (--skip-build)");
|
|
1011
|
-
|
|
1081
|
+
const canWarmTpr = options.experimentalTPR && !prerenderDecision && hasBuildIdentityHeader;
|
|
1082
|
+
if (options.experimentalTPR && prerenderDecision) console.log(" TPR: Skipping route selection (all-route prerendering configured)");
|
|
1083
|
+
else if (options.experimentalTPR && !hasBuildIdentityHeader) console.log(workerEntryHasCacheHandler(root) ? " TPR: Skipping pre-warm (legacy imperative cache handlers must migrate to declarative vinext({ cache }) for standard warming)" : " TPR: Skipping pre-warm (configured cache does not expose build identity)");
|
|
1084
|
+
const tpr = canWarmTpr ? await resolveTPRRoutes({
|
|
1085
|
+
root,
|
|
1086
|
+
config: options.config,
|
|
1087
|
+
env: buildEnv,
|
|
1088
|
+
hostname: warmCdnTarget ? new URL(warmCdnTarget).hostname : void 0,
|
|
1089
|
+
window: Math.max(1, options.tprWindow ?? 24)
|
|
1090
|
+
}) : null;
|
|
1091
|
+
if (tpr?.skipped) console.log(` TPR: Skipped (${tpr.skipped})`);
|
|
1092
|
+
const tprRoutes = tpr?.routes ?? [];
|
|
1093
|
+
const wranglerOptions = {
|
|
1094
|
+
env: deployEnv === "production" && !options.env ? void 0 : deployEnv,
|
|
1095
|
+
name: options.name,
|
|
1096
|
+
config: options.config,
|
|
1097
|
+
verbose: options.verbose
|
|
1098
|
+
};
|
|
1099
|
+
let shouldWarmTpr = tprRoutes.length > 0;
|
|
1100
|
+
if (shouldWarmTpr && !options.warmCdnCache) {
|
|
1101
|
+
try {
|
|
1102
|
+
shouldWarmTpr = getZeroPercentStagingTraffic(runWranglerDeploymentStatus(root, wranglerOptions), "tpr-preflight") !== null;
|
|
1103
|
+
} catch {
|
|
1104
|
+
shouldWarmTpr = false;
|
|
1105
|
+
}
|
|
1106
|
+
if (!shouldWarmTpr) console.log(" TPR: Skipping pre-warm (current deployment cannot be staged safely)");
|
|
1107
|
+
}
|
|
1108
|
+
const shouldWarmCdnCache = options.warmCdnCache || shouldWarmTpr;
|
|
1109
|
+
const shouldSelectTpr = shouldWarmTpr && !options.warmCdnCache;
|
|
1110
|
+
const candidatePathsOnly = shouldSelectTpr && !needsCacheabilityProbeManifest;
|
|
1111
|
+
const shouldPrerenderLocally = prerenderDecision && (!shouldWarmCdnCache || prerenderDecision.reason === "next-export");
|
|
1112
|
+
if (shouldWarmCdnCache && cdnAdapterConfig) {
|
|
1012
1113
|
const wrangler = await loadProjectWranglerApi(info.root);
|
|
1013
1114
|
const previousCwd = process.cwd();
|
|
1014
1115
|
try {
|
|
@@ -1034,11 +1135,13 @@ async function deploy(options) {
|
|
|
1034
1135
|
root: info.root,
|
|
1035
1136
|
nextConfig,
|
|
1036
1137
|
buildIdentity: hasBuildIdentityHeader ? "response-header" : void 0,
|
|
1138
|
+
requestRouting: hasStagedRequestRouting ? "uncached-stage" : void 0,
|
|
1037
1139
|
responseVary: hasStrictResponseVary ? "verbatim" : void 0,
|
|
1140
|
+
isResponsePolicyHeader: (name) => isConfiguredCdnResponsePolicyHeader(viteConfigMetadata.cacheConfig, name),
|
|
1038
1141
|
routeRootConfig: viteConfigMetadata.routeRootConfig
|
|
1039
1142
|
});
|
|
1040
1143
|
let ranPrerender = false;
|
|
1041
|
-
if (
|
|
1144
|
+
if (shouldPrerenderLocally) {
|
|
1042
1145
|
console.log(`\n ${formatVinextPrerenderLabel(prerenderDecision)}`);
|
|
1043
1146
|
if (nextConfig.enablePrerenderSourceMaps) {
|
|
1044
1147
|
process.setSourceMapsEnabled(true);
|
|
@@ -1047,7 +1150,8 @@ async function deploy(options) {
|
|
|
1047
1150
|
await runPrerender({
|
|
1048
1151
|
root: info.root,
|
|
1049
1152
|
concurrency: options.prerenderConcurrency,
|
|
1050
|
-
nextConfig
|
|
1153
|
+
nextConfig,
|
|
1154
|
+
routeRootConfig: viteConfigMetadata.routeRootConfig
|
|
1051
1155
|
});
|
|
1052
1156
|
ranPrerender = true;
|
|
1053
1157
|
}
|
|
@@ -1056,68 +1160,73 @@ async function deploy(options) {
|
|
|
1056
1160
|
} catch (error) {
|
|
1057
1161
|
console.log(` KV cache: Skipping prerender upload (${formatUnknownError(error)}). Continuing with deploy.`);
|
|
1058
1162
|
}
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1163
|
+
let url;
|
|
1164
|
+
if (shouldWarmCdnCache) try {
|
|
1165
|
+
url = await deployWithCdnWarmup(root, [], {
|
|
1166
|
+
...wranglerOptions,
|
|
1167
|
+
allowEmptyWarmPlan: tprRoutes.length > 0 && !options.warmCdnCache,
|
|
1168
|
+
cacheabilityProbe: needsCacheabilityProbeManifest,
|
|
1169
|
+
discoverWarmPlan: async ({ headers, targetUrl }) => {
|
|
1170
|
+
const discovery = await discoverPrerenderPathManifest({
|
|
1171
|
+
root: info.root,
|
|
1172
|
+
candidatePaths: tprRoutes.map(({ path }) => path),
|
|
1173
|
+
candidatePathsOnly,
|
|
1174
|
+
nextConfig,
|
|
1175
|
+
buildIdentity: hasBuildIdentityHeader ? "response-header" : void 0,
|
|
1176
|
+
includeCanonicalRsc: hasCanonicalRscWarmup,
|
|
1177
|
+
requestRouting: hasStagedRequestRouting ? "uncached-stage" : void 0,
|
|
1178
|
+
responseVary: hasStrictResponseVary ? "verbatim" : void 0,
|
|
1179
|
+
isResponsePolicyHeader: (name) => isConfiguredCdnResponsePolicyHeader(viteConfigMetadata.cacheConfig, name),
|
|
1180
|
+
routeRootConfig: viteConfigMetadata.routeRootConfig,
|
|
1181
|
+
pathDiscoveryTarget: {
|
|
1182
|
+
baseUrl: targetUrl,
|
|
1183
|
+
headers,
|
|
1184
|
+
phaseTimeoutMs: options.warmCdnDiscoveryTimeout ?? DEFAULT_REMOTE_PATH_DISCOVERY_PHASE_TIMEOUT_MS,
|
|
1185
|
+
retries: options.warmCdnDiscoveryRetries,
|
|
1186
|
+
retryDelayMs: DEFAULT_REMOTE_PATH_DISCOVERY_RETRY_DELAY_MS
|
|
1187
|
+
}
|
|
1188
|
+
});
|
|
1189
|
+
if (!discovery) return {
|
|
1190
|
+
loadingShellPaths: [],
|
|
1191
|
+
paths: [],
|
|
1192
|
+
rscPaths: []
|
|
1193
|
+
};
|
|
1194
|
+
return createPrerenderWarmPlan(root, discovery, {
|
|
1195
|
+
includeCanonicalRsc: hasCanonicalRscWarmup,
|
|
1196
|
+
includeFallbackShells: options.warmCdnIncludeFallbacks,
|
|
1197
|
+
strict: options.warmCdnCertify === true || !options.dangerouslyPromoteOnCdnWarmError
|
|
1198
|
+
});
|
|
1199
|
+
},
|
|
1200
|
+
selectWarmPlan: shouldSelectTpr ? (plan) => selectTPRWarmPlan(plan, tprRoutes, Math.max(1, Math.min(100, options.tprCoverage ?? 90)), Math.max(1, options.tprLimit ?? 1e3)) : void 0,
|
|
1201
|
+
statusSource: warmupStatusSource,
|
|
1202
|
+
warmCdnConcurrency: options.warmCdnConcurrency,
|
|
1203
|
+
warmCdnTarget,
|
|
1204
|
+
warmCdnTimeout: options.warmCdnTimeout,
|
|
1205
|
+
warmCdnRetries: options.warmCdnRetries,
|
|
1206
|
+
warmCdnDiscoveryTimeout: options.warmCdnDiscoveryTimeout,
|
|
1207
|
+
warmCdnDiscoveryRetries: options.warmCdnDiscoveryRetries,
|
|
1208
|
+
warmCdnProbeTimeout: options.warmCdnProbeTimeout,
|
|
1209
|
+
warmCdnProbeRetries: options.warmCdnProbeRetries,
|
|
1210
|
+
warmCdnCertify: options.warmCdnCertify,
|
|
1211
|
+
warmCdnReadinessTimeout: options.warmCdnReadinessTimeout,
|
|
1212
|
+
warmCdnReadinessRetries: options.warmCdnReadinessRetries,
|
|
1213
|
+
warmCdnReadinessProbes: options.warmCdnReadinessProbes,
|
|
1214
|
+
warmCdnReadinessProbeDelay: options.warmCdnReadinessProbeDelay,
|
|
1215
|
+
dangerouslyPromoteOnCdnWarmError: options.dangerouslyPromoteOnCdnWarmError,
|
|
1216
|
+
warmCdnPromote: options.warmCdnPromote,
|
|
1217
|
+
warmCdnPromotionDelay: options.warmCdnPromotionDelay
|
|
1067
1218
|
});
|
|
1068
|
-
|
|
1219
|
+
} catch (error) {
|
|
1220
|
+
if (options.warmCdnCache || options.warmCdnPromote === false && error instanceof StagedWarmupError) throw error;
|
|
1221
|
+
console.log(` TPR: Skipping pre-warm (${formatUnknownError(error)}). Continuing with deploy.`);
|
|
1069
1222
|
}
|
|
1070
|
-
|
|
1071
|
-
env: deployEnv === "production" && !options.env ? void 0 : deployEnv,
|
|
1072
|
-
name: options.name,
|
|
1073
|
-
config: options.config,
|
|
1074
|
-
verbose: options.verbose
|
|
1075
|
-
};
|
|
1076
|
-
let url;
|
|
1077
|
-
if (options.warmCdnCache) url = await deployWithCdnWarmup(root, [], {
|
|
1223
|
+
if (url === void 0) url = await runWranglerDeploy(root, {
|
|
1078
1224
|
...wranglerOptions,
|
|
1079
|
-
|
|
1080
|
-
discoverWarmPlan: async ({ headers, targetUrl }) => {
|
|
1081
|
-
await emitPrerenderPathManifest({
|
|
1082
|
-
root: info.root,
|
|
1083
|
-
nextConfig,
|
|
1084
|
-
buildIdentity: hasBuildIdentityHeader ? "response-header" : void 0,
|
|
1085
|
-
responseVary: hasStrictResponseVary ? "verbatim" : void 0,
|
|
1086
|
-
routeRootConfig: viteConfigMetadata.routeRootConfig,
|
|
1087
|
-
pathDiscoveryTarget: {
|
|
1088
|
-
baseUrl: targetUrl,
|
|
1089
|
-
headers,
|
|
1090
|
-
phaseTimeoutMs: options.warmCdnDiscoveryTimeout ?? DEFAULT_REMOTE_PATH_DISCOVERY_PHASE_TIMEOUT_MS,
|
|
1091
|
-
retries: options.warmCdnDiscoveryRetries,
|
|
1092
|
-
retryDelayMs: DEFAULT_REMOTE_PATH_DISCOVERY_RETRY_DELAY_MS
|
|
1093
|
-
}
|
|
1094
|
-
});
|
|
1095
|
-
return readPrerenderWarmPlan(root, {
|
|
1096
|
-
includeFallbackShells: options.warmCdnIncludeFallbacks,
|
|
1097
|
-
strict: options.warmCdnCertify === true || !options.dangerouslyPromoteOnCdnWarmError
|
|
1098
|
-
});
|
|
1099
|
-
},
|
|
1100
|
-
warmCdnConcurrency: options.warmCdnConcurrency,
|
|
1101
|
-
warmCdnTarget,
|
|
1102
|
-
warmCdnTimeout: options.warmCdnTimeout,
|
|
1103
|
-
warmCdnRetries: options.warmCdnRetries,
|
|
1104
|
-
warmCdnDiscoveryTimeout: options.warmCdnDiscoveryTimeout,
|
|
1105
|
-
warmCdnDiscoveryRetries: options.warmCdnDiscoveryRetries,
|
|
1106
|
-
warmCdnProbeTimeout: options.warmCdnProbeTimeout,
|
|
1107
|
-
warmCdnProbeRetries: options.warmCdnProbeRetries,
|
|
1108
|
-
warmCdnCertify: options.warmCdnCertify,
|
|
1109
|
-
warmCdnReadinessTimeout: options.warmCdnReadinessTimeout,
|
|
1110
|
-
warmCdnReadinessRetries: options.warmCdnReadinessRetries,
|
|
1111
|
-
warmCdnReadinessProbes: options.warmCdnReadinessProbes,
|
|
1112
|
-
warmCdnReadinessProbeDelay: options.warmCdnReadinessProbeDelay,
|
|
1113
|
-
dangerouslyPromoteOnCdnWarmError: options.dangerouslyPromoteOnCdnWarmError,
|
|
1114
|
-
warmCdnPromote: options.warmCdnPromote,
|
|
1115
|
-
warmCdnPromotionDelay: options.warmCdnPromotionDelay
|
|
1225
|
+
promote: options.warmCdnPromote
|
|
1116
1226
|
});
|
|
1117
|
-
else url = await runWranglerDeploy(root, wranglerOptions);
|
|
1118
1227
|
console.log("\n ─────────────────────────────────────────");
|
|
1119
|
-
console.log(` Deployed to: ${url}`);
|
|
1228
|
+
console.log(` ${options.warmCdnPromote === false ? "Version URL" : "Deployed to"}: ${url}`);
|
|
1120
1229
|
console.log(" ─────────────────────────────────────────\n");
|
|
1121
1230
|
}
|
|
1122
1231
|
//#endregion
|
|
1123
|
-
export { DEFAULT_CDN_WARM_PROMOTION_DELAY_MS, buildNodeCliInvocation, buildVersionOverrideHeaders, buildWranglerDeployArgs, buildWranglerInvocation, buildWranglerKVBulkPutArgs, deploy, deployWithCdnWarmup, getZeroPercentStagingTraffic, hasCdnWarmRequests, parseDeployArgs, projectRequiresRouteCacheabilityProbeManifest, resolveCdnWarmupTargetUrl, resolveWorkerNameForVersionOverride, resolveWranglerBin, runWranglerDeploy, runWranglerKVBulkPut, validateWranglerEnvName, withCloudflareEnv };
|
|
1232
|
+
export { DEFAULT_CDN_WARM_PROMOTION_DELAY_MS, buildNodeCliInvocation, buildVersionOverrideHeaders, buildWranglerDeployArgs, buildWranglerInvocation, buildWranglerKVBulkPutArgs, deploy, deployWithCdnWarmup, getZeroPercentStagingTraffic, hasCdnWarmRequests, parseDeployArgs, projectRequiresRouteCacheabilityProbeManifest, resolveCdnWarmupTargetUrl, resolveWorkerNameForVersionOverride, resolveWranglerBin, runWranglerDeploy, runWranglerKVBulkPut, selectTPRWarmPlan, validateWranglerEnvName, withCloudflareEnv };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
//#region src/images/images-optimizer.d.ts
|
|
2
2
|
/** Options accepted by {@link imagesOptimizer}, forwarded to the runtime factory. */
|
|
3
|
-
type ImagesOptimizerOptions = {
|
|
3
|
+
export type ImagesOptimizerOptions = {
|
|
4
4
|
/** Cloudflare Images binding name on the Worker `env`. @default "IMAGES" */
|
|
5
5
|
binding?: string;
|
|
6
6
|
};
|
|
@@ -21,9 +21,8 @@ type ImagesOptimizerOptions = {
|
|
|
21
21
|
* plugins: [vinext({ images: { optimizer: imagesOptimizer() } })],
|
|
22
22
|
* });
|
|
23
23
|
*/
|
|
24
|
-
declare function imagesOptimizer(options?: ImagesOptimizerOptions): {
|
|
24
|
+
export declare function imagesOptimizer(options?: ImagesOptimizerOptions): {
|
|
25
25
|
adapter: string;
|
|
26
26
|
options: ImagesOptimizerOptions | undefined;
|
|
27
27
|
};
|
|
28
|
-
//#endregion
|
|
29
|
-
export { ImagesOptimizerOptions, imagesOptimizer };
|
|
28
|
+
//#endregion
|
|
@@ -7,13 +7,13 @@
|
|
|
7
7
|
* KVCacheEntry shape written by KVCacheHandler.set(), and returns Wrangler KV
|
|
8
8
|
* bulk import records for deploy-time upload.
|
|
9
9
|
*/
|
|
10
|
-
type KVBulkPair = {
|
|
10
|
+
export type KVBulkPair = {
|
|
11
11
|
key: string;
|
|
12
12
|
value: string;
|
|
13
13
|
expiration_ttl?: number;
|
|
14
14
|
metadata?: Record<string, unknown>;
|
|
15
15
|
};
|
|
16
|
-
declare function buildPrerenderKVPairs(serverDir: string, options?: {
|
|
16
|
+
export declare function buildPrerenderKVPairs(serverDir: string, options?: {
|
|
17
17
|
appPrefix?: string;
|
|
18
18
|
now?: number;
|
|
19
19
|
ttlSeconds?: number;
|
|
@@ -21,5 +21,4 @@ declare function buildPrerenderKVPairs(serverDir: string, options?: {
|
|
|
21
21
|
routeCount: number;
|
|
22
22
|
pairs: KVBulkPair[];
|
|
23
23
|
};
|
|
24
|
-
//#endregion
|
|
25
|
-
export { KVBulkPair, buildPrerenderKVPairs };
|
|
24
|
+
//#endregion
|
|
@@ -16,7 +16,7 @@ import { getAppRouteOutputPath, getOutputPath, getRscOutputPath } from "vinext/i
|
|
|
16
16
|
* bulk import records for deploy-time upload.
|
|
17
17
|
*/
|
|
18
18
|
/** Default KV expiration TTL used by KVCacheHandler for revalidating entries. */
|
|
19
|
-
const DEFAULT_KV_TTL_SECONDS =
|
|
19
|
+
const DEFAULT_KV_TTL_SECONDS = 2592e3;
|
|
20
20
|
function resolveContainedFile(rootDir, relativePath) {
|
|
21
21
|
const resolvedRoot = path.resolve(rootDir);
|
|
22
22
|
const resolvedFile = path.resolve(resolvedRoot, relativePath);
|
|
@@ -48,7 +48,8 @@ function buildMetadata(tags) {
|
|
|
48
48
|
return JSON.stringify(metadata).length <= 1024 ? metadata : void 0;
|
|
49
49
|
}
|
|
50
50
|
function buildPrerenderKVPairs(serverDir, options) {
|
|
51
|
-
const
|
|
51
|
+
const manifestPath = path.join(serverDir, "vinext-prerender.json");
|
|
52
|
+
const manifest = readPrerenderManifest(manifestPath);
|
|
52
53
|
if (!manifest?.buildId || !Array.isArray(manifest.routes)) return {
|
|
53
54
|
routeCount: 0,
|
|
54
55
|
pairs: []
|