wrangler 0.0.0-de73fa2 → 0.0.0-e151223

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.
Files changed (48) hide show
  1. package/bin/wrangler.js +2 -2
  2. package/package.json +12 -9
  3. package/pages/functions/buildWorker.ts +1 -1
  4. package/pages/functions/filepath-routing.test.ts +21 -13
  5. package/pages/functions/filepath-routing.ts +38 -28
  6. package/pages/functions/routes.ts +8 -6
  7. package/pages/functions/template-worker.ts +16 -24
  8. package/src/__tests__/dev.test.tsx +7 -3
  9. package/src/__tests__/{clipboardy-mock.js → helpers/clipboardy-mock.js} +0 -0
  10. package/src/__tests__/helpers/mock-account-id.ts +30 -0
  11. package/src/__tests__/{mock-cfetch.ts → helpers/mock-cfetch.ts} +10 -8
  12. package/src/__tests__/helpers/mock-console.ts +56 -0
  13. package/src/__tests__/{mock-dialogs.ts → helpers/mock-dialogs.ts} +1 -1
  14. package/src/__tests__/helpers/mock-kv.ts +40 -0
  15. package/src/__tests__/helpers/mock-user.ts +27 -0
  16. package/src/__tests__/helpers/run-in-tmp.ts +29 -0
  17. package/src/__tests__/helpers/run-wrangler.ts +14 -0
  18. package/src/__tests__/index.test.ts +173 -54
  19. package/src/__tests__/jest.setup.ts +14 -2
  20. package/src/__tests__/kv.test.ts +327 -289
  21. package/src/__tests__/logout.test.ts +50 -0
  22. package/src/__tests__/publish.test.ts +1222 -0
  23. package/src/__tests__/secret.test.ts +210 -0
  24. package/src/__tests__/whoami.test.tsx +86 -0
  25. package/src/api/form_data.ts +10 -7
  26. package/src/api/preview.ts +2 -2
  27. package/src/api/worker.ts +3 -3
  28. package/src/cfetch/index.ts +13 -4
  29. package/src/cfetch/internal.ts +10 -7
  30. package/src/config.ts +162 -8
  31. package/src/dev.tsx +105 -57
  32. package/src/dialogs.tsx +2 -2
  33. package/src/index.tsx +388 -302
  34. package/src/inspect.ts +80 -23
  35. package/src/kv.tsx +1 -1
  36. package/src/module-collection.ts +5 -6
  37. package/src/npm-installer.ts +20 -0
  38. package/src/pages.tsx +42 -28
  39. package/src/paths.ts +26 -0
  40. package/src/proxy.ts +78 -10
  41. package/src/publish.ts +97 -51
  42. package/src/sites.tsx +175 -53
  43. package/src/user.tsx +51 -59
  44. package/src/whoami.tsx +69 -0
  45. package/wrangler-dist/cli.js +111330 -110202
  46. package/wrangler-dist/cli.js.map +3 -3
  47. package/src/__tests__/run-in-tmp.ts +0 -19
  48. package/src/__tests__/run-wrangler.ts +0 -32
@@ -0,0 +1,29 @@
1
+ import * as fs from "node:fs";
2
+ import os from "node:os";
3
+ import * as path from "node:path";
4
+
5
+ const originalCwd = process.cwd();
6
+
7
+ export function runInTempDir({ homedir }: { homedir?: string } = {}) {
8
+ let tmpDir: string;
9
+
10
+ beforeEach(() => {
11
+ tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "wrangler-tests"));
12
+ process.chdir(tmpDir);
13
+ if (homedir !== undefined) {
14
+ // Override where the home directory is so that we can write our own user config,
15
+ // without destroying the real thing.
16
+ fs.mkdirSync(homedir);
17
+ // Note it is very important that we use the "default" value from "node:os" (e.g. `import os from "node:os";`)
18
+ // rather than an alias to the module (e.g. `import * as os from "node:os";`).
19
+ // This is because the module gets transpiled so that the "method" `homedir()` gets converted to a
20
+ // getter that is not configurable (and so cannot be spied upon).
21
+ jest.spyOn(os, "homedir").mockReturnValue(homedir);
22
+ }
23
+ });
24
+
25
+ afterEach(() => {
26
+ process.chdir(originalCwd);
27
+ fs.rmSync(tmpDir, { recursive: true });
28
+ });
29
+ }
@@ -0,0 +1,14 @@
1
+ import { main } from "../../index";
2
+ import { normalizeSlashes, stripTimings } from "./mock-console";
3
+
4
+ /**
5
+ * A helper to 'run' wrangler commands for tests.
6
+ */
7
+ export async function runWrangler(cmd?: string) {
8
+ try {
9
+ await main(cmd?.split(" ") ?? []);
10
+ } catch (e) {
11
+ e.message = normalizeSlashes(stripTimings(e.message));
12
+ throw e;
13
+ }
14
+ }
@@ -1,22 +1,33 @@
1
+ import * as fs from "node:fs";
1
2
  import * as fsp from "node:fs/promises";
2
3
  import * as TOML from "@iarna/toml";
3
- import { mockConfirm } from "./mock-dialogs";
4
- import { runWrangler } from "./run-wrangler";
5
- import { runInTempDir } from "./run-in-tmp";
6
- import * as fs from "node:fs";
4
+ import { version as wranglerVersion } from "../../package.json";
5
+ import { npm } from "../npm-installer";
6
+ import { mockConsoleMethods } from "./helpers/mock-console";
7
+ import { mockConfirm } from "./helpers/mock-dialogs";
8
+ import { runInTempDir } from "./helpers/run-in-tmp";
9
+ import { runWrangler } from "./helpers/run-wrangler";
7
10
 
8
11
  describe("wrangler", () => {
9
12
  runInTempDir();
10
13
 
14
+ beforeEach(() => {
15
+ jest.spyOn(npm, "addDevDeps").mockResolvedValue();
16
+ jest.spyOn(npm, "install").mockResolvedValue();
17
+ });
18
+
19
+ const std = mockConsoleMethods();
20
+
11
21
  describe("no command", () => {
12
22
  it("should display a list of available commands", async () => {
13
- const { stdout, stderr } = await runWrangler();
23
+ await runWrangler();
14
24
 
15
- expect(stdout).toMatchInlineSnapshot(`
25
+ expect(std.out).toMatchInlineSnapshot(`
16
26
  "wrangler
17
27
 
18
28
  Commands:
19
29
  wrangler init [name] 📥 Create a wrangler.toml configuration file
30
+ wrangler whoami 🕵️ Retrieve your user info and test your auth config
20
31
  wrangler dev <filename> 👂 Start a local server for developing your worker
21
32
  wrangler publish [script] 🆙 Publish your Worker to Cloudflare.
22
33
  wrangler tail [name] 🦚 Starts a log tailing session for a deployed Worker.
@@ -35,20 +46,25 @@ describe("wrangler", () => {
35
46
  -l, --local Run on my machine [boolean] [default: false]"
36
47
  `);
37
48
 
38
- expect(stderr).toMatchInlineSnapshot(`""`);
49
+ expect(std.err).toMatchInlineSnapshot(`""`);
39
50
  });
40
51
  });
41
52
 
42
53
  describe("invalid command", () => {
43
54
  it("should display an error", async () => {
44
- const { error, stdout, stderr } = await runWrangler("invalid-command");
55
+ await expect(
56
+ runWrangler("invalid-command")
57
+ ).rejects.toThrowErrorMatchingInlineSnapshot(
58
+ `"Unknown command: invalid-command."`
59
+ );
45
60
 
46
- expect(stdout).toMatchInlineSnapshot(`""`);
47
- expect(stderr).toMatchInlineSnapshot(`
61
+ expect(std.out).toMatchInlineSnapshot(`""`);
62
+ expect(std.err).toMatchInlineSnapshot(`
48
63
  "wrangler
49
64
 
50
65
  Commands:
51
66
  wrangler init [name] 📥 Create a wrangler.toml configuration file
67
+ wrangler whoami 🕵️ Retrieve your user info and test your auth config
52
68
  wrangler dev <filename> 👂 Start a local server for developing your worker
53
69
  wrangler publish [script] 🆙 Publish your Worker to Cloudflare.
54
70
  wrangler tail [name] 🦚 Starts a log tailing session for a deployed Worker.
@@ -68,9 +84,6 @@ describe("wrangler", () => {
68
84
 
69
85
  Unknown command: invalid-command."
70
86
  `);
71
- expect(error).toMatchInlineSnapshot(
72
- `[Error: Unknown command: invalid-command.]`
73
- );
74
87
  });
75
88
  });
76
89
 
@@ -88,19 +101,27 @@ describe("wrangler", () => {
88
101
  });
89
102
 
90
103
  it("should display warning when wrangler.toml already exists, and exit if user does not want to carry on", async () => {
91
- fs.writeFileSync("./wrangler.toml", "", "utf-8");
104
+ fs.writeFileSync(
105
+ "./wrangler.toml",
106
+ 'compatibility_date="something-else"', // use a fake value to make sure the file is not overwritten
107
+ "utf-8"
108
+ );
92
109
  mockConfirm({
93
110
  text: "Do you want to continue initializing this project?",
94
111
  result: false,
95
112
  });
96
- const { warnings } = await runWrangler("init");
97
- expect(warnings).toContain("wrangler.toml file already exists!");
113
+ await runWrangler("init");
114
+ expect(std.warn).toContain("wrangler.toml file already exists!");
98
115
  const parsed = TOML.parse(await fsp.readFile("./wrangler.toml", "utf-8"));
99
- expect(typeof parsed.compatibility_date).toBe("undefined");
116
+ expect(parsed.compatibility_date).toBe("something-else");
100
117
  });
101
118
 
102
119
  it("should display warning when wrangler.toml already exists, but continue if user does want to carry on", async () => {
103
- fs.writeFileSync("./wrangler.toml", "", "utf-8");
120
+ fs.writeFileSync(
121
+ "./wrangler.toml",
122
+ `compatibility_date="something-else"`,
123
+ "utf-8"
124
+ );
104
125
  mockConfirm(
105
126
  {
106
127
  text: "Do you want to continue initializing this project?",
@@ -111,10 +132,10 @@ describe("wrangler", () => {
111
132
  result: false,
112
133
  }
113
134
  );
114
- const { warnings } = await runWrangler("init");
115
- expect(warnings).toContain("wrangler.toml file already exists!");
135
+ await runWrangler("init");
136
+ expect(std.warn).toContain("wrangler.toml file already exists!");
116
137
  const parsed = TOML.parse(await fsp.readFile("./wrangler.toml", "utf-8"));
117
- expect(typeof parsed.compatibility_date).toBe("string");
138
+ expect(parsed.compatibility_date).toBe("something-else");
118
139
  });
119
140
 
120
141
  it("should create a package.json if none is found and user confirms", async () => {
@@ -134,15 +155,25 @@ describe("wrangler", () => {
134
155
  fs.readFileSync("./package.json", "utf-8")
135
156
  );
136
157
  expect(packageJson.name).toEqual("worker"); // TODO: should we infer the name from the directory?
137
- expect(packageJson.version).toEqual("0.0.1");
158
+ expect(packageJson.version).toEqual("0.0.0");
159
+ expect(packageJson.devDependencies).toEqual({
160
+ wrangler: expect.any(String),
161
+ });
138
162
  expect(fs.existsSync("./tsconfig.json")).toBe(false);
163
+ expect(npm.install).toHaveBeenCalled();
139
164
  });
140
165
 
141
166
  it("should not touch an existing package.json in the same directory", async () => {
142
- mockConfirm({
143
- text: "Would you like to use typescript?",
144
- result: false,
145
- });
167
+ mockConfirm(
168
+ {
169
+ text: "Would you like to install wrangler into your package.json?",
170
+ result: false,
171
+ },
172
+ {
173
+ text: "Would you like to use typescript?",
174
+ result: false,
175
+ }
176
+ );
146
177
 
147
178
  fs.writeFileSync(
148
179
  "./package.json",
@@ -158,11 +189,46 @@ describe("wrangler", () => {
158
189
  expect(packageJson.version).toEqual("1.0.0");
159
190
  });
160
191
 
192
+ it("should offer to install wrangler into an existing package.json", async () => {
193
+ mockConfirm(
194
+ {
195
+ text: "Would you like to install wrangler into your package.json?",
196
+ result: true,
197
+ },
198
+ {
199
+ text: "Would you like to use typescript?",
200
+ result: false,
201
+ }
202
+ );
203
+
204
+ fs.writeFileSync(
205
+ "./package.json",
206
+ JSON.stringify({ name: "test", version: "1.0.0" }),
207
+ "utf-8"
208
+ );
209
+
210
+ await runWrangler("init");
211
+ const packageJson = JSON.parse(
212
+ fs.readFileSync("./package.json", "utf-8")
213
+ );
214
+ expect(packageJson.name).toEqual("test");
215
+ expect(packageJson.version).toEqual("1.0.0");
216
+ expect(npm.addDevDeps).toHaveBeenCalledWith(
217
+ `wrangler@${wranglerVersion}`
218
+ );
219
+ });
220
+
161
221
  it("should not touch an existing package.json in an ancestor directory", async () => {
162
- mockConfirm({
163
- text: "Would you like to use typescript?",
164
- result: false,
165
- });
222
+ mockConfirm(
223
+ {
224
+ text: "Would you like to install wrangler into your package.json?",
225
+ result: false,
226
+ },
227
+ {
228
+ text: "Would you like to use typescript?",
229
+ result: false,
230
+ }
231
+ );
166
232
 
167
233
  fs.writeFileSync(
168
234
  "./package.json",
@@ -180,8 +246,12 @@ describe("wrangler", () => {
180
246
  const packageJson = JSON.parse(
181
247
  fs.readFileSync("../../package.json", "utf-8")
182
248
  );
183
- expect(packageJson.name).toEqual("test");
184
- expect(packageJson.version).toEqual("1.0.0");
249
+ expect(packageJson).toMatchInlineSnapshot(`
250
+ Object {
251
+ "name": "test",
252
+ "version": "1.0.0",
253
+ }
254
+ `);
185
255
  });
186
256
 
187
257
  it("should create a tsconfig.json and install `workers-types` if none is found and user confirms", async () => {
@@ -203,18 +273,23 @@ describe("wrangler", () => {
203
273
  expect(tsconfigJson.compilerOptions.types).toEqual([
204
274
  "@cloudflare/workers-types",
205
275
  ]);
206
- const packageJson = JSON.parse(
207
- fs.readFileSync("./package.json", "utf-8")
276
+ expect(npm.addDevDeps).toHaveBeenCalledWith(
277
+ "@cloudflare/workers-types",
278
+ "typescript"
208
279
  );
209
- expect(packageJson.devDependencies).toEqual({
210
- "@cloudflare/workers-types": expect.any(String),
211
- });
212
280
  });
213
281
 
214
282
  it("should not touch an existing tsconfig.json in the same directory", async () => {
215
283
  fs.writeFileSync(
216
284
  "./package.json",
217
- JSON.stringify({ name: "test", version: "1.0.0" }),
285
+ JSON.stringify({
286
+ name: "test",
287
+ version: "1.0.0",
288
+ devDependencies: {
289
+ wrangler: "0.0.0",
290
+ "@cloudflare/workers-types": "0.0.0",
291
+ },
292
+ }),
218
293
  "utf-8"
219
294
  );
220
295
  fs.writeFileSync(
@@ -230,10 +305,51 @@ describe("wrangler", () => {
230
305
  expect(tsconfigJson.compilerOptions).toEqual({});
231
306
  });
232
307
 
233
- it("should not touch an existing package.json in an ancestor directory", async () => {
308
+ it("should offer to install type definitions in an existing typescript project", async () => {
309
+ mockConfirm(
310
+ {
311
+ text: "Would you like to install wrangler into your package.json?",
312
+ result: false,
313
+ },
314
+ {
315
+ text: "Would you like to install the type definitions for Workers into your package.json?",
316
+ result: true,
317
+ }
318
+ );
234
319
  fs.writeFileSync(
235
320
  "./package.json",
236
- JSON.stringify({ name: "test", version: "1.0.0" }),
321
+ JSON.stringify({
322
+ name: "test",
323
+ version: "1.0.0",
324
+ }),
325
+ "utf-8"
326
+ );
327
+ fs.writeFileSync(
328
+ "./tsconfig.json",
329
+ JSON.stringify({ compilerOptions: {} }),
330
+ "utf-8"
331
+ );
332
+
333
+ await runWrangler("init");
334
+ const tsconfigJson = JSON.parse(
335
+ fs.readFileSync("./tsconfig.json", "utf-8")
336
+ );
337
+ // unchanged tsconfig
338
+ expect(tsconfigJson.compilerOptions).toEqual({});
339
+ expect(npm.addDevDeps).toHaveBeenCalledWith("@cloudflare/workers-types");
340
+ });
341
+
342
+ it("should not touch an existing tsconfig.json in an ancestor directory", async () => {
343
+ fs.writeFileSync(
344
+ "./package.json",
345
+ JSON.stringify({
346
+ name: "test",
347
+ version: "1.0.0",
348
+ devDependencies: {
349
+ wrangler: "0.0.0",
350
+ "@cloudflare/workers-types": "0.0.0",
351
+ },
352
+ }),
237
353
  "utf-8"
238
354
  );
239
355
  fs.writeFileSync(
@@ -256,32 +372,35 @@ describe("wrangler", () => {
256
372
  });
257
373
 
258
374
  it("should error if `--type` is used", async () => {
259
- const { error } = await runWrangler("init --type");
260
- expect(error).toMatchInlineSnapshot(
261
- `[Error: The --type option is no longer supported.]`
375
+ await expect(
376
+ runWrangler("init --type")
377
+ ).rejects.toThrowErrorMatchingInlineSnapshot(
378
+ `"The --type option is no longer supported."`
262
379
  );
263
380
  });
264
381
 
265
382
  it("should error if `--type javascript` is used", async () => {
266
- const { error } = await runWrangler("init --type javascript");
267
- expect(error).toMatchInlineSnapshot(
268
- `[Error: The --type option is no longer supported.]`
383
+ await expect(
384
+ runWrangler("init --type javascript")
385
+ ).rejects.toThrowErrorMatchingInlineSnapshot(
386
+ `"The --type option is no longer supported."`
269
387
  );
270
388
  });
271
389
 
272
390
  it("should error if `--type rust` is used", async () => {
273
- const { error } = await runWrangler("init --type rust");
274
- expect(error).toMatchInlineSnapshot(
275
- `[Error: The --type option is no longer supported.]`
391
+ await expect(
392
+ runWrangler("init --type rust")
393
+ ).rejects.toThrowErrorMatchingInlineSnapshot(
394
+ `"The --type option is no longer supported."`
276
395
  );
277
396
  });
278
397
 
279
398
  it("should error if `--type webpack` is used", async () => {
280
- const { error } = await runWrangler("init --type webpack");
281
- expect(error).toMatchInlineSnapshot(`
282
- [Error: The --type option is no longer supported.
283
- If you wish to use webpack then you will need to create a custom build.]
284
- `);
399
+ await expect(runWrangler("init --type webpack")).rejects
400
+ .toThrowErrorMatchingInlineSnapshot(`
401
+ "The --type option is no longer supported.
402
+ If you wish to use webpack then you will need to create a custom build."
403
+ `);
285
404
  });
286
405
  });
287
406
  });
@@ -1,6 +1,18 @@
1
- import { mockFetchInternal } from "./mock-cfetch";
2
- import { confirm, prompt } from "../dialogs";
1
+ import fetchMock from "jest-fetch-mock";
3
2
  import { fetchInternal } from "../cfetch/internal";
3
+ import { confirm, prompt } from "../dialogs";
4
+ import { mockFetchInternal } from "./helpers/mock-cfetch";
5
+
6
+ jest.mock("undici", () => {
7
+ return {
8
+ ...jest.requireActual("undici"),
9
+ fetch: jest.requireActual("jest-fetch-mock"),
10
+ };
11
+ });
12
+ fetchMock.doMock(() => {
13
+ // Any un-mocked fetches should throw
14
+ throw new Error("Unexpected fetch request");
15
+ });
4
16
 
5
17
  jest.mock("../cfetch/internal");
6
18
  (fetchInternal as jest.Mock).mockImplementation(mockFetchInternal);