@vinext/cloudflare 1.0.0-beta.10 → 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.
- package/README.md +105 -6
- package/dist/cache/cdn-adapter-config.d.ts +2 -1
- package/dist/cache/cdn-adapter-config.js +10 -2
- package/dist/cache/cdn-adapter.d.ts +8 -7
- package/dist/cache/cdn-adapter.js +8 -7
- package/dist/cache/cdn-build-id.d.ts +1 -1
- package/dist/cache/cdn-build-id.js +1 -1
- package/dist/cache/config.d.ts +137 -0
- package/dist/cache/config.js +87 -0
- package/dist/cacheability-artifact.d.ts +2 -1
- package/dist/cacheability-artifact.js +34 -10
- package/dist/deploy-config.d.ts +2 -1
- package/dist/deploy-config.js +3 -2
- package/dist/deploy-help.js +5 -5
- package/dist/deploy.d.ts +19 -2
- package/dist/deploy.js +245 -89
- package/dist/tpr.d.ts +2 -0
- package/dist/tpr.js +8 -4
- package/dist/version-deploy.d.ts +27 -0
- package/dist/version-deploy.js +121 -3
- package/package.json +10 -3
package/dist/deploy.js
CHANGED
|
@@ -7,7 +7,7 @@ import { VINEXT_EXPECTED_WORKER_VERSION_HEADER } from "./version-headers.js";
|
|
|
7
7
|
import { formatImageOptimizationHint, formatMissingCacheAdapterError, resolveCdnAdapterConfig, resolveKvDataAdapterConfig, viteConfigHasCacheAdapter, viteConfigHasCloudflarePlugin, viteConfigHasImageAdapter, workerEntryHasCacheHandler } from "./deploy-config.js";
|
|
8
8
|
import { assertCdnVersionMetadataConfig } from "./wrangler-version-metadata.js";
|
|
9
9
|
import { parseWorkerDeploymentUrl } from "./worker-deployment-url.js";
|
|
10
|
-
import { runWranglerDeploymentStatus, runWranglerTriggersDeploy, runWranglerVersionDeploy, runWranglerVersionUpload } from "./version-deploy.js";
|
|
10
|
+
import { readBuildOutputWorkerName, runCfDeploymentStatus, runCfTriggersDeploy, runCfVersionDeploy, runCfVersionUpload, runWranglerDeploymentStatus, runWranglerTriggersDeploy, runWranglerVersionDeploy, runWranglerVersionUpload } from "./version-deploy.js";
|
|
11
11
|
import { buildPrerenderKVPairs } from "./prerender-kv-populate.js";
|
|
12
12
|
import { createRequire } from "node:module";
|
|
13
13
|
import fs from "node:fs";
|
|
@@ -20,7 +20,9 @@ import os from "node:os";
|
|
|
20
20
|
import { spawn } from "node:child_process";
|
|
21
21
|
import { parseArgs } from "node:util";
|
|
22
22
|
import { pathToFileURL } from "node:url";
|
|
23
|
+
import { VINEXT_BUILD_LIFECYCLE_CONFIG } from "vinext/internal/build/lifecycle";
|
|
23
24
|
import { runPrerender } from "vinext/internal/build/run-prerender";
|
|
25
|
+
import { printBuildReport } from "vinext/internal/build/report";
|
|
24
26
|
import { loadDotenv } from "vinext/internal/config/dotenv";
|
|
25
27
|
import { findVinextNextConfigInPlugins, loadNextConfig, resolveNextConfig, resolveNextConfigInput } from "vinext/internal/config/next-config";
|
|
26
28
|
import { cacheWarmupStatusSource, findVinextCacheConfigInPlugins, findVinextPrerenderConfigInPlugins, findVinextRouteRootConfigInPlugins, formatVinextPrerenderLabel, hasBuildIdentityResponseHeader, hasUncachedRequestRouting, hasVerbatimResponseVary, isConfiguredCdnResponsePolicyHeader, requiresRouteCacheabilityProbeManifest, resolveVinextPrerenderDecision, supportsCanonicalRscWarmup } from "vinext/internal/config/prerender";
|
|
@@ -256,10 +258,13 @@ async function loadProjectWranglerApi(root) {
|
|
|
256
258
|
pathToFileURL(wranglerPath).href
|
|
257
259
|
);
|
|
258
260
|
}
|
|
259
|
-
|
|
261
|
+
function resolveViteBuildMode(deploymentTool, env) {
|
|
262
|
+
return deploymentTool === "cf" ? env ?? "production" : "production";
|
|
263
|
+
}
|
|
264
|
+
async function loadDeployViteConfigMetadata(root, mode) {
|
|
260
265
|
const plugins = (await (await loadProjectViteApi(root)).loadConfigFromFile({
|
|
261
266
|
command: "build",
|
|
262
|
-
mode
|
|
267
|
+
mode
|
|
263
268
|
}, void 0, root))?.config.plugins;
|
|
264
269
|
return {
|
|
265
270
|
cacheConfig: await findVinextCacheConfigInPlugins(plugins),
|
|
@@ -268,14 +273,23 @@ async function loadDeployViteConfigMetadata(root) {
|
|
|
268
273
|
routeRootConfig: await findVinextRouteRootConfigInPlugins(plugins)
|
|
269
274
|
};
|
|
270
275
|
}
|
|
271
|
-
async function runBuild(info, env) {
|
|
276
|
+
async function runBuild(info, env, mode) {
|
|
272
277
|
console.log("\n Building for Cloudflare Workers...\n");
|
|
273
278
|
const { createBuilder } = await loadProjectViteApi(info.root);
|
|
279
|
+
let completed = false;
|
|
274
280
|
await withCloudflareEnv(env, async () => {
|
|
275
|
-
|
|
281
|
+
const invocation = { onComplete() {
|
|
282
|
+
completed = true;
|
|
283
|
+
} };
|
|
284
|
+
await (await createBuilder({
|
|
285
|
+
root: info.root,
|
|
286
|
+
mode,
|
|
287
|
+
[VINEXT_BUILD_LIFECYCLE_CONFIG]: invocation
|
|
288
|
+
})).buildApp();
|
|
276
289
|
});
|
|
290
|
+
if (!completed) throw new Error("[vinext] The Cloudflare build lifecycle did not complete.");
|
|
277
291
|
}
|
|
278
|
-
async function populateKVCacheFromPrerenderedArtifacts(root,
|
|
292
|
+
async function populateKVCacheFromPrerenderedArtifacts(root, deploymentTool, env, cacheConfig) {
|
|
279
293
|
const kvConfig = resolveKvDataAdapterConfig(cacheConfig);
|
|
280
294
|
if (!kvConfig) return;
|
|
281
295
|
const { routeCount, pairs } = buildPrerenderKVPairs(path.join(root, "dist", "server"), {
|
|
@@ -286,9 +300,10 @@ async function populateKVCacheFromPrerenderedArtifacts(root, wranglerEnv, cacheC
|
|
|
286
300
|
console.log(" KV cache: Skipping prerender upload (no App Router prerendered cache entries found).");
|
|
287
301
|
return;
|
|
288
302
|
}
|
|
289
|
-
await
|
|
303
|
+
await runKVBulkPut(root, {
|
|
290
304
|
binding: kvConfig.binding,
|
|
291
|
-
|
|
305
|
+
deploymentTool,
|
|
306
|
+
env,
|
|
292
307
|
pairs
|
|
293
308
|
});
|
|
294
309
|
console.log(` KV cache: Uploaded ${pairs.length} entr${pairs.length === 1 ? "y" : "ies"} for ${routeCount} prerendered route${routeCount === 1 ? "" : "s"}.`);
|
|
@@ -309,6 +324,27 @@ function buildWranglerDeployArgs(options) {
|
|
|
309
324
|
env
|
|
310
325
|
};
|
|
311
326
|
}
|
|
327
|
+
function resolveDeploymentTool(root) {
|
|
328
|
+
return fs.existsSync(path.join(root, "cloudflare.config.ts")) ? "cf" : "wrangler";
|
|
329
|
+
}
|
|
330
|
+
function isCfCliInstalled(root, resolvePackageJson = (projectRoot) => {
|
|
331
|
+
try {
|
|
332
|
+
return createRequire(path.join(projectRoot, "package.json")).resolve("cf/package.json");
|
|
333
|
+
} catch {
|
|
334
|
+
return findInNodeModules(projectRoot, "cf/package.json");
|
|
335
|
+
}
|
|
336
|
+
}) {
|
|
337
|
+
return resolvePackageJson(root) !== null;
|
|
338
|
+
}
|
|
339
|
+
function buildCfDeployArgs(options) {
|
|
340
|
+
const mode = options.env || (options.preview ? "preview" : void 0);
|
|
341
|
+
const args = ["deploy", "--prebuilt"];
|
|
342
|
+
if (mode) args.push("--mode", validateWranglerEnvName(mode));
|
|
343
|
+
return {
|
|
344
|
+
args,
|
|
345
|
+
mode
|
|
346
|
+
};
|
|
347
|
+
}
|
|
312
348
|
function buildWranglerKVBulkPutArgs(options) {
|
|
313
349
|
const env = options.env || void 0;
|
|
314
350
|
const args = [
|
|
@@ -347,6 +383,21 @@ function resolveWranglerBin(root, resolvePackageJson = (projectRoot) => {
|
|
|
347
383
|
}
|
|
348
384
|
return path.join(root, "node_modules", "wrangler", "bin", "wrangler.js");
|
|
349
385
|
}
|
|
386
|
+
function resolveCfBin(root, resolvePackageJson = (projectRoot) => {
|
|
387
|
+
try {
|
|
388
|
+
return createRequire(path.join(projectRoot, "package.json")).resolve("cf/package.json");
|
|
389
|
+
} catch {
|
|
390
|
+
return findInNodeModules(projectRoot, "cf/package.json");
|
|
391
|
+
}
|
|
392
|
+
}) {
|
|
393
|
+
const packageJsonPath = resolvePackageJson(root);
|
|
394
|
+
if (packageJsonPath) {
|
|
395
|
+
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf-8"));
|
|
396
|
+
const bin = typeof packageJson.bin === "string" ? packageJson.bin : packageJson.bin?.cf;
|
|
397
|
+
if (bin) return path.resolve(path.dirname(packageJsonPath), bin);
|
|
398
|
+
}
|
|
399
|
+
return path.join(root, "node_modules", "cf", "bin", "cf");
|
|
400
|
+
}
|
|
350
401
|
function buildNodeCliInvocation(scriptPath, args, nodeExecutable = process.execPath) {
|
|
351
402
|
return {
|
|
352
403
|
file: nodeExecutable,
|
|
@@ -361,21 +412,35 @@ function buildWranglerInvocation(root, options, nodeExecutable = process.execPat
|
|
|
361
412
|
env
|
|
362
413
|
};
|
|
363
414
|
}
|
|
364
|
-
async function
|
|
415
|
+
async function runKVBulkPut(root, options, execute = spawn, nodeExecutable = process.execPath) {
|
|
416
|
+
const cfNamespaceId = (() => {
|
|
417
|
+
if (options.deploymentTool !== "cf") return void 0;
|
|
418
|
+
const configPath = path.join(root, ".cloudflare/output/v0/workers/default/worker.config.json");
|
|
419
|
+
const binding = JSON.parse(fs.readFileSync(configPath, "utf8")).env?.[options.binding];
|
|
420
|
+
if (binding?.type !== "kv" || typeof binding.id !== "string" || !binding.id) throw new Error(`[vinext] Generated Cloudflare Build Output does not declare KV binding ${JSON.stringify(options.binding)} with a namespace ID.`);
|
|
421
|
+
return binding.id;
|
|
422
|
+
})();
|
|
365
423
|
const tempDir = fs.mkdtempSync(path.join(options.tempDir ?? os.tmpdir(), "vinext-kv-bulk-"));
|
|
366
424
|
try {
|
|
367
|
-
const
|
|
425
|
+
const cliBin = cfNamespaceId ? resolveCfBin(root) : resolveWranglerBin(root);
|
|
368
426
|
const totalChunks = Math.ceil(options.pairs.length / KV_BULK_PUT_CHUNK_SIZE);
|
|
369
427
|
for (let i = 0; i < totalChunks; i++) {
|
|
370
428
|
const filePath = path.join(tempDir, `prerender-kv-${i}.json`);
|
|
371
429
|
const chunk = options.pairs.slice(i * KV_BULK_PUT_CHUNK_SIZE, (i + 1) * KV_BULK_PUT_CHUNK_SIZE);
|
|
372
430
|
fs.writeFileSync(filePath, JSON.stringify(chunk), "utf-8");
|
|
373
|
-
const
|
|
431
|
+
const invocation = buildNodeCliInvocation(cliBin, cfNamespaceId ? [
|
|
432
|
+
"kv",
|
|
433
|
+
"bulk",
|
|
434
|
+
"update",
|
|
435
|
+
cfNamespaceId,
|
|
436
|
+
"--body",
|
|
437
|
+
`@${filePath}`,
|
|
438
|
+
...options.env ? ["--mode", validateWranglerEnvName(options.env)] : []
|
|
439
|
+
] : buildWranglerKVBulkPutArgs({
|
|
374
440
|
binding: options.binding,
|
|
375
441
|
env: options.env,
|
|
376
442
|
filePath
|
|
377
|
-
});
|
|
378
|
-
const invocation = buildNodeCliInvocation(wranglerBin, args, nodeExecutable);
|
|
443
|
+
}).args, nodeExecutable);
|
|
379
444
|
const child = execute(invocation.file, invocation.args, {
|
|
380
445
|
cwd: root,
|
|
381
446
|
stdio: "inherit",
|
|
@@ -389,7 +454,7 @@ async function runWranglerKVBulkPut(root, options, execute = spawn, nodeExecutab
|
|
|
389
454
|
return;
|
|
390
455
|
}
|
|
391
456
|
const exitReason = signal ? `signal ${signal}` : `exit code ${code ?? "unknown"}`;
|
|
392
|
-
reject(/* @__PURE__ */ new Error(
|
|
457
|
+
reject(/* @__PURE__ */ new Error(`${cfNamespaceId ? "cf" : "Wrangler"} KV bulk upload failed with ${exitReason}.`));
|
|
393
458
|
});
|
|
394
459
|
});
|
|
395
460
|
}
|
|
@@ -439,6 +504,38 @@ async function runWranglerDeploy(root, options, execute = spawn) {
|
|
|
439
504
|
});
|
|
440
505
|
return parseWorkerDeploymentUrl(output) ?? "(URL not detected in wrangler output)";
|
|
441
506
|
}
|
|
507
|
+
async function runCfDeploy(root, options, execute = spawn) {
|
|
508
|
+
const { args, mode } = buildCfDeployArgs(options);
|
|
509
|
+
console.log(mode ? `\n Deploying Build Output in mode: ${mode}...` : "\n Deploying Build Output...");
|
|
510
|
+
const child = execute(process.execPath, [resolveCfBin(root), ...args], {
|
|
511
|
+
cwd: root,
|
|
512
|
+
stdio: [
|
|
513
|
+
"inherit",
|
|
514
|
+
"pipe",
|
|
515
|
+
"pipe"
|
|
516
|
+
],
|
|
517
|
+
shell: false
|
|
518
|
+
});
|
|
519
|
+
let output = "";
|
|
520
|
+
child.stdout?.on("data", (chunk) => {
|
|
521
|
+
const text = chunk.toString();
|
|
522
|
+
output += text;
|
|
523
|
+
process.stdout.write(text);
|
|
524
|
+
});
|
|
525
|
+
child.stderr?.on("data", (chunk) => {
|
|
526
|
+
const text = chunk.toString();
|
|
527
|
+
output += text;
|
|
528
|
+
process.stderr.write(text);
|
|
529
|
+
});
|
|
530
|
+
await new Promise((resolve, reject) => {
|
|
531
|
+
child.once("error", reject);
|
|
532
|
+
child.once("close", (code, signal) => {
|
|
533
|
+
if (code === 0) resolve();
|
|
534
|
+
else reject(/* @__PURE__ */ new Error(`cf deploy failed with ${signal ? `signal ${signal}` : `exit code ${code ?? "unknown"}`}.`));
|
|
535
|
+
});
|
|
536
|
+
});
|
|
537
|
+
return parseWorkerDeploymentUrl(output) ?? "(URL not detected in cf output)";
|
|
538
|
+
}
|
|
442
539
|
function hasCdnWarmRequests(plan) {
|
|
443
540
|
return plan.paths.length + (plan.pagesDataPaths?.length ?? 0) + (plan.routeHandlerPaths?.length ?? 0) + plan.rscPaths.length + plan.loadingShellPaths.length > 0;
|
|
444
541
|
}
|
|
@@ -472,6 +569,30 @@ function selectTPRWarmPlan(plan, traffic, coverage, limit) {
|
|
|
472
569
|
function projectRequiresRouteCacheabilityProbeManifest(project, cacheConfig) {
|
|
473
570
|
return (project.isAppRouter || project.isPagesRouter) && requiresRouteCacheabilityProbeManifest(cacheConfig);
|
|
474
571
|
}
|
|
572
|
+
function deploymentWorkerName(options) {
|
|
573
|
+
if (!options.name) throw new Error("Could not detect the Worker name for its deployment.");
|
|
574
|
+
return options.name;
|
|
575
|
+
}
|
|
576
|
+
function runDeploymentStatus(root, options) {
|
|
577
|
+
return options.deploymentTool === "cf" ? runCfDeploymentStatus(root, {
|
|
578
|
+
name: deploymentWorkerName(options),
|
|
579
|
+
env: options.env,
|
|
580
|
+
verbose: options.verbose
|
|
581
|
+
}) : runWranglerDeploymentStatus(root, options);
|
|
582
|
+
}
|
|
583
|
+
function runVersionDeploy(root, traffic, options, phase) {
|
|
584
|
+
return options.deploymentTool === "cf" ? runCfVersionDeploy(root, traffic, {
|
|
585
|
+
name: deploymentWorkerName(options),
|
|
586
|
+
env: options.env,
|
|
587
|
+
verbose: options.verbose
|
|
588
|
+
}, phase) : runWranglerVersionDeploy(root, traffic, options, phase);
|
|
589
|
+
}
|
|
590
|
+
function runTriggersDeploy(root, options) {
|
|
591
|
+
return options.deploymentTool === "cf" ? runCfTriggersDeploy(root, options) : runWranglerTriggersDeploy(root, options);
|
|
592
|
+
}
|
|
593
|
+
function runVersionUpload(root, options) {
|
|
594
|
+
return options.deploymentTool === "cf" ? runCfVersionUpload(root, options) : runWranglerVersionUpload(root, options);
|
|
595
|
+
}
|
|
475
596
|
function cdnWarmTargetKey(target) {
|
|
476
597
|
return `${target.kind}\0${target.sourcePathname}`;
|
|
477
598
|
}
|
|
@@ -555,7 +676,8 @@ async function deployUploadedVersionWithCdnWarmup(root, paths, options) {
|
|
|
555
676
|
warmPlanDiscovered = true;
|
|
556
677
|
};
|
|
557
678
|
if (!options.discoverWarmPlan || hasPreparedWarmPlan) remainingWarmPlan = prepareWarmPlan(remainingWarmPlan);
|
|
558
|
-
const upload = options.uploadedVersion ??
|
|
679
|
+
const upload = options.uploadedVersion ?? runVersionUpload(root, options);
|
|
680
|
+
const wranglerOptions = resolveDeploymentControlPlaneOptions(options, upload);
|
|
559
681
|
const warmUploadedVersion = (targetUrl, headers, propagatingTarget = false, plan = {
|
|
560
682
|
loadingShellPaths: remainingWarmPlan.loadingShellPaths,
|
|
561
683
|
pagesDataPaths: remainingWarmPlan.pagesDataPaths,
|
|
@@ -584,10 +706,10 @@ async function deployUploadedVersionWithCdnWarmup(root, paths, options) {
|
|
|
584
706
|
strict: requireCacheHit || !allowUnverifiedPromotion,
|
|
585
707
|
statusSource: options.statusSource
|
|
586
708
|
});
|
|
587
|
-
const wranglerConfig = parseWranglerConfig(root, options.config);
|
|
709
|
+
const wranglerConfig = options.deploymentTool === "cf" ? null : parseWranglerConfig(root, options.config);
|
|
588
710
|
let deploymentStatus;
|
|
589
711
|
try {
|
|
590
|
-
deploymentStatus =
|
|
712
|
+
deploymentStatus = runDeploymentStatus(root, wranglerOptions);
|
|
591
713
|
} catch (error) {
|
|
592
714
|
if (!hasPreparedWarmPlan) throw error;
|
|
593
715
|
throw new StagedWarmupError(formatUnknownError(error), { cause: error });
|
|
@@ -603,14 +725,14 @@ async function deployUploadedVersionWithCdnWarmup(root, paths, options) {
|
|
|
603
725
|
let triggersApplied = options.triggersAlreadyApplied === true;
|
|
604
726
|
function applyTriggers() {
|
|
605
727
|
if (triggersApplied) return;
|
|
606
|
-
triggersDeployedUrl =
|
|
728
|
+
triggersDeployedUrl = runTriggersDeploy(root, wranglerOptions).deployedUrl;
|
|
607
729
|
triggersApplied = true;
|
|
608
730
|
}
|
|
609
731
|
if (stagingTraffic) {
|
|
610
732
|
try {
|
|
611
|
-
staged =
|
|
733
|
+
staged = runVersionDeploy(root, stagingTraffic, wranglerOptions, "stage");
|
|
612
734
|
} catch (error) {
|
|
613
|
-
throw reconcileVersionDeployFailure(root,
|
|
735
|
+
throw reconcileVersionDeployFailure(root, wranglerOptions, error, {
|
|
614
736
|
desiredTraffic: stagingTraffic,
|
|
615
737
|
desiredDescription: "The uploaded version is staged at 0% with the previous version still serving 100% traffic; Worker triggers/routes were not changed.",
|
|
616
738
|
priorState: deploymentStatus,
|
|
@@ -619,7 +741,7 @@ async function deployUploadedVersionWithCdnWarmup(root, paths, options) {
|
|
|
619
741
|
}
|
|
620
742
|
try {
|
|
621
743
|
if (hasPreparedWarmPlan) {
|
|
622
|
-
stagedDeploymentState =
|
|
744
|
+
stagedDeploymentState = runDeploymentStatus(root, wranglerOptions);
|
|
623
745
|
if (!deploymentTrafficEquals(stagedDeploymentState.versions, stagingTraffic)) throw new Error("Two-stage CDN warming stopped because Worker deployment traffic changed before production triggers could be applied. No final version was promoted.");
|
|
624
746
|
}
|
|
625
747
|
applyTriggers();
|
|
@@ -627,7 +749,7 @@ async function deployUploadedVersionWithCdnWarmup(root, paths, options) {
|
|
|
627
749
|
throw withStagedVersionCleanupNote(error);
|
|
628
750
|
}
|
|
629
751
|
const targetUrl = resolveCdnWarmupTargetUrl(root, triggersDeployedUrl, options) ?? staged.deployedUrl;
|
|
630
|
-
const headers = buildVersionOverrideHeaders(options.name ?? upload.workerName ?? resolveWorkerNameForVersionOverride(wranglerConfig,
|
|
752
|
+
const headers = buildVersionOverrideHeaders(options.name ?? upload.workerName ?? resolveWorkerNameForVersionOverride(wranglerConfig, wranglerOptions), upload.versionId);
|
|
631
753
|
if (targetUrl && headers) try {
|
|
632
754
|
if (!warmPlanDiscovered) {
|
|
633
755
|
console.log(" CDN warmup: discovering paths from the staged Worker version...");
|
|
@@ -719,9 +841,9 @@ async function deployUploadedVersionWithCdnWarmup(root, paths, options) {
|
|
|
719
841
|
if (hasPreparedWarmPlan && stagedDeploymentState) {
|
|
720
842
|
let currentDeployment;
|
|
721
843
|
try {
|
|
722
|
-
currentDeployment =
|
|
844
|
+
currentDeployment = runDeploymentStatus(root, wranglerOptions);
|
|
723
845
|
} catch (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
|
|
846
|
+
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 the active Worker deployment before continuing.`, { cause: error });
|
|
725
847
|
}
|
|
726
848
|
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.");
|
|
727
849
|
}
|
|
@@ -744,13 +866,13 @@ async function deployUploadedVersionWithCdnWarmup(root, paths, options) {
|
|
|
744
866
|
}
|
|
745
867
|
}
|
|
746
868
|
if (hasPreparedWarmPlan && stagingTraffic) {
|
|
747
|
-
prePromotionState =
|
|
869
|
+
prePromotionState = runDeploymentStatus(root, wranglerOptions);
|
|
748
870
|
if (!deploymentTrafficEquals(prePromotionState.versions, stagingTraffic) || stagedDeploymentState && !deploymentStateEquals(prePromotionState, stagedDeploymentState)) throw new Error("Two-stage CDN warming stopped because Worker deployment traffic or deployment identity changed before the final version could be promoted. No final version was promoted.");
|
|
749
871
|
}
|
|
750
872
|
promotionAttempted = true;
|
|
751
|
-
deployed =
|
|
873
|
+
deployed = runVersionDeploy(root, promotionTraffic, wranglerOptions, stagedCacheFilled ? "promote-warmed" : "promote-uploaded");
|
|
752
874
|
} catch (error) {
|
|
753
|
-
if (promotionAttempted) throw reconcileVersionDeployFailure(root,
|
|
875
|
+
if (promotionAttempted) throw reconcileVersionDeployFailure(root, wranglerOptions, error, {
|
|
754
876
|
desiredTraffic: promotionTraffic,
|
|
755
877
|
desiredDescription: "The uploaded version is already promoted to 100%; Worker triggers/routes may already have changed.",
|
|
756
878
|
priorState: prePromotionState ?? (stagingTraffic ? {
|
|
@@ -802,7 +924,7 @@ function reconcileVersionDeployFailure(root, options, error, expected) {
|
|
|
802
924
|
let reconciliation;
|
|
803
925
|
let mayNeedCleanup = true;
|
|
804
926
|
try {
|
|
805
|
-
const current =
|
|
927
|
+
const current = runDeploymentStatus(root, options);
|
|
806
928
|
if (deploymentTrafficEquals(current.versions, expected.desiredTraffic)) reconciliation = expected.desiredDescription;
|
|
807
929
|
else if (deploymentStateEquals(current, expected.priorState)) {
|
|
808
930
|
reconciliation = expected.priorDescription;
|
|
@@ -815,20 +937,21 @@ function reconcileVersionDeployFailure(root, options, error, expected) {
|
|
|
815
937
|
return mayNeedCleanup ? new StagedWarmupError(detail, { cause: error }) : new Error(detail, { cause: error });
|
|
816
938
|
}
|
|
817
939
|
function assertDeploymentStateUnchanged(root, options, expected, message) {
|
|
818
|
-
if (!deploymentStateEquals(
|
|
940
|
+
if (!deploymentStateEquals(runDeploymentStatus(root, options), expected)) throw new Error(message);
|
|
819
941
|
}
|
|
820
942
|
async function deployWithCacheabilityProbe(root, options) {
|
|
821
943
|
if (!options.discoverWarmPlan) throw new Error("Two-stage CDN warming requires staged Worker route discovery before cacheability probing.");
|
|
822
944
|
const prerenderSecret = readPrerenderSecret(root);
|
|
823
|
-
const probeUpload =
|
|
824
|
-
const
|
|
945
|
+
const probeUpload = runVersionUpload(root, options);
|
|
946
|
+
const wranglerOptions = resolveDeploymentControlPlaneOptions(options, probeUpload);
|
|
947
|
+
const initialDeployment = runDeploymentStatus(root, wranglerOptions);
|
|
825
948
|
const probeTraffic = getZeroPercentStagingTraffic(initialDeployment, probeUpload.versionId);
|
|
826
949
|
if (!probeTraffic) throw new Error("Two-stage CDN warming cannot stage the probe Worker at 0% because the current deployment is not exactly one version serving 100% traffic. No traffic or triggers were changed.");
|
|
827
950
|
let stagedProbe;
|
|
828
951
|
try {
|
|
829
|
-
stagedProbe =
|
|
952
|
+
stagedProbe = runVersionDeploy(root, probeTraffic, wranglerOptions, "stage");
|
|
830
953
|
} catch (error) {
|
|
831
|
-
throw reconcileVersionDeployFailure(root,
|
|
954
|
+
throw reconcileVersionDeployFailure(root, wranglerOptions, error, {
|
|
832
955
|
desiredTraffic: probeTraffic,
|
|
833
956
|
desiredDescription: "The probe version is staged at 0% with the previous version still serving 100% traffic; production Worker triggers/routes were not changed.",
|
|
834
957
|
priorState: initialDeployment,
|
|
@@ -837,16 +960,16 @@ async function deployWithCacheabilityProbe(root, options) {
|
|
|
837
960
|
}
|
|
838
961
|
let stagedProbeDeployment;
|
|
839
962
|
try {
|
|
840
|
-
stagedProbeDeployment =
|
|
963
|
+
stagedProbeDeployment = runDeploymentStatus(root, wranglerOptions);
|
|
841
964
|
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.");
|
|
842
965
|
} catch (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
|
|
966
|
+
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 the active Worker deployment and remove the staged probe version if necessary.`, { cause: error });
|
|
844
967
|
}
|
|
845
968
|
let prepared;
|
|
846
969
|
try {
|
|
847
970
|
const targetUrl = resolveCdnWarmupTargetUrl(root, stagedProbe.deployedUrl ?? probeUpload.previewUrl, options);
|
|
848
|
-
const wranglerConfig = parseWranglerConfig(root,
|
|
849
|
-
const headers = buildVersionOverrideHeaders(options.name ?? probeUpload.workerName ?? resolveWorkerNameForVersionOverride(wranglerConfig,
|
|
971
|
+
const wranglerConfig = options.deploymentTool === "cf" ? null : parseWranglerConfig(root, wranglerOptions.config);
|
|
972
|
+
const headers = buildVersionOverrideHeaders(options.name ?? probeUpload.workerName ?? resolveWorkerNameForVersionOverride(wranglerConfig, wranglerOptions), probeUpload.versionId);
|
|
850
973
|
if (!targetUrl || !headers) throw new Error("Two-stage CDN warming needs a production URL and Worker name for version-overridden cacheability probes.");
|
|
851
974
|
console.log(" CDN warmup: discovering paths from the staged probe Worker...");
|
|
852
975
|
const discovered = await options.discoverWarmPlan({
|
|
@@ -937,14 +1060,11 @@ async function deployWithCacheabilityProbe(root, options) {
|
|
|
937
1060
|
rscPaths: probe.cacheableTargets.filter((target) => target.kind === "rsc-full").map((target) => target.sourcePathname)
|
|
938
1061
|
};
|
|
939
1062
|
const selectedFinalPlan = options.selectWarmPlan?.(finalPlan) ?? finalPlan;
|
|
940
|
-
assertDeploymentStateUnchanged(root,
|
|
941
|
-
const finalConfig = writeCacheabilityManifestArtifact(root, options.config, probe.manifest);
|
|
942
|
-
const finalUpload =
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
name: options.name,
|
|
946
|
-
preview: options.preview,
|
|
947
|
-
verbose: options.verbose
|
|
1063
|
+
assertDeploymentStateUnchanged(root, wranglerOptions, stagedProbeDeployment, "Two-stage CDN warming stopped because Worker deployment traffic or deployment identity changed while cacheability was being probed. No final version was promoted.");
|
|
1064
|
+
const finalConfig = writeCacheabilityManifestArtifact(root, options.config, probe.manifest, options.deploymentTool);
|
|
1065
|
+
const finalUpload = runVersionUpload(root, {
|
|
1066
|
+
...options,
|
|
1067
|
+
config: options.deploymentTool === "cf" ? options.config : finalConfig
|
|
948
1068
|
});
|
|
949
1069
|
prepared = {
|
|
950
1070
|
optionalWarmTargetKeys: new Set(probe.speculativeTargets.map(cdnWarmTargetKey)),
|
|
@@ -986,6 +1106,15 @@ function getZeroPercentStagingTraffic(deployment, versionId) {
|
|
|
986
1106
|
function getWranglerTargetEnv(options) {
|
|
987
1107
|
return options.env || (options.preview ? "preview" : void 0);
|
|
988
1108
|
}
|
|
1109
|
+
function resolveDeploymentControlPlaneOptions(options, upload) {
|
|
1110
|
+
if (options.deploymentTool !== "cf") return options;
|
|
1111
|
+
const name = upload.workerName ?? options.name;
|
|
1112
|
+
if (!name) throw new Error("Could not detect the uploaded Worker name needed for staged CDN warming.");
|
|
1113
|
+
return {
|
|
1114
|
+
...options,
|
|
1115
|
+
name
|
|
1116
|
+
};
|
|
1117
|
+
}
|
|
989
1118
|
function resolveWorkerNameForVersionOverride(config, options) {
|
|
990
1119
|
if (options.name) return options.name;
|
|
991
1120
|
const env = getWranglerTargetEnv(options);
|
|
@@ -1010,24 +1139,29 @@ function withStagedProbeVersionCleanupNote(error) {
|
|
|
1010
1139
|
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 });
|
|
1011
1140
|
}
|
|
1012
1141
|
function getStagedVersionCleanupNote() {
|
|
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
|
|
1142
|
+
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 create a deployment with the desired version split.";
|
|
1014
1143
|
}
|
|
1015
1144
|
function withPromotedVersionTriggerNote(error) {
|
|
1016
1145
|
const message = error instanceof Error ? error.message : String(error);
|
|
1017
|
-
return new Error(`${message} The uploaded version may already be promoted to 100%, but Worker triggers/routes may not be updated; rerun deploy or
|
|
1146
|
+
return new Error(`${message} The uploaded version may already be promoted to 100%, but Worker triggers/routes may not be updated; rerun deploy or apply the Worker triggers after fixing the trigger error.`, { cause: error });
|
|
1018
1147
|
}
|
|
1019
1148
|
function withPromotedVersionWarmupNote(error) {
|
|
1020
1149
|
const message = error instanceof Error ? error.message : String(error);
|
|
1021
|
-
return new Error(`${message} The uploaded version is already promoted to 100% and its Worker triggers/routes were updated; rerun deploy to retry cache warming or
|
|
1150
|
+
return new Error(`${message} The uploaded version is already promoted to 100% and its Worker triggers/routes were updated; rerun deploy to retry cache warming or create a deployment for the previous version.`, { cause: error });
|
|
1022
1151
|
}
|
|
1023
1152
|
async function deploy(options) {
|
|
1024
1153
|
if (options.warmCdnTarget !== void 0 && !options.warmCdnCache) throw new Error("--warm-cdn-target requires --experimental-warm-cdn-cache.");
|
|
1025
1154
|
const warmCdnTarget = options.warmCdnTarget === void 0 ? void 0 : validateCdnWarmTarget(options.warmCdnTarget);
|
|
1026
|
-
const deployEnv =
|
|
1155
|
+
const deployEnv = options.env || (options.preview ? "preview" : void 0);
|
|
1156
|
+
if (deployEnv) validateWranglerEnvName(deployEnv);
|
|
1027
1157
|
const root = path.resolve(options.root);
|
|
1158
|
+
const deploymentTool = resolveDeploymentTool(root);
|
|
1159
|
+
if (deploymentTool === "cf" && options.name) throw new Error("--name is not supported for cloudflare.config.ts projects. Set `name` in cloudflare.config.ts instead.");
|
|
1160
|
+
const viteMode = resolveViteBuildMode(deploymentTool, deployEnv);
|
|
1161
|
+
const wranglerFallbackEnv = deploymentTool === "cf" ? void 0 : deployEnv;
|
|
1028
1162
|
loadDotenv({
|
|
1029
1163
|
root,
|
|
1030
|
-
mode:
|
|
1164
|
+
mode: viteMode
|
|
1031
1165
|
});
|
|
1032
1166
|
console.log("\n vinext-cloudflare deploy\n");
|
|
1033
1167
|
const info = detectProject(root);
|
|
@@ -1045,20 +1179,20 @@ async function deploy(options) {
|
|
|
1045
1179
|
if (missingScaffolding.length > 0) throw new Error(`Missing Cloudflare deployment setup: ${missingScaffolding.join(", ")}. Run \`vinext init --platform=cloudflare\` first.`);
|
|
1046
1180
|
const missingDeps = getMissingDeps(info);
|
|
1047
1181
|
if (missingDeps.length > 0) throw new Error(`Missing deployment dependencies: ${missingDeps.map((dependency) => dependency.name).join(", ")}. Run \`vinext init --platform=cloudflare\` first.`);
|
|
1182
|
+
if (deploymentTool === "cf" && !isCfCliInstalled(root)) throw new Error("Missing deployment dependencies: cf. Run `vinext init --platform=cloudflare` first.");
|
|
1048
1183
|
if (info.hasViteConfig && !viteConfigHasCloudflarePlugin(root)) throw new Error(formatMissingCloudflarePluginError({ isAppRouter: info.isAppRouter }));
|
|
1049
|
-
if (info.hasISR && !viteConfigHasCacheAdapter(root) && !workerEntryHasCacheHandler(root)) throw new Error(formatMissingCacheAdapterError({}));
|
|
1184
|
+
if (info.hasISR && !viteConfigHasCacheAdapter(root) && !workerEntryHasCacheHandler(root)) throw new Error(formatMissingCacheAdapterError({ typedConfig: deploymentTool === "cf" }));
|
|
1050
1185
|
if (!viteConfigHasImageAdapter(root)) {
|
|
1051
1186
|
console.log();
|
|
1052
|
-
console.log(formatImageOptimizationHint());
|
|
1187
|
+
console.log(formatImageOptimizationHint(deploymentTool === "cf"));
|
|
1053
1188
|
}
|
|
1054
1189
|
if (options.dryRun) {
|
|
1055
1190
|
console.log("\n Dry run complete. No build or deploy performed.\n");
|
|
1056
1191
|
return;
|
|
1057
1192
|
}
|
|
1058
|
-
const
|
|
1059
|
-
const viteConfigMetadata = await withCloudflareEnv(buildEnv, () => loadDeployViteConfigMetadata(info.root));
|
|
1193
|
+
const viteConfigMetadata = await withCloudflareEnv(deployEnv, () => loadDeployViteConfigMetadata(info.root, viteMode));
|
|
1060
1194
|
const cdnAdapterConfig = resolveCdnAdapterConfig(viteConfigMetadata.cacheConfig);
|
|
1061
|
-
const nextConfig = await withCloudflareEnv(
|
|
1195
|
+
const nextConfig = await withCloudflareEnv(deployEnv, async () => {
|
|
1062
1196
|
const inlineNextConfig = viteConfigMetadata.nextConfig;
|
|
1063
1197
|
const rawNextConfig = inlineNextConfig ? await resolveNextConfigInput(inlineNextConfig, PHASE_PRODUCTION_BUILD) : await loadNextConfig(info.root, PHASE_PRODUCTION_BUILD);
|
|
1064
1198
|
return resolveNextConfig(rawNextConfig, info.root);
|
|
@@ -1076,7 +1210,7 @@ async function deploy(options) {
|
|
|
1076
1210
|
const hasCanonicalRscWarmup = supportsCanonicalRscWarmup(viteConfigMetadata.cacheConfig);
|
|
1077
1211
|
const needsCacheabilityProbeManifest = projectRequiresRouteCacheabilityProbeManifest(info, viteConfigMetadata.cacheConfig);
|
|
1078
1212
|
const shouldEmitPrerenderPathManifest = !options.skipBuild && prerenderDecision;
|
|
1079
|
-
if (!options.skipBuild) await runBuild(info,
|
|
1213
|
+
if (!options.skipBuild) await runBuild(info, deployEnv, viteMode);
|
|
1080
1214
|
else console.log("\n Skipping build (--skip-build)");
|
|
1081
1215
|
const canWarmTpr = options.experimentalTPR && !prerenderDecision && hasBuildIdentityHeader;
|
|
1082
1216
|
if (options.experimentalTPR && prerenderDecision) console.log(" TPR: Skipping route selection (all-route prerendering configured)");
|
|
@@ -1084,22 +1218,24 @@ async function deploy(options) {
|
|
|
1084
1218
|
const tpr = canWarmTpr ? await resolveTPRRoutes({
|
|
1085
1219
|
root,
|
|
1086
1220
|
config: options.config,
|
|
1087
|
-
env:
|
|
1221
|
+
env: wranglerFallbackEnv,
|
|
1088
1222
|
hostname: warmCdnTarget ? new URL(warmCdnTarget).hostname : void 0,
|
|
1223
|
+
typedConfig: deploymentTool === "cf",
|
|
1089
1224
|
window: Math.max(1, options.tprWindow ?? 24)
|
|
1090
1225
|
}) : null;
|
|
1091
1226
|
if (tpr?.skipped) console.log(` TPR: Skipped (${tpr.skipped})`);
|
|
1092
1227
|
const tprRoutes = tpr?.routes ?? [];
|
|
1093
1228
|
const wranglerOptions = {
|
|
1094
|
-
env:
|
|
1095
|
-
name: options.name,
|
|
1229
|
+
env: deploymentTool === "cf" ? viteMode : deployEnv,
|
|
1230
|
+
name: deploymentTool === "cf" ? readBuildOutputWorkerName(root) : options.name,
|
|
1096
1231
|
config: options.config,
|
|
1097
|
-
verbose: options.verbose
|
|
1232
|
+
verbose: options.verbose,
|
|
1233
|
+
deploymentTool
|
|
1098
1234
|
};
|
|
1099
1235
|
let shouldWarmTpr = tprRoutes.length > 0;
|
|
1100
1236
|
if (shouldWarmTpr && !options.warmCdnCache) {
|
|
1101
1237
|
try {
|
|
1102
|
-
shouldWarmTpr = getZeroPercentStagingTraffic(
|
|
1238
|
+
shouldWarmTpr = getZeroPercentStagingTraffic(runDeploymentStatus(root, wranglerOptions), "tpr-preflight") !== null;
|
|
1103
1239
|
} catch {
|
|
1104
1240
|
shouldWarmTpr = false;
|
|
1105
1241
|
}
|
|
@@ -1110,25 +1246,32 @@ async function deploy(options) {
|
|
|
1110
1246
|
const candidatePathsOnly = shouldSelectTpr && !needsCacheabilityProbeManifest;
|
|
1111
1247
|
const shouldPrerenderLocally = prerenderDecision && (!shouldWarmCdnCache || prerenderDecision.reason === "next-export");
|
|
1112
1248
|
if (shouldWarmCdnCache && cdnAdapterConfig) {
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1249
|
+
if (deploymentTool === "cf") {
|
|
1250
|
+
const configPath = path.join(root, ".cloudflare/output/v0/workers/default/worker.config.json");
|
|
1251
|
+
const config = JSON.parse(fs.readFileSync(configPath, "utf8"));
|
|
1252
|
+
const binding = cdnAdapterConfig.versionMetadataBinding;
|
|
1253
|
+
if (config.env?.[binding]?.type !== "version-metadata") throw new Error(`[vinext] Cloudflare CDN warmup requires version metadata binding ${JSON.stringify(binding)} in the generated Build Output Worker config ${configPath}.`);
|
|
1254
|
+
} else {
|
|
1255
|
+
const wrangler = await loadProjectWranglerApi(info.root);
|
|
1256
|
+
const previousCwd = process.cwd();
|
|
1257
|
+
try {
|
|
1258
|
+
process.chdir(info.root);
|
|
1259
|
+
const config = wrangler.unstable_readConfig({
|
|
1260
|
+
config: options.config,
|
|
1261
|
+
env: wranglerFallbackEnv
|
|
1262
|
+
}, {
|
|
1263
|
+
hideWarnings: true,
|
|
1264
|
+
preserveOriginalMain: true,
|
|
1265
|
+
useRedirectIfAvailable: true
|
|
1266
|
+
});
|
|
1267
|
+
assertCdnVersionMetadataConfig({
|
|
1268
|
+
binding: cdnAdapterConfig.versionMetadataBinding,
|
|
1269
|
+
configuredBinding: config.version_metadata?.binding,
|
|
1270
|
+
configPath: config.configPath
|
|
1271
|
+
});
|
|
1272
|
+
} finally {
|
|
1273
|
+
process.chdir(previousCwd);
|
|
1274
|
+
}
|
|
1132
1275
|
}
|
|
1133
1276
|
}
|
|
1134
1277
|
if (shouldEmitPrerenderPathManifest) await emitPrerenderPathManifest({
|
|
@@ -1141,22 +1284,31 @@ async function deploy(options) {
|
|
|
1141
1284
|
routeRootConfig: viteConfigMetadata.routeRootConfig
|
|
1142
1285
|
});
|
|
1143
1286
|
let ranPrerender = false;
|
|
1144
|
-
|
|
1287
|
+
let prerenderResult = void 0;
|
|
1288
|
+
if (shouldPrerenderLocally && !ranPrerender) {
|
|
1145
1289
|
console.log(`\n ${formatVinextPrerenderLabel(prerenderDecision)}`);
|
|
1146
1290
|
if (nextConfig.enablePrerenderSourceMaps) {
|
|
1147
1291
|
process.setSourceMapsEnabled(true);
|
|
1148
1292
|
Error.stackTraceLimit = Math.max(Error.stackTraceLimit, 50);
|
|
1149
1293
|
}
|
|
1150
|
-
await runPrerender({
|
|
1294
|
+
prerenderResult = await runPrerender({
|
|
1151
1295
|
root: info.root,
|
|
1152
|
-
concurrency: options.prerenderConcurrency,
|
|
1296
|
+
concurrency: options.prerenderConcurrency ?? viteConfigMetadata.prerenderConfig?.concurrency,
|
|
1153
1297
|
nextConfig,
|
|
1154
1298
|
routeRootConfig: viteConfigMetadata.routeRootConfig
|
|
1155
1299
|
});
|
|
1156
1300
|
ranPrerender = true;
|
|
1157
1301
|
}
|
|
1302
|
+
if (!options.skipBuild) {
|
|
1303
|
+
await printBuildReport({
|
|
1304
|
+
root: info.root,
|
|
1305
|
+
pageExtensions: nextConfig.pageExtensions,
|
|
1306
|
+
prerenderResult: prerenderResult ?? void 0
|
|
1307
|
+
});
|
|
1308
|
+
console.log("\n Build complete.\n");
|
|
1309
|
+
}
|
|
1158
1310
|
if (ranPrerender) try {
|
|
1159
|
-
await populateKVCacheFromPrerenderedArtifacts(root,
|
|
1311
|
+
await populateKVCacheFromPrerenderedArtifacts(root, deploymentTool, deploymentTool === "cf" ? viteMode : wranglerFallbackEnv, viteConfigMetadata.cacheConfig);
|
|
1160
1312
|
} catch (error) {
|
|
1161
1313
|
console.log(` KV cache: Skipping prerender upload (${formatUnknownError(error)}). Continuing with deploy.`);
|
|
1162
1314
|
}
|
|
@@ -1220,13 +1372,17 @@ async function deploy(options) {
|
|
|
1220
1372
|
if (options.warmCdnCache || options.warmCdnPromote === false && error instanceof StagedWarmupError) throw error;
|
|
1221
1373
|
console.log(` TPR: Skipping pre-warm (${formatUnknownError(error)}). Continuing with deploy.`);
|
|
1222
1374
|
}
|
|
1223
|
-
if (url === void 0)
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1375
|
+
if (url === void 0) {
|
|
1376
|
+
if (deploymentTool === "cf" && options.warmCdnPromote === false) url = runCfVersionUpload(root, wranglerOptions).previewUrl ?? "(Preview URL not detected in cf output)";
|
|
1377
|
+
else if (deploymentTool === "cf") url = await runCfDeploy(root, wranglerOptions);
|
|
1378
|
+
else url = await runWranglerDeploy(root, {
|
|
1379
|
+
...wranglerOptions,
|
|
1380
|
+
promote: options.warmCdnPromote
|
|
1381
|
+
});
|
|
1382
|
+
}
|
|
1227
1383
|
console.log("\n ─────────────────────────────────────────");
|
|
1228
1384
|
console.log(` ${options.warmCdnPromote === false ? "Version URL" : "Deployed to"}: ${url}`);
|
|
1229
1385
|
console.log(" ─────────────────────────────────────────\n");
|
|
1230
1386
|
}
|
|
1231
1387
|
//#endregion
|
|
1232
|
-
export { DEFAULT_CDN_WARM_PROMOTION_DELAY_MS, buildNodeCliInvocation, buildVersionOverrideHeaders, buildWranglerDeployArgs, buildWranglerInvocation, buildWranglerKVBulkPutArgs, deploy, deployWithCdnWarmup, getZeroPercentStagingTraffic, hasCdnWarmRequests, parseDeployArgs, projectRequiresRouteCacheabilityProbeManifest, resolveCdnWarmupTargetUrl, resolveWorkerNameForVersionOverride, resolveWranglerBin,
|
|
1388
|
+
export { DEFAULT_CDN_WARM_PROMOTION_DELAY_MS, buildCfDeployArgs, buildNodeCliInvocation, buildVersionOverrideHeaders, buildWranglerDeployArgs, buildWranglerInvocation, buildWranglerKVBulkPutArgs, deploy, deployWithCdnWarmup, getZeroPercentStagingTraffic, hasCdnWarmRequests, isCfCliInstalled, parseDeployArgs, projectRequiresRouteCacheabilityProbeManifest, resolveCdnWarmupTargetUrl, resolveCfBin, resolveDeploymentControlPlaneOptions, resolveDeploymentTool, resolveViteBuildMode, resolveWorkerNameForVersionOverride, resolveWranglerBin, runCfDeploy, runKVBulkPut, runWranglerDeploy, selectTPRWarmPlan, validateWranglerEnvName, withCloudflareEnv };
|
package/dist/tpr.d.ts
CHANGED
|
@@ -9,6 +9,8 @@ export type TPROptions = {
|
|
|
9
9
|
env?: string;
|
|
10
10
|
/** Explicit domain used to resolve the analytics zone, overriding Wrangler routes. */
|
|
11
11
|
hostname?: string;
|
|
12
|
+
/** Read domains from generated Build Output instead of a Wrangler config. */
|
|
13
|
+
typedConfig?: boolean;
|
|
12
14
|
/** Analytics lookback window in hours. Default: 24. */
|
|
13
15
|
window: number;
|
|
14
16
|
};
|