wrangler 2.0.8 → 2.0.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/package.json +1 -1
- package/src/__tests__/dev.test.tsx +61 -58
- package/src/__tests__/init.test.ts +3 -0
- package/src/__tests__/pages.test.ts +98 -1
- package/src/__tests__/publish.test.ts +123 -3
- package/src/__tests__/whoami.test.tsx +34 -0
- package/src/cfetch/internal.ts +6 -9
- package/src/config/config.ts +1 -1
- package/src/create-worker-preview.ts +15 -15
- package/src/dev/dev.tsx +4 -12
- package/src/dev/remote.tsx +26 -16
- package/src/index.tsx +22 -83
- package/src/pages.tsx +14 -3
- package/src/publish.ts +148 -15
- package/src/user.tsx +12 -1
- package/src/whoami.tsx +3 -2
- package/src/worker.ts +2 -1
- package/src/zones.ts +73 -0
- package/wrangler-dist/cli.js +188 -80
package/src/zones.ts
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { fetchListResult } from "./cfetch";
|
|
2
|
+
import type { Route } from "./config/environment";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* An object holding information about a zone for publishing.
|
|
6
|
+
*/
|
|
7
|
+
export interface Zone {
|
|
8
|
+
id: string;
|
|
9
|
+
host: string;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Try to compute the a zone ID and host name for one or more routes.
|
|
14
|
+
*
|
|
15
|
+
* When we're given a route, we do 2 things:
|
|
16
|
+
* - We try to extract a host from it
|
|
17
|
+
* - We try to get a zone id from the host
|
|
18
|
+
*/
|
|
19
|
+
export async function getZoneForRoute(route: Route): Promise<Zone | undefined> {
|
|
20
|
+
const host =
|
|
21
|
+
typeof route === "string"
|
|
22
|
+
? getHostFromUrl(route)
|
|
23
|
+
: typeof route === "object"
|
|
24
|
+
? "zone_name" in route
|
|
25
|
+
? getHostFromUrl(route.zone_name)
|
|
26
|
+
: getHostFromUrl(route.pattern)
|
|
27
|
+
: undefined;
|
|
28
|
+
const id =
|
|
29
|
+
typeof route === "object" && "zone_id" in route
|
|
30
|
+
? route.zone_id
|
|
31
|
+
: host
|
|
32
|
+
? await getZoneIdFromHost(host)
|
|
33
|
+
: undefined;
|
|
34
|
+
return id && host ? { id, host } : undefined;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Given something that resembles a URL, try to extract a host from it.
|
|
39
|
+
*/
|
|
40
|
+
function getHostFromUrl(urlLike: string): string | undefined {
|
|
41
|
+
// strip leading * / *.
|
|
42
|
+
urlLike = urlLike.replace(/^\*(\.)?/g, "");
|
|
43
|
+
|
|
44
|
+
if (!(urlLike.startsWith("http://") || urlLike.startsWith("https://"))) {
|
|
45
|
+
urlLike = "http://" + urlLike;
|
|
46
|
+
}
|
|
47
|
+
return new URL(urlLike).host;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Given something that resembles a host, try to infer a zone id from it.
|
|
52
|
+
*
|
|
53
|
+
* It's hard to get a 'valid' domain from a string, so we don't even try to validate TLDs, etc.
|
|
54
|
+
* For each domain-like part of the host (e.g. w.x.y.z) try to get a zone id for it by
|
|
55
|
+
* lopping off subdomains until we get a hit from the API.
|
|
56
|
+
*/
|
|
57
|
+
export async function getZoneIdFromHost(host: string): Promise<string> {
|
|
58
|
+
const hostPieces = host.split(".");
|
|
59
|
+
|
|
60
|
+
while (hostPieces.length > 1) {
|
|
61
|
+
const zones = await fetchListResult<{ id: string }>(
|
|
62
|
+
`/zones`,
|
|
63
|
+
{},
|
|
64
|
+
new URLSearchParams({ name: hostPieces.join(".") })
|
|
65
|
+
);
|
|
66
|
+
if (zones.length > 0) {
|
|
67
|
+
return zones[0].id;
|
|
68
|
+
}
|
|
69
|
+
hostPieces.shift();
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
throw new Error(`Could not find zone for ${host}`);
|
|
73
|
+
}
|
package/wrangler-dist/cli.js
CHANGED
|
@@ -116942,7 +116942,7 @@ var yargs_default = Yargs;
|
|
|
116942
116942
|
|
|
116943
116943
|
// package.json
|
|
116944
116944
|
var name = "wrangler";
|
|
116945
|
-
var version = "2.0.
|
|
116945
|
+
var version = "2.0.9";
|
|
116946
116946
|
var author = "wrangler@cloudflare.com";
|
|
116947
116947
|
var description = "Command-line interface for all things Cloudflare Workers";
|
|
116948
116948
|
var bin = {
|
|
@@ -117223,6 +117223,7 @@ function indexLocation(file, index) {
|
|
|
117223
117223
|
|
|
117224
117224
|
// src/cfetch/internal.ts
|
|
117225
117225
|
init_import_meta_url();
|
|
117226
|
+
var import_node_assert2 = __toESM(require("node:assert"));
|
|
117226
117227
|
var import_undici2 = __toESM(require_undici());
|
|
117227
117228
|
|
|
117228
117229
|
// src/environment-variables.ts
|
|
@@ -117940,6 +117941,13 @@ async function requireAuth(config) {
|
|
|
117940
117941
|
}
|
|
117941
117942
|
return accountId;
|
|
117942
117943
|
}
|
|
117944
|
+
function requireApiToken() {
|
|
117945
|
+
const authToken = getAPIToken();
|
|
117946
|
+
if (!authToken) {
|
|
117947
|
+
throw new Error("No API token found.");
|
|
117948
|
+
}
|
|
117949
|
+
return authToken;
|
|
117950
|
+
}
|
|
117943
117951
|
|
|
117944
117952
|
// src/cfetch/internal.ts
|
|
117945
117953
|
var getCloudflareAPIBaseURL = getEnvironmentVariableFactory({
|
|
@@ -117948,6 +117956,7 @@ var getCloudflareAPIBaseURL = getEnvironmentVariableFactory({
|
|
|
117948
117956
|
defaultValue: "https://api.cloudflare.com/client/v4"
|
|
117949
117957
|
});
|
|
117950
117958
|
async function fetchInternal(resource, init = {}, queryParams, abortSignal) {
|
|
117959
|
+
(0, import_node_assert2.default)(resource.startsWith("/"), `CF API fetch - resource path must start with a "/" but got "${resource}"`);
|
|
117951
117960
|
await requireLoggedIn();
|
|
117952
117961
|
const apiToken = requireApiToken();
|
|
117953
117962
|
const headers = cloneHeaders(init.headers);
|
|
@@ -117994,13 +118003,6 @@ async function requireLoggedIn() {
|
|
|
117994
118003
|
throw new Error("Not logged in.");
|
|
117995
118004
|
}
|
|
117996
118005
|
}
|
|
117997
|
-
function requireApiToken() {
|
|
117998
|
-
const authToken = getAPIToken();
|
|
117999
|
-
if (!authToken) {
|
|
118000
|
-
throw new Error("No API token found.");
|
|
118001
|
-
}
|
|
118002
|
-
return authToken;
|
|
118003
|
-
}
|
|
118004
118006
|
function addAuthorizationHeaderIfUnspecified(headers, apiToken) {
|
|
118005
118007
|
if (!("Authorization" in headers)) {
|
|
118006
118008
|
headers["Authorization"] = `Bearer ${apiToken}`;
|
|
@@ -119451,7 +119453,7 @@ var import_undici5 = __toESM(require_undici());
|
|
|
119451
119453
|
|
|
119452
119454
|
// src/entry.ts
|
|
119453
119455
|
init_import_meta_url();
|
|
119454
|
-
var
|
|
119456
|
+
var import_node_assert3 = __toESM(require("node:assert"));
|
|
119455
119457
|
var import_node_fs4 = require("node:fs");
|
|
119456
119458
|
var import_node_path10 = __toESM(require("node:path"));
|
|
119457
119459
|
var esbuild = __toESM(require("esbuild"));
|
|
@@ -119528,8 +119530,8 @@ async function guessWorkerFormat(entryFile, entryWorkingDirectory, hint, tsconfi
|
|
|
119528
119530
|
});
|
|
119529
119531
|
const metafile = result.metafile;
|
|
119530
119532
|
const entryPoints = Object.entries(metafile.outputs).filter(([_path, output]) => output.entryPoint !== void 0);
|
|
119531
|
-
(0,
|
|
119532
|
-
(0,
|
|
119533
|
+
(0, import_node_assert3.default)(entryPoints.length > 0, `Cannot find entry-point "${entryFile}" in generated bundle.` + listEntryPoints(entryPoints));
|
|
119534
|
+
(0, import_node_assert3.default)(entryPoints.length < 2, "More than one entry-point found for generated bundle." + listEntryPoints(entryPoints));
|
|
119533
119535
|
let guessedWorkerFormat;
|
|
119534
119536
|
const scriptExports = entryPoints[0][1].exports;
|
|
119535
119537
|
if (scriptExports.length > 0) {
|
|
@@ -119623,7 +119625,7 @@ Did you mean to set the main field to${possiblePaths.length > 1 ? " one of" : ""
|
|
|
119623
119625
|
|
|
119624
119626
|
// src/inspect.ts
|
|
119625
119627
|
init_import_meta_url();
|
|
119626
|
-
var
|
|
119628
|
+
var import_node_assert4 = __toESM(require("node:assert"));
|
|
119627
119629
|
var import_node_http3 = require("node:http");
|
|
119628
119630
|
var import_node_os6 = __toESM(require("node:os"));
|
|
119629
119631
|
var import_node_url8 = require("node:url");
|
|
@@ -120138,7 +120140,7 @@ function useInspector(props) {
|
|
|
120138
120140
|
}
|
|
120139
120141
|
function sendMessageToRemoteWebSocket(event) {
|
|
120140
120142
|
try {
|
|
120141
|
-
(0,
|
|
120143
|
+
(0, import_node_assert4.default)(remoteWebSocket, "Trying to send a message to an undefined `remoteWebSocket`");
|
|
120142
120144
|
remoteWebSocket.send(event.data);
|
|
120143
120145
|
} catch (e2) {
|
|
120144
120146
|
if (e2.message !== "WebSocket is not open: readyState 0 (CONNECTING)") {
|
|
@@ -120147,7 +120149,7 @@ function useInspector(props) {
|
|
|
120147
120149
|
}
|
|
120148
120150
|
}
|
|
120149
120151
|
function sendMessageToLocalWebSocket(event) {
|
|
120150
|
-
(0,
|
|
120152
|
+
(0, import_node_assert4.default)(localWebSocket, "Trying to send a message to an undefined `localWebSocket`");
|
|
120151
120153
|
localWebSocket.send(event.data);
|
|
120152
120154
|
}
|
|
120153
120155
|
if (localWebSocket && remoteWebSocket) {
|
|
@@ -120645,7 +120647,6 @@ function useLocalWorker({
|
|
|
120645
120647
|
|
|
120646
120648
|
// src/dev/remote.tsx
|
|
120647
120649
|
init_import_meta_url();
|
|
120648
|
-
var import_node_assert5 = __toESM(require("node:assert"));
|
|
120649
120650
|
var import_promises4 = require("node:fs/promises");
|
|
120650
120651
|
var import_node_path13 = __toESM(require("node:path"));
|
|
120651
120652
|
var import_react5 = __toESM(require_react());
|
|
@@ -120656,7 +120657,7 @@ var import_node_url9 = require("node:url");
|
|
|
120656
120657
|
var import_undici4 = __toESM(require_undici());
|
|
120657
120658
|
async function sessionToken(account, ctx, abortSignal) {
|
|
120658
120659
|
const { accountId } = account;
|
|
120659
|
-
const initUrl = ctx.zone ? `/zones/${ctx.zone
|
|
120660
|
+
const initUrl = ctx.zone ? `/zones/${ctx.zone}/workers/edge-preview` : `/accounts/${accountId}/workers/subdomain/edge-preview`;
|
|
120660
120661
|
const { exchange_url } = await fetchResult(initUrl, void 0, void 0, abortSignal);
|
|
120661
120662
|
const { inspector_websocket, prewarm, token } = await (await (0, import_undici4.fetch)(exchange_url, { signal: abortSignal })).json();
|
|
120662
120663
|
const { host } = new import_node_url9.URL(inspector_websocket);
|
|
@@ -120677,7 +120678,7 @@ function randomId2() {
|
|
|
120677
120678
|
async function createPreviewToken(account, worker, ctx, abortSignal) {
|
|
120678
120679
|
const { value, host, inspectorUrl, prewarmUrl } = await sessionToken(account, ctx, abortSignal);
|
|
120679
120680
|
const { accountId } = account;
|
|
120680
|
-
const scriptId = ctx.zone ? randomId2() :
|
|
120681
|
+
const scriptId = worker.name || (ctx.zone ? randomId2() : host.split(".")[0]);
|
|
120681
120682
|
const url3 = ctx.env && !ctx.legacyEnv ? `/accounts/${accountId}/workers/services/${scriptId}/environments/${ctx.env}/edge-preview` : `/accounts/${accountId}/workers/scripts/${scriptId}/edge-preview`;
|
|
120682
120683
|
const mode = ctx.zone ? { routes: ["*/*"] } : { workers_dev: true };
|
|
120683
120684
|
const formData = createWorkerUploadForm(worker);
|
|
@@ -120691,7 +120692,7 @@ async function createPreviewToken(account, worker, ctx, abortSignal) {
|
|
|
120691
120692
|
}, void 0, abortSignal);
|
|
120692
120693
|
return {
|
|
120693
120694
|
value: preview_token,
|
|
120694
|
-
host: ctx.
|
|
120695
|
+
host: ctx.host ?? (worker.name ? `${worker.name}.${host.split(".").slice(1).join(".")}` : host),
|
|
120695
120696
|
inspectorUrl,
|
|
120696
120697
|
prewarmUrl
|
|
120697
120698
|
};
|
|
@@ -120713,7 +120714,7 @@ async function createWorkerPreview(init, account, ctx, abortSignal) {
|
|
|
120713
120714
|
|
|
120714
120715
|
// src/sites.tsx
|
|
120715
120716
|
init_import_meta_url();
|
|
120716
|
-
var
|
|
120717
|
+
var import_node_assert5 = __toESM(require("node:assert"));
|
|
120717
120718
|
var import_promises3 = require("node:fs/promises");
|
|
120718
120719
|
var path13 = __toESM(require("node:path"));
|
|
120719
120720
|
var import_ignore = __toESM(require_ignore());
|
|
@@ -120992,7 +120993,7 @@ async function syncAssets(accountId, scriptName, siteAssets, preview, dryRun) {
|
|
|
120992
120993
|
logger.log("(Note: doing a dry run, not uploading or deleting anything.)");
|
|
120993
120994
|
return { manifest: void 0, namespace: void 0 };
|
|
120994
120995
|
}
|
|
120995
|
-
(0,
|
|
120996
|
+
(0, import_node_assert5.default)(accountId, "Missing accountId");
|
|
120996
120997
|
const title = `__${scriptName}-workers_sites_assets${preview ? "_preview" : ""}`;
|
|
120997
120998
|
const { id: namespace } = await createKVNamespaceIfNotAlreadyExisting(title, accountId);
|
|
120998
120999
|
const namespaceKeysResponse = await listKVNamespaceKeys(accountId, namespace);
|
|
@@ -121074,15 +121075,12 @@ function getAssetPaths(config, assetDirectory = config.site?.bucket, includePatt
|
|
|
121074
121075
|
|
|
121075
121076
|
// src/dev/remote.tsx
|
|
121076
121077
|
function Remote(props) {
|
|
121077
|
-
(0, import_node_assert5.default)(props.accountId, "accountId is required");
|
|
121078
|
-
(0, import_node_assert5.default)(props.apiToken, "apiToken is required");
|
|
121079
121078
|
const previewToken = useWorker({
|
|
121080
121079
|
name: props.name,
|
|
121081
121080
|
bundle: props.bundle,
|
|
121082
121081
|
format: props.format,
|
|
121083
121082
|
modules: props.bundle ? props.bundle.modules : [],
|
|
121084
121083
|
accountId: props.accountId,
|
|
121085
|
-
apiToken: props.apiToken,
|
|
121086
121084
|
bindings: props.bindings,
|
|
121087
121085
|
assetPaths: props.assetPaths,
|
|
121088
121086
|
port: props.port,
|
|
@@ -121091,7 +121089,8 @@ function Remote(props) {
|
|
|
121091
121089
|
usageModel: props.usageModel,
|
|
121092
121090
|
env: props.env,
|
|
121093
121091
|
legacyEnv: props.legacyEnv,
|
|
121094
|
-
zone: props.zone
|
|
121092
|
+
zone: props.zone,
|
|
121093
|
+
host: props.host
|
|
121095
121094
|
});
|
|
121096
121095
|
usePreviewServer({
|
|
121097
121096
|
previewToken,
|
|
@@ -121114,7 +121113,6 @@ function useWorker(props) {
|
|
|
121114
121113
|
format: format4,
|
|
121115
121114
|
modules,
|
|
121116
121115
|
accountId,
|
|
121117
|
-
apiToken,
|
|
121118
121116
|
bindings,
|
|
121119
121117
|
assetPaths,
|
|
121120
121118
|
compatibilityDate,
|
|
@@ -121124,6 +121122,7 @@ function useWorker(props) {
|
|
|
121124
121122
|
} = props;
|
|
121125
121123
|
const [token, setToken] = (0, import_react5.useState)();
|
|
121126
121124
|
const startedRef = (0, import_react5.useRef)(false);
|
|
121125
|
+
const accountIdRef = (0, import_react5.useRef)(accountId);
|
|
121127
121126
|
(0, import_react5.useEffect)(() => {
|
|
121128
121127
|
const abortController = new AbortController();
|
|
121129
121128
|
async function start() {
|
|
@@ -121135,7 +121134,10 @@ function useWorker(props) {
|
|
|
121135
121134
|
} else {
|
|
121136
121135
|
logger.log("\u2394 Detected changes, restarted server.");
|
|
121137
121136
|
}
|
|
121138
|
-
|
|
121137
|
+
accountIdRef.current = await requireAuth({
|
|
121138
|
+
account_id: accountIdRef.current
|
|
121139
|
+
});
|
|
121140
|
+
const assets = await syncAssets(accountIdRef.current, name2 + (!props.legacyEnv && props.env ? `-${props.env}` : ""), assetPaths, true, false);
|
|
121139
121141
|
const content = await (0, import_promises4.readFile)(bundle.path, "utf-8");
|
|
121140
121142
|
const init = {
|
|
121141
121143
|
name: name2,
|
|
@@ -121165,16 +121167,21 @@ function useWorker(props) {
|
|
|
121165
121167
|
usage_model: usageModel
|
|
121166
121168
|
};
|
|
121167
121169
|
setToken(await createWorkerPreview(init, {
|
|
121168
|
-
accountId,
|
|
121169
|
-
apiToken
|
|
121170
|
-
}, {
|
|
121170
|
+
accountId: accountIdRef.current,
|
|
121171
|
+
apiToken: requireApiToken()
|
|
121172
|
+
}, {
|
|
121173
|
+
env: props.env,
|
|
121174
|
+
legacyEnv: props.legacyEnv,
|
|
121175
|
+
zone: props.zone,
|
|
121176
|
+
host: props.host
|
|
121177
|
+
}, abortController.signal));
|
|
121171
121178
|
}
|
|
121172
121179
|
start().catch((err2) => {
|
|
121173
121180
|
if (err2.code !== "ABORT_ERR") {
|
|
121174
121181
|
if (err2.code === 10063) {
|
|
121175
121182
|
const errorMessage = "Error: You need to register a workers.dev subdomain before running the dev command in remote mode";
|
|
121176
121183
|
const solutionMessage = "You can either enable local mode by pressing l, or register a workers.dev subdomain here:";
|
|
121177
|
-
const onboardingLink = `https://dash.cloudflare.com/${
|
|
121184
|
+
const onboardingLink = `https://dash.cloudflare.com/${accountIdRef.current}/workers/onboarding`;
|
|
121178
121185
|
logger.error(`${errorMessage}
|
|
121179
121186
|
${solutionMessage}
|
|
121180
121187
|
${onboardingLink}`);
|
|
@@ -121191,7 +121198,6 @@ ${onboardingLink}`);
|
|
|
121191
121198
|
bundle,
|
|
121192
121199
|
format4,
|
|
121193
121200
|
accountId,
|
|
121194
|
-
apiToken,
|
|
121195
121201
|
port,
|
|
121196
121202
|
assetPaths,
|
|
121197
121203
|
compatibilityDate,
|
|
@@ -121201,7 +121207,8 @@ ${onboardingLink}`);
|
|
|
121201
121207
|
modules,
|
|
121202
121208
|
props.env,
|
|
121203
121209
|
props.legacyEnv,
|
|
121204
|
-
props.zone
|
|
121210
|
+
props.zone,
|
|
121211
|
+
props.host
|
|
121205
121212
|
]);
|
|
121206
121213
|
return token;
|
|
121207
121214
|
}
|
|
@@ -121390,7 +121397,6 @@ function useEsbuild({
|
|
|
121390
121397
|
|
|
121391
121398
|
// src/dev/dev.tsx
|
|
121392
121399
|
function DevImplementation(props) {
|
|
121393
|
-
const apiToken = props.initialMode === "remote" ? getAPIToken() : void 0;
|
|
121394
121400
|
const directory = useTmpDir();
|
|
121395
121401
|
useCustomBuild(props.entry, props.build);
|
|
121396
121402
|
if (props.public && props.entry.format === "service-worker") {
|
|
@@ -121420,12 +121426,10 @@ function DevImplementation(props) {
|
|
|
121420
121426
|
const { isRawModeSupported } = (0, import_ink3.useStdin)();
|
|
121421
121427
|
return isRawModeSupported ? /* @__PURE__ */ import_react7.default.createElement(InteractiveDevSession, {
|
|
121422
121428
|
...props,
|
|
121423
|
-
bundle
|
|
121424
|
-
apiToken
|
|
121429
|
+
bundle
|
|
121425
121430
|
}) : /* @__PURE__ */ import_react7.default.createElement(DevSession, {
|
|
121426
121431
|
...props,
|
|
121427
121432
|
bundle,
|
|
121428
|
-
apiToken,
|
|
121429
121433
|
local: props.initialMode === "local"
|
|
121430
121434
|
});
|
|
121431
121435
|
}
|
|
@@ -121475,7 +121479,6 @@ function DevSession(props) {
|
|
|
121475
121479
|
bundle: props.bundle,
|
|
121476
121480
|
format: props.entry.format,
|
|
121477
121481
|
accountId: props.accountId,
|
|
121478
|
-
apiToken: props.apiToken,
|
|
121479
121482
|
bindings: props.bindings,
|
|
121480
121483
|
assetPaths: props.assetPaths,
|
|
121481
121484
|
public: props.public,
|
|
@@ -121488,7 +121491,8 @@ function DevSession(props) {
|
|
|
121488
121491
|
usageModel: props.usageModel,
|
|
121489
121492
|
env: props.env,
|
|
121490
121493
|
legacyEnv: props.legacyEnv,
|
|
121491
|
-
zone: props.zone
|
|
121494
|
+
zone: props.zone,
|
|
121495
|
+
host: props.host
|
|
121492
121496
|
});
|
|
121493
121497
|
}
|
|
121494
121498
|
function useTmpDir() {
|
|
@@ -123605,7 +123609,10 @@ ${name2} is ${prettyBytes(filestat.size)} in size`);
|
|
|
123605
123609
|
throw new FatalError(`Error: Pages only supports up to 20,000 files in a deployment. Ensure you have specified your build output directory correctly.`, 1);
|
|
123606
123610
|
}
|
|
123607
123611
|
const files2 = [...fileMap.values()];
|
|
123608
|
-
|
|
123612
|
+
async function fetchJwt() {
|
|
123613
|
+
return (await fetchResult(`/accounts/${accountId}/pages/projects/${projectName}/upload-token`)).jwt;
|
|
123614
|
+
}
|
|
123615
|
+
let jwt = await fetchJwt();
|
|
123609
123616
|
const start = Date.now();
|
|
123610
123617
|
const missingHashes = await fetchResult(`/pages/assets/check-missing`, {
|
|
123611
123618
|
method: "POST",
|
|
@@ -123673,6 +123680,9 @@ ${name2} is ${prettyBytes(filestat.size)} in size`);
|
|
|
123673
123680
|
} catch (e2) {
|
|
123674
123681
|
if (attempts < MAX_UPLOAD_ATTEMPTS) {
|
|
123675
123682
|
await new Promise((resolve11) => setTimeout(resolve11, attempts++ * 1e3));
|
|
123683
|
+
if (e2.code === 8000013) {
|
|
123684
|
+
jwt = await fetchJwt();
|
|
123685
|
+
}
|
|
123676
123686
|
return doUpload();
|
|
123677
123687
|
} else {
|
|
123678
123688
|
throw e2;
|
|
@@ -124265,6 +124275,32 @@ async function getMigrationsToUpload(scriptName, props) {
|
|
|
124265
124275
|
return migrations;
|
|
124266
124276
|
}
|
|
124267
124277
|
|
|
124278
|
+
// src/zones.ts
|
|
124279
|
+
init_import_meta_url();
|
|
124280
|
+
async function getZoneForRoute(route) {
|
|
124281
|
+
const host = typeof route === "string" ? getHostFromUrl(route) : typeof route === "object" ? "zone_name" in route ? getHostFromUrl(route.zone_name) : getHostFromUrl(route.pattern) : void 0;
|
|
124282
|
+
const id = typeof route === "object" && "zone_id" in route ? route.zone_id : host ? await getZoneIdFromHost(host) : void 0;
|
|
124283
|
+
return id && host ? { id, host } : void 0;
|
|
124284
|
+
}
|
|
124285
|
+
function getHostFromUrl(urlLike) {
|
|
124286
|
+
urlLike = urlLike.replace(/^\*(\.)?/g, "");
|
|
124287
|
+
if (!(urlLike.startsWith("http://") || urlLike.startsWith("https://"))) {
|
|
124288
|
+
urlLike = "http://" + urlLike;
|
|
124289
|
+
}
|
|
124290
|
+
return new URL(urlLike).host;
|
|
124291
|
+
}
|
|
124292
|
+
async function getZoneIdFromHost(host) {
|
|
124293
|
+
const hostPieces = host.split(".");
|
|
124294
|
+
while (hostPieces.length > 1) {
|
|
124295
|
+
const zones = await fetchListResult(`/zones`, {}, new URLSearchParams({ name: hostPieces.join(".") }));
|
|
124296
|
+
if (zones.length > 0) {
|
|
124297
|
+
return zones[0].id;
|
|
124298
|
+
}
|
|
124299
|
+
hostPieces.shift();
|
|
124300
|
+
}
|
|
124301
|
+
throw new Error(`Could not find zone for ${host}`);
|
|
124302
|
+
}
|
|
124303
|
+
|
|
124268
124304
|
// src/publish.ts
|
|
124269
124305
|
function sleep3(ms) {
|
|
124270
124306
|
return new Promise((resolve11) => setTimeout(resolve11, ms));
|
|
@@ -124398,7 +124434,7 @@ async function publish(props) {
|
|
|
124398
124434
|
const minify = props.minify ?? config.minify;
|
|
124399
124435
|
const nodeCompat = props.nodeCompat ?? config.node_compat;
|
|
124400
124436
|
if (nodeCompat) {
|
|
124401
|
-
logger.warn("Enabling node.js compatibility mode for
|
|
124437
|
+
logger.warn("Enabling node.js compatibility mode for built-ins and globals. This is experimental and has serious tradeoffs. Please see https://github.com/ionic-team/rollup-plugin-node-polyfills/ for more details.");
|
|
124402
124438
|
}
|
|
124403
124439
|
const scriptName = props.name;
|
|
124404
124440
|
(0, import_node_assert9.default)(scriptName, 'You need to provide a name when publishing a worker. Either pass it as a cli arg with `--name <name>` or in your config file as `name = "<name>"`');
|
|
@@ -124411,7 +124447,7 @@ async function publish(props) {
|
|
|
124411
124447
|
const destination = props.outDir ?? await import_tmp_promise2.default.dir({ unsafeCleanup: true });
|
|
124412
124448
|
const envName = props.env ?? "production";
|
|
124413
124449
|
const start = Date.now();
|
|
124414
|
-
const notProd = !props.legacyEnv && props.env;
|
|
124450
|
+
const notProd = Boolean(!props.legacyEnv && props.env);
|
|
124415
124451
|
const workerName = notProd ? `${scriptName} (${envName})` : scriptName;
|
|
124416
124452
|
const workerUrl = notProd ? `/accounts/${accountId}/workers/services/${scriptName}/environments/${envName}` : `/accounts/${accountId}/workers/scripts/${scriptName}`;
|
|
124417
124453
|
let available_on_subdomain;
|
|
@@ -124539,13 +124575,7 @@ async function publish(props) {
|
|
|
124539
124575
|
}
|
|
124540
124576
|
logger.log("Uploaded", workerName, formatTime2(uploadMs));
|
|
124541
124577
|
if (routesOnly.length > 0) {
|
|
124542
|
-
deployments.push(
|
|
124543
|
-
method: "PUT",
|
|
124544
|
-
body: JSON.stringify(routesOnly.map((route) => typeof route !== "object" ? { pattern: route } : route)),
|
|
124545
|
-
headers: {
|
|
124546
|
-
"Content-Type": "application/json"
|
|
124547
|
-
}
|
|
124548
|
-
}).then(() => {
|
|
124578
|
+
deployments.push(publishRoutes(routesOnly, { workerUrl, scriptName, notProd }).then(() => {
|
|
124549
124579
|
if (routesOnly.length > 10) {
|
|
124550
124580
|
return routesOnly.slice(0, 9).map((route) => renderRoute(route)).concat([`...and ${routesOnly.length - 10} more routes`]);
|
|
124551
124581
|
}
|
|
@@ -124596,6 +124626,92 @@ ${onboardingLink}`);
|
|
|
124596
124626
|
}
|
|
124597
124627
|
}
|
|
124598
124628
|
}
|
|
124629
|
+
async function publishRoutes(routes, {
|
|
124630
|
+
workerUrl,
|
|
124631
|
+
scriptName,
|
|
124632
|
+
notProd
|
|
124633
|
+
}) {
|
|
124634
|
+
try {
|
|
124635
|
+
return await fetchResult(`${workerUrl}/routes`, {
|
|
124636
|
+
method: "PUT",
|
|
124637
|
+
body: JSON.stringify(routes.map((route) => typeof route !== "object" ? { pattern: route } : route)),
|
|
124638
|
+
headers: {
|
|
124639
|
+
"Content-Type": "application/json"
|
|
124640
|
+
}
|
|
124641
|
+
});
|
|
124642
|
+
} catch (e2) {
|
|
124643
|
+
if (isAuthenticationError(e2)) {
|
|
124644
|
+
return await publishRoutesFallback(routes, { scriptName, notProd });
|
|
124645
|
+
} else {
|
|
124646
|
+
throw e2;
|
|
124647
|
+
}
|
|
124648
|
+
}
|
|
124649
|
+
}
|
|
124650
|
+
async function publishRoutesFallback(routes, { scriptName, notProd }) {
|
|
124651
|
+
if (notProd) {
|
|
124652
|
+
throw new Error("Service environments combined with an API token that doesn't have 'All Zones' permissions is not supported.\nEither turn off service environments by setting `legacy_env = true`, creating an API token with 'All Zones' permissions, or logging in via OAuth");
|
|
124653
|
+
}
|
|
124654
|
+
logger.warn("The current authentication token does not have 'All Zones' permissions.\nFalling back to using the zone-based API endpoint to update each route individually.\nNote that there is no access to routes associated with zones that the API token does not have permission for.\nExisting routes for this Worker in such zones will not be deleted.");
|
|
124655
|
+
const deployedRoutes = [];
|
|
124656
|
+
const activeZones = /* @__PURE__ */ new Map();
|
|
124657
|
+
const routesToDeploy = /* @__PURE__ */ new Map();
|
|
124658
|
+
for (const route of routes) {
|
|
124659
|
+
const zone = await getZoneForRoute(route);
|
|
124660
|
+
if (zone) {
|
|
124661
|
+
activeZones.set(zone.id, zone.host);
|
|
124662
|
+
routesToDeploy.set(typeof route === "string" ? route : route.pattern, zone.id);
|
|
124663
|
+
}
|
|
124664
|
+
}
|
|
124665
|
+
const allRoutes = /* @__PURE__ */ new Map();
|
|
124666
|
+
const alreadyDeployedRoutes = /* @__PURE__ */ new Set();
|
|
124667
|
+
for (const [zone, host] of activeZones) {
|
|
124668
|
+
try {
|
|
124669
|
+
for (const { pattern, script } of await fetchListResult(`/zones/${zone}/workers/routes`)) {
|
|
124670
|
+
allRoutes.set(pattern, script);
|
|
124671
|
+
if (script === scriptName) {
|
|
124672
|
+
alreadyDeployedRoutes.add(pattern);
|
|
124673
|
+
}
|
|
124674
|
+
}
|
|
124675
|
+
} catch (e2) {
|
|
124676
|
+
if (isAuthenticationError(e2)) {
|
|
124677
|
+
e2.notes.push({
|
|
124678
|
+
text: `This could be because the API token being used does not have permission to access the zone "${host}" (${zone}).`
|
|
124679
|
+
});
|
|
124680
|
+
}
|
|
124681
|
+
throw e2;
|
|
124682
|
+
}
|
|
124683
|
+
}
|
|
124684
|
+
for (const [routePattern, zoneId] of routesToDeploy.entries()) {
|
|
124685
|
+
if (allRoutes.has(routePattern)) {
|
|
124686
|
+
const knownScript = allRoutes.get(routePattern);
|
|
124687
|
+
if (knownScript === scriptName) {
|
|
124688
|
+
alreadyDeployedRoutes.delete(routePattern);
|
|
124689
|
+
continue;
|
|
124690
|
+
} else {
|
|
124691
|
+
throw new Error(`The route with pattern "${routePattern}" is already associated with another worker called "${knownScript}".`);
|
|
124692
|
+
}
|
|
124693
|
+
}
|
|
124694
|
+
const { pattern } = await fetchResult(`/zones/${zoneId}/workers/routes`, {
|
|
124695
|
+
method: "POST",
|
|
124696
|
+
body: JSON.stringify({
|
|
124697
|
+
pattern: routePattern,
|
|
124698
|
+
script: scriptName
|
|
124699
|
+
}),
|
|
124700
|
+
headers: {
|
|
124701
|
+
"Content-Type": "application/json"
|
|
124702
|
+
}
|
|
124703
|
+
});
|
|
124704
|
+
deployedRoutes.push(pattern);
|
|
124705
|
+
}
|
|
124706
|
+
if (alreadyDeployedRoutes.size) {
|
|
124707
|
+
logger.warn("Previously deployed routes:\nThe following routes were already associated with this worker, and have not been deleted:\n" + [...alreadyDeployedRoutes.values()].map((route) => ` - "${route}"
|
|
124708
|
+
`) + "If these routes are not wanted then you can remove them in the dashboard.");
|
|
124709
|
+
}
|
|
124710
|
+
return deployedRoutes;
|
|
124711
|
+
}
|
|
124712
|
+
function isAuthenticationError(e2) {
|
|
124713
|
+
return e2 instanceof ParseError && e2.code === 1e4;
|
|
124714
|
+
}
|
|
124599
124715
|
|
|
124600
124716
|
// src/r2.ts
|
|
124601
124717
|
init_import_meta_url();
|
|
@@ -124824,9 +124940,10 @@ function Accounts(props) {
|
|
|
124824
124940
|
}
|
|
124825
124941
|
async function getUserInfo() {
|
|
124826
124942
|
const apiToken = getAPIToken();
|
|
124943
|
+
const apiTokenFromEnv = getCloudflareAPITokenFromEnv();
|
|
124827
124944
|
return apiToken ? {
|
|
124828
124945
|
apiToken,
|
|
124829
|
-
authType: "OAuth",
|
|
124946
|
+
authType: apiTokenFromEnv ? "API" : "OAuth",
|
|
124830
124947
|
email: await getEmail(),
|
|
124831
124948
|
accounts: await getAccounts()
|
|
124832
124949
|
} : void 0;
|
|
@@ -125037,7 +125154,10 @@ ${err2.message ?? err2}`);
|
|
|
125037
125154
|
if (!isInsideGitProject && isGitInstalled) {
|
|
125038
125155
|
const shouldInitGit = yesFlag || await confirm("Would you like to use git to manage this Worker?");
|
|
125039
125156
|
if (shouldInitGit) {
|
|
125040
|
-
await execa("git", ["init"
|
|
125157
|
+
await execa("git", ["init"], {
|
|
125158
|
+
cwd: creationDirectory
|
|
125159
|
+
});
|
|
125160
|
+
await execa("git", ["branch", "-m", "main"], {
|
|
125041
125161
|
cwd: creationDirectory
|
|
125042
125162
|
});
|
|
125043
125163
|
await (0, import_promises10.writeFile)(import_node_path21.default.join(creationDirectory, ".gitignore"), readFileSync5(import_node_path21.default.join(__dirname, "../templates/gitignore")));
|
|
@@ -125378,35 +125498,21 @@ To start developing your Worker, run \`npx wrangler dev\`${isCreatingWranglerTom
|
|
|
125378
125498
|
if (upstreamProtocol === "http") {
|
|
125379
125499
|
logger.warn("Setting upstream-protocol to http is not currently implemented.\nIf this is required in your project, please add your use case to the following issue:\nhttps://github.com/cloudflare/wrangler2/issues/583.");
|
|
125380
125500
|
}
|
|
125381
|
-
|
|
125382
|
-
|
|
125383
|
-
urlLike = urlLike.replace(/^\*(\.)?/g, "");
|
|
125384
|
-
if (!(urlLike.startsWith("http://") || urlLike.startsWith("https://"))) {
|
|
125385
|
-
urlLike = "http://" + urlLike;
|
|
125386
|
-
}
|
|
125387
|
-
return new URL(urlLike).host;
|
|
125388
|
-
}
|
|
125389
|
-
async function getZoneId(host) {
|
|
125390
|
-
const zones = await fetchResult(`/zones`, {}, new URLSearchParams({ name: host }));
|
|
125391
|
-
return zones[0]?.id;
|
|
125392
|
-
}
|
|
125393
|
-
let zone;
|
|
125501
|
+
let host = args.host || config.dev.host;
|
|
125502
|
+
let zoneId;
|
|
125394
125503
|
if (!args.local) {
|
|
125395
|
-
|
|
125396
|
-
|
|
125397
|
-
|
|
125398
|
-
const
|
|
125399
|
-
|
|
125400
|
-
|
|
125401
|
-
|
|
125402
|
-
|
|
125403
|
-
|
|
125404
|
-
|
|
125405
|
-
|
|
125406
|
-
|
|
125407
|
-
host,
|
|
125408
|
-
id: zoneId
|
|
125409
|
-
} : void 0;
|
|
125504
|
+
if (host) {
|
|
125505
|
+
zoneId = await getZoneIdFromHost(host);
|
|
125506
|
+
}
|
|
125507
|
+
const routes = args.routes || config.route || config.routes;
|
|
125508
|
+
if (!zoneId && routes) {
|
|
125509
|
+
const firstRoute = Array.isArray(routes) ? routes[0] : routes;
|
|
125510
|
+
const zone = await getZoneForRoute(firstRoute);
|
|
125511
|
+
if (zone) {
|
|
125512
|
+
zoneId = zone.id;
|
|
125513
|
+
host = zone.host;
|
|
125514
|
+
}
|
|
125515
|
+
}
|
|
125410
125516
|
}
|
|
125411
125517
|
const nodeCompat = args.nodeCompat ?? config.node_compat;
|
|
125412
125518
|
if (nodeCompat) {
|
|
@@ -125453,7 +125559,8 @@ To start developing your Worker, run \`npx wrangler dev\`${isCreatingWranglerTom
|
|
|
125453
125559
|
name: getScriptName(args, config),
|
|
125454
125560
|
entry,
|
|
125455
125561
|
env: args.env,
|
|
125456
|
-
zone,
|
|
125562
|
+
zone: zoneId,
|
|
125563
|
+
host,
|
|
125457
125564
|
rules: getRules(config),
|
|
125458
125565
|
legacyEnv: isLegacyEnv(config),
|
|
125459
125566
|
minify: args.minify ?? config.minify,
|
|
@@ -125466,7 +125573,7 @@ To start developing your Worker, run \`npx wrangler dev\`${isCreatingWranglerTom
|
|
|
125466
125573
|
upstreamProtocol,
|
|
125467
125574
|
localProtocol: args["local-protocol"] || config.dev.local_protocol,
|
|
125468
125575
|
enableLocalPersistence: args["experimental-enable-local-persistence"] || false,
|
|
125469
|
-
accountId,
|
|
125576
|
+
accountId: config.account_id,
|
|
125470
125577
|
assetPaths: getAssetPaths(config, args.site, args.siteInclude, args.siteExclude),
|
|
125471
125578
|
port: args.port || config.dev.port || await getPorts({ port: DEFAULT_LOCAL_PORT }),
|
|
125472
125579
|
ip: args.ip || config.dev.ip,
|
|
@@ -125739,6 +125846,7 @@ To start developing your Worker, run \`npx wrangler dev\`${isCreatingWranglerTom
|
|
|
125739
125846
|
rules: getRules(config),
|
|
125740
125847
|
env: args.env,
|
|
125741
125848
|
zone: void 0,
|
|
125849
|
+
host: void 0,
|
|
125742
125850
|
legacyEnv: isLegacyEnv(config),
|
|
125743
125851
|
build: config.build || {},
|
|
125744
125852
|
minify: void 0,
|