wrangler 2.0.17 → 2.0.18

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wrangler",
3
- "version": "2.0.17",
3
+ "version": "2.0.18",
4
4
  "description": "Command-line interface for all things Cloudflare Workers",
5
5
  "keywords": [
6
6
  "wrangler",
@@ -149,6 +149,7 @@
149
149
  "undici": "^5.5.1",
150
150
  "update-check": "^1.5.4",
151
151
  "ws": "^8.5.0",
152
+ "xdg-app-paths": "^7.3.0",
152
153
  "yargs": "^17.4.1"
153
154
  },
154
155
  "optionalDependencies": {
@@ -5,42 +5,34 @@ import { reinitialiseAuthTokens } from "../../user";
5
5
 
6
6
  const originalCwd = process.cwd();
7
7
 
8
- export function runInTempDir(
9
- { homedir }: { homedir?: string } = { homedir: "./home" }
10
- ) {
11
- let tmpDir: string;
12
-
13
- beforeAll(() => {
14
- if (tmpDir !== undefined) {
15
- process.chdir(originalCwd);
16
- fs.rmSync(tmpDir, { recursive: true });
17
- }
18
- });
8
+ export function runInTempDir({ homedir } = { homedir: "./home" }) {
9
+ let tmpDir: string | undefined;
19
10
 
20
11
  beforeEach(() => {
21
12
  // Use realpath because the temporary path can point to a symlink rather than the actual path.
22
13
  tmpDir = fs.realpathSync(
23
14
  fs.mkdtempSync(path.join(os.tmpdir(), "wrangler-tests"))
24
15
  );
16
+
25
17
  process.chdir(tmpDir);
26
- if (homedir !== undefined) {
27
- // The path that is returned from `homedir()` should be absolute.
28
- const absHomedir = path.resolve(tmpDir, homedir);
29
- // Override where the home directory is so that we can write our own user config,
30
- // without destroying the real thing.
31
- fs.mkdirSync(absHomedir, { recursive: true });
32
- // Note it is very important that we use the "default" value from "node:os" (e.g. `import os from "node:os";`)
33
- // rather than an alias to the module (e.g. `import * as os from "node:os";`).
34
- // This is because the module gets transpiled so that the "method" `homedir()` gets converted to a
35
- // getter that is not configurable (and so cannot be spied upon).
36
- jest.spyOn(os, "homedir").mockReturnValue(absHomedir);
37
- // Now that we have changed the home directory location, we must reinitialize the user auth state
38
- reinitialiseAuthTokens();
39
- }
18
+ // The path that is returned from `homedir()` should be absolute.
19
+ const absHomedir = path.resolve(tmpDir, homedir);
20
+ // Override where the home directory is so that we can write our own user config,
21
+ // without destroying the real thing.
22
+ fs.mkdirSync(absHomedir, { recursive: true });
23
+ // Note it is very important that we use the "default" value from "node:os" (e.g. `import os from "node:os";`)
24
+ // rather than an alias to the module (e.g. `import * as os from "node:os";`).
25
+ // This is because the module gets transpiled so that the "method" `homedir()` gets converted to a
26
+ // getter that is not configurable (and so cannot be spied upon).
27
+ jest.spyOn(os, "homedir")?.mockReturnValue(absHomedir);
28
+ // Now that we have changed the home directory location, we must reinitialize the user auth state
29
+ reinitialiseAuthTokens();
40
30
  });
41
31
 
42
32
  afterEach(() => {
43
- process.chdir(originalCwd);
44
- fs.rmSync(tmpDir, { recursive: true });
33
+ if (tmpDir && fs.existsSync(tmpDir)) {
34
+ process.chdir(originalCwd);
35
+ fs.rmSync(tmpDir, { recursive: true });
36
+ }
45
37
  });
46
38
  }
@@ -1,6 +1,7 @@
1
1
  import fs from "node:fs";
2
2
  import os from "node:os";
3
- import { resolve } from "node:path";
3
+ import path from "node:path";
4
+ import { getGlobalWranglerConfigPath } from "../global-wrangler-config-path";
4
5
  import { getHttpsOptions } from "../https-options";
5
6
  import { mockConsoleMethods } from "./helpers/mock-console";
6
7
  import { runInTempDir } from "./helpers/run-in-tmp";
@@ -10,15 +11,15 @@ describe("getHttpsOptions()", () => {
10
11
  const std = mockConsoleMethods();
11
12
 
12
13
  it("should use cached values if they have not expired", async () => {
13
- fs.mkdirSync(resolve(os.homedir(), ".wrangler/local-cert"), {
14
+ fs.mkdirSync(path.resolve(getGlobalWranglerConfigPath(), "local-cert"), {
14
15
  recursive: true,
15
16
  });
16
17
  fs.writeFileSync(
17
- resolve(os.homedir(), ".wrangler/local-cert/key.pem"),
18
+ path.resolve(getGlobalWranglerConfigPath(), "local-cert/key.pem"),
18
19
  "PRIVATE KEY"
19
20
  );
20
21
  fs.writeFileSync(
21
- resolve(os.homedir(), ".wrangler/local-cert/cert.pem"),
22
+ path.resolve(getGlobalWranglerConfigPath(), "local-cert/cert.pem"),
22
23
  "PUBLIC KEY"
23
24
  );
24
25
  const result = await getHttpsOptions();
@@ -32,11 +33,11 @@ describe("getHttpsOptions()", () => {
32
33
  it("should generate and cache new keys if none are cached", async () => {
33
34
  const result = await getHttpsOptions();
34
35
  const key = fs.readFileSync(
35
- resolve(os.homedir(), ".wrangler/local-cert/key.pem"),
36
+ path.resolve(getGlobalWranglerConfigPath(), "local-cert/key.pem"),
36
37
  "utf8"
37
38
  );
38
39
  const cert = fs.readFileSync(
39
- resolve(os.homedir(), ".wrangler/local-cert/cert.pem"),
40
+ path.resolve(getGlobalWranglerConfigPath(), "local-cert/cert.pem"),
40
41
  "utf8"
41
42
  );
42
43
  expect(result.key).toEqual(key);
@@ -49,28 +50,28 @@ describe("getHttpsOptions()", () => {
49
50
  });
50
51
 
51
52
  it("should generate and cache new keys if cached files have expired", async () => {
52
- fs.mkdirSync(resolve(os.homedir(), ".wrangler/local-cert"), {
53
+ fs.mkdirSync(path.resolve(getGlobalWranglerConfigPath(), "local-cert"), {
53
54
  recursive: true,
54
55
  });
55
56
  const ORIGINAL_KEY = "EXPIRED PRIVATE KEY";
56
57
  const ORIGINAL_CERT = "EXPIRED PUBLIC KEY";
57
58
  fs.writeFileSync(
58
- resolve(os.homedir(), ".wrangler/local-cert/key.pem"),
59
+ path.resolve(getGlobalWranglerConfigPath(), "local-cert/key.pem"),
59
60
  ORIGINAL_KEY
60
61
  );
61
62
  fs.writeFileSync(
62
- resolve(os.homedir(), ".wrangler/local-cert/cert.pem"),
63
+ path.resolve(getGlobalWranglerConfigPath(), "local-cert/cert.pem"),
63
64
  ORIGINAL_CERT
64
65
  );
65
66
  mockStatSync(/\.pem$/, { mtimeMs: new Date(2000).valueOf() });
66
67
 
67
68
  const result = await getHttpsOptions();
68
69
  const key = fs.readFileSync(
69
- resolve(os.homedir(), ".wrangler/local-cert/key.pem"),
70
+ path.resolve(getGlobalWranglerConfigPath(), "local-cert/key.pem"),
70
71
  "utf8"
71
72
  );
72
73
  const cert = fs.readFileSync(
73
- resolve(os.homedir(), ".wrangler/local-cert/cert.pem"),
74
+ path.resolve(getGlobalWranglerConfigPath(), "local-cert/cert.pem"),
74
75
  "utf8"
75
76
  );
76
77
  expect(key).not.toEqual(ORIGINAL_KEY);
@@ -84,25 +85,57 @@ describe("getHttpsOptions()", () => {
84
85
  expect(std.err).toMatchInlineSnapshot(`""`);
85
86
  });
86
87
 
88
+ it("should warn if not able to write to the cache (legacy config path)", async () => {
89
+ fs.mkdirSync(path.join(os.homedir(), ".wrangler"));
90
+ mockWriteFileSyncThrow(/\.pem$/);
91
+ await getHttpsOptions();
92
+ expect(
93
+ fs.existsSync(
94
+ path.resolve(getGlobalWranglerConfigPath(), "local-cert/key.pem")
95
+ )
96
+ ).toBe(false);
97
+ expect(
98
+ fs.existsSync(
99
+ path.resolve(getGlobalWranglerConfigPath(), "local-cert/cert.pem")
100
+ )
101
+ ).toBe(false);
102
+ expect(std.out).toMatchInlineSnapshot(
103
+ `"Generating new self-signed certificate..."`
104
+ );
105
+ expect(std.warn).toMatchInlineSnapshot(`
106
+ "▲ [WARNING] Unable to cache generated self-signed certificate in home/.wrangler/local-cert.
107
+
108
+ ERROR: Cannot write file
109
+
110
+ "
111
+ `);
112
+ expect(std.err).toMatchInlineSnapshot(`""`);
113
+ fs.rmSync(path.join(os.homedir(), ".wrangler"), { recursive: true });
114
+ });
115
+
87
116
  it("should warn if not able to write to the cache", async () => {
88
117
  mockWriteFileSyncThrow(/\.pem$/);
89
118
  await getHttpsOptions();
90
119
  expect(
91
- fs.existsSync(resolve(os.homedir(), ".wrangler/local-cert/key.pem"))
120
+ fs.existsSync(
121
+ path.resolve(getGlobalWranglerConfigPath(), "local-cert/key.pem")
122
+ )
92
123
  ).toBe(false);
93
124
  expect(
94
- fs.existsSync(resolve(os.homedir(), ".wrangler/local-cert/cert.pem"))
125
+ fs.existsSync(
126
+ path.resolve(getGlobalWranglerConfigPath(), "local-cert/cert.pem")
127
+ )
95
128
  ).toBe(false);
96
129
  expect(std.out).toMatchInlineSnapshot(
97
130
  `"Generating new self-signed certificate..."`
98
131
  );
99
132
  expect(std.warn).toMatchInlineSnapshot(`
100
- "▲ [WARNING] Unable to cache generated self-signed certificate in home/.wrangler/local-cert.
133
+ "▲ [WARNING] Unable to cache generated self-signed certificate in test-xdg-config/local-cert.
101
134
 
102
- ERROR: Cannot write file
135
+ ERROR: Cannot write file
103
136
 
104
- "
105
- `);
137
+ "
138
+ `);
106
139
  expect(std.err).toMatchInlineSnapshot(`""`);
107
140
  });
108
141
  });
@@ -105,3 +105,16 @@ jest.mock("../user/generate-random-state", () => {
105
105
  generateRandomState: jest.fn().mockImplementation(() => "MOCK_STATE_PARAM"),
106
106
  };
107
107
  });
108
+
109
+ jest.mock("xdg-app-paths", () => {
110
+ return {
111
+ __esModule: true,
112
+ default: jest.fn().mockImplementation(() => {
113
+ return {
114
+ config() {
115
+ return jest.requireActual("node:path").resolve("test-xdg-config");
116
+ },
117
+ };
118
+ }),
119
+ };
120
+ });
@@ -45,6 +45,13 @@ describe("pages", () => {
45
45
  outOfBandTests.forEach((fn) => fn());
46
46
  });
47
47
 
48
+ beforeEach(() => {
49
+ // @ts-expect-error we're using a very simple setTimeout mock here
50
+ jest.spyOn(global, "setTimeout").mockImplementation((fn, _period) => {
51
+ setImmediate(fn);
52
+ });
53
+ });
54
+
48
55
  it("should should display a list of available subcommands, for pages with no subcommand", async () => {
49
56
  await runWrangler("pages");
50
57
  await endEventLoop();
@@ -645,8 +652,8 @@ describe("pages", () => {
645
652
  });
646
653
  bodies.push(JSON.parse(init.body as string) as UploadPayloadFile[]);
647
654
  }
648
- // First bucket should end up with 2 files
649
- expect(bodies.map((b) => b.length)).toEqual([2, 1, 1]);
655
+ // One bucket should end up with 2 files
656
+ expect(bodies.map((b) => b.length).sort()).toEqual([1, 1, 2]);
650
657
  // But we don't know the order, so flatten and test without ordering
651
658
  expect(bodies.flatMap((b) => b)).toEqual(
652
659
  expect.arrayContaining([
@@ -759,8 +766,8 @@ describe("pages", () => {
759
766
  });
760
767
  bodies.push(JSON.parse(init.body as string) as UploadPayloadFile[]);
761
768
  }
762
- // First bucket should end up with 2 files
763
- expect(bodies.map((b) => b.length)).toEqual([2, 1, 1]);
769
+ // One bucket should end up with 2 files
770
+ expect(bodies.map((b) => b.length).sort()).toEqual([1, 1, 2]);
764
771
  // But we don't know the order, so flatten and test without ordering
765
772
  expect(bodies.flatMap((b) => b)).toEqual(
766
773
  expect.arrayContaining([
@@ -874,8 +881,8 @@ describe("pages", () => {
874
881
  });
875
882
  bodies.push(JSON.parse(init.body as string) as UploadPayloadFile[]);
876
883
  }
877
- // First bucket should end up with 2 files
878
- expect(bodies.map((b) => b.length)).toEqual([2, 1, 1]);
884
+ // One bucket should end up with 2 files
885
+ expect(bodies.map((b) => b.length).sort()).toEqual([1, 1, 2]);
879
886
  // But we don't know the order, so flatten and test without ordering
880
887
  expect(bodies.flatMap((b) => b)).toEqual(
881
888
  expect.arrayContaining([
@@ -1163,8 +1170,8 @@ describe("pages", () => {
1163
1170
  });
1164
1171
  bodies.push(JSON.parse(init.body as string) as UploadPayloadFile[]);
1165
1172
  }
1166
- // First bucket should end up with 2 files
1167
- expect(bodies.map((b) => b.length)).toEqual([2, 1, 1]);
1173
+ // One bucket should end up with 2 files
1174
+ expect(bodies.map((b) => b.length).sort()).toEqual([1, 1, 2]);
1168
1175
  // But we don't know the order, so flatten and test without ordering
1169
1176
  expect(bodies.flatMap((b) => b)).toEqual(
1170
1177
  expect.arrayContaining([
@@ -51,6 +51,31 @@ describe("publish", () => {
51
51
  unsetMockFetchKVGetValues();
52
52
  });
53
53
 
54
+ describe("output additional script information", () => {
55
+ mockApiToken();
56
+
57
+ it("should print worker information at log level", async () => {
58
+ setIsTTY(false);
59
+ writeWranglerToml();
60
+ writeWorkerSource();
61
+ mockSubDomainRequest();
62
+ mockUploadWorkerRequest({ expectedType: "esm", sendScriptIds: true });
63
+ mockOAuthServerCallback();
64
+
65
+ await runWrangler("publish ./index");
66
+
67
+ expect(std.out).toMatchInlineSnapshot(`
68
+ "Total Upload: 0xx KiB / gzip: 0xx KiB
69
+ Worker ID: abc12345
70
+ Worker ETag: etag98765
71
+ Worker PipelineHash: hash9999
72
+ Uploaded test-name (TIMINGS)
73
+ Published test-name (TIMINGS)
74
+ test-name.test-sub-domain.workers.dev"
75
+ `);
76
+ });
77
+ });
78
+
54
79
  describe("authentication", () => {
55
80
  mockApiToken({ apiToken: null });
56
81
  beforeEach(() => {
@@ -6113,6 +6138,7 @@ function mockUploadWorkerRequest(
6113
6138
  expectedMigrations?: CfWorkerInit["migrations"];
6114
6139
  env?: string;
6115
6140
  legacyEnv?: boolean;
6141
+ sendScriptIds?: boolean;
6116
6142
  } = {}
6117
6143
  ) {
6118
6144
  const {
@@ -6127,6 +6153,7 @@ function mockUploadWorkerRequest(
6127
6153
  env = undefined,
6128
6154
  legacyEnv = false,
6129
6155
  expectedMigrations,
6156
+ sendScriptIds,
6130
6157
  } = options;
6131
6158
  setMockResponse(
6132
6159
  env && !legacyEnv
@@ -6175,7 +6202,16 @@ function mockUploadWorkerRequest(
6175
6202
  expect(await (formBody.get(name) as File).text()).toEqual(content);
6176
6203
  }
6177
6204
 
6178
- return { available_on_subdomain };
6205
+ return {
6206
+ available_on_subdomain,
6207
+ ...(sendScriptIds
6208
+ ? {
6209
+ id: "abc12345",
6210
+ etag: "etag98765",
6211
+ pipeline_hash: "hash9999",
6212
+ }
6213
+ : {}),
6214
+ };
6179
6215
  }
6180
6216
  );
6181
6217
  }
@@ -1,7 +1,7 @@
1
1
  import fs from "node:fs";
2
- import os from "node:os";
3
2
  import path from "node:path";
4
3
  import fetchMock from "jest-fetch-mock";
4
+ import { getGlobalWranglerConfigPath } from "../global-wrangler-config-path";
5
5
  import {
6
6
  loginOrRefreshIfRequired,
7
7
  readAuthConfigFile,
@@ -86,7 +86,10 @@ describe("User", () => {
86
86
  expect(fetchMock).toHaveBeenCalledTimes(1);
87
87
 
88
88
  // Make sure that logout removed the config file containing the auth tokens.
89
- const config = path.join(os.homedir(), USER_AUTH_CONFIG_FILE);
89
+ const config = path.join(
90
+ getGlobalWranglerConfigPath(),
91
+ USER_AUTH_CONFIG_FILE
92
+ );
90
93
  expect(fs.existsSync(config)).toBeFalsy();
91
94
  });
92
95
  });
@@ -0,0 +1,26 @@
1
+ import fs from "node:fs";
2
+ import os from "node:os";
3
+ import path from "node:path";
4
+ import xdgAppPaths from "xdg-app-paths";
5
+
6
+ function isDirectory(configPath: string) {
7
+ try {
8
+ return fs.statSync(configPath).isDirectory();
9
+ } catch (error) {
10
+ // ignore error
11
+ return false;
12
+ }
13
+ }
14
+
15
+ export function getGlobalWranglerConfigPath() {
16
+ //TODO: We should implement a custom path --global-config and/or the WRANGLER_HOME type environment variable
17
+ const configDir = xdgAppPaths(".wrangler").config(); // New XDG compliant config path
18
+ const legacyConfigDir = path.join(os.homedir(), ".wrangler"); // Legacy config in user's home directory
19
+
20
+ // Check for the .wrangler directory in root if it is not there then use the XDG compliant path.
21
+ if (isDirectory(legacyConfigDir)) {
22
+ return legacyConfigDir;
23
+ } else {
24
+ return configDir;
25
+ }
26
+ }
@@ -2,6 +2,7 @@ import * as fs from "node:fs";
2
2
  import os from "node:os";
3
3
  import * as path from "node:path";
4
4
  import { promisify } from "node:util";
5
+ import { getGlobalWranglerConfigPath } from "./global-wrangler-config-path";
5
6
  import { logger } from "./logger";
6
7
  import type { Attributes, Options } from "selfsigned";
7
8
 
@@ -17,7 +18,7 @@ const ONE_DAY_IN_MS = 86400000;
17
18
  * The certificates are self-signed and generated locally, and cached in the `CERT_ROOT` directory.
18
19
  */
19
20
  export async function getHttpsOptions() {
20
- const certDirectory = path.join(os.homedir(), ".wrangler/local-cert");
21
+ const certDirectory = path.join(getGlobalWranglerConfigPath(), "local-cert");
21
22
  const keyPath = path.join(certDirectory, "key.pem");
22
23
  const certPath = path.join(certDirectory, "cert.pem");
23
24
 
@@ -95,7 +95,7 @@ export const upload = async (
95
95
  }
96
96
 
97
97
  type FileContainer = {
98
- content: string;
98
+ path: string;
99
99
  contentType: string;
100
100
  sizeInBytes: number;
101
101
  hash: string;
@@ -112,6 +112,14 @@ export const upload = async (
112
112
 
113
113
  const directory = resolve(args.directory);
114
114
 
115
+ // TODO(future): Use this to more efficiently load files in and speed up uploading
116
+ // Limit memory to 1 GB unless more is specified
117
+ // let maxMemory = 1_000_000_000;
118
+ // if (process.env.NODE_OPTIONS && (process.env.NODE_OPTIONS.includes('--max-old-space-size=') || process.env.NODE_OPTIONS.includes('--max_old_space_size='))) {
119
+ // const parsed = parser(process.env.NODE_OPTIONS);
120
+ // maxMemory = (parsed['max-old-space-size'] ? parsed['max-old-space-size'] : parsed['max_old_space_size']) * 1000 * 1000; // Turn MB into bytes
121
+ // }
122
+
115
123
  const walk = async (
116
124
  dir: string,
117
125
  fileMap: Map<string, FileContainer> = new Map(),
@@ -137,7 +145,6 @@ export const upload = async (
137
145
  } else {
138
146
  const name = relative(startingDir, filepath).split(sep).join("/");
139
147
 
140
- // TODO: Move this to later so we don't hold as much in memory
141
148
  const fileContent = await readFile(filepath);
142
149
 
143
150
  const base64Content = fileContent.toString("base64");
@@ -152,8 +159,9 @@ export const upload = async (
152
159
  );
153
160
  }
154
161
 
162
+ // We don't want to hold the content in memory. We instead only want to read it when it's needed
155
163
  fileMap.set(name, {
156
- content: base64Content,
164
+ path: filepath,
157
165
  contentType: getType(name) || "application/octet-stream",
158
166
  sizeInBytes: filestat.size,
159
167
  hash: blake3hash(base64Content + extension)
@@ -248,17 +256,21 @@ export const upload = async (
248
256
  // Don't upload empty buckets (can happen for tiny projects)
249
257
  if (bucket.files.length === 0) continue;
250
258
 
251
- const payload: UploadPayloadFile[] = bucket.files.map((file) => ({
252
- key: file.hash,
253
- value: file.content,
254
- metadata: {
255
- contentType: file.contentType,
256
- },
257
- base64: true,
258
- }));
259
-
260
259
  let attempts = 0;
261
260
  const doUpload = async (): Promise<void> => {
261
+ // Populate the payload only when actually uploading (this is limited to 3 concurrent uploads at 50 MiB per bucket meaning we'd only load in a max of ~150 MiB)
262
+ // This is so we don't run out of memory trying to upload the files.
263
+ const payload: UploadPayloadFile[] = await Promise.all(
264
+ bucket.files.map(async (file) => ({
265
+ key: file.hash,
266
+ value: (await readFile(file.path)).toString("base64"),
267
+ metadata: {
268
+ contentType: file.contentType,
269
+ },
270
+ base64: true,
271
+ }))
272
+ );
273
+
262
274
  try {
263
275
  return await fetchResult(`/pages/assets/upload`, {
264
276
  method: "POST",
package/src/publish.ts CHANGED
@@ -469,21 +469,34 @@ See https://developers.cloudflare.com/workers/platform/compatibility-dates for m
469
469
  if (!props.dryRun) {
470
470
  // Upload the script so it has time to propagate.
471
471
  // We can also now tell whether available_on_subdomain is set
472
- available_on_subdomain = (
473
- await fetchResult<{ available_on_subdomain: boolean }>(
474
- workerUrl,
475
- {
476
- method: "PUT",
477
- body: createWorkerUploadForm(worker),
478
- },
479
- new URLSearchParams({
480
- include_subdomain_availability: "true",
481
- // pass excludeScript so the whole body of the
482
- // script doesn't get included in the response
483
- excludeScript: "true",
484
- })
485
- )
486
- ).available_on_subdomain;
472
+ const result = await fetchResult<{
473
+ available_on_subdomain: boolean;
474
+ id: string | null;
475
+ etag: string | null;
476
+ pipeline_hash: string | null;
477
+ }>(
478
+ workerUrl,
479
+ {
480
+ method: "PUT",
481
+ body: createWorkerUploadForm(worker),
482
+ },
483
+ new URLSearchParams({
484
+ include_subdomain_availability: "true",
485
+ // pass excludeScript so the whole body of the
486
+ // script doesn't get included in the response
487
+ excludeScript: "true",
488
+ })
489
+ );
490
+
491
+ available_on_subdomain = result.available_on_subdomain;
492
+
493
+ // Print some useful information returned after publishing
494
+ // Not all fields will be populated for every worker
495
+ // These fields are likely to be scraped by tools, so do not rename
496
+ if (result.id) logger.log("Worker ID: ", result.id);
497
+ if (result.etag) logger.log("Worker ETag: ", result.etag);
498
+ if (result.pipeline_hash)
499
+ logger.log("Worker PipelineHash: ", result.pipeline_hash);
487
500
  }
488
501
  } finally {
489
502
  if (typeof destination !== "string") {
package/src/user/user.tsx CHANGED
@@ -209,7 +209,6 @@ import assert from "node:assert";
209
209
  import { webcrypto as crypto } from "node:crypto";
210
210
  import { mkdirSync, rmSync, writeFileSync } from "node:fs";
211
211
  import http from "node:http";
212
- import os from "node:os";
213
212
  import path from "node:path";
214
213
  import url from "node:url";
215
214
  import { TextEncoder } from "node:util";
@@ -224,6 +223,7 @@ import {
224
223
  purgeConfigCaches,
225
224
  saveToConfigCache,
226
225
  } from "../config-cache";
226
+ import { getGlobalWranglerConfigPath } from "../global-wrangler-config-path";
227
227
  import isInteractive from "../is-interactive";
228
228
  import { logger } from "../logger";
229
229
  import openInBrowser from "../open-in-browser";
@@ -270,7 +270,7 @@ interface AuthTokens {
270
270
  * The path to the config file that holds user authentication data,
271
271
  * relative to the user's home directory.
272
272
  */
273
- export const USER_AUTH_CONFIG_FILE = ".wrangler/config/default.toml";
273
+ export const USER_AUTH_CONFIG_FILE = "config/default.toml";
274
274
 
275
275
  /**
276
276
  * The data that may be read from the `USER_CONFIG_FILE`.
@@ -843,7 +843,10 @@ async function generatePKCECodes(): Promise<PKCECodes> {
843
843
  * and updates the user auth state with the new credentials.
844
844
  */
845
845
  export function writeAuthConfigFile(config: UserAuthConfig) {
846
- const authConfigFilePath = path.join(os.homedir(), USER_AUTH_CONFIG_FILE);
846
+ const authConfigFilePath = path.join(
847
+ getGlobalWranglerConfigPath(),
848
+ USER_AUTH_CONFIG_FILE
849
+ );
847
850
  mkdirSync(path.dirname(authConfigFilePath), {
848
851
  recursive: true,
849
852
  });
@@ -857,7 +860,10 @@ export function writeAuthConfigFile(config: UserAuthConfig) {
857
860
  }
858
861
 
859
862
  export function readAuthConfigFile(): UserAuthConfig {
860
- const authConfigFilePath = path.join(os.homedir(), USER_AUTH_CONFIG_FILE);
863
+ const authConfigFilePath = path.join(
864
+ getGlobalWranglerConfigPath(),
865
+ USER_AUTH_CONFIG_FILE
866
+ );
861
867
  const toml = parseTOML(readFileSync(authConfigFilePath));
862
868
  return toml;
863
869
  }
@@ -1042,7 +1048,7 @@ export async function logout(): Promise<void> {
1042
1048
  },
1043
1049
  });
1044
1050
  await response.text(); // blank text? would be nice if it was something meaningful
1045
- rmSync(path.join(os.homedir(), USER_AUTH_CONFIG_FILE));
1051
+ rmSync(path.join(getGlobalWranglerConfigPath(), USER_AUTH_CONFIG_FILE));
1046
1052
  logger.log(`Successfully logged out.`);
1047
1053
  }
1048
1054