wrangler 0.0.0-e2f9bb2 → 0.0.0-e322475

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 (103) hide show
  1. package/Cloudflare_CA.pem +18 -0
  2. package/README.md +3 -1
  3. package/bin/wrangler.js +36 -4
  4. package/kv-asset-handler.js +1 -0
  5. package/package.json +15 -7
  6. package/pages/functions/buildPlugin.ts +13 -0
  7. package/pages/functions/buildWorker.ts +14 -1
  8. package/pages/functions/template-plugin.ts +3 -2
  9. package/src/__tests__/configuration.test.ts +652 -229
  10. package/src/__tests__/dev.test.tsx +372 -79
  11. package/src/__tests__/helpers/mock-cfetch.ts +2 -2
  12. package/src/__tests__/helpers/mock-console.ts +11 -1
  13. package/src/__tests__/helpers/mock-dialogs.ts +75 -11
  14. package/src/__tests__/helpers/mock-process.ts +24 -0
  15. package/src/__tests__/index.test.ts +81 -72
  16. package/src/__tests__/init.test.ts +1360 -410
  17. package/src/__tests__/jest.setup.ts +38 -0
  18. package/src/__tests__/kv.test.ts +218 -152
  19. package/src/__tests__/logger.test.ts +26 -0
  20. package/src/__tests__/package-manager.test.ts +154 -7
  21. package/src/__tests__/pages.test.ts +478 -53
  22. package/src/__tests__/parse.test.ts +8 -0
  23. package/src/__tests__/publish.test.ts +1614 -333
  24. package/src/__tests__/r2.test.ts +55 -36
  25. package/src/__tests__/secret.test.ts +39 -4
  26. package/src/__tests__/user.test.ts +1 -0
  27. package/src/__tests__/whoami.test.tsx +34 -0
  28. package/src/abort.d.ts +3 -0
  29. package/src/bundle-reporter.tsx +29 -0
  30. package/src/bundle.ts +42 -7
  31. package/src/cfetch/index.ts +21 -4
  32. package/src/cfetch/internal.ts +25 -20
  33. package/src/config/config.ts +11 -2
  34. package/src/config/environment.ts +41 -15
  35. package/src/config/index.ts +162 -0
  36. package/src/config/validation-helpers.ts +10 -1
  37. package/src/config/validation.ts +234 -78
  38. package/src/create-worker-preview.ts +32 -22
  39. package/src/create-worker-upload-form.ts +22 -8
  40. package/src/dev/dev.tsx +48 -67
  41. package/src/dev/local.tsx +16 -7
  42. package/src/dev/remote.tsx +57 -21
  43. package/src/dev/use-esbuild.ts +1 -7
  44. package/src/dialogs.tsx +48 -0
  45. package/src/durable.ts +102 -0
  46. package/src/entry.ts +71 -10
  47. package/src/generate-auth-url.ts +33 -0
  48. package/src/generate-random-state.ts +16 -0
  49. package/src/git-client.ts +42 -0
  50. package/src/index.tsx +619 -338
  51. package/src/inspect.ts +39 -0
  52. package/src/kv.ts +116 -27
  53. package/src/logger.ts +8 -1
  54. package/src/open-in-browser.ts +3 -12
  55. package/src/package-manager.ts +50 -3
  56. package/src/pages.tsx +434 -207
  57. package/src/parse.ts +44 -5
  58. package/src/proxy.ts +66 -44
  59. package/src/publish.ts +407 -137
  60. package/src/sites.tsx +103 -28
  61. package/src/user.tsx +35 -26
  62. package/src/whoami.tsx +3 -2
  63. package/src/worker.ts +10 -1
  64. package/src/zones.ts +73 -0
  65. package/templates/new-worker-scheduled.js +17 -0
  66. package/templates/new-worker-scheduled.ts +32 -0
  67. package/templates/new-worker.ts +16 -1
  68. package/templates/no-op-worker.js +10 -0
  69. package/templates/static-asset-facade.js +2 -6
  70. package/wrangler-dist/cli.js +46122 -32396
  71. package/vendor/@cloudflare/kv-asset-handler/CHANGELOG.md +0 -332
  72. package/vendor/@cloudflare/kv-asset-handler/LICENSE_APACHE +0 -176
  73. package/vendor/@cloudflare/kv-asset-handler/LICENSE_MIT +0 -25
  74. package/vendor/@cloudflare/kv-asset-handler/README.md +0 -245
  75. package/vendor/@cloudflare/kv-asset-handler/dist/index.d.ts +0 -32
  76. package/vendor/@cloudflare/kv-asset-handler/dist/index.js +0 -354
  77. package/vendor/@cloudflare/kv-asset-handler/dist/mocks.d.ts +0 -13
  78. package/vendor/@cloudflare/kv-asset-handler/dist/mocks.js +0 -148
  79. package/vendor/@cloudflare/kv-asset-handler/dist/test/getAssetFromKV.d.ts +0 -1
  80. package/vendor/@cloudflare/kv-asset-handler/dist/test/getAssetFromKV.js +0 -436
  81. package/vendor/@cloudflare/kv-asset-handler/dist/test/mapRequestToAsset.d.ts +0 -1
  82. package/vendor/@cloudflare/kv-asset-handler/dist/test/mapRequestToAsset.js +0 -40
  83. package/vendor/@cloudflare/kv-asset-handler/dist/test/serveSinglePageApp.d.ts +0 -1
  84. package/vendor/@cloudflare/kv-asset-handler/dist/test/serveSinglePageApp.js +0 -42
  85. package/vendor/@cloudflare/kv-asset-handler/dist/types.d.ts +0 -26
  86. package/vendor/@cloudflare/kv-asset-handler/dist/types.js +0 -31
  87. package/vendor/@cloudflare/kv-asset-handler/package.json +0 -52
  88. package/vendor/@cloudflare/kv-asset-handler/src/index.ts +0 -296
  89. package/vendor/@cloudflare/kv-asset-handler/src/mocks.ts +0 -136
  90. package/vendor/@cloudflare/kv-asset-handler/src/test/getAssetFromKV.ts +0 -464
  91. package/vendor/@cloudflare/kv-asset-handler/src/test/mapRequestToAsset.ts +0 -33
  92. package/vendor/@cloudflare/kv-asset-handler/src/test/serveSinglePageApp.ts +0 -42
  93. package/vendor/@cloudflare/kv-asset-handler/src/types.ts +0 -39
  94. package/vendor/wrangler-mime/CHANGELOG.md +0 -289
  95. package/vendor/wrangler-mime/LICENSE +0 -21
  96. package/vendor/wrangler-mime/Mime.js +0 -97
  97. package/vendor/wrangler-mime/README.md +0 -187
  98. package/vendor/wrangler-mime/cli.js +0 -46
  99. package/vendor/wrangler-mime/index.js +0 -4
  100. package/vendor/wrangler-mime/lite.js +0 -4
  101. package/vendor/wrangler-mime/package.json +0 -52
  102. package/vendor/wrangler-mime/types/other.js +0 -1
  103. package/vendor/wrangler-mime/types/standard.js +0 -1
@@ -1,17 +1,30 @@
1
1
  import * as fs from "node:fs";
2
- import * as fsp from "node:fs/promises";
3
2
  import path from "node:path";
4
3
  import * as TOML from "@iarna/toml";
5
- import { execa } from "execa";
4
+ import { execa, execaSync } from "execa";
6
5
  import { parseConfigFileTextToJson } from "typescript";
7
6
  import { version as wranglerVersion } from "../../package.json";
8
7
  import { getPackageManager } from "../package-manager";
9
8
  import { mockConsoleMethods } from "./helpers/mock-console";
10
- import { mockConfirm, clearConfirmMocks } from "./helpers/mock-dialogs";
9
+ import {
10
+ mockConfirm,
11
+ clearConfirmMocks,
12
+ mockSelect,
13
+ clearSelectMocks,
14
+ } from "./helpers/mock-dialogs";
11
15
  import { runInTempDir } from "./helpers/run-in-tmp";
12
16
  import { runWrangler } from "./helpers/run-wrangler";
13
17
  import type { PackageManager } from "../package-manager";
14
18
 
19
+ /**
20
+ * An expectation matcher for the minimal generated wrangler.toml.
21
+ */
22
+ const MINIMAL_WRANGLER_TOML = {
23
+ compatibility_date: expect.any(String),
24
+ name: expect.stringContaining("wrangler-tests"),
25
+ main: "src/index.ts",
26
+ };
27
+
15
28
  describe("init", () => {
16
29
  let mockPackageManager: PackageManager;
17
30
  runInTempDir();
@@ -29,6 +42,7 @@ describe("init", () => {
29
42
 
30
43
  afterEach(() => {
31
44
  clearConfirmMocks();
45
+ clearSelectMocks();
32
46
  });
33
47
 
34
48
  const std = mockConsoleMethods();
@@ -37,20 +51,26 @@ describe("init", () => {
37
51
  it("should initialize with no interactive prompts if `--yes` is used", async () => {
38
52
  await runWrangler("init --yes");
39
53
 
40
- expect(fs.existsSync("./src/index.js")).toBe(false);
41
- expect(fs.existsSync("./src/index.ts")).toBe(true);
42
- expect(fs.existsSync("./tsconfig.json")).toBe(true);
43
- expect(fs.existsSync("./package.json")).toBe(true);
44
- expect(fs.existsSync("./wrangler.toml")).toBe(true);
54
+ checkFiles({
55
+ items: {
56
+ "./src/index.js": false,
57
+ "./src/index.ts": true,
58
+ "./tsconfig.json": true,
59
+ "./package.json": true,
60
+ "./wrangler.toml": true,
61
+ },
62
+ });
63
+
45
64
  expect(std.out).toMatchInlineSnapshot(`
46
- "✨ Successfully created wrangler.toml
65
+ "✨ Created wrangler.toml
47
66
  ✨ Initialized git repository
48
67
  ✨ Created package.json
49
- ✨ Created tsconfig.json, installed @cloudflare/workers-types into devDependencies
68
+ ✨ Created tsconfig.json
50
69
  ✨ Created src/index.ts
70
+ ✨ Installed @cloudflare/workers-types and typescript into devDependencies
51
71
 
52
72
  To start developing your Worker, run \`npm start\`
53
- To publish your Worker to the Internet, run \`npm run publish\`"
73
+ To publish your Worker to the Internet, run \`npm run deploy\`"
54
74
  `);
55
75
  expect(std.err).toMatchInlineSnapshot(`""`);
56
76
  expect(std.warn).toMatchInlineSnapshot(`""`);
@@ -59,24 +79,29 @@ describe("init", () => {
59
79
  it("should initialize with no interactive prompts if `--yes` is used (named worker)", async () => {
60
80
  await runWrangler("init my-worker --yes");
61
81
 
62
- expect(fs.existsSync("./my-worker/src/index.js")).toBe(false);
63
- expect(fs.existsSync("./my-worker/src/index.ts")).toBe(true);
64
- expect(fs.existsSync("./my-worker/tsconfig.json")).toBe(true);
65
- expect(fs.existsSync("./my-worker/package.json")).toBe(true);
66
- expect(fs.existsSync("./my-worker/wrangler.toml")).toBe(true);
67
- const parsedWranglerToml = TOML.parse(
68
- fs.readFileSync("./my-worker/wrangler.toml", "utf-8")
69
- );
70
- expect(parsedWranglerToml.main).toEqual("src/index.ts");
82
+ checkFiles({
83
+ items: {
84
+ "./my-worker/src/index.js": false,
85
+ "./my-worker/src/index.ts": true,
86
+ "./my-worker/tsconfig.json": true,
87
+ "./my-worker/package.json": true,
88
+ "./my-worker/wrangler.toml": wranglerToml({
89
+ ...MINIMAL_WRANGLER_TOML,
90
+ name: "my-worker",
91
+ }),
92
+ },
93
+ });
94
+
71
95
  expect(std.out).toMatchInlineSnapshot(`
72
- "✨ Successfully created wrangler.toml
73
- ✨ Initialized git repository
74
- ✨ Created package.json
75
- ✨ Created tsconfig.json, installed @cloudflare/workers-types into devDependencies
76
- ✨ Created src/index.ts
96
+ "✨ Created my-worker/wrangler.toml
97
+ ✨ Initialized git repository at my-worker
98
+ ✨ Created my-worker/package.json
99
+ ✨ Created my-worker/tsconfig.json
100
+ ✨ Created my-worker/src/index.ts
101
+ ✨ Installed @cloudflare/workers-types and typescript into devDependencies
77
102
 
78
103
  To start developing your Worker, run \`cd my-worker && npm start\`
79
- To publish your Worker to the Internet, run \`npm run publish\`"
104
+ To publish your Worker to the Internet, run \`npm run deploy\`"
80
105
  `);
81
106
  expect(std.err).toMatchInlineSnapshot(`""`);
82
107
  expect(std.warn).toMatchInlineSnapshot(`""`);
@@ -85,23 +110,29 @@ describe("init", () => {
85
110
  it("should initialize with no interactive prompts if `-y` is used", async () => {
86
111
  await runWrangler("init -y");
87
112
 
88
- expect(fs.existsSync("./src/index.js")).toBe(false);
89
- expect(fs.existsSync("./src/index.ts")).toBe(true);
90
- expect(fs.existsSync("./tsconfig.json")).toBe(true);
91
- expect(fs.existsSync("./package.json")).toBe(true);
92
- expect(fs.existsSync("./wrangler.toml")).toBe(true);
113
+ checkFiles({
114
+ items: {
115
+ "./src/index.js": false,
116
+ "./src/index.ts": true,
117
+ "./tsconfig.json": true,
118
+ "./package.json": true,
119
+ "./wrangler.toml": true,
120
+ },
121
+ });
122
+
93
123
  expect(std).toMatchInlineSnapshot(`
94
124
  Object {
95
125
  "debug": "",
96
126
  "err": "",
97
- "out": "✨ Successfully created wrangler.toml
127
+ "out": "✨ Created wrangler.toml
98
128
  ✨ Initialized git repository
99
129
  ✨ Created package.json
100
- ✨ Created tsconfig.json, installed @cloudflare/workers-types into devDependencies
130
+ ✨ Created tsconfig.json
101
131
  ✨ Created src/index.ts
132
+ ✨ Installed @cloudflare/workers-types and typescript into devDependencies
102
133
 
103
134
  To start developing your Worker, run \`npm start\`
104
- To publish your Worker to the Internet, run \`npm run publish\`",
135
+ To publish your Worker to the Internet, run \`npm run deploy\`",
105
136
  "warn": "",
106
137
  }
107
138
  `);
@@ -161,11 +192,25 @@ describe("init", () => {
161
192
  }
162
193
  );
163
194
  await runWrangler("init");
164
- const parsed = TOML.parse(await fsp.readFile("./wrangler.toml", "utf-8"));
165
- expect(typeof parsed.compatibility_date).toBe("string");
166
- expect(parsed.name).toContain("wrangler-tests");
167
- expect(fs.existsSync("./package.json")).toBe(false);
168
- expect(fs.existsSync("./tsconfig.json")).toBe(false);
195
+ checkFiles({
196
+ items: {
197
+ "wrangler.toml": wranglerToml({
198
+ compatibility_date: expect.any(String),
199
+ name: expect.stringContaining("wrangler-tests"),
200
+ }),
201
+ "package.json": false,
202
+ "tsconfig.json": false,
203
+ },
204
+ });
205
+
206
+ expect(std).toMatchInlineSnapshot(`
207
+ Object {
208
+ "debug": "",
209
+ "err": "",
210
+ "out": "✨ Created wrangler.toml",
211
+ "warn": "",
212
+ }
213
+ `);
169
214
  });
170
215
 
171
216
  it("should create a wrangler.toml and a directory for a named Worker ", async () => {
@@ -180,37 +225,113 @@ describe("init", () => {
180
225
  }
181
226
  );
182
227
  await runWrangler("init my-worker");
183
- const parsed = TOML.parse(
184
- await fsp.readFile("./my-worker/wrangler.toml", "utf-8")
185
- );
186
- expect(typeof parsed.compatibility_date).toBe("string");
187
- expect(parsed.name).toBe("my-worker");
188
- expect(fs.existsSync("./my-worker/package.json")).toBe(false);
189
- expect(fs.existsSync("./my-worker/tsconfig.json")).toBe(false);
228
+
229
+ checkFiles({
230
+ items: {
231
+ "my-worker/wrangler.toml": wranglerToml({
232
+ compatibility_date: expect.any(String),
233
+ name: "my-worker",
234
+ }),
235
+ "my-worker/package.json": false,
236
+ "my-worker/tsconfig.json": false,
237
+ },
238
+ });
239
+
240
+ expect(std).toMatchInlineSnapshot(`
241
+ Object {
242
+ "debug": "",
243
+ "err": "",
244
+ "out": "✨ Created my-worker/wrangler.toml",
245
+ "warn": "",
246
+ }
247
+ `);
190
248
  });
191
249
 
192
250
  it("should display warning when wrangler.toml already exists, and exit if user does not want to carry on", async () => {
193
- fs.writeFileSync(
194
- "./wrangler.toml",
195
- 'compatibility_date="something-else"', // use a fake value to make sure the file is not overwritten
196
- "utf-8"
197
- );
251
+ writeFiles({
252
+ items: {
253
+ "wrangler.toml": wranglerToml({
254
+ // use a fake value to make sure the file is not overwritten
255
+ compatibility_date: "something-else",
256
+ }),
257
+ },
258
+ });
259
+
198
260
  mockConfirm({
199
261
  text: "Do you want to continue initializing this project?",
200
262
  result: false,
201
263
  });
264
+
202
265
  await runWrangler("init");
203
- expect(std.warn).toContain("wrangler.toml file already exists!");
204
- const parsed = TOML.parse(await fsp.readFile("./wrangler.toml", "utf-8"));
205
- expect(parsed.compatibility_date).toBe("something-else");
266
+ expect(std.warn).toContain("wrangler.toml already exists!");
267
+
268
+ checkFiles({
269
+ items: {
270
+ "wrangler.toml": wranglerToml({
271
+ compatibility_date: "something-else",
272
+ }),
273
+ "package.json": false,
274
+ "tsconfig.json": false,
275
+ },
276
+ });
277
+
278
+ expect(std).toMatchInlineSnapshot(`
279
+ Object {
280
+ "debug": "",
281
+ "err": "",
282
+ "out": "",
283
+ "warn": "▲ [WARNING] wrangler.toml already exists!
284
+
285
+ ",
286
+ }
287
+ `);
288
+ });
289
+
290
+ it("should display warning when wrangler.toml already exists in the target directory, and exit if user does not want to carry on", async () => {
291
+ writeFiles({
292
+ items: {
293
+ "path/to/worker/wrangler.toml": wranglerToml({
294
+ compatibility_date: "something-else",
295
+ }),
296
+ },
297
+ });
298
+ mockConfirm({
299
+ text: "Do you want to continue initializing this project?",
300
+ result: false,
301
+ });
302
+
303
+ await runWrangler("init path/to/worker");
304
+
305
+ expect(std.warn).toContain("wrangler.toml already exists!");
306
+ checkFiles({
307
+ items: {
308
+ "path/to/worker/wrangler.toml": wranglerToml({
309
+ compatibility_date: "something-else",
310
+ }),
311
+ "package.json": false,
312
+ "tsconfig.json": false,
313
+ },
314
+ });
315
+ expect(std).toMatchInlineSnapshot(`
316
+ Object {
317
+ "debug": "",
318
+ "err": "",
319
+ "out": "",
320
+ "warn": "▲ [WARNING] path/to/worker/wrangler.toml already exists!
321
+
322
+ ",
323
+ }
324
+ `);
206
325
  });
207
326
 
208
327
  it("should not overwrite an existing wrangler.toml, after agreeing to other prompts", async () => {
209
- fs.writeFileSync(
210
- "./wrangler.toml",
211
- 'compatibility_date="something-else"', // use a fake value to make sure the file is not overwritten
212
- "utf-8"
213
- );
328
+ writeFiles({
329
+ items: {
330
+ "wrangler.toml": wranglerToml({
331
+ compatibility_date: "something-else",
332
+ }),
333
+ },
334
+ });
214
335
  mockConfirm(
215
336
  {
216
337
  text: "Would you like to use git to manage this Worker?",
@@ -227,25 +348,33 @@ describe("init", () => {
227
348
  {
228
349
  text: "Would you like to use TypeScript?",
229
350
  result: true,
230
- },
231
- {
232
- text: "Would you like to create a Worker at src/index.ts?",
233
- result: true,
234
351
  }
235
352
  );
236
353
 
354
+ mockSelect({
355
+ text: "Would you like to create a Worker at src/index.ts?",
356
+ result: "fetch",
357
+ });
358
+
237
359
  await runWrangler("init");
238
- expect(fs.readFileSync("./wrangler.toml", "utf-8")).toMatchInlineSnapshot(
239
- `"compatibility_date=\\"something-else\\""`
240
- );
360
+
361
+ checkFiles({
362
+ items: {
363
+ "wrangler.toml": wranglerToml({
364
+ compatibility_date: "something-else",
365
+ }),
366
+ },
367
+ });
241
368
  });
242
369
 
243
370
  it("should display warning when wrangler.toml already exists, but continue if user does want to carry on", async () => {
244
- fs.writeFileSync(
245
- "./wrangler.toml",
246
- `compatibility_date="something-else"`,
247
- "utf-8"
248
- );
371
+ writeFiles({
372
+ items: {
373
+ "wrangler.toml": wranglerToml({
374
+ compatibility_date: "something-else",
375
+ }),
376
+ },
377
+ });
249
378
  mockConfirm(
250
379
  {
251
380
  text: "Do you want to continue initializing this project?",
@@ -260,10 +389,101 @@ describe("init", () => {
260
389
  result: false,
261
390
  }
262
391
  );
392
+
393
+ await runWrangler("init");
394
+
395
+ expect(std.warn).toContain("wrangler.toml already exists!");
396
+ checkFiles({
397
+ items: {
398
+ "wrangler.toml": wranglerToml({
399
+ compatibility_date: "something-else",
400
+ }),
401
+ },
402
+ });
403
+ expect(std).toMatchInlineSnapshot(`
404
+ Object {
405
+ "debug": "",
406
+ "err": "",
407
+ "out": "",
408
+ "warn": "▲ [WARNING] wrangler.toml already exists!
409
+
410
+ ",
411
+ }
412
+ `);
413
+ });
414
+
415
+ it("should not add a Cron Trigger to wrangler.toml when creating a Scheduled Worker if wrangler.toml already exists", async () => {
416
+ writeFiles({
417
+ items: {
418
+ "wrangler.toml": wranglerToml({
419
+ compatibility_date: "something-else",
420
+ }),
421
+ },
422
+ });
423
+ mockConfirm(
424
+ {
425
+ text: "Would you like to use git to manage this Worker?",
426
+ result: true,
427
+ },
428
+ {
429
+ text: "Do you want to continue initializing this project?",
430
+ result: true,
431
+ },
432
+ {
433
+ text: "No package.json found. Would you like to create one?",
434
+ result: true,
435
+ },
436
+ {
437
+ text: "Would you like to use TypeScript?",
438
+ result: true,
439
+ }
440
+ );
441
+ mockSelect({
442
+ text: "Would you like to create a Worker at src/index.ts?",
443
+ result: "scheduled",
444
+ });
445
+
446
+ await runWrangler("init");
447
+
448
+ checkFiles({
449
+ items: {
450
+ "wrangler.toml": wranglerToml({
451
+ compatibility_date: "something-else",
452
+ }),
453
+ },
454
+ });
455
+ });
456
+
457
+ it("should add a Cron Trigger to wrangler.toml when creating a Scheduled Worker, but only if wrangler.toml is being created during init", async () => {
458
+ mockConfirm(
459
+ {
460
+ text: "Would you like to use git to manage this Worker?",
461
+ result: true,
462
+ },
463
+ {
464
+ text: "No package.json found. Would you like to create one?",
465
+ result: true,
466
+ },
467
+ {
468
+ text: "Would you like to use TypeScript?",
469
+ result: true,
470
+ }
471
+ );
472
+ mockSelect({
473
+ text: "Would you like to create a Worker at src/index.ts?",
474
+ result: "scheduled",
475
+ });
476
+
263
477
  await runWrangler("init");
264
- expect(std.warn).toContain("wrangler.toml file already exists!");
265
- const parsed = TOML.parse(await fsp.readFile("./wrangler.toml", "utf-8"));
266
- expect(parsed.compatibility_date).toBe("something-else");
478
+
479
+ checkFiles({
480
+ items: {
481
+ "wrangler.toml": wranglerToml({
482
+ ...MINIMAL_WRANGLER_TOML,
483
+ triggers: { crons: ["1 * * * *"] },
484
+ }),
485
+ },
486
+ });
267
487
  });
268
488
  });
269
489
 
@@ -279,48 +499,124 @@ describe("init", () => {
279
499
  result: false,
280
500
  }
281
501
  );
502
+
282
503
  await runWrangler("init");
504
+
505
+ checkFiles({
506
+ items: {
507
+ "wrangler.toml": wranglerToml({
508
+ compatibility_date: expect.any(String),
509
+ name: expect.stringContaining("wrangler-tests"),
510
+ }),
511
+ ".git": { items: {} },
512
+ ".gitignore": true,
513
+ },
514
+ });
283
515
  expect(std).toMatchInlineSnapshot(`
284
516
  Object {
285
517
  "debug": "",
286
518
  "err": "",
287
- "out": "✨ Successfully created wrangler.toml
519
+ "out": "✨ Created wrangler.toml
288
520
  ✨ Initialized git repository",
289
521
  "warn": "",
290
522
  }
291
523
  `);
292
- expect(fs.lstatSync(".git").isDirectory()).toBe(true);
293
- expect(fs.lstatSync(".gitignore").isFile()).toBe(true);
524
+ expect((await execa("git", ["branch", "--show-current"])).stdout).toEqual(
525
+ "main"
526
+ );
294
527
  });
295
528
 
296
529
  it("should not offer to initialize a git repo if it's already inside one", async () => {
297
530
  await execa("git", ["init"]);
298
- fs.mkdirSync("some-folder");
299
- process.chdir("some-folder");
531
+ setWorkingDirectory("some-folder");
532
+
300
533
  await runWrangler("init -y");
301
534
 
535
+ checkFiles({
536
+ items: {
537
+ "wrangler.toml": wranglerToml({
538
+ ...MINIMAL_WRANGLER_TOML,
539
+ name: "some-folder",
540
+ }),
541
+ ".git": { items: {} },
542
+ ".gitignore": false,
543
+ },
544
+ });
545
+
302
546
  // Note the lack of "✨ Initialized git repository" in the log
303
547
  expect(std).toMatchInlineSnapshot(`
304
548
  Object {
305
549
  "debug": "",
306
550
  "err": "",
307
- "out": "✨ Successfully created wrangler.toml
308
- ✨ Initialized git repository
551
+ "out": "✨ Created wrangler.toml
309
552
  ✨ Created package.json
310
- ✨ Created tsconfig.json, installed @cloudflare/workers-types into devDependencies
553
+ ✨ Created tsconfig.json
311
554
  ✨ Created src/index.ts
555
+ ✨ Installed @cloudflare/workers-types and typescript into devDependencies
312
556
 
313
557
  To start developing your Worker, run \`npm start\`
314
- To publish your Worker to the Internet, run \`npm run publish\`",
558
+ To publish your Worker to the Internet, run \`npm run deploy\`",
559
+ "warn": "",
560
+ }
561
+ `);
562
+ });
563
+
564
+ it("should not offer to initialize a git repo if it's already inside one (when using a path as name)", async () => {
565
+ fs.mkdirSync("path/to/worker", { recursive: true });
566
+ await execa("git", ["init"], { cwd: "path/to/worker" });
567
+ expect(fs.lstatSync("path/to/worker/.git").isDirectory()).toBe(true);
568
+
569
+ await runWrangler("init path/to/worker/my-worker -y");
570
+
571
+ // Note the lack of "✨ Initialized git repository" in the log
572
+ expect(std).toMatchInlineSnapshot(`
573
+ Object {
574
+ "debug": "",
575
+ "err": "",
576
+ "out": "✨ Created path/to/worker/my-worker/wrangler.toml
577
+ ✨ Created path/to/worker/my-worker/package.json
578
+ ✨ Created path/to/worker/my-worker/tsconfig.json
579
+ ✨ Created path/to/worker/my-worker/src/index.ts
580
+ ✨ Installed @cloudflare/workers-types and typescript into devDependencies
581
+
582
+ To start developing your Worker, run \`cd path/to/worker/my-worker && npm start\`
583
+ To publish your Worker to the Internet, run \`npm run deploy\`",
315
584
  "warn": "",
316
585
  }
317
586
  `);
318
587
  });
319
588
 
589
+ // I... don't know how to test this lol
320
590
  it.todo(
321
591
  "should not offer to initialize a git repo if git is not installed"
322
592
  );
323
- // I... don't know how to test this lol
593
+
594
+ it("should initialize git repo with `main` default branch", async () => {
595
+ mockConfirm(
596
+ {
597
+ text: "Would you like to use git to manage this Worker?",
598
+ result: true,
599
+ },
600
+ {
601
+ text: "No package.json found. Would you like to create one?",
602
+ result: false,
603
+ }
604
+ );
605
+ await runWrangler("init");
606
+ expect(std).toMatchInlineSnapshot(`
607
+ Object {
608
+ "debug": "",
609
+ "err": "",
610
+ "out": "✨ Created wrangler.toml
611
+ ✨ Initialized git repository",
612
+ "warn": "",
613
+ }
614
+ `);
615
+
616
+ expect(execaSync("git", ["symbolic-ref", "HEAD"]).stdout).toEqual(
617
+ "refs/heads/main"
618
+ );
619
+ });
324
620
  });
325
621
 
326
622
  describe("package.json", () => {
@@ -337,24 +633,39 @@ describe("init", () => {
337
633
  {
338
634
  text: "Would you like to use TypeScript?",
339
635
  result: false,
340
- },
341
- {
342
- text: "Would you like to create a Worker at src/index.js?",
343
- result: false,
344
636
  }
345
637
  );
638
+ mockSelect({
639
+ text: "Would you like to create a Worker at src/index.js?",
640
+ result: "none",
641
+ });
642
+
346
643
  await runWrangler("init");
347
- expect(fs.existsSync("./package.json")).toBe(true);
348
- const packageJson = JSON.parse(
349
- fs.readFileSync("./package.json", "utf-8")
350
- );
351
- expect(packageJson.name).toContain("wrangler-tests");
352
- expect(packageJson.version).toEqual("0.0.0");
353
- expect(packageJson.devDependencies).toEqual({
354
- wrangler: expect.any(String),
644
+
645
+ checkFiles({
646
+ items: {
647
+ "package.json": {
648
+ contents: expect.objectContaining({
649
+ name: expect.stringContaining("wrangler-tests"),
650
+ version: "0.0.0",
651
+ devDependencies: {
652
+ wrangler: expect.any(String),
653
+ },
654
+ }),
655
+ },
656
+ "tsconfig.json": false,
657
+ },
355
658
  });
356
- expect(fs.existsSync("./tsconfig.json")).toBe(false);
357
659
  expect(mockPackageManager.install).toHaveBeenCalled();
660
+ expect(std).toMatchInlineSnapshot(`
661
+ Object {
662
+ "debug": "",
663
+ "err": "",
664
+ "out": "✨ Created wrangler.toml
665
+ ✨ Created package.json",
666
+ "warn": "",
667
+ }
668
+ `);
358
669
  });
359
670
 
360
671
  it("should create a package.json, with the specified name, if none is found and user confirms", async () => {
@@ -370,17 +681,38 @@ describe("init", () => {
370
681
  {
371
682
  text: "Would you like to use TypeScript?",
372
683
  result: false,
373
- },
374
- {
375
- text: "Would you like to create a Worker at src/index.js?",
376
- result: false,
377
684
  }
378
685
  );
686
+ mockSelect({
687
+ text: "Would you like to create a Worker at my-worker/src/index.js?",
688
+ result: "none",
689
+ });
690
+
379
691
  await runWrangler("init my-worker");
380
- const packageJson = JSON.parse(
381
- fs.readFileSync("./my-worker/package.json", "utf-8")
382
- );
383
- expect(packageJson.name).toBe("my-worker");
692
+
693
+ checkFiles({
694
+ items: {
695
+ "my-worker/package.json": {
696
+ contents: expect.objectContaining({
697
+ name: "my-worker",
698
+ version: "0.0.0",
699
+ devDependencies: {
700
+ wrangler: expect.any(String),
701
+ },
702
+ }),
703
+ },
704
+ "my-worker/tsconfig.json": false,
705
+ },
706
+ });
707
+ expect(std).toMatchInlineSnapshot(`
708
+ Object {
709
+ "debug": "",
710
+ "err": "",
711
+ "out": "✨ Created my-worker/wrangler.toml
712
+ ✨ Created my-worker/package.json",
713
+ "warn": "",
714
+ }
715
+ `);
384
716
  });
385
717
 
386
718
  it("should not touch an existing package.json in the same directory", async () => {
@@ -390,110 +722,240 @@ describe("init", () => {
390
722
  result: false,
391
723
  },
392
724
  {
393
- text: "Would you like to install wrangler into your package.json?",
725
+ text: "Would you like to install wrangler into package.json?",
394
726
  result: false,
395
727
  },
396
728
  {
397
729
  text: "Would you like to use TypeScript?",
398
730
  result: false,
399
- },
400
- {
401
- text: "Would you like to create a Worker at src/index.js?",
402
- result: false,
403
731
  }
404
732
  );
405
-
406
- fs.writeFileSync(
407
- "./package.json",
408
- JSON.stringify({ name: "test", version: "1.0.0" }),
409
- "utf-8"
410
- );
733
+ mockSelect({
734
+ text: "Would you like to create a Worker at src/index.js?",
735
+ result: "none",
736
+ });
737
+ writeFiles({
738
+ items: {
739
+ "package.json": { contents: { name: "test", version: "1.0.0" } },
740
+ },
741
+ });
411
742
 
412
743
  await runWrangler("init");
413
- const packageJson = JSON.parse(
414
- fs.readFileSync("./package.json", "utf-8")
415
- );
416
- expect(packageJson.name).toEqual("test");
417
- expect(packageJson.version).toEqual("1.0.0");
744
+
745
+ checkFiles({
746
+ items: {
747
+ "package.json": { contents: { name: "test", version: "1.0.0" } },
748
+ },
749
+ });
750
+ expect(std).toMatchInlineSnapshot(`
751
+ Object {
752
+ "debug": "",
753
+ "err": "",
754
+ "out": "✨ Created wrangler.toml",
755
+ "warn": "",
756
+ }
757
+ `);
418
758
  });
419
759
 
420
- it("should offer to install wrangler into an existing package.json", async () => {
760
+ it("should not touch an existing package.json in an ancestor directory, when a name is passed", async () => {
421
761
  mockConfirm(
422
762
  {
423
763
  text: "Would you like to use git to manage this Worker?",
424
764
  result: false,
425
765
  },
426
766
  {
427
- text: "Would you like to install wrangler into your package.json?",
767
+ text: "No package.json found. Would you like to create one?",
428
768
  result: true,
429
769
  },
430
770
  {
431
- text: "Would you like to use TypeScript?",
771
+ text: "Would you like to install wrangler into path/to/worker/my-worker/package.json?",
432
772
  result: false,
433
773
  },
434
774
  {
435
- text: "Would you like to create a Worker at src/index.js?",
775
+ text: "Would you like to use TypeScript?",
436
776
  result: false,
437
777
  }
438
778
  );
779
+ mockSelect({
780
+ text: "Would you like to create a Worker at path/to/worker/my-worker/src/index.js?",
781
+ result: "none",
782
+ });
783
+ writeFiles({
784
+ items: {
785
+ "path/to/worker/package.json": {
786
+ contents: { name: "test", version: "1.0.0" },
787
+ },
788
+ },
789
+ });
439
790
 
440
- fs.writeFileSync(
441
- "./package.json",
442
- JSON.stringify({ name: "test", version: "1.0.0" }),
443
- "utf-8"
444
- );
791
+ await runWrangler("init path/to/worker/my-worker");
445
792
 
446
- await runWrangler("init");
447
- const packageJson = JSON.parse(
448
- fs.readFileSync("./package.json", "utf-8")
449
- );
450
- expect(packageJson.name).toEqual("test");
451
- expect(packageJson.version).toEqual("1.0.0");
452
- expect(mockPackageManager.addDevDeps).toHaveBeenCalledWith(
453
- `wrangler@${wranglerVersion}`
454
- );
793
+ checkFiles({
794
+ items: {
795
+ "path/to/worker/package.json": {
796
+ contents: { name: "test", version: "1.0.0" },
797
+ },
798
+ },
799
+ });
800
+ expect(std).toMatchInlineSnapshot(`
801
+ Object {
802
+ "debug": "",
803
+ "err": "",
804
+ "out": "✨ Created path/to/worker/my-worker/wrangler.toml
805
+ ✨ Created path/to/worker/my-worker/package.json",
806
+ "warn": "",
807
+ }
808
+ `);
455
809
  });
456
810
 
457
- it("should not touch an existing package.json in an ancestor directory", async () => {
811
+ it("should offer to install wrangler into an existing package.json", async () => {
458
812
  mockConfirm(
459
813
  {
460
814
  text: "Would you like to use git to manage this Worker?",
461
815
  result: false,
462
816
  },
463
817
  {
464
- text: "Would you like to install wrangler into your package.json?",
465
- result: false,
818
+ text: "Would you like to install wrangler into package.json?",
819
+ result: true,
466
820
  },
467
821
  {
468
822
  text: "Would you like to use TypeScript?",
469
823
  result: false,
824
+ }
825
+ );
826
+ mockSelect({
827
+ text: "Would you like to create a Worker at src/index.js?",
828
+ result: "none",
829
+ });
830
+ writeFiles({
831
+ items: {
832
+ "package.json": {
833
+ contents: { name: "test", version: "1.0.0" },
834
+ },
835
+ },
836
+ });
837
+
838
+ await runWrangler("init");
839
+
840
+ checkFiles({
841
+ items: {
842
+ "package.json": {
843
+ contents: { name: "test", version: "1.0.0" },
844
+ },
845
+ },
846
+ });
847
+ expect(mockPackageManager.addDevDeps).toHaveBeenCalledWith(
848
+ `wrangler@${wranglerVersion}`
849
+ );
850
+ expect(std).toMatchInlineSnapshot(`
851
+ Object {
852
+ "debug": "",
853
+ "err": "",
854
+ "out": "✨ Created wrangler.toml
855
+ ✨ Installed wrangler into devDependencies",
856
+ "warn": "",
857
+ }
858
+ `);
859
+ });
860
+
861
+ it("should offer to install wrangler into a package.json relative to the target directory, if no name is provided", async () => {
862
+ mockConfirm(
863
+ {
864
+ text: "Would you like to use git to manage this Worker?",
865
+ result: false,
470
866
  },
471
867
  {
472
- text: "Would you like to create a Worker at src/index.js?",
868
+ text: "Would you like to install wrangler into ../package.json?",
869
+ result: true,
870
+ },
871
+ {
872
+ text: "Would you like to use TypeScript?",
473
873
  result: false,
474
874
  }
475
875
  );
876
+ mockSelect({
877
+ text: "Would you like to create a Worker at src/index.js?",
878
+ result: "none",
879
+ });
880
+ writeFiles({
881
+ items: {
882
+ "path/to/worker/package.json": {
883
+ contents: { name: "test", version: "1.0.0" },
884
+ },
885
+ },
886
+ });
887
+ setWorkingDirectory("path/to/worker/my-worker");
476
888
 
477
- fs.writeFileSync(
478
- "./package.json",
479
- JSON.stringify({ name: "test", version: "1.0.0" }),
480
- "utf-8"
889
+ await runWrangler("init");
890
+
891
+ setWorkingDirectory("../../../..");
892
+ checkFiles({
893
+ items: {
894
+ "path/to/worker/package.json": {
895
+ contents: { name: "test", version: "1.0.0" },
896
+ },
897
+ "path/to/worker/my-worker/package.json": false,
898
+ },
899
+ });
900
+ expect(mockPackageManager.addDevDeps).toHaveBeenCalledWith(
901
+ `wrangler@${wranglerVersion}`
481
902
  );
903
+ expect(mockPackageManager.cwd).toBe(process.cwd());
904
+ expect(std).toMatchInlineSnapshot(`
905
+ Object {
906
+ "debug": "",
907
+ "err": "",
908
+ "out": "✨ Created wrangler.toml
909
+ ✨ Installed wrangler into devDependencies",
910
+ "warn": "",
911
+ }
912
+ `);
913
+ });
482
914
 
483
- fs.mkdirSync("./sub-1/sub-2", { recursive: true });
484
- process.chdir("./sub-1/sub-2");
915
+ it("should not touch an existing package.json in an ancestor directory", async () => {
916
+ mockConfirm(
917
+ {
918
+ text: "Would you like to use git to manage this Worker?",
919
+ result: false,
920
+ },
921
+ {
922
+ text: "Would you like to install wrangler into ../../package.json?",
923
+ result: false,
924
+ },
925
+ {
926
+ text: "Would you like to use TypeScript?",
927
+ result: false,
928
+ }
929
+ );
930
+ mockSelect({
931
+ text: "Would you like to create a Worker at src/index.js?",
932
+ result: "none",
933
+ });
934
+ writeFiles({
935
+ items: {
936
+ "package.json": {
937
+ contents: { name: "test", version: "1.0.0" },
938
+ },
939
+ },
940
+ });
941
+ setWorkingDirectory("./sub-1/sub-2");
485
942
 
486
943
  await runWrangler("init");
487
- expect(fs.existsSync("./package.json")).toBe(false);
488
- expect(fs.existsSync("../../package.json")).toBe(true);
489
944
 
490
- const packageJson = JSON.parse(
491
- fs.readFileSync("../../package.json", "utf-8")
492
- );
493
- expect(packageJson).toMatchInlineSnapshot(`
945
+ checkFiles({
946
+ items: {
947
+ "package.json": false,
948
+ "../../package.json": {
949
+ contents: { name: "test", version: "1.0.0" },
950
+ },
951
+ },
952
+ });
953
+ expect(std).toMatchInlineSnapshot(`
494
954
  Object {
495
- "name": "test",
496
- "version": "1.0.0",
955
+ "debug": "",
956
+ "err": "",
957
+ "out": "✨ Created wrangler.toml",
958
+ "warn": "",
497
959
  }
498
960
  `);
499
961
  });
@@ -507,28 +969,50 @@ describe("init", () => {
507
969
  result: false,
508
970
  },
509
971
  {
510
- text: "Would you like to install wrangler into your package.json?",
972
+ text: "Would you like to install wrangler into package.json?",
511
973
  result: false,
512
974
  },
513
975
  {
514
976
  text: "Would you like to use TypeScript?",
515
977
  result: false,
516
- },
517
- {
518
- text: "Would you like to create a Worker at src/index.js?",
519
- result: true,
520
978
  }
521
979
  );
522
-
523
- fs.writeFileSync(
524
- "./package.json",
525
- JSON.stringify({ name: "test", version: "1.0.0" }),
526
- "utf-8"
527
- );
980
+ mockSelect({
981
+ text: "Would you like to create a Worker at src/index.js?",
982
+ result: "fetch",
983
+ });
984
+ writeFiles({
985
+ items: {
986
+ "package.json": {
987
+ contents: { name: "test", version: "1.0.0" },
988
+ },
989
+ },
990
+ });
528
991
 
529
992
  await runWrangler("init");
530
- expect(fs.existsSync("./src/index.js")).toBe(true);
531
- expect(fs.existsSync("./src/index.ts")).toBe(false);
993
+
994
+ checkFiles({
995
+ items: {
996
+ "wrangler.toml": wranglerToml({
997
+ ...MINIMAL_WRANGLER_TOML,
998
+ main: "src/index.js",
999
+ }),
1000
+ "src/index.js": true,
1001
+ "src/index.ts": false,
1002
+ },
1003
+ });
1004
+ expect(std).toMatchInlineSnapshot(`
1005
+ Object {
1006
+ "debug": "",
1007
+ "err": "",
1008
+ "out": "✨ Created wrangler.toml
1009
+ ✨ Created src/index.js
1010
+
1011
+ To start developing your Worker, run \`npx wrangler dev\`
1012
+ To publish your Worker to the Internet, run \`npx wrangler publish\`",
1013
+ "warn": "",
1014
+ }
1015
+ `);
532
1016
  });
533
1017
 
534
1018
  it("should offer to create a worker in a typescript project", async () => {
@@ -538,28 +1022,48 @@ describe("init", () => {
538
1022
  result: false,
539
1023
  },
540
1024
  {
541
- text: "Would you like to install wrangler into your package.json?",
1025
+ text: "Would you like to install wrangler into package.json?",
542
1026
  result: false,
543
1027
  },
544
1028
  {
545
1029
  text: "Would you like to use TypeScript?",
546
1030
  result: true,
547
- },
548
- {
549
- text: "Would you like to create a Worker at src/index.ts?",
550
- result: true,
551
1031
  }
552
1032
  );
553
-
554
- fs.writeFileSync(
555
- "./package.json",
556
- JSON.stringify({ name: "test", version: "1.0.0" }),
557
- "utf-8"
558
- );
1033
+ mockSelect({
1034
+ text: "Would you like to create a Worker at src/index.ts?",
1035
+ result: "fetch",
1036
+ });
1037
+ writeFiles({
1038
+ items: {
1039
+ "package.json": {
1040
+ contents: { name: "test", version: "1.0.0" },
1041
+ },
1042
+ },
1043
+ });
559
1044
 
560
1045
  await runWrangler("init");
561
- expect(fs.existsSync("./src/index.js")).toBe(false);
562
- expect(fs.existsSync("./src/index.ts")).toBe(true);
1046
+
1047
+ checkFiles({
1048
+ items: {
1049
+ "src/index.js": false,
1050
+ "src/index.ts": true,
1051
+ },
1052
+ });
1053
+ expect(std).toMatchInlineSnapshot(`
1054
+ Object {
1055
+ "debug": "",
1056
+ "err": "",
1057
+ "out": "✨ Created wrangler.toml
1058
+ ✨ Created tsconfig.json
1059
+ ✨ Created src/index.ts
1060
+ ✨ Installed @cloudflare/workers-types and typescript into devDependencies
1061
+
1062
+ To start developing your Worker, run \`npx wrangler dev\`
1063
+ To publish your Worker to the Internet, run \`npx wrangler publish\`",
1064
+ "warn": "",
1065
+ }
1066
+ `);
563
1067
  });
564
1068
 
565
1069
  it("should add scripts for a typescript project with .ts extension", async () => {
@@ -573,40 +1077,46 @@ describe("init", () => {
573
1077
  result: true,
574
1078
  },
575
1079
  {
576
- text: "Would you like to install wrangler into your package.json?",
1080
+ text: "Would you like to install wrangler into package.json?",
577
1081
  result: false,
578
1082
  },
579
1083
  {
580
1084
  text: "Would you like to use TypeScript?",
581
1085
  result: true,
582
- },
583
- {
584
- text: "Would you like to create a Worker at src/index.ts?",
585
- result: true,
586
1086
  }
587
1087
  );
588
- await runWrangler("init");
589
-
590
- expect(fs.existsSync("./package.json")).toBe(true);
591
- const packageJson = JSON.parse(
592
- fs.readFileSync("./package.json", "utf-8")
593
- );
1088
+ mockSelect({
1089
+ text: "Would you like to create a Worker at src/index.ts?",
1090
+ result: "fetch",
1091
+ });
594
1092
 
595
- expect(fs.existsSync("./src/index.js")).toBe(false);
596
- expect(fs.existsSync("./src/index.ts")).toBe(true);
1093
+ await runWrangler("init");
597
1094
 
598
- expect(packageJson.scripts.start).toBe("wrangler dev");
599
- expect(packageJson.scripts.publish).toBe("wrangler publish");
600
- expect(packageJson.name).toContain("wrangler-tests");
601
- expect(packageJson.version).toEqual("0.0.0");
1095
+ checkFiles({
1096
+ items: {
1097
+ "package.json": {
1098
+ contents: expect.objectContaining({
1099
+ name: expect.stringContaining("wrangler-tests"),
1100
+ version: "0.0.0",
1101
+ scripts: {
1102
+ start: "wrangler dev",
1103
+ deploy: "wrangler publish",
1104
+ },
1105
+ }),
1106
+ },
1107
+ "src/index.js": false,
1108
+ "src/index.ts": true,
1109
+ },
1110
+ });
602
1111
  expect(std.out).toMatchInlineSnapshot(`
603
- "✨ Successfully created wrangler.toml
1112
+ "✨ Created wrangler.toml
604
1113
  ✨ Created package.json
605
- ✨ Created tsconfig.json, installed @cloudflare/workers-types into devDependencies
1114
+ ✨ Created tsconfig.json
606
1115
  ✨ Created src/index.ts
1116
+ ✨ Installed @cloudflare/workers-types and typescript into devDependencies
607
1117
 
608
1118
  To start developing your Worker, run \`npm start\`
609
- To publish your Worker to the Internet, run \`npm run publish\`"
1119
+ To publish your Worker to the Internet, run \`npm run deploy\`"
610
1120
  `);
611
1121
  });
612
1122
 
@@ -617,41 +1127,52 @@ describe("init", () => {
617
1127
  result: false,
618
1128
  },
619
1129
  {
620
- text: "Would you like to install wrangler into your package.json?",
1130
+ text: "Would you like to install wrangler into package.json?",
621
1131
  result: false,
622
1132
  },
623
1133
  {
624
1134
  text: "Would you like to use TypeScript?",
625
1135
  result: true,
626
- },
627
- {
628
- text: "Would you like to create a Worker at src/index.ts?",
629
- result: true,
630
1136
  }
631
1137
  );
632
- await fsp.writeFile(
633
- "./package.json",
634
- JSON.stringify({
635
- scripts: {
636
- start: "test-start",
637
- publish: "test-publish",
1138
+ mockSelect({
1139
+ text: "Would you like to create a Worker at src/index.ts?",
1140
+ result: "fetch",
1141
+ });
1142
+ writeFiles({
1143
+ items: {
1144
+ "package.json": {
1145
+ contents: {
1146
+ scripts: {
1147
+ start: "test-start",
1148
+ deploy: "test-publish",
1149
+ },
1150
+ },
638
1151
  },
639
- })
640
- );
641
- const packageJson = JSON.parse(
642
- fs.readFileSync("./package.json", "utf-8")
643
- );
644
- await runWrangler("init");
1152
+ },
1153
+ });
645
1154
 
646
- expect(fs.existsSync("./src/index.js")).toBe(false);
647
- expect(fs.existsSync("./src/index.ts")).toBe(true);
1155
+ await runWrangler("init");
648
1156
 
649
- expect(packageJson.scripts.start).toBe("test-start");
650
- expect(packageJson.scripts.publish).toBe("test-publish");
1157
+ checkFiles({
1158
+ items: {
1159
+ "package.json": {
1160
+ contents: {
1161
+ scripts: {
1162
+ start: "test-start",
1163
+ deploy: "test-publish",
1164
+ },
1165
+ },
1166
+ },
1167
+ "src/index.js": false,
1168
+ "src/index.ts": true,
1169
+ },
1170
+ });
651
1171
  expect(std.out).toMatchInlineSnapshot(`
652
- "✨ Successfully created wrangler.toml
653
- ✨ Created tsconfig.json, installed @cloudflare/workers-types into devDependencies
1172
+ "✨ Created wrangler.toml
1173
+ ✨ Created tsconfig.json
654
1174
  ✨ Created src/index.ts
1175
+ ✨ Installed @cloudflare/workers-types and typescript into devDependencies
655
1176
 
656
1177
  To start developing your Worker, run \`npx wrangler dev\`
657
1178
  To publish your Worker to the Internet, run \`npx wrangler publish\`"
@@ -665,7 +1186,7 @@ describe("init", () => {
665
1186
  result: false,
666
1187
  },
667
1188
  {
668
- text: "Would you like to install wrangler into your package.json?",
1189
+ text: "Would you like to install wrangler into package.json?",
669
1190
  result: false,
670
1191
  },
671
1192
  {
@@ -673,22 +1194,35 @@ describe("init", () => {
673
1194
  result: true,
674
1195
  }
675
1196
  );
676
-
677
- fs.writeFileSync(
678
- "./package.json",
679
- JSON.stringify({ name: "test", version: "1.0.0" }),
680
- "utf-8"
681
- );
682
- fs.mkdirSync("./src", { recursive: true });
683
1197
  const PLACEHOLDER = "/* placeholder text */";
684
- fs.writeFileSync("./src/index.ts", PLACEHOLDER, "utf-8");
1198
+ writeFiles({
1199
+ items: {
1200
+ "package.json": { contents: { name: "test", version: "1.0.0" } },
1201
+ "src/index.ts": { contents: PLACEHOLDER },
1202
+ },
1203
+ });
685
1204
 
686
1205
  await runWrangler("init");
687
- expect(fs.existsSync("./src/index.js")).toBe(false);
688
- expect(fs.readFileSync("./src/index.ts", "utf-8")).toBe(PLACEHOLDER);
1206
+
1207
+ checkFiles({
1208
+ items: {
1209
+ "src/index.js": false,
1210
+ "src/index.ts": { contents: PLACEHOLDER },
1211
+ },
1212
+ });
1213
+ expect(std).toMatchInlineSnapshot(`
1214
+ Object {
1215
+ "debug": "",
1216
+ "err": "",
1217
+ "out": "✨ Created wrangler.toml
1218
+ ✨ Created tsconfig.json
1219
+ ✨ Installed @cloudflare/workers-types and typescript into devDependencies",
1220
+ "warn": "",
1221
+ }
1222
+ `);
689
1223
  });
690
1224
 
691
- it("should create a tsconfig.json and install `workers-types` if none is found and user confirms", async () => {
1225
+ it("should not offer to create a worker in a ts project for a named worker if a file already exists at the location", async () => {
692
1226
  mockConfirm(
693
1227
  {
694
1228
  text: "Would you like to use git to manage this Worker?",
@@ -698,67 +1232,204 @@ describe("init", () => {
698
1232
  text: "No package.json found. Would you like to create one?",
699
1233
  result: true,
700
1234
  },
1235
+ {
1236
+ text: "Would you like to install wrangler into package.json?",
1237
+ result: false,
1238
+ },
701
1239
  {
702
1240
  text: "Would you like to use TypeScript?",
703
1241
  result: true,
1242
+ }
1243
+ );
1244
+ const PLACEHOLDER = "/* placeholder text */";
1245
+ writeFiles({
1246
+ items: {
1247
+ "package.json": { contents: { name: "test", version: "1.0.0" } },
1248
+ "my-worker/src/index.ts": { contents: PLACEHOLDER },
704
1249
  },
1250
+ });
1251
+
1252
+ await runWrangler("init my-worker");
1253
+
1254
+ checkFiles({
1255
+ items: {
1256
+ "my-worker/src/index.js": false,
1257
+ "my-worker/src/index.ts": { contents: PLACEHOLDER },
1258
+ },
1259
+ });
1260
+ expect(std).toMatchInlineSnapshot(`
1261
+ Object {
1262
+ "debug": "",
1263
+ "err": "",
1264
+ "out": "✨ Created my-worker/wrangler.toml
1265
+ ✨ Created my-worker/package.json
1266
+ ✨ Created my-worker/tsconfig.json
1267
+ ✨ Installed @cloudflare/workers-types and typescript into devDependencies",
1268
+ "warn": "",
1269
+ }
1270
+ `);
1271
+ });
1272
+
1273
+ it("should create a tsconfig.json and install `workers-types` if none is found and user confirms", async () => {
1274
+ mockConfirm(
705
1275
  {
706
- text: "Would you like to create a Worker at src/index.ts?",
1276
+ text: "Would you like to use git to manage this Worker?",
707
1277
  result: false,
1278
+ },
1279
+ {
1280
+ text: "No package.json found. Would you like to create one?",
1281
+ result: true,
1282
+ },
1283
+ {
1284
+ text: "Would you like to use TypeScript?",
1285
+ result: true,
708
1286
  }
709
1287
  );
1288
+ mockSelect({
1289
+ text: "Would you like to create a Worker at src/index.ts?",
1290
+ result: "none",
1291
+ });
1292
+
710
1293
  await runWrangler("init");
711
- expect(fs.existsSync("./tsconfig.json")).toBe(true);
712
- const { config: tsconfigJson, error: tsConfigParseError } =
713
- parseConfigFileTextToJson(
714
- "./tsconfig.json",
715
- fs.readFileSync("./tsconfig.json", "utf-8")
716
- );
717
- expect(tsConfigParseError).toBeUndefined();
718
- expect(tsconfigJson.compilerOptions.types).toEqual([
719
- "@cloudflare/workers-types",
720
- ]);
1294
+
1295
+ checkFiles({
1296
+ items: {
1297
+ "tsconfig.json": {
1298
+ contents: {
1299
+ config: {
1300
+ compilerOptions: expect.objectContaining({
1301
+ types: ["@cloudflare/workers-types"],
1302
+ }),
1303
+ },
1304
+ error: undefined,
1305
+ },
1306
+ },
1307
+ },
1308
+ });
721
1309
  expect(mockPackageManager.addDevDeps).toHaveBeenCalledWith(
722
1310
  "@cloudflare/workers-types",
723
1311
  "typescript"
724
1312
  );
1313
+ expect(std).toMatchInlineSnapshot(`
1314
+ Object {
1315
+ "debug": "",
1316
+ "err": "",
1317
+ "out": "✨ Created wrangler.toml
1318
+ ✨ Created package.json
1319
+ ✨ Created tsconfig.json
1320
+ ✨ Installed @cloudflare/workers-types and typescript into devDependencies",
1321
+ "warn": "",
1322
+ }
1323
+ `);
725
1324
  });
726
1325
 
727
1326
  it("should not touch an existing tsconfig.json in the same directory", async () => {
728
- fs.writeFileSync(
729
- "./package.json",
730
- JSON.stringify({
731
- name: "test",
732
- version: "1.0.0",
733
- devDependencies: {
734
- wrangler: "0.0.0",
735
- "@cloudflare/workers-types": "0.0.0",
1327
+ mockConfirm({
1328
+ text: "Would you like to use git to manage this Worker?",
1329
+ result: false,
1330
+ });
1331
+ mockSelect({
1332
+ text: "Would you like to create a Worker at src/index.ts?",
1333
+ result: "fetch",
1334
+ });
1335
+ writeFiles({
1336
+ items: {
1337
+ "package.json": {
1338
+ contents: {
1339
+ name: "test",
1340
+ version: "1.0.0",
1341
+ devDependencies: {
1342
+ wrangler: "0.0.0",
1343
+ "@cloudflare/workers-types": "0.0.0",
1344
+ },
1345
+ },
736
1346
  },
737
- }),
738
- "utf-8"
739
- );
740
- fs.writeFileSync(
741
- "./tsconfig.json",
742
- JSON.stringify({ compilerOptions: {} }),
743
- "utf-8"
744
- );
1347
+ "tsconfig.json": { contents: { compilerOptions: {} } },
1348
+ },
1349
+ });
745
1350
 
1351
+ await runWrangler("init");
1352
+
1353
+ checkFiles({
1354
+ items: {
1355
+ "tsconfig.json": {
1356
+ contents: { config: { compilerOptions: {} }, error: undefined },
1357
+ },
1358
+ },
1359
+ });
1360
+ expect(std).toMatchInlineSnapshot(`
1361
+ Object {
1362
+ "debug": "",
1363
+ "err": "",
1364
+ "out": "✨ Created wrangler.toml
1365
+ ✨ Created src/index.ts
1366
+
1367
+ To start developing your Worker, run \`npx wrangler dev\`
1368
+ To publish your Worker to the Internet, run \`npx wrangler publish\`",
1369
+ "warn": "",
1370
+ }
1371
+ `);
1372
+ });
1373
+
1374
+ it("should not touch an existing tsconfig.json in the ancestor of a target directory, if a name is passed", async () => {
746
1375
  mockConfirm(
747
1376
  {
748
1377
  text: "Would you like to use git to manage this Worker?",
749
1378
  result: false,
750
1379
  },
751
1380
  {
752
- text: "Would you like to create a Worker at src/index.ts?",
1381
+ text: "No package.json found. Would you like to create one?",
1382
+ result: true,
1383
+ },
1384
+ {
1385
+ text: "Would you like to use TypeScript?",
753
1386
  result: true,
754
1387
  }
755
1388
  );
1389
+ mockSelect({
1390
+ text: "Would you like to create a Worker at path/to/worker/my-worker/src/index.ts?",
1391
+ result: "fetch",
1392
+ });
1393
+ writeFiles({
1394
+ items: {
1395
+ "path/to/worker/package.json": {
1396
+ contents: {
1397
+ name: "test",
1398
+ version: "1.0.0",
1399
+ devDependencies: {
1400
+ wrangler: "0.0.0",
1401
+ "@cloudflare/workers-types": "0.0.0",
1402
+ },
1403
+ },
1404
+ },
1405
+ "path/to/worker/tsconfig.json": { contents: { compilerOptions: {} } },
1406
+ },
1407
+ });
756
1408
 
757
- await runWrangler("init");
758
- const tsconfigJson = JSON.parse(
759
- fs.readFileSync("./tsconfig.json", "utf-8")
760
- );
761
- expect(tsconfigJson.compilerOptions).toEqual({});
1409
+ await runWrangler("init path/to/worker/my-worker");
1410
+
1411
+ checkFiles({
1412
+ items: {
1413
+ "path/to/worker/tsconfig.json": {
1414
+ contents: { config: { compilerOptions: {}, error: undefined } },
1415
+ },
1416
+ },
1417
+ });
1418
+ expect(std).toMatchInlineSnapshot(`
1419
+ Object {
1420
+ "debug": "",
1421
+ "err": "",
1422
+ "out": "✨ Created path/to/worker/my-worker/wrangler.toml
1423
+ ✨ Created path/to/worker/my-worker/package.json
1424
+ ✨ Created path/to/worker/my-worker/tsconfig.json
1425
+ ✨ Created path/to/worker/my-worker/src/index.ts
1426
+ ✨ Installed @cloudflare/workers-types and typescript into devDependencies
1427
+
1428
+ To start developing your Worker, run \`cd path/to/worker/my-worker && npm start\`
1429
+ To publish your Worker to the Internet, run \`npm run deploy\`",
1430
+ "warn": "",
1431
+ }
1432
+ `);
762
1433
  });
763
1434
 
764
1435
  it("should offer to install type definitions in an existing typescript project", async () => {
@@ -768,90 +1439,94 @@ describe("init", () => {
768
1439
  result: false,
769
1440
  },
770
1441
  {
771
- text: "Would you like to install wrangler into your package.json?",
1442
+ text: "Would you like to install wrangler into package.json?",
772
1443
  result: false,
773
1444
  },
774
1445
  {
775
1446
  text: "Would you like to install the type definitions for Workers into your package.json?",
776
1447
  result: true,
777
- },
778
- {
779
- text: "Would you like to create a Worker at src/index.ts?",
780
- result: false,
781
1448
  }
782
1449
  );
783
- fs.writeFileSync(
784
- "./package.json",
785
- JSON.stringify({
786
- name: "test",
787
- version: "1.0.0",
788
- }),
789
- "utf-8"
790
- );
791
- fs.writeFileSync(
792
- "./tsconfig.json",
793
- JSON.stringify({ compilerOptions: {} }),
794
- "utf-8"
795
- );
1450
+ mockSelect({
1451
+ text: "Would you like to create a Worker at src/index.ts?",
1452
+ result: "none",
1453
+ });
1454
+ writeFiles({
1455
+ items: {
1456
+ "./package.json": {
1457
+ contents: {
1458
+ name: "test",
1459
+ version: "1.0.0",
1460
+ },
1461
+ },
1462
+ "./tsconfig.json": { contents: { compilerOptions: {} } },
1463
+ },
1464
+ });
796
1465
 
797
1466
  await runWrangler("init");
798
- const tsconfigJson = JSON.parse(
799
- fs.readFileSync("./tsconfig.json", "utf-8")
800
- );
801
- // unchanged tsconfig
802
- expect(tsconfigJson.compilerOptions).toEqual({});
1467
+
1468
+ checkFiles({
1469
+ items: {
1470
+ // unchanged tsconfig
1471
+ "tsconfig.json": { contents: { config: { compilerOptions: {} } } },
1472
+ },
1473
+ });
803
1474
  expect(mockPackageManager.addDevDeps).toHaveBeenCalledWith(
804
1475
  "@cloudflare/workers-types"
805
1476
  );
1477
+ expect(std).toMatchInlineSnapshot(`
1478
+ Object {
1479
+ "debug": "",
1480
+ "err": "",
1481
+ "out": "✨ Created wrangler.toml
1482
+ ✨ Installed @cloudflare/workers-types into devDependencies
1483
+ 🚨 Please add \\"@cloudflare/workers-types\\" to compilerOptions.types in tsconfig.json",
1484
+ "warn": "",
1485
+ }
1486
+ `);
806
1487
  });
807
1488
 
808
1489
  it("should not touch an existing tsconfig.json in an ancestor directory", async () => {
809
- fs.writeFileSync(
810
- "./package.json",
811
- JSON.stringify({
812
- name: "test",
813
- version: "1.0.0",
814
- devDependencies: {
815
- wrangler: "0.0.0",
816
- "@cloudflare/workers-types": "0.0.0",
1490
+ mockConfirm({
1491
+ text: "Would you like to use git to manage this Worker?",
1492
+ result: false,
1493
+ });
1494
+ mockSelect({
1495
+ text: "Would you like to create a Worker at src/index.ts?",
1496
+ result: "fetch",
1497
+ });
1498
+ writeFiles({
1499
+ items: {
1500
+ "package.json": {
1501
+ contents: {
1502
+ name: "test",
1503
+ version: "1.0.0",
1504
+ devDependencies: {
1505
+ wrangler: "0.0.0",
1506
+ "@cloudflare/workers-types": "0.0.0",
1507
+ },
1508
+ },
817
1509
  },
818
- }),
819
- "utf-8"
820
- );
821
- fs.writeFileSync(
822
- "./tsconfig.json",
823
- JSON.stringify({ compilerOptions: {} }),
824
- "utf-8"
825
- );
826
-
827
- mockConfirm(
828
- {
829
- text: "Would you like to use git to manage this Worker?",
830
- result: false,
1510
+ "tsconfig.json": { contents: { compilerOptions: {} } },
831
1511
  },
832
- {
833
- text: "Would you like to create a Worker at src/index.ts?",
834
- result: true,
835
- }
836
- );
837
-
838
- fs.mkdirSync("./sub-1/sub-2", { recursive: true });
839
- process.chdir("./sub-1/sub-2");
1512
+ });
1513
+ setWorkingDirectory("./sub-1/sub-2");
840
1514
 
841
1515
  await runWrangler("init");
842
- expect(fs.existsSync("./tsconfig.json")).toBe(false);
843
- expect(fs.existsSync("../../tsconfig.json")).toBe(true);
844
-
845
- const tsconfigJson = JSON.parse(
846
- fs.readFileSync("../../tsconfig.json", "utf-8")
847
- );
848
- expect(tsconfigJson.compilerOptions).toEqual({});
849
1516
 
1517
+ checkFiles({
1518
+ items: {
1519
+ "tsconfig.json": false,
1520
+ "../../tsconfig.json": {
1521
+ contents: { config: { compilerOptions: {} } },
1522
+ },
1523
+ },
1524
+ });
850
1525
  expect(std).toMatchInlineSnapshot(`
851
1526
  Object {
852
1527
  "debug": "",
853
1528
  "err": "",
854
- "out": "✨ Successfully created wrangler.toml
1529
+ "out": "✨ Created wrangler.toml
855
1530
  ✨ Created src/index.ts
856
1531
 
857
1532
  To start developing your Worker, run \`npx wrangler dev\`
@@ -874,39 +1549,44 @@ describe("init", () => {
874
1549
  result: true,
875
1550
  },
876
1551
  {
877
- text: "Would you like to install wrangler into your package.json?",
1552
+ text: "Would you like to install wrangler into package.json?",
878
1553
  result: false,
879
1554
  },
880
1555
  {
881
1556
  text: "Would you like to use TypeScript?",
882
1557
  result: false,
883
- },
884
- {
885
- text: "Would you like to create a Worker at src/index.js?",
886
- result: true,
887
1558
  }
888
1559
  );
889
- await runWrangler("init");
890
-
891
- expect(fs.existsSync("./package.json")).toBe(true);
892
- const packageJson = JSON.parse(
893
- fs.readFileSync("./package.json", "utf-8")
894
- );
1560
+ mockSelect({
1561
+ text: "Would you like to create a Worker at src/index.js?",
1562
+ result: "fetch",
1563
+ });
895
1564
 
896
- expect(fs.existsSync("./src/index.js")).toBe(true);
897
- expect(fs.existsSync("./src/index.ts")).toBe(false);
1565
+ await runWrangler("init");
898
1566
 
899
- expect(packageJson.scripts.start).toBe("wrangler dev");
900
- expect(packageJson.scripts.publish).toBe("wrangler publish");
901
- expect(packageJson.name).toContain("wrangler-tests");
902
- expect(packageJson.version).toEqual("0.0.0");
1567
+ checkFiles({
1568
+ items: {
1569
+ "src/index.js": true,
1570
+ "src/index.ts": false,
1571
+ "package.json": {
1572
+ contents: expect.objectContaining({
1573
+ name: expect.stringContaining("wrangler-tests"),
1574
+ version: "0.0.0",
1575
+ scripts: {
1576
+ start: "wrangler dev",
1577
+ deploy: "wrangler publish",
1578
+ },
1579
+ }),
1580
+ },
1581
+ },
1582
+ });
903
1583
  expect(std.out).toMatchInlineSnapshot(`
904
- "✨ Successfully created wrangler.toml
1584
+ "✨ Created wrangler.toml
905
1585
  ✨ Created package.json
906
1586
  ✨ Created src/index.js
907
1587
 
908
1588
  To start developing your Worker, run \`npm start\`
909
- To publish your Worker to the Internet, run \`npm run publish\`"
1589
+ To publish your Worker to the Internet, run \`npm run deploy\`"
910
1590
  `);
911
1591
  });
912
1592
 
@@ -917,39 +1597,49 @@ describe("init", () => {
917
1597
  result: false,
918
1598
  },
919
1599
  {
920
- text: "Would you like to install wrangler into your package.json?",
1600
+ text: "Would you like to install wrangler into package.json?",
921
1601
  result: false,
922
1602
  },
923
1603
  {
924
1604
  text: "Would you like to use TypeScript?",
925
1605
  result: false,
926
- },
927
- {
928
- text: "Would you like to create a Worker at src/index.js?",
929
- result: true,
930
1606
  }
931
1607
  );
932
- await fsp.writeFile(
933
- "./package.json",
934
- JSON.stringify({
935
- scripts: {
936
- start: "test-start",
937
- publish: "test-publish",
1608
+ mockSelect({
1609
+ text: "Would you like to create a Worker at src/index.js?",
1610
+ result: "fetch",
1611
+ });
1612
+ writeFiles({
1613
+ items: {
1614
+ "package.json": {
1615
+ contents: {
1616
+ scripts: {
1617
+ start: "test-start",
1618
+ deploy: "test-publish",
1619
+ },
1620
+ },
938
1621
  },
939
- })
940
- );
941
- const packageJson = JSON.parse(
942
- fs.readFileSync("./package.json", "utf-8")
943
- );
944
- await runWrangler("init");
1622
+ },
1623
+ });
945
1624
 
946
- expect(fs.existsSync("./src/index.js")).toBe(true);
947
- expect(fs.existsSync("./src/index.ts")).toBe(false);
1625
+ await runWrangler("init");
948
1626
 
949
- expect(packageJson.scripts.start).toBe("test-start");
950
- expect(packageJson.scripts.publish).toBe("test-publish");
1627
+ checkFiles({
1628
+ items: {
1629
+ "src/index.js": true,
1630
+ "src/index.ts": false,
1631
+ "package.json": {
1632
+ contents: expect.objectContaining({
1633
+ scripts: {
1634
+ start: "test-start",
1635
+ deploy: "test-publish",
1636
+ },
1637
+ }),
1638
+ },
1639
+ },
1640
+ });
951
1641
  expect(std.out).toMatchInlineSnapshot(`
952
- "✨ Successfully created wrangler.toml
1642
+ "✨ Created wrangler.toml
953
1643
  ✨ Created src/index.js
954
1644
 
955
1645
  To start developing your Worker, run \`npx wrangler dev\`
@@ -964,7 +1654,7 @@ describe("init", () => {
964
1654
  result: false,
965
1655
  },
966
1656
  {
967
- text: "Would you like to install wrangler into your package.json?",
1657
+ text: "Would you like to install wrangler into package.json?",
968
1658
  result: false,
969
1659
  },
970
1660
  {
@@ -972,19 +1662,73 @@ describe("init", () => {
972
1662
  result: false,
973
1663
  }
974
1664
  );
1665
+ const PLACEHOLDER = "/* placeholder text */";
1666
+ writeFiles({
1667
+ items: {
1668
+ "package.json": { contents: { name: "test", version: "1.0.0" } },
1669
+ "src/index.js": { contents: PLACEHOLDER },
1670
+ },
1671
+ });
1672
+
1673
+ await runWrangler("init");
1674
+
1675
+ checkFiles({
1676
+ items: {
1677
+ "src/index.js": { contents: PLACEHOLDER },
1678
+ "src/index.ts": false,
1679
+ },
1680
+ });
1681
+ expect(std).toMatchInlineSnapshot(`
1682
+ Object {
1683
+ "debug": "",
1684
+ "err": "",
1685
+ "out": "✨ Created wrangler.toml",
1686
+ "warn": "",
1687
+ }
1688
+ `);
1689
+ });
975
1690
 
976
- fs.writeFileSync(
977
- "./package.json",
978
- JSON.stringify({ name: "test", version: "1.0.0" }),
979
- "utf-8"
1691
+ it("should not offer to create a worker in a non-ts named worker project if a file already exists at the location", async () => {
1692
+ mockConfirm(
1693
+ {
1694
+ text: "Would you like to use git to manage this Worker?",
1695
+ result: false,
1696
+ },
1697
+ {
1698
+ text: "Would you like to install wrangler into my-worker/package.json?",
1699
+ result: false,
1700
+ },
1701
+ {
1702
+ text: "Would you like to use TypeScript?",
1703
+ result: false,
1704
+ }
980
1705
  );
981
- fs.mkdirSync("./src", { recursive: true });
982
1706
  const PLACEHOLDER = "/* placeholder text */";
983
- fs.writeFileSync("./src/index.js", PLACEHOLDER, "utf-8");
1707
+ writeFiles({
1708
+ items: {
1709
+ "my-worker/package.json": {
1710
+ contents: { name: "test", version: "1.0.0" },
1711
+ },
1712
+ "my-worker/src/index.js": { contents: PLACEHOLDER },
1713
+ },
1714
+ });
984
1715
 
985
- await runWrangler("init");
986
- expect(fs.readFileSync("./src/index.js", "utf-8")).toBe(PLACEHOLDER);
987
- expect(fs.existsSync("./src/index.ts")).toBe(false);
1716
+ await runWrangler("init my-worker");
1717
+
1718
+ checkFiles({
1719
+ items: {
1720
+ "my-worker/src/index.js": { contents: PLACEHOLDER },
1721
+ "my-worker/src/index.ts": false,
1722
+ },
1723
+ });
1724
+ expect(std).toMatchInlineSnapshot(`
1725
+ Object {
1726
+ "debug": "",
1727
+ "err": "",
1728
+ "out": "✨ Created my-worker/wrangler.toml",
1729
+ "warn": "",
1730
+ }
1731
+ `);
988
1732
  });
989
1733
  });
990
1734
 
@@ -992,51 +1736,257 @@ describe("init", () => {
992
1736
  it("should create a worker with a given name", async () => {
993
1737
  await runWrangler("init my-worker -y");
994
1738
 
995
- const parsed = TOML.parse(
996
- await fsp.readFile("./my-worker/wrangler.toml", "utf-8")
997
- );
998
-
999
- expect(typeof parsed.compatibility_date).toBe("string");
1000
- expect(parsed.name).toBe("my-worker");
1739
+ checkFiles({
1740
+ items: {
1741
+ "my-worker/wrangler.toml": wranglerToml({
1742
+ ...MINIMAL_WRANGLER_TOML,
1743
+ name: "my-worker",
1744
+ }),
1745
+ },
1746
+ });
1001
1747
  });
1002
1748
 
1003
1749
  it('should create a worker with the name of the current directory if "name" is .', async () => {
1004
1750
  await runWrangler("init . -y");
1005
1751
 
1006
- const parsed = TOML.parse(await fsp.readFile("wrangler.toml", "utf-8"));
1752
+ const workerName = path.basename(process.cwd()).toLowerCase();
1753
+ checkFiles({
1754
+ items: {
1755
+ "wrangler.toml": wranglerToml({
1756
+ ...MINIMAL_WRANGLER_TOML,
1757
+ name: workerName,
1758
+ }),
1759
+ },
1760
+ });
1761
+ expect(std).toMatchInlineSnapshot(`
1762
+ Object {
1763
+ "debug": "",
1764
+ "err": "",
1765
+ "out": "✨ Created wrangler.toml
1766
+ ✨ Initialized git repository
1767
+ ✨ Created package.json
1768
+ ✨ Created tsconfig.json
1769
+ ✨ Created src/index.ts
1770
+ ✨ Installed @cloudflare/workers-types and typescript into devDependencies
1007
1771
 
1008
- expect(typeof parsed.compatibility_date).toBe("string");
1009
- expect(parsed.name).toBe(path.basename(process.cwd()).toLowerCase());
1010
- expect(fs.existsSync("./my-worker/package.json")).toBe(false);
1011
- expect(fs.existsSync("./my-worker/tsconfig.json")).toBe(false);
1772
+ To start developing your Worker, run \`npm start\`
1773
+ To publish your Worker to the Internet, run \`npm run deploy\`",
1774
+ "warn": "",
1775
+ }
1776
+ `);
1012
1777
  });
1013
1778
 
1014
1779
  it('should create a worker in a nested directory if "name" is path/to/worker', async () => {
1015
1780
  await runWrangler("init path/to/worker -y");
1016
1781
 
1017
- const parsed = TOML.parse(
1018
- await fsp.readFile("path/to/worker/wrangler.toml", "utf-8")
1019
- );
1020
-
1021
- expect(typeof parsed.compatibility_date).toBe("string");
1022
- expect(parsed.name).toBe("worker");
1023
- expect(fs.existsSync("./my-worker/package.json")).toBe(false);
1024
- expect(fs.existsSync("./my-worker/tsconfig.json")).toBe(false);
1782
+ checkFiles({
1783
+ items: {
1784
+ "path/to/worker/wrangler.toml": wranglerToml({
1785
+ ...MINIMAL_WRANGLER_TOML,
1786
+ name: "worker",
1787
+ }),
1788
+ },
1789
+ });
1790
+ expect(std).toMatchInlineSnapshot(`
1791
+ Object {
1792
+ "debug": "",
1793
+ "err": "",
1794
+ "out": "✨ Created path/to/worker/wrangler.toml
1795
+ ✨ Initialized git repository at path/to/worker
1796
+ ✨ Created path/to/worker/package.json
1797
+ ✨ Created path/to/worker/tsconfig.json
1798
+ ✨ Created path/to/worker/src/index.ts
1799
+ ✨ Installed @cloudflare/workers-types and typescript into devDependencies
1800
+
1801
+ To start developing your Worker, run \`cd path/to/worker && npm start\`
1802
+ To publish your Worker to the Internet, run \`npm run deploy\`",
1803
+ "warn": "",
1804
+ }
1805
+ `);
1025
1806
  });
1026
1807
 
1027
1808
  it("should normalize characters that aren't lowercase alphanumeric, underscores, or dashes", async () => {
1028
1809
  await runWrangler("init WEIRD_w0rkr_N4m3.js.tsx.tar.gz -y");
1029
- const parsed = TOML.parse(
1030
- await fsp.readFile(
1031
- "WEIRD_w0rkr_N4m3.js.tsx.tar.gz/wrangler.toml",
1032
- "utf-8"
1033
- )
1810
+
1811
+ checkFiles({
1812
+ items: {
1813
+ "WEIRD_w0rkr_N4m3.js.tsx.tar.gz/wrangler.toml": wranglerToml({
1814
+ ...MINIMAL_WRANGLER_TOML,
1815
+ name: "weird_w0rkr_n4m3-js-tsx-tar-gz",
1816
+ }),
1817
+ },
1818
+ });
1819
+ expect(std).toMatchInlineSnapshot(`
1820
+ Object {
1821
+ "debug": "",
1822
+ "err": "",
1823
+ "out": "✨ Created WEIRD_w0rkr_N4m3.js.tsx.tar.gz/wrangler.toml
1824
+ ✨ Initialized git repository at WEIRD_w0rkr_N4m3.js.tsx.tar.gz
1825
+ ✨ Created WEIRD_w0rkr_N4m3.js.tsx.tar.gz/package.json
1826
+ ✨ Created WEIRD_w0rkr_N4m3.js.tsx.tar.gz/tsconfig.json
1827
+ ✨ Created WEIRD_w0rkr_N4m3.js.tsx.tar.gz/src/index.ts
1828
+ ✨ Installed @cloudflare/workers-types and typescript into devDependencies
1829
+
1830
+ To start developing your Worker, run \`cd WEIRD_w0rkr_N4m3.js.tsx.tar.gz && npm start\`
1831
+ To publish your Worker to the Internet, run \`npm run deploy\`",
1832
+ "warn": "",
1833
+ }
1834
+ `);
1835
+ });
1836
+
1837
+ it("should ignore ancestor files (such as wrangler.toml, package.json and tsconfig.json) if a name/path is given", async () => {
1838
+ mockConfirm(
1839
+ {
1840
+ text: "Would you like to use git to manage this Worker?",
1841
+ result: false,
1842
+ },
1843
+ {
1844
+ text: "Would you like to use TypeScript?",
1845
+ result: true,
1846
+ },
1847
+ {
1848
+ text: "No package.json found. Would you like to create one?",
1849
+ result: true,
1850
+ },
1851
+ {
1852
+ text: "Would you like to install the type definitions for Workers into your package.json?",
1853
+ result: true,
1854
+ }
1034
1855
  );
1856
+ mockSelect({
1857
+ text: "Would you like to create a Worker at sub/folder/worker/src/index.ts?",
1858
+ result: "fetch",
1859
+ });
1860
+ writeFiles({
1861
+ items: {
1862
+ "package.json": { contents: { name: "top-level" } },
1863
+ "tsconfig.json": { contents: { compilerOptions: {} } },
1864
+ "wrangler.toml": wranglerToml({
1865
+ name: "top-level",
1866
+ compatibility_date: "some-date",
1867
+ }),
1868
+ },
1869
+ });
1870
+
1871
+ await runWrangler("init sub/folder/worker");
1035
1872
 
1036
- expect(typeof parsed.compatibility_date).toBe("string");
1037
- expect(parsed.name).toBe("weird_w0rkr_n4m3-js-tsx-tar-gz");
1038
- expect(fs.existsSync("./my-worker/package.json")).toBe(false);
1039
- expect(fs.existsSync("./my-worker/tsconfig.json")).toBe(false);
1873
+ // Ancestor files are untouched.
1874
+ checkFiles({
1875
+ items: {
1876
+ "package.json": { contents: { name: "top-level" } },
1877
+ "tsconfig.json": {
1878
+ contents: { config: { compilerOptions: {} }, error: undefined },
1879
+ },
1880
+ "wrangler.toml": wranglerToml({
1881
+ name: "top-level",
1882
+ compatibility_date: "some-date",
1883
+ }),
1884
+ },
1885
+ });
1886
+ // New initialized Worker has its own files.
1887
+ checkFiles({
1888
+ items: {
1889
+ "sub/folder/worker/package.json": {
1890
+ contents: expect.objectContaining({
1891
+ name: "worker",
1892
+ }),
1893
+ },
1894
+ "sub/folder/worker/tsconfig.json": true,
1895
+ "sub/folder/worker/wrangler.toml": wranglerToml({
1896
+ ...MINIMAL_WRANGLER_TOML,
1897
+ name: "worker",
1898
+ }),
1899
+ },
1900
+ });
1040
1901
  });
1041
1902
  });
1042
1903
  });
1904
+
1905
+ /**
1906
+ * Change the current working directory, ensuring that this exists.
1907
+ */
1908
+ function setWorkingDirectory(directory: string) {
1909
+ fs.mkdirSync(directory, { recursive: true });
1910
+ process.chdir(directory);
1911
+ }
1912
+
1913
+ /**
1914
+ * Write the given folder/files to disk at the given `cwd`.
1915
+ */
1916
+ function writeFiles(folder: TestFolder, cwd = process.cwd()) {
1917
+ for (const name in folder.items) {
1918
+ const item = folder.items[name];
1919
+ const itemPath = path.resolve(cwd, name);
1920
+ if (typeof item !== "boolean") {
1921
+ if ("contents" in item) {
1922
+ fs.mkdirSync(path.dirname(itemPath), { recursive: true });
1923
+ fs.writeFileSync(itemPath, stringify(name, item.contents));
1924
+ } else {
1925
+ fs.mkdirSync(itemPath, { recursive: true });
1926
+ writeFiles(item, itemPath);
1927
+ }
1928
+ } else {
1929
+ throw new Error("Cannot write boolean flags to disk: " + itemPath);
1930
+ }
1931
+ }
1932
+ }
1933
+
1934
+ /**
1935
+ * Check that the given test folders/files match what is in on disk.
1936
+ */
1937
+ function checkFiles(folder: TestFolder, cwd = process.cwd()) {
1938
+ for (const name in folder.items) {
1939
+ const item = folder.items[name];
1940
+ const itemPath = path.resolve(cwd, name);
1941
+ if (typeof item === "boolean") {
1942
+ if (fs.existsSync(itemPath) !== item) {
1943
+ throw new Error(`Expected ${itemPath} ${item ? "" : "not "}to exist.`);
1944
+ }
1945
+ } else if ("contents" in item) {
1946
+ const actualContents = parse(name, fs.readFileSync(itemPath, "utf-8"));
1947
+ expect(actualContents).toEqual(item.contents);
1948
+ } else if ("items" in item) {
1949
+ checkFiles(item, itemPath);
1950
+ } else {
1951
+ throw new Error("Unexpected TestFile object.");
1952
+ }
1953
+ }
1954
+ }
1955
+
1956
+ function stringify(name: string, value: unknown) {
1957
+ if (name.endsWith(".toml")) {
1958
+ return TOML.stringify(value as TOML.JsonMap);
1959
+ }
1960
+ if (name.endsWith(".json")) {
1961
+ return JSON.stringify(value);
1962
+ }
1963
+ return `${value}`;
1964
+ }
1965
+
1966
+ function parse(name: string, value: string): unknown {
1967
+ if (name.endsWith(".toml")) {
1968
+ return TOML.parse(value);
1969
+ }
1970
+ if (name.endsWith("tsconfig.json")) {
1971
+ return parseConfigFileTextToJson(name, value);
1972
+ }
1973
+ if (name.endsWith(".json")) {
1974
+ return JSON.parse(value);
1975
+ }
1976
+ return value;
1977
+ }
1978
+
1979
+ function wranglerToml(options: TOML.JsonMap = {}): TestFile {
1980
+ return {
1981
+ contents: options,
1982
+ };
1983
+ }
1984
+
1985
+ interface TestFile {
1986
+ contents: unknown;
1987
+ }
1988
+ interface TestFolder {
1989
+ items: {
1990
+ [id: string]: TestFile | TestFolder | boolean;
1991
+ };
1992
+ }