@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/tpr.js
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { parseWranglerConfig } from "./wrangler-config.js";
|
|
2
|
+
import fs from "node:fs";
|
|
3
|
+
import path from "node:path";
|
|
2
4
|
//#region src/tpr.ts
|
|
3
5
|
/**
|
|
4
6
|
* TPR: traffic-aware pre-warm route selection
|
|
@@ -7,7 +9,7 @@ import { parseWranglerConfig } from "./wrangler-config.js";
|
|
|
7
9
|
* the standard CDN pre-warming flow.
|
|
8
10
|
*
|
|
9
11
|
* Flow:
|
|
10
|
-
* 1.
|
|
12
|
+
* 1. Find the custom domain in the generated Worker or Wrangler config
|
|
11
13
|
* 2. Resolve the Cloudflare zone for the custom domain
|
|
12
14
|
* 3. Query zone analytics (GraphQL) for top pages by request count
|
|
13
15
|
* 4. Return the ranked candidates for standard route resolution and selection
|
|
@@ -143,9 +145,11 @@ async function resolveTPRRoutes(options) {
|
|
|
143
145
|
});
|
|
144
146
|
const apiToken = process.env.CLOUDFLARE_API_TOKEN;
|
|
145
147
|
if (!apiToken) return skip("no CLOUDFLARE_API_TOKEN set");
|
|
146
|
-
const wranglerConfig = parseWranglerConfig(root, config);
|
|
147
|
-
|
|
148
|
-
const
|
|
148
|
+
const wranglerConfig = options.hostname || options.typedConfig ? null : parseWranglerConfig(root, config);
|
|
149
|
+
const buildOutputConfigPath = path.join(root, ".cloudflare/output/v0/workers/default/worker.config.json");
|
|
150
|
+
const typedDomains = options.typedConfig && !options.hostname && fs.existsSync(buildOutputConfigPath) ? JSON.parse(fs.readFileSync(buildOutputConfigPath, "utf8")).domains : void 0;
|
|
151
|
+
if (!wranglerConfig && !options.hostname && !options.typedConfig) return skip("could not parse wrangler config");
|
|
152
|
+
const hostname = options.hostname ?? (Array.isArray(typedDomains) ? typedDomains.find((domain) => typeof domain === "string" && domain.length > 0) : void 0) ?? wranglerConfig?.env?.[options.env ?? ""]?.customDomain ?? wranglerConfig?.customDomain;
|
|
149
153
|
if (!hostname) return skip("no custom domain — zone analytics unavailable");
|
|
150
154
|
console.log(` TPR: Analyzing zone traffic for ${hostname} (last ${windowHours}h)`);
|
|
151
155
|
const zoneId = await resolveZoneId(hostname, apiToken);
|
package/dist/version-deploy.d.ts
CHANGED
|
@@ -25,19 +25,46 @@ type WranglerVersionArgs = {
|
|
|
25
25
|
args: string[];
|
|
26
26
|
env: string | undefined;
|
|
27
27
|
};
|
|
28
|
+
type CfVersionArgs = {
|
|
29
|
+
args: string[];
|
|
30
|
+
mode: string | undefined;
|
|
31
|
+
};
|
|
32
|
+
export declare function readBuildOutputWorkerName(root: string): string;
|
|
28
33
|
export declare function parseVersionId(output: string): string | null;
|
|
29
34
|
export declare function parseUploadedWorkerName(output: string): string | null;
|
|
30
35
|
export declare function parseWranglerVersionUploadOutput(output: string): WranglerVersionUploadResult;
|
|
31
36
|
export declare function buildWranglerVersionUploadArgs(options: Pick<DeployOptions, "preview" | "env" | "name" | "config" | "verbose"> & {
|
|
32
37
|
previewAlias?: string;
|
|
33
38
|
}): WranglerVersionArgs;
|
|
39
|
+
export declare function buildCfVersionUploadArgs(options: Pick<DeployOptions, "preview" | "env"> & {
|
|
40
|
+
previewAlias?: string;
|
|
41
|
+
}): CfVersionArgs;
|
|
34
42
|
export declare function buildWranglerVersionDeployArgs(versionTraffic: readonly WranglerVersionTraffic[], options: Pick<DeployOptions, "preview" | "env" | "name" | "config" | "verbose">): WranglerVersionArgs;
|
|
35
43
|
export declare function buildWranglerDeploymentsStatusArgs(options: Pick<DeployOptions, "preview" | "env" | "name" | "config" | "verbose">): WranglerVersionArgs;
|
|
36
44
|
export declare function buildWranglerTriggersDeployArgs(options: Pick<DeployOptions, "preview" | "env" | "name" | "config" | "verbose">): WranglerVersionArgs;
|
|
37
45
|
export declare function parseWranglerDeploymentStatusOutput(output: string): WranglerDeploymentStatus;
|
|
46
|
+
/** The first entry is the deployment currently serving traffic. */
|
|
47
|
+
export declare function parseCfDeploymentStatusOutput(output: string): WranglerDeploymentStatus;
|
|
48
|
+
export declare function runCfDeploymentStatus(root: string, options: {
|
|
49
|
+
name: string;
|
|
50
|
+
env?: string;
|
|
51
|
+
verbose?: boolean;
|
|
52
|
+
}, execute?: typeof execFileSync): WranglerDeploymentStatus;
|
|
53
|
+
export declare function runCfVersionDeploy(root: string, versionTraffic: readonly WranglerVersionTraffic[], options: {
|
|
54
|
+
name: string;
|
|
55
|
+
env?: string;
|
|
56
|
+
verbose?: boolean;
|
|
57
|
+
}, _phase?: "stage" | "promote-warmed" | "promote-uploaded", execute?: typeof execFileSync): WranglerVersionDeployResult;
|
|
58
|
+
export declare function runCfTriggersDeploy(root: string, options: {
|
|
59
|
+
env?: string;
|
|
60
|
+
verbose?: boolean;
|
|
61
|
+
}, execute?: typeof execFileSync): WranglerVersionDeployResult;
|
|
38
62
|
export declare function runWranglerVersionUpload(root: string, options: Pick<DeployOptions, "preview" | "env" | "name" | "config" | "verbose"> & {
|
|
39
63
|
previewAlias?: string;
|
|
40
64
|
}, execute?: typeof execFileSync): WranglerVersionUploadResult;
|
|
65
|
+
export declare function runCfVersionUpload(root: string, options: Pick<DeployOptions, "preview" | "env" | "name" | "config" | "verbose"> & {
|
|
66
|
+
previewAlias?: string;
|
|
67
|
+
}, execute?: typeof execFileSync): WranglerVersionUploadResult;
|
|
41
68
|
export declare function runWranglerVersionDeploy(root: string, versionTraffic: readonly WranglerVersionTraffic[], options: Pick<DeployOptions, "preview" | "env" | "name" | "config" | "verbose">, phase?: "stage" | "promote-warmed" | "promote-uploaded", execute?: typeof execFileSync): WranglerVersionDeployResult;
|
|
42
69
|
export declare function runWranglerDeploymentStatus(root: string, options: Pick<DeployOptions, "preview" | "env" | "name" | "config" | "verbose">, execute?: typeof execFileSync): WranglerDeploymentStatus;
|
|
43
70
|
export declare function runWranglerTriggersDeploy(root: string, options: Pick<DeployOptions, "preview" | "env" | "name" | "config" | "verbose">, execute?: typeof execFileSync): WranglerVersionDeployResult;
|
package/dist/version-deploy.js
CHANGED
|
@@ -1,11 +1,26 @@
|
|
|
1
1
|
import { parseWorkersDevUrl } from "./workers-dev-url.js";
|
|
2
2
|
import { parseCdnWarmupDeploymentUrl } from "./worker-deployment-url.js";
|
|
3
|
-
import { buildNodeCliInvocation, resolveWranglerBin, validateWranglerEnvName } from "./deploy.js";
|
|
3
|
+
import { buildNodeCliInvocation, resolveCfBin, resolveWranglerBin, validateWranglerEnvName } from "./deploy.js";
|
|
4
|
+
import fs from "node:fs";
|
|
5
|
+
import path from "node:path";
|
|
4
6
|
import { execFileSync } from "node:child_process";
|
|
7
|
+
import { stripVTControlCharacters } from "node:util";
|
|
5
8
|
//#region src/version-deploy.ts
|
|
6
9
|
function isRecord(value) {
|
|
7
10
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
8
11
|
}
|
|
12
|
+
function readBuildOutputWorkerName(root) {
|
|
13
|
+
const configPath = path.join(root, ".cloudflare", "output", "v0", "workers", "default", "worker.config.json");
|
|
14
|
+
let config;
|
|
15
|
+
try {
|
|
16
|
+
config = JSON.parse(fs.readFileSync(configPath, "utf8"));
|
|
17
|
+
} catch (cause) {
|
|
18
|
+
throw new Error("Could not read the generated Cloudflare Build Output config. Rebuild the app before deploying.", { cause });
|
|
19
|
+
}
|
|
20
|
+
const name = isRecord(config) ? config.name : void 0;
|
|
21
|
+
if (typeof name !== "string" || name.length === 0) throw new Error("The generated Cloudflare Build Output config does not declare a Worker name.");
|
|
22
|
+
return name;
|
|
23
|
+
}
|
|
9
24
|
function parseJsonObject(output) {
|
|
10
25
|
const trimmed = output.trim();
|
|
11
26
|
if (!trimmed.startsWith("{") && !trimmed.startsWith("[")) return null;
|
|
@@ -63,7 +78,7 @@ function parseVersionId(output) {
|
|
|
63
78
|
return output.match(new RegExp(`\\b${versionIdPattern}\\b`))?.[0] ?? null;
|
|
64
79
|
}
|
|
65
80
|
function parseUploadedWorkerName(output) {
|
|
66
|
-
return output.match(/^\s*Uploaded\s+(\S+)\s+\(\d+(?:\.\d+)?\s+sec\)\s*$/im)?.[1] ?? null;
|
|
81
|
+
return stripVTControlCharacters(output).match(/^\s*(?:[│|]\s*)?Uploaded\s+(\S+)\s+\(\d+(?:\.\d+)?\s+sec\)\s*$/im)?.[1] ?? null;
|
|
67
82
|
}
|
|
68
83
|
function parseWranglerVersionUploadOutput(output) {
|
|
69
84
|
const parsed = parseJsonObject(output);
|
|
@@ -90,6 +105,21 @@ function buildWranglerVersionUploadArgs(options) {
|
|
|
90
105
|
env
|
|
91
106
|
};
|
|
92
107
|
}
|
|
108
|
+
function buildCfVersionUploadArgs(options) {
|
|
109
|
+
const mode = options.env || (options.preview ? "preview" : void 0);
|
|
110
|
+
const args = [
|
|
111
|
+
"workers",
|
|
112
|
+
"versions",
|
|
113
|
+
"create",
|
|
114
|
+
"--prebuilt"
|
|
115
|
+
];
|
|
116
|
+
if (mode) args.push("--mode", validateWranglerEnvName(mode));
|
|
117
|
+
if (options.previewAlias) args.push("--preview-alias", options.previewAlias);
|
|
118
|
+
return {
|
|
119
|
+
args,
|
|
120
|
+
mode
|
|
121
|
+
};
|
|
122
|
+
}
|
|
93
123
|
function buildWranglerVersionDeployArgs(versionTraffic, options) {
|
|
94
124
|
const args = [
|
|
95
125
|
"versions",
|
|
@@ -145,6 +175,17 @@ function runWranglerCommand(root, args, execute = execFileSync, verbose = false)
|
|
|
145
175
|
if (verbose && output.trim()) for (const line of output.trim().split("\n")) console.log(` ${line}`);
|
|
146
176
|
return output;
|
|
147
177
|
}
|
|
178
|
+
function runCfCommand(root, args, execute = execFileSync, verbose = false) {
|
|
179
|
+
const invocation = buildNodeCliInvocation(resolveCfBin(root), args);
|
|
180
|
+
const output = execute(invocation.file, invocation.args, {
|
|
181
|
+
cwd: root,
|
|
182
|
+
stdio: "pipe",
|
|
183
|
+
encoding: "utf-8",
|
|
184
|
+
shell: false
|
|
185
|
+
});
|
|
186
|
+
if (verbose && output.trim()) for (const line of output.trim().split("\n")) console.log(` ${line}`);
|
|
187
|
+
return output;
|
|
188
|
+
}
|
|
148
189
|
function errorText(error) {
|
|
149
190
|
if (!error || typeof error !== "object") return String(error);
|
|
150
191
|
const parts = error instanceof Error ? [error.message] : [];
|
|
@@ -195,6 +236,69 @@ function parseWranglerDeploymentStatusOutput(output) {
|
|
|
195
236
|
output
|
|
196
237
|
};
|
|
197
238
|
}
|
|
239
|
+
/** The first entry is the deployment currently serving traffic. */
|
|
240
|
+
function parseCfDeploymentStatusOutput(output) {
|
|
241
|
+
const parsed = parseJsonObject(output);
|
|
242
|
+
if (!isRecord(parsed) || !Array.isArray(parsed.deployments) || !parsed.deployments.length) throw new Error("Could not parse the active deployment from `cf workers deployments list` output.");
|
|
243
|
+
const current = parsed.deployments[0];
|
|
244
|
+
const deploymentId = findStringInRecord(current, [
|
|
245
|
+
"id",
|
|
246
|
+
"deployment_id",
|
|
247
|
+
"deploymentId"
|
|
248
|
+
]);
|
|
249
|
+
const versions = parseDeploymentVersions(current);
|
|
250
|
+
if (!deploymentId || !versions.length) throw new Error("The active `cf workers deployments list` entry is missing its ID or versions.");
|
|
251
|
+
return {
|
|
252
|
+
deploymentId,
|
|
253
|
+
versions,
|
|
254
|
+
output
|
|
255
|
+
};
|
|
256
|
+
}
|
|
257
|
+
function runCfDeploymentStatus(root, options, execute = execFileSync) {
|
|
258
|
+
return parseCfDeploymentStatusOutput(runCfCommand(root, [
|
|
259
|
+
"workers",
|
|
260
|
+
"deployments",
|
|
261
|
+
"list",
|
|
262
|
+
"--worker",
|
|
263
|
+
options.name,
|
|
264
|
+
...options.env ? ["--mode", validateWranglerEnvName(options.env)] : []
|
|
265
|
+
], execute, options.verbose));
|
|
266
|
+
}
|
|
267
|
+
function runCfVersionDeploy(root, versionTraffic, options, _phase = "promote-uploaded", execute = execFileSync) {
|
|
268
|
+
const versions = versionTraffic.map(({ versionId, percentage }) => ({
|
|
269
|
+
version_id: versionId,
|
|
270
|
+
percentage
|
|
271
|
+
}));
|
|
272
|
+
const output = runCfCommand(root, [
|
|
273
|
+
"workers",
|
|
274
|
+
"deployments",
|
|
275
|
+
"create",
|
|
276
|
+
"--worker",
|
|
277
|
+
options.name,
|
|
278
|
+
"--strategy",
|
|
279
|
+
"percentage",
|
|
280
|
+
"--versions",
|
|
281
|
+
JSON.stringify(versions),
|
|
282
|
+
...options.env ? ["--mode", validateWranglerEnvName(options.env)] : []
|
|
283
|
+
], execute, options.verbose);
|
|
284
|
+
return {
|
|
285
|
+
deployedUrl: parseWorkersDevUrl(output),
|
|
286
|
+
output
|
|
287
|
+
};
|
|
288
|
+
}
|
|
289
|
+
function runCfTriggersDeploy(root, options, execute = execFileSync) {
|
|
290
|
+
const output = runCfCommand(root, [
|
|
291
|
+
"workers",
|
|
292
|
+
"triggers",
|
|
293
|
+
"deploy",
|
|
294
|
+
"--prebuilt",
|
|
295
|
+
...options.env ? ["--mode", validateWranglerEnvName(options.env)] : []
|
|
296
|
+
], execute, options.verbose);
|
|
297
|
+
return {
|
|
298
|
+
deployedUrl: parseCdnWarmupDeploymentUrl(output),
|
|
299
|
+
output
|
|
300
|
+
};
|
|
301
|
+
}
|
|
198
302
|
function runWranglerVersionUpload(root, options, execute = execFileSync) {
|
|
199
303
|
const { args, env } = buildWranglerVersionUploadArgs(options);
|
|
200
304
|
if (env) console.log(`\n Uploading Worker version for env: ${env}...`);
|
|
@@ -208,6 +312,20 @@ function runWranglerVersionUpload(root, options, execute = execFileSync) {
|
|
|
208
312
|
throw error;
|
|
209
313
|
}
|
|
210
314
|
}
|
|
315
|
+
function runCfVersionUpload(root, options, execute = execFileSync) {
|
|
316
|
+
const workerName = readBuildOutputWorkerName(root);
|
|
317
|
+
const { args, mode } = buildCfVersionUploadArgs(options);
|
|
318
|
+
console.log(mode ? `\n Uploading Worker Build Output in mode: ${mode}...` : "\n Uploading Worker Build Output...");
|
|
319
|
+
try {
|
|
320
|
+
return {
|
|
321
|
+
...parseWranglerVersionUploadOutput(runCfCommand(root, args, execute, options.verbose === true)),
|
|
322
|
+
workerName
|
|
323
|
+
};
|
|
324
|
+
} catch (error) {
|
|
325
|
+
if (isMissingWorkerVersionUploadError(error)) throw withInitialDeployRequiredMessage();
|
|
326
|
+
throw error;
|
|
327
|
+
}
|
|
328
|
+
}
|
|
211
329
|
function runWranglerVersionDeploy(root, versionTraffic, options, phase = "promote-uploaded", execute = execFileSync) {
|
|
212
330
|
const { args, env } = buildWranglerVersionDeployArgs(versionTraffic, options);
|
|
213
331
|
const target = env ? `env: ${env}` : "production";
|
|
@@ -239,4 +357,4 @@ function runWranglerTriggersDeploy(root, options, execute = execFileSync) {
|
|
|
239
357
|
};
|
|
240
358
|
}
|
|
241
359
|
//#endregion
|
|
242
|
-
export { buildWranglerDeploymentsStatusArgs, buildWranglerTriggersDeployArgs, buildWranglerVersionDeployArgs, buildWranglerVersionUploadArgs, parseUploadedWorkerName, parseVersionId, parseWorkersDevUrl, parseWranglerDeploymentStatusOutput, parseWranglerVersionUploadOutput, runWranglerDeploymentStatus, runWranglerTriggersDeploy, runWranglerVersionDeploy, runWranglerVersionUpload };
|
|
360
|
+
export { buildCfVersionUploadArgs, buildWranglerDeploymentsStatusArgs, buildWranglerTriggersDeployArgs, buildWranglerVersionDeployArgs, buildWranglerVersionUploadArgs, parseCfDeploymentStatusOutput, parseUploadedWorkerName, parseVersionId, parseWorkersDevUrl, parseWranglerDeploymentStatusOutput, parseWranglerVersionUploadOutput, readBuildOutputWorkerName, runCfDeploymentStatus, runCfTriggersDeploy, runCfVersionDeploy, runCfVersionUpload, runWranglerDeploymentStatus, runWranglerTriggersDeploy, runWranglerVersionDeploy, runWranglerVersionUpload };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vinext/cloudflare",
|
|
3
|
-
"version": "1.0.0-beta.
|
|
3
|
+
"version": "1.0.0-beta.11",
|
|
4
4
|
"description": "Cloudflare cache and image adapters for vinext.",
|
|
5
5
|
"homepage": "https://vinext.dev/",
|
|
6
6
|
"license": "MIT",
|
|
@@ -51,15 +51,22 @@
|
|
|
51
51
|
"@cloudflare/workers-response-store": "0.1.0-beta.2"
|
|
52
52
|
},
|
|
53
53
|
"devDependencies": {
|
|
54
|
+
"@cloudflare/vite-plugin": "2.0.0-beta.sha-805ec1ff3",
|
|
54
55
|
"@types/node": "^25.9.2",
|
|
55
56
|
"miniflare": "5.20260730.0-alpha",
|
|
56
57
|
"vite": "npm:@voidzero-dev/vite-plus-core@0.3.2",
|
|
57
58
|
"vite-plus": "0.3.2",
|
|
58
59
|
"vitest": "4.1.11",
|
|
59
|
-
"vinext": "1.0.0-beta.
|
|
60
|
+
"vinext": "1.0.0-beta.13"
|
|
60
61
|
},
|
|
61
62
|
"peerDependencies": {
|
|
62
|
-
"
|
|
63
|
+
"@cloudflare/vite-plugin": "*",
|
|
64
|
+
"vinext": "^1.0.0-beta.13"
|
|
65
|
+
},
|
|
66
|
+
"peerDependenciesMeta": {
|
|
67
|
+
"@cloudflare/vite-plugin": {
|
|
68
|
+
"optional": true
|
|
69
|
+
}
|
|
63
70
|
},
|
|
64
71
|
"engines": {
|
|
65
72
|
"node": ">=22"
|