wrangler 0.0.0-ece06ea → 0.0.0-ed4f2ef

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 (109) hide show
  1. package/README.md +3 -3
  2. package/bin/wrangler.js +12 -3
  3. package/miniflare-dist/index.mjs +79 -0
  4. package/miniflare-dist/index.mjs.map +7 -0
  5. package/package.json +49 -22
  6. package/pages/functions/buildWorker.ts +62 -0
  7. package/pages/functions/filepath-routing.test.ts +223 -0
  8. package/pages/functions/filepath-routing.ts +181 -0
  9. package/pages/functions/identifiers.ts +78 -0
  10. package/pages/functions/routes.ts +151 -0
  11. package/pages/functions/template-worker.ts +130 -0
  12. package/src/__tests__/configuration.test.ts +2874 -0
  13. package/src/__tests__/dev.test.tsx +588 -0
  14. package/src/__tests__/guess-worker-format.test.ts +83 -0
  15. package/src/__tests__/{clipboardy-mock.js → helpers/clipboardy-mock.js} +0 -0
  16. package/src/__tests__/helpers/cmd-shim.d.ts +11 -0
  17. package/src/__tests__/helpers/faye-websocket.d.ts +6 -0
  18. package/src/__tests__/helpers/mock-account-id.ts +48 -0
  19. package/src/__tests__/helpers/mock-bin.ts +36 -0
  20. package/src/__tests__/helpers/mock-cfetch.ts +207 -0
  21. package/src/__tests__/helpers/mock-console.ts +70 -0
  22. package/src/__tests__/helpers/mock-dialogs.ts +65 -0
  23. package/src/__tests__/helpers/mock-kv.ts +33 -0
  24. package/src/__tests__/helpers/mock-oauth-flow.ts +178 -0
  25. package/src/__tests__/helpers/mock-stdin.ts +103 -0
  26. package/src/__tests__/helpers/mock-web-socket.ts +29 -0
  27. package/src/__tests__/helpers/run-in-tmp.ts +32 -0
  28. package/src/__tests__/helpers/run-wrangler.ts +16 -0
  29. package/src/__tests__/helpers/write-wrangler-toml.ts +17 -0
  30. package/src/__tests__/https-options.test.ts +127 -0
  31. package/src/__tests__/index.test.ts +953 -119
  32. package/src/__tests__/jest.setup.ts +74 -0
  33. package/src/__tests__/kv.test.ts +1380 -0
  34. package/src/__tests__/package-manager.test.ts +206 -0
  35. package/src/__tests__/pages.test.ts +180 -0
  36. package/src/__tests__/parse.test.ts +322 -0
  37. package/src/__tests__/publish.test.ts +3946 -0
  38. package/src/__tests__/r2.test.ts +198 -0
  39. package/src/__tests__/route.test.ts +45 -0
  40. package/src/__tests__/secret.test.ts +425 -0
  41. package/src/__tests__/sentry.test.ts +146 -0
  42. package/src/__tests__/tail.test.ts +638 -0
  43. package/src/__tests__/user.test.ts +83 -0
  44. package/src/__tests__/whoami.test.tsx +95 -0
  45. package/src/bundle.ts +155 -0
  46. package/src/cfetch/index.ts +104 -0
  47. package/src/cfetch/internal.ts +139 -0
  48. package/src/cli.ts +18 -7
  49. package/src/config/README.md +107 -0
  50. package/src/config/config.ts +229 -0
  51. package/src/config/diagnostics.ts +80 -0
  52. package/src/config/environment.ts +371 -0
  53. package/src/config/index.ts +62 -0
  54. package/src/config/validation-helpers.ts +557 -0
  55. package/src/config/validation.ts +1240 -0
  56. package/src/create-worker-preview.ts +173 -0
  57. package/src/create-worker-upload-form.ts +240 -0
  58. package/src/dev/dev.tsx +413 -0
  59. package/src/dev/local.tsx +287 -0
  60. package/src/dev/remote.tsx +209 -0
  61. package/src/dev/use-esbuild.ts +109 -0
  62. package/src/dialogs.tsx +6 -14
  63. package/src/entry.ts +256 -0
  64. package/src/environment-variables.ts +33 -0
  65. package/src/errors.ts +11 -0
  66. package/src/https-options.ts +122 -0
  67. package/src/index.tsx +1503 -959
  68. package/src/inspect.ts +624 -0
  69. package/src/intl-polyfill.d.ts +139 -0
  70. package/src/kv.ts +319 -0
  71. package/src/miniflare-cli/README.md +30 -0
  72. package/src/miniflare-cli/enum-keys.ts +17 -0
  73. package/src/miniflare-cli/index.ts +38 -0
  74. package/src/module-collection.ts +257 -0
  75. package/src/open-in-browser.ts +25 -0
  76. package/src/package-manager.ts +126 -0
  77. package/src/pages.tsx +1074 -212
  78. package/src/parse.ts +183 -0
  79. package/src/paths.ts +26 -0
  80. package/src/proxy.ts +455 -0
  81. package/src/publish.ts +326 -295
  82. package/src/r2.ts +50 -0
  83. package/src/reporting.ts +131 -0
  84. package/src/selfsigned.d.ts +29 -0
  85. package/src/sites.tsx +224 -59
  86. package/src/tail/filters.ts +279 -0
  87. package/src/tail/index.ts +299 -0
  88. package/src/tail/printing.ts +62 -0
  89. package/src/user.tsx +340 -203
  90. package/src/whoami.tsx +69 -0
  91. package/src/worker.ts +172 -0
  92. package/templates/new-worker.js +15 -0
  93. package/templates/new-worker.ts +15 -0
  94. package/{static-asset-facade.js → templates/static-asset-facade.js} +1 -1
  95. package/templates/tsconfig.json +105 -0
  96. package/wrangler-dist/cli.js +136988 -131174
  97. package/wrangler-dist/cli.js.map +3 -3
  98. package/src/__tests__/fixtures/init/.gitkeep +0 -0
  99. package/src/__tests__/mock-cfetch.js +0 -46
  100. package/src/api/form_data.ts +0 -158
  101. package/src/api/inspect.ts +0 -441
  102. package/src/api/preview.ts +0 -123
  103. package/src/api/worker.ts +0 -161
  104. package/src/cfetch.ts +0 -72
  105. package/src/config.ts +0 -124
  106. package/src/dev.tsx +0 -736
  107. package/src/kv.tsx +0 -211
  108. package/src/tail.tsx +0 -71
  109. package/src/util/fetch.ts +0 -74
@@ -1,153 +1,987 @@
1
1
  import * as fs from "node:fs";
2
2
  import * as fsp from "node:fs/promises";
3
- import * as path from "node:path";
4
3
  import * as TOML from "@iarna/toml";
5
- import { main } from "../index";
6
- // @ts-expect-error we're mocking cfetch, so of course setMock isn't a thing
7
- import { setMock, unsetAllMocks } from "../cfetch";
8
-
9
- jest.mock("../cfetch", () => {
10
- return jest.requireActual("./mock-cfetch");
11
- });
12
-
13
- async function w(cmd: void | string, options?: { tap: boolean }) {
14
- const tapped = options?.tap ? tap() : undefined;
15
- await main([...(cmd ? cmd.split(" ") : [])]);
16
- tapped?.off();
17
- return { stdout: tapped?.out, stderr: tapped?.err };
18
- }
19
-
20
- function tap() {
21
- const oldLog = console.log;
22
- const oldError = console.error;
23
-
24
- const toReturn = {
25
- off: () => {
26
- console.log = oldLog;
27
- console.error = oldError;
28
- },
29
- out: "",
30
- err: "",
31
- };
32
-
33
- console.log = (...args) => {
34
- toReturn.out += args.join("");
35
- oldLog.apply(console, args);
36
- // console.trace(...args); // use this if you want to find the true source of your console.log
37
- };
38
- console.error = (...args) => {
39
- toReturn.err += args.join("");
40
- oldError.apply(console, args);
41
- };
42
-
43
- return toReturn;
44
- }
4
+ import { parseConfigFileTextToJson } from "typescript";
5
+ import { version as wranglerVersion } from "../../package.json";
6
+ import { getPackageManager } from "../package-manager";
7
+ import { mockConsoleMethods } from "./helpers/mock-console";
8
+ import { mockConfirm } from "./helpers/mock-dialogs";
9
+ import { runInTempDir } from "./helpers/run-in-tmp";
10
+ import { runWrangler } from "./helpers/run-wrangler";
11
+ import type { PackageManager } from "../package-manager";
45
12
 
46
13
  describe("wrangler", () => {
47
- it("should run", async () => {
48
- const { stdout } = await w(undefined, { tap: true });
49
-
50
- expect(stdout).toMatchInlineSnapshot(`
51
- "wrangler
52
-
53
- Commands:
54
- wrangler init [name] 📥 Create a wrangler.toml configuration file
55
- wrangler dev <filename> 👂 Start a local server for developing your worker
56
- wrangler publish [script] 🆙 Publish your Worker to Cloudflare.
57
- wrangler tail [name] 🦚 Starts a log tailing session for a deployed Worker.
58
- wrangler secret 🤫 Generate a secret that can be referenced in the worker script
59
- wrangler kv:namespace 🗂️ Interact with your Workers KV Namespaces
60
- wrangler kv:key 🔑 Individually manage Workers KV key-value pairs
61
- wrangler kv:bulk 💪 Interact with multiple Workers KV key-value pairs at once
62
- wrangler pages ⚡️ Configure Cloudflare Pages
63
-
64
- Flags:
65
- --config Path to .toml configuration file [string]
66
- --help Show help [boolean]
67
- --version Show version number [boolean]
68
-
69
- Options:
70
- --local Run on my machine [boolean] [default: false]"
71
- `);
14
+ let mockPackageManager: PackageManager;
15
+ runInTempDir();
16
+
17
+ beforeEach(() => {
18
+ mockPackageManager = {
19
+ cwd: process.cwd(),
20
+ // @ts-expect-error we're making a fake package manager here
21
+ type: "mockpm",
22
+ addDevDeps: jest.fn(),
23
+ install: jest.fn(),
24
+ };
25
+ (getPackageManager as jest.Mock).mockResolvedValue(mockPackageManager);
72
26
  });
73
27
 
74
- describe("init", () => {
75
- const ogcwd = process.cwd();
28
+ const std = mockConsoleMethods();
29
+
30
+ describe("no command", () => {
31
+ it("should display a list of available commands", async () => {
32
+ await runWrangler();
33
+
34
+ expect(std.out).toMatchInlineSnapshot(`
35
+ "wrangler
76
36
 
77
- beforeEach(() => {
78
- process.chdir(path.join(__dirname, "fixtures", "init"));
37
+ Commands:
38
+ wrangler init [name] 📥 Create a wrangler.toml configuration file
39
+ wrangler dev [script] 👂 Start a local server for developing your worker
40
+ wrangler publish [script] 🆙 Publish your Worker to Cloudflare.
41
+ wrangler tail [name] 🦚 Starts a log tailing session for a published Worker.
42
+ wrangler secret 🤫 Generate a secret that can be referenced in the worker script
43
+ wrangler kv:namespace 🗂️ Interact with your Workers KV Namespaces
44
+ wrangler kv:key 🔑 Individually manage Workers KV key-value pairs
45
+ wrangler kv:bulk 💪 Interact with multiple Workers KV key-value pairs at once
46
+ wrangler pages ⚡️ Configure Cloudflare Pages
47
+ wrangler r2 📦 Interact with an R2 store
48
+ wrangler login 🔓 Login to Cloudflare
49
+ wrangler logout 🚪 Logout from Cloudflare
50
+ wrangler whoami 🕵️ Retrieve your user info and test your auth config
51
+
52
+ Flags:
53
+ -c, --config Path to .toml configuration file [string]
54
+ -h, --help Show help [boolean]
55
+ -v, --version Show version number [boolean]
56
+ --legacy-env Use legacy environments [boolean]"
57
+ `);
58
+
59
+ expect(std.err).toMatchInlineSnapshot(`""`);
79
60
  });
61
+ });
62
+
63
+ describe("invalid command", () => {
64
+ it("should display an error", async () => {
65
+ await expect(
66
+ runWrangler("invalid-command")
67
+ ).rejects.toThrowErrorMatchingInlineSnapshot(
68
+ `"Unknown argument: invalid-command"`
69
+ );
70
+
71
+ expect(std.out).toMatchInlineSnapshot(`""`);
72
+ expect(std.err).toMatchInlineSnapshot(`
73
+ "wrangler
74
+
75
+ Commands:
76
+ wrangler init [name] 📥 Create a wrangler.toml configuration file
77
+ wrangler dev [script] 👂 Start a local server for developing your worker
78
+ wrangler publish [script] 🆙 Publish your Worker to Cloudflare.
79
+ wrangler tail [name] 🦚 Starts a log tailing session for a published Worker.
80
+ wrangler secret 🤫 Generate a secret that can be referenced in the worker script
81
+ wrangler kv:namespace 🗂️ Interact with your Workers KV Namespaces
82
+ wrangler kv:key 🔑 Individually manage Workers KV key-value pairs
83
+ wrangler kv:bulk 💪 Interact with multiple Workers KV key-value pairs at once
84
+ wrangler pages ⚡️ Configure Cloudflare Pages
85
+ wrangler r2 📦 Interact with an R2 store
86
+ wrangler login 🔓 Login to Cloudflare
87
+ wrangler logout 🚪 Logout from Cloudflare
88
+ wrangler whoami 🕵️ Retrieve your user info and test your auth config
80
89
 
81
- afterEach(async () => {
82
- await fsp.rm("./wrangler.toml");
83
- process.chdir(ogcwd);
90
+ Flags:
91
+ -c, --config Path to .toml configuration file [string]
92
+ -h, --help Show help [boolean]
93
+ -v, --version Show version number [boolean]
94
+ --legacy-env Use legacy environments [boolean]
95
+
96
+ Unknown argument: invalid-command"
97
+ `);
84
98
  });
99
+ });
85
100
 
101
+ describe("init", () => {
86
102
  it("should create a wrangler.toml", async () => {
87
- await w("init");
103
+ mockConfirm({
104
+ text: "No package.json found. Would you like to create one?",
105
+ result: false,
106
+ });
107
+ await runWrangler("init");
88
108
  const parsed = TOML.parse(await fsp.readFile("./wrangler.toml", "utf-8"));
89
109
  expect(typeof parsed.compatibility_date).toBe("string");
110
+ expect(parsed.name).toContain("wrangler-tests");
111
+ expect(fs.existsSync("./package.json")).toBe(false);
112
+ expect(fs.existsSync("./tsconfig.json")).toBe(false);
90
113
  });
91
114
 
92
- it("should error when wrangler.toml already exists", async () => {
93
- fs.closeSync(fs.openSync("./wrangler.toml", "w"));
94
- const { stderr } = await w("init", { tap: true });
95
- expect(stderr.endsWith("wrangler.toml already exists.")).toBe(true);
115
+ it("should create a wrangler.toml and a directory for a named Worker ", async () => {
116
+ mockConfirm({
117
+ text: "No package.json found. Would you like to create one?",
118
+ result: false,
119
+ });
120
+ await runWrangler("init my-worker");
121
+ const parsed = TOML.parse(
122
+ await fsp.readFile("./my-worker/wrangler.toml", "utf-8")
123
+ );
124
+ expect(typeof parsed.compatibility_date).toBe("string");
125
+ expect(parsed.name).toBe("my-worker");
126
+ expect(fs.existsSync("./my-worker/package.json")).toBe(false);
127
+ expect(fs.existsSync("./my-worker/tsconfig.json")).toBe(false);
96
128
  });
97
- });
98
129
 
99
- describe("kv:namespace", () => {
100
- afterAll(() => {
101
- unsetAllMocks();
102
- });
103
- let KVNamespaces: { title: string; id: string }[] = [];
104
- it("can create a namespace", async () => {
105
- setMock("/accounts/:accountId/storage/kv/namespaces", (uri, init) => {
106
- expect(init.method === "POST");
107
- const body = JSON.parse(init.body);
108
- expect(body.title).toBe("worker-UnitTestNamespace");
109
- KVNamespaces.push({ title: body.title, id: "some-namespace-id" });
110
- return { id: "some-namespace-id" };
130
+ it("should display warning when wrangler.toml already exists, and exit if user does not want to carry on", async () => {
131
+ fs.writeFileSync(
132
+ "./wrangler.toml",
133
+ 'compatibility_date="something-else"', // use a fake value to make sure the file is not overwritten
134
+ "utf-8"
135
+ );
136
+ mockConfirm({
137
+ text: "Do you want to continue initializing this project?",
138
+ result: false,
111
139
  });
140
+ await runWrangler("init");
141
+ expect(std.warn).toContain("wrangler.toml file already exists!");
142
+ const parsed = TOML.parse(await fsp.readFile("./wrangler.toml", "utf-8"));
143
+ expect(parsed.compatibility_date).toBe("something-else");
144
+ });
145
+
146
+ it("should not overwrite an existing wrangler.toml, after agreeing to other prompts", async () => {
147
+ fs.writeFileSync(
148
+ "./wrangler.toml",
149
+ 'compatibility_date="something-else"', // use a fake value to make sure the file is not overwritten
150
+ "utf-8"
151
+ );
152
+ mockConfirm(
153
+ {
154
+ text: "Do you want to continue initializing this project?",
155
+ result: true,
156
+ },
157
+ {
158
+ text: "No package.json found. Would you like to create one?",
159
+ result: true,
160
+ },
161
+ {
162
+ text: "Would you like to use TypeScript?",
163
+ result: true,
164
+ },
165
+ {
166
+ text: "Would you like to create a Worker at src/index.ts?",
167
+ result: true,
168
+ }
169
+ );
170
+
171
+ await runWrangler("init");
172
+ expect(fs.readFileSync("./wrangler.toml", "utf-8")).toMatchInlineSnapshot(
173
+ `"compatibility_date=\\"something-else\\""`
174
+ );
175
+ });
176
+
177
+ it("should display warning when wrangler.toml already exists, but continue if user does want to carry on", async () => {
178
+ fs.writeFileSync(
179
+ "./wrangler.toml",
180
+ `compatibility_date="something-else"`,
181
+ "utf-8"
182
+ );
183
+ mockConfirm(
184
+ {
185
+ text: "Do you want to continue initializing this project?",
186
+ result: true,
187
+ },
188
+ {
189
+ text: "No package.json found. Would you like to create one?",
190
+ result: false,
191
+ }
192
+ );
193
+ await runWrangler("init");
194
+ expect(std.warn).toContain("wrangler.toml file already exists!");
195
+ const parsed = TOML.parse(await fsp.readFile("./wrangler.toml", "utf-8"));
196
+ expect(parsed.compatibility_date).toBe("something-else");
197
+ });
198
+
199
+ it("should create a package.json if none is found and user confirms", async () => {
200
+ mockConfirm(
201
+ {
202
+ text: "No package.json found. Would you like to create one?",
203
+ result: true,
204
+ },
205
+ {
206
+ text: "Would you like to use TypeScript?",
207
+ result: false,
208
+ },
209
+ {
210
+ text: "Would you like to create a Worker at src/index.js?",
211
+ result: false,
212
+ }
213
+ );
214
+ await runWrangler("init");
215
+ expect(fs.existsSync("./package.json")).toBe(true);
216
+ const packageJson = JSON.parse(
217
+ fs.readFileSync("./package.json", "utf-8")
218
+ );
219
+ expect(packageJson.name).toContain("wrangler-tests");
220
+ expect(packageJson.version).toEqual("0.0.0");
221
+ expect(packageJson.devDependencies).toEqual({
222
+ wrangler: expect.any(String),
223
+ });
224
+ expect(fs.existsSync("./tsconfig.json")).toBe(false);
225
+ expect(mockPackageManager.install).toHaveBeenCalled();
226
+ });
227
+
228
+ it("should create a package.json, with the specified name, if none is found and user confirms", async () => {
229
+ mockConfirm(
230
+ {
231
+ text: "No package.json found. Would you like to create one?",
232
+ result: true,
233
+ },
234
+ {
235
+ text: "Would you like to use TypeScript?",
236
+ result: false,
237
+ },
238
+ {
239
+ text: "Would you like to create a Worker at src/index.js?",
240
+ result: false,
241
+ }
242
+ );
243
+ await runWrangler("init my-worker");
244
+ const packageJson = JSON.parse(
245
+ fs.readFileSync("./my-worker/package.json", "utf-8")
246
+ );
247
+ expect(packageJson.name).toBe("my-worker");
248
+ });
249
+
250
+ it("should not touch an existing package.json in the same directory", async () => {
251
+ mockConfirm(
252
+ {
253
+ text: "Would you like to install wrangler into your package.json?",
254
+ result: false,
255
+ },
256
+ {
257
+ text: "Would you like to use TypeScript?",
258
+ result: false,
259
+ },
260
+ {
261
+ text: "Would you like to create a Worker at src/index.js?",
262
+ result: false,
263
+ }
264
+ );
265
+
266
+ fs.writeFileSync(
267
+ "./package.json",
268
+ JSON.stringify({ name: "test", version: "1.0.0" }),
269
+ "utf-8"
270
+ );
271
+
272
+ await runWrangler("init");
273
+ const packageJson = JSON.parse(
274
+ fs.readFileSync("./package.json", "utf-8")
275
+ );
276
+ expect(packageJson.name).toEqual("test");
277
+ expect(packageJson.version).toEqual("1.0.0");
278
+ });
279
+
280
+ it("should offer to install wrangler into an existing package.json", async () => {
281
+ mockConfirm(
282
+ {
283
+ text: "Would you like to install wrangler into your package.json?",
284
+ result: true,
285
+ },
286
+ {
287
+ text: "Would you like to use TypeScript?",
288
+ result: false,
289
+ },
290
+ {
291
+ text: "Would you like to create a Worker at src/index.js?",
292
+ result: false,
293
+ }
294
+ );
295
+
296
+ fs.writeFileSync(
297
+ "./package.json",
298
+ JSON.stringify({ name: "test", version: "1.0.0" }),
299
+ "utf-8"
300
+ );
301
+
302
+ await runWrangler("init");
303
+ const packageJson = JSON.parse(
304
+ fs.readFileSync("./package.json", "utf-8")
305
+ );
306
+ expect(packageJson.name).toEqual("test");
307
+ expect(packageJson.version).toEqual("1.0.0");
308
+ expect(mockPackageManager.addDevDeps).toHaveBeenCalledWith(
309
+ `wrangler@${wranglerVersion}`
310
+ );
311
+ });
312
+
313
+ it("should not touch an existing package.json in an ancestor directory", async () => {
314
+ mockConfirm(
315
+ {
316
+ text: "Would you like to install wrangler into your package.json?",
317
+ result: false,
318
+ },
319
+ {
320
+ text: "Would you like to use TypeScript?",
321
+ result: false,
322
+ },
323
+ {
324
+ text: "Would you like to create a Worker at src/index.js?",
325
+ result: false,
326
+ }
327
+ );
328
+
329
+ fs.writeFileSync(
330
+ "./package.json",
331
+ JSON.stringify({ name: "test", version: "1.0.0" }),
332
+ "utf-8"
333
+ );
334
+
335
+ fs.mkdirSync("./sub-1/sub-2", { recursive: true });
336
+ process.chdir("./sub-1/sub-2");
337
+
338
+ await runWrangler("init");
339
+ expect(fs.existsSync("./package.json")).toBe(false);
340
+ expect(fs.existsSync("../../package.json")).toBe(true);
341
+
342
+ const packageJson = JSON.parse(
343
+ fs.readFileSync("../../package.json", "utf-8")
344
+ );
345
+ expect(packageJson).toMatchInlineSnapshot(`
346
+ Object {
347
+ "name": "test",
348
+ "version": "1.0.0",
349
+ }
350
+ `);
351
+ });
352
+
353
+ it("should offer to create a worker in a non-typescript project", async () => {
354
+ mockConfirm(
355
+ {
356
+ text: "Would you like to install wrangler into your package.json?",
357
+ result: false,
358
+ },
359
+ {
360
+ text: "Would you like to use TypeScript?",
361
+ result: false,
362
+ },
363
+ {
364
+ text: "Would you like to create a Worker at src/index.js?",
365
+ result: true,
366
+ }
367
+ );
368
+
369
+ fs.writeFileSync(
370
+ "./package.json",
371
+ JSON.stringify({ name: "test", version: "1.0.0" }),
372
+ "utf-8"
373
+ );
374
+
375
+ await runWrangler("init");
376
+ expect(fs.existsSync("./src/index.js")).toBe(true);
377
+ expect(fs.existsSync("./src/index.ts")).toBe(false);
378
+ });
379
+
380
+ it("should offer to create a worker in a typescript project", async () => {
381
+ mockConfirm(
382
+ {
383
+ text: "Would you like to install wrangler into your package.json?",
384
+ result: false,
385
+ },
386
+ {
387
+ text: "Would you like to use TypeScript?",
388
+ result: true,
389
+ },
390
+ {
391
+ text: "Would you like to create a Worker at src/index.ts?",
392
+ result: true,
393
+ }
394
+ );
395
+
396
+ fs.writeFileSync(
397
+ "./package.json",
398
+ JSON.stringify({ name: "test", version: "1.0.0" }),
399
+ "utf-8"
400
+ );
401
+
402
+ await runWrangler("init");
403
+ expect(fs.existsSync("./src/index.js")).toBe(false);
404
+ expect(fs.existsSync("./src/index.ts")).toBe(true);
405
+ });
406
+
407
+ it("should add scripts for a typescript project with .ts extension", async () => {
408
+ mockConfirm(
409
+ {
410
+ text: "No package.json found. Would you like to create one?",
411
+ result: true,
412
+ },
413
+ {
414
+ text: "Would you like to install wrangler into your package.json?",
415
+ result: false,
416
+ },
417
+ {
418
+ text: "Would you like to use TypeScript?",
419
+ result: true,
420
+ },
421
+ {
422
+ text: "Would you like to create a Worker at src/index.ts?",
423
+ result: true,
424
+ }
425
+ );
426
+ await runWrangler("init");
427
+
428
+ expect(fs.existsSync("./package.json")).toBe(true);
429
+ const packageJson = JSON.parse(
430
+ fs.readFileSync("./package.json", "utf-8")
431
+ );
432
+
433
+ expect(fs.existsSync("./src/index.js")).toBe(false);
434
+ expect(fs.existsSync("./src/index.ts")).toBe(true);
435
+
436
+ expect(packageJson.scripts.start).toBe("wrangler dev");
437
+ expect(packageJson.scripts.publish).toBe("wrangler publish");
438
+ expect(packageJson.name).toContain("wrangler-tests");
439
+ expect(packageJson.version).toEqual("0.0.0");
440
+ expect(std.out).toMatchInlineSnapshot(`
441
+ "✨ Successfully created wrangler.toml
442
+ ✨ Created package.json
443
+ ✨ Created tsconfig.json, installed @cloudflare/workers-types into devDependencies
444
+ ✨ Created src/index.ts
445
+
446
+ To start developing your Worker, run \`npm start\`
447
+ To publish your Worker to the Internet, run \`npm run publish\`"
448
+ `);
449
+ });
450
+
451
+ it("should not overwrite package.json scripts for a typescript project", async () => {
452
+ mockConfirm(
453
+ {
454
+ text: "Would you like to install wrangler into your package.json?",
455
+ result: false,
456
+ },
457
+ {
458
+ text: "Would you like to use TypeScript?",
459
+ result: true,
460
+ },
461
+ {
462
+ text: "Would you like to create a Worker at src/index.ts?",
463
+ result: true,
464
+ }
465
+ );
466
+ await fsp.writeFile(
467
+ "./package.json",
468
+ JSON.stringify({
469
+ scripts: {
470
+ start: "test-start",
471
+ publish: "test-publish",
472
+ },
473
+ })
474
+ );
475
+ const packageJson = JSON.parse(
476
+ fs.readFileSync("./package.json", "utf-8")
477
+ );
478
+ await runWrangler("init");
112
479
 
113
- await w("kv:namespace create UnitTestNamespace");
114
- expect(
115
- KVNamespaces.find((ns) => ns.title === `worker-UnitTestNamespace`)
116
- ).toBeTruthy();
480
+ expect(fs.existsSync("./src/index.js")).toBe(false);
481
+ expect(fs.existsSync("./src/index.ts")).toBe(true);
482
+
483
+ expect(packageJson.scripts.start).toBe("test-start");
484
+ expect(packageJson.scripts.publish).toBe("test-publish");
485
+ expect(std.out).toMatchInlineSnapshot(`
486
+ "✨ Successfully created wrangler.toml
487
+ ✨ Created tsconfig.json, installed @cloudflare/workers-types into devDependencies
488
+ ✨ Created src/index.ts
489
+
490
+ To start developing your Worker, run \`npx wrangler dev\`
491
+ To publish your Worker to the Internet, run \`npx wrangler publish\`"
492
+ `);
117
493
  });
118
494
 
119
- let createdNamespace: { id: string; title: string };
120
- it("can list namespaces", async () => {
121
- setMock(
122
- "/accounts/:accountId/storage/kv/namespaces\\?:qs",
123
- (uri, init) => {
124
- expect(init).toBe(undefined);
125
- return KVNamespaces;
495
+ it("should add missing scripts for a non-ts project with .js extension", async () => {
496
+ mockConfirm(
497
+ {
498
+ text: "No package.json found. Would you like to create one?",
499
+ result: true,
500
+ },
501
+ {
502
+ text: "Would you like to install wrangler into your package.json?",
503
+ result: false,
504
+ },
505
+ {
506
+ text: "Would you like to use TypeScript?",
507
+ result: false,
508
+ },
509
+ {
510
+ text: "Would you like to create a Worker at src/index.js?",
511
+ result: true,
126
512
  }
127
513
  );
128
- const { stdout } = await w("kv:namespace list", { tap: true });
129
- const namespaces = JSON.parse(stdout);
130
- createdNamespace = namespaces.find(
131
- (ns) => ns.title === "worker-UnitTestNamespace"
514
+ await runWrangler("init");
515
+
516
+ expect(fs.existsSync("./package.json")).toBe(true);
517
+ const packageJson = JSON.parse(
518
+ fs.readFileSync("./package.json", "utf-8")
132
519
  );
133
- expect(createdNamespace.title).toBe("worker-UnitTestNamespace");
520
+
521
+ expect(fs.existsSync("./src/index.js")).toBe(true);
522
+ expect(fs.existsSync("./src/index.ts")).toBe(false);
523
+
524
+ expect(packageJson.scripts.start).toBe("wrangler dev");
525
+ expect(packageJson.scripts.publish).toBe("wrangler publish");
526
+ expect(packageJson.name).toContain("wrangler-tests");
527
+ expect(packageJson.version).toEqual("0.0.0");
528
+ expect(std.out).toMatchInlineSnapshot(`
529
+ "✨ Successfully created wrangler.toml
530
+ ✨ Created package.json
531
+ ✨ Created src/index.js
532
+
533
+ To start developing your Worker, run \`npm start\`
534
+ To publish your Worker to the Internet, run \`npm run publish\`"
535
+ `);
134
536
  });
135
537
 
136
- it("can delete a namespace", async () => {
137
- const namespaceIdToDelete = createdNamespace.id;
138
- setMock(
139
- "/accounts/:accountId/storage/kv/namespaces/:namespaceId",
140
- (uri, init) => {
141
- expect(init.method).toBe("DELETE");
142
- KVNamespaces = KVNamespaces.filter(
143
- (ns) => ns.id !== namespaceIdToDelete
144
- );
538
+ it("should not overwrite package.json scripts for a non-ts project with .js extension", async () => {
539
+ mockConfirm(
540
+ {
541
+ text: "Would you like to install wrangler into your package.json?",
542
+ result: false,
543
+ },
544
+ {
545
+ text: "Would you like to use TypeScript?",
546
+ result: false,
547
+ },
548
+ {
549
+ text: "Would you like to create a Worker at src/index.js?",
550
+ result: true,
145
551
  }
146
552
  );
147
- await w(`kv:namespace delete --namespace-id ${namespaceIdToDelete}`);
148
- expect(KVNamespaces.find((ns) => ns.id === namespaceIdToDelete)).toBe(
149
- undefined
553
+ await fsp.writeFile(
554
+ "./package.json",
555
+ JSON.stringify({
556
+ scripts: {
557
+ start: "test-start",
558
+ publish: "test-publish",
559
+ },
560
+ })
561
+ );
562
+ const packageJson = JSON.parse(
563
+ fs.readFileSync("./package.json", "utf-8")
564
+ );
565
+ await runWrangler("init");
566
+
567
+ expect(fs.existsSync("./src/index.js")).toBe(true);
568
+ expect(fs.existsSync("./src/index.ts")).toBe(false);
569
+
570
+ expect(packageJson.scripts.start).toBe("test-start");
571
+ expect(packageJson.scripts.publish).toBe("test-publish");
572
+ expect(std.out).toMatchInlineSnapshot(`
573
+ "✨ Successfully created wrangler.toml
574
+ ✨ Created src/index.js
575
+
576
+ To start developing your Worker, run \`npx wrangler dev\`
577
+ To publish your Worker to the Internet, run \`npx wrangler publish\`"
578
+ `);
579
+ });
580
+
581
+ it("should not offer to create a worker in a non-ts project if a file already exists at the location", async () => {
582
+ mockConfirm(
583
+ {
584
+ text: "Would you like to install wrangler into your package.json?",
585
+ result: false,
586
+ },
587
+ {
588
+ text: "Would you like to use TypeScript?",
589
+ result: false,
590
+ }
150
591
  );
592
+
593
+ fs.writeFileSync(
594
+ "./package.json",
595
+ JSON.stringify({ name: "test", version: "1.0.0" }),
596
+ "utf-8"
597
+ );
598
+ fs.mkdirSync("./src", { recursive: true });
599
+ const PLACEHOLDER = "/* placeholder text */";
600
+ fs.writeFileSync("./src/index.js", PLACEHOLDER, "utf-8");
601
+
602
+ await runWrangler("init");
603
+ expect(fs.readFileSync("./src/index.js", "utf-8")).toBe(PLACEHOLDER);
604
+ expect(fs.existsSync("./src/index.ts")).toBe(false);
605
+ });
606
+
607
+ it("should not offer to create a worker in a ts project if a file already exists at the location", async () => {
608
+ mockConfirm(
609
+ {
610
+ text: "Would you like to install wrangler into your package.json?",
611
+ result: false,
612
+ },
613
+ {
614
+ text: "Would you like to use TypeScript?",
615
+ result: true,
616
+ }
617
+ );
618
+
619
+ fs.writeFileSync(
620
+ "./package.json",
621
+ JSON.stringify({ name: "test", version: "1.0.0" }),
622
+ "utf-8"
623
+ );
624
+ fs.mkdirSync("./src", { recursive: true });
625
+ const PLACEHOLDER = "/* placeholder text */";
626
+ fs.writeFileSync("./src/index.ts", PLACEHOLDER, "utf-8");
627
+
628
+ await runWrangler("init");
629
+ expect(fs.existsSync("./src/index.js")).toBe(false);
630
+ expect(fs.readFileSync("./src/index.ts", "utf-8")).toBe(PLACEHOLDER);
631
+ });
632
+
633
+ it("should create a tsconfig.json and install `workers-types` if none is found and user confirms", async () => {
634
+ mockConfirm(
635
+ {
636
+ text: "No package.json found. Would you like to create one?",
637
+ result: true,
638
+ },
639
+ {
640
+ text: "Would you like to use TypeScript?",
641
+ result: true,
642
+ },
643
+ {
644
+ text: "Would you like to create a Worker at src/index.ts?",
645
+ result: false,
646
+ }
647
+ );
648
+ await runWrangler("init");
649
+ expect(fs.existsSync("./tsconfig.json")).toBe(true);
650
+ const { config: tsconfigJson, error: tsConfigParseError } =
651
+ parseConfigFileTextToJson(
652
+ "./tsconfig.json",
653
+ fs.readFileSync("./tsconfig.json", "utf-8")
654
+ );
655
+ expect(tsConfigParseError).toBeUndefined();
656
+ expect(tsconfigJson.compilerOptions.types).toEqual([
657
+ "@cloudflare/workers-types",
658
+ ]);
659
+ expect(mockPackageManager.addDevDeps).toHaveBeenCalledWith(
660
+ "@cloudflare/workers-types",
661
+ "typescript"
662
+ );
663
+ });
664
+
665
+ it("should not touch an existing tsconfig.json in the same directory", async () => {
666
+ fs.writeFileSync(
667
+ "./package.json",
668
+ JSON.stringify({
669
+ name: "test",
670
+ version: "1.0.0",
671
+ devDependencies: {
672
+ wrangler: "0.0.0",
673
+ "@cloudflare/workers-types": "0.0.0",
674
+ },
675
+ }),
676
+ "utf-8"
677
+ );
678
+ fs.writeFileSync(
679
+ "./tsconfig.json",
680
+ JSON.stringify({ compilerOptions: {} }),
681
+ "utf-8"
682
+ );
683
+
684
+ await runWrangler("init");
685
+ const tsconfigJson = JSON.parse(
686
+ fs.readFileSync("./tsconfig.json", "utf-8")
687
+ );
688
+ expect(tsconfigJson.compilerOptions).toEqual({});
689
+ });
690
+
691
+ it("should offer to install type definitions in an existing typescript project", async () => {
692
+ mockConfirm(
693
+ {
694
+ text: "Would you like to install wrangler into your package.json?",
695
+ result: false,
696
+ },
697
+ {
698
+ text: "Would you like to install the type definitions for Workers into your package.json?",
699
+ result: true,
700
+ },
701
+ {
702
+ text: "Would you like to create a Worker at src/index.ts?",
703
+ result: false,
704
+ }
705
+ );
706
+ fs.writeFileSync(
707
+ "./package.json",
708
+ JSON.stringify({
709
+ name: "test",
710
+ version: "1.0.0",
711
+ }),
712
+ "utf-8"
713
+ );
714
+ fs.writeFileSync(
715
+ "./tsconfig.json",
716
+ JSON.stringify({ compilerOptions: {} }),
717
+ "utf-8"
718
+ );
719
+
720
+ await runWrangler("init");
721
+ const tsconfigJson = JSON.parse(
722
+ fs.readFileSync("./tsconfig.json", "utf-8")
723
+ );
724
+ // unchanged tsconfig
725
+ expect(tsconfigJson.compilerOptions).toEqual({});
726
+ expect(mockPackageManager.addDevDeps).toHaveBeenCalledWith(
727
+ "@cloudflare/workers-types"
728
+ );
729
+ });
730
+
731
+ it("should not touch an existing tsconfig.json in an ancestor directory", async () => {
732
+ fs.writeFileSync(
733
+ "./package.json",
734
+ JSON.stringify({
735
+ name: "test",
736
+ version: "1.0.0",
737
+ devDependencies: {
738
+ wrangler: "0.0.0",
739
+ "@cloudflare/workers-types": "0.0.0",
740
+ },
741
+ }),
742
+ "utf-8"
743
+ );
744
+ fs.writeFileSync(
745
+ "./tsconfig.json",
746
+ JSON.stringify({ compilerOptions: {} }),
747
+ "utf-8"
748
+ );
749
+
750
+ fs.mkdirSync("./sub-1/sub-2", { recursive: true });
751
+ process.chdir("./sub-1/sub-2");
752
+
753
+ await runWrangler("init");
754
+ expect(fs.existsSync("./tsconfig.json")).toBe(false);
755
+ expect(fs.existsSync("../../tsconfig.json")).toBe(true);
756
+
757
+ const tsconfigJson = JSON.parse(
758
+ fs.readFileSync("../../tsconfig.json", "utf-8")
759
+ );
760
+ expect(tsconfigJson.compilerOptions).toEqual({});
761
+ });
762
+
763
+ it("should initialize with no interactive prompts if `--yes` is used", async () => {
764
+ await runWrangler("init --yes");
765
+
766
+ expect(fs.existsSync("./src/index.js")).toBe(false);
767
+ expect(fs.existsSync("./src/index.ts")).toBe(true);
768
+ expect(fs.existsSync("./tsconfig.json")).toBe(true);
769
+ expect(fs.existsSync("./package.json")).toBe(true);
770
+ expect(fs.existsSync("./wrangler.toml")).toBe(true);
771
+ expect(std.out).toMatchInlineSnapshot(`
772
+ "✨ Successfully created wrangler.toml
773
+ ✨ Created package.json
774
+ ✨ Created tsconfig.json, installed @cloudflare/workers-types into devDependencies
775
+ ✨ Created src/index.ts
776
+
777
+ To start developing your Worker, run \`npm start\`
778
+ To publish your Worker to the Internet, run \`npm run publish\`"
779
+ `);
780
+ expect(std.err).toMatchInlineSnapshot(`""`);
781
+ expect(std.warn).toMatchInlineSnapshot(`""`);
782
+ });
783
+
784
+ it("should initialize with no interactive prompts if `--yes` is used (named worker)", async () => {
785
+ await runWrangler("init my-worker --yes");
786
+
787
+ expect(fs.existsSync("./my-worker/src/index.js")).toBe(false);
788
+ expect(fs.existsSync("./my-worker/src/index.ts")).toBe(true);
789
+ expect(fs.existsSync("./my-worker/tsconfig.json")).toBe(true);
790
+ expect(fs.existsSync("./my-worker/package.json")).toBe(true);
791
+ expect(fs.existsSync("./my-worker/wrangler.toml")).toBe(true);
792
+ const parsedWranglerToml = TOML.parse(
793
+ fs.readFileSync("./my-worker/wrangler.toml", "utf-8")
794
+ );
795
+ expect(parsedWranglerToml.main).toEqual("src/index.ts");
796
+ expect(std.out).toMatchInlineSnapshot(`
797
+ "✨ Successfully created wrangler.toml
798
+ ✨ Created package.json
799
+ ✨ Created tsconfig.json, installed @cloudflare/workers-types into devDependencies
800
+ ✨ Created src/index.ts
801
+
802
+ To start developing your Worker, run \`cd my-worker && npm start\`
803
+ To publish your Worker to the Internet, run \`npm run publish\`"
804
+ `);
805
+ expect(std.err).toMatchInlineSnapshot(`""`);
806
+ expect(std.warn).toMatchInlineSnapshot(`""`);
807
+ });
808
+
809
+ it("should initialize with no interactive prompts if `-y` is used", async () => {
810
+ await runWrangler("init -y");
811
+
812
+ expect(fs.existsSync("./src/index.js")).toBe(false);
813
+ expect(fs.existsSync("./src/index.ts")).toBe(true);
814
+ expect(fs.existsSync("./tsconfig.json")).toBe(true);
815
+ expect(fs.existsSync("./package.json")).toBe(true);
816
+ expect(fs.existsSync("./wrangler.toml")).toBe(true);
817
+ });
818
+
819
+ it("should error if `--type javascript` is used", async () => {
820
+ await expect(
821
+ runWrangler("init --type javascript")
822
+ ).rejects.toThrowErrorMatchingInlineSnapshot(
823
+ `"The --type option is no longer supported."`
824
+ );
825
+ });
826
+
827
+ it("should error if `--type rust` is used", async () => {
828
+ await expect(
829
+ runWrangler("init --type rust")
830
+ ).rejects.toThrowErrorMatchingInlineSnapshot(
831
+ `"The --type option is no longer supported."`
832
+ );
833
+ });
834
+
835
+ it("should error if `--type webpack` is used", async () => {
836
+ await expect(runWrangler("init --type webpack")).rejects
837
+ .toThrowErrorMatchingInlineSnapshot(`
838
+ "The --type option is no longer supported.
839
+ If you wish to use webpack then you will need to create a custom build."
840
+ `);
841
+ });
842
+ });
843
+
844
+ describe("preview", () => {
845
+ it("should throw an error if the deprecated command is used with positional arguments", async () => {
846
+ await expect(runWrangler("preview GET")).rejects
847
+ .toThrowErrorMatchingInlineSnapshot(`
848
+ "🦺 DEPRECATION:
849
+ The \`wrangler preview\` command has been deprecated.
850
+ Try using \`wrangler dev\` to to try out a worker during development.
851
+ "
852
+ `);
853
+ await expect(runWrangler(`preview GET "SomeBody"`)).rejects
854
+ .toThrowErrorMatchingInlineSnapshot(`
855
+ "🦺 DEPRECATION:
856
+ The \`wrangler preview\` command has been deprecated.
857
+ Try using \`wrangler dev\` to to try out a worker during development.
858
+ "
859
+ `);
860
+ });
861
+ });
862
+
863
+ describe("subcommand implicit help ran on imcomplete command execution", () => {
864
+ function endEventLoop() {
865
+ return new Promise((resolve) => setImmediate(resolve));
866
+ }
867
+ it("no subcommand for 'secret' should display a list of available subcommands", async () => {
868
+ await runWrangler("secret");
869
+ await endEventLoop();
870
+ expect(std.out).toMatchInlineSnapshot(`
871
+ "wrangler secret
872
+
873
+ 🤫 Generate a secret that can be referenced in the worker script
874
+
875
+ Commands:
876
+ wrangler secret put <key> Create or update a secret variable for a script
877
+ wrangler secret delete <key> Delete a secret variable from a script
878
+ wrangler secret list List all secrets for a script
879
+
880
+ Flags:
881
+ -c, --config Path to .toml configuration file [string]
882
+ -h, --help Show help [boolean]
883
+ -v, --version Show version number [boolean]
884
+ --legacy-env Use legacy environments [boolean]"
885
+ `);
886
+ });
887
+
888
+ it("no subcommand 'kv:namespace' should display a list of available subcommands", async () => {
889
+ await runWrangler("kv:namespace");
890
+ await endEventLoop();
891
+ expect(std.out).toMatchInlineSnapshot(`
892
+ "wrangler kv:namespace
893
+
894
+ 🗂️ Interact with your Workers KV Namespaces
895
+
896
+ Commands:
897
+ wrangler kv:namespace create <namespace> Create a new namespace
898
+ wrangler kv:namespace list Outputs a list of all KV namespaces associated with your account id.
899
+ wrangler kv:namespace delete Deletes a given namespace.
900
+
901
+ Flags:
902
+ -c, --config Path to .toml configuration file [string]
903
+ -h, --help Show help [boolean]
904
+ -v, --version Show version number [boolean]
905
+ --legacy-env Use legacy environments [boolean]"
906
+ `);
907
+ });
908
+
909
+ it("no subcommand 'kv:key' should display a list of available subcommands", async () => {
910
+ await runWrangler("kv:key");
911
+ await endEventLoop();
912
+ expect(std.out).toMatchInlineSnapshot(`
913
+ "wrangler kv:key
914
+
915
+ 🔑 Individually manage Workers KV key-value pairs
916
+
917
+ Commands:
918
+ wrangler kv:key put <key> [value] Writes a single key/value pair to the given namespace.
919
+ wrangler kv:key list Outputs a list of all keys in a given namespace.
920
+ wrangler kv:key get <key> Reads a single value by key from the given namespace.
921
+ wrangler kv:key delete <key> Removes a single key value pair from the given namespace.
922
+
923
+ Flags:
924
+ -c, --config Path to .toml configuration file [string]
925
+ -h, --help Show help [boolean]
926
+ -v, --version Show version number [boolean]
927
+ --legacy-env Use legacy environments [boolean]"
928
+ `);
929
+ });
930
+
931
+ it("no subcommand 'kv:bulk' should display a list of available subcommands", async () => {
932
+ await runWrangler("kv:bulk");
933
+ await endEventLoop();
934
+ expect(std.out).toMatchInlineSnapshot(`
935
+ "wrangler kv:bulk
936
+
937
+ 💪 Interact with multiple Workers KV key-value pairs at once
938
+
939
+ Commands:
940
+ wrangler kv:bulk put <filename> Upload multiple key-value pairs to a namespace
941
+ wrangler kv:bulk delete <filename> Delete multiple key-value pairs from a namespace
942
+
943
+ Flags:
944
+ -c, --config Path to .toml configuration file [string]
945
+ -h, --help Show help [boolean]
946
+ -v, --version Show version number [boolean]
947
+ --legacy-env Use legacy environments [boolean]"
948
+ `);
949
+ });
950
+ it("no subcommand 'r2' should display a list of available subcommands", async () => {
951
+ await runWrangler("r2");
952
+ await endEventLoop();
953
+ expect(std.out).toMatchInlineSnapshot(`
954
+ "wrangler r2
955
+
956
+ 📦 Interact with an R2 store
957
+
958
+ Commands:
959
+ wrangler r2 bucket Manage R2 buckets
960
+
961
+ Flags:
962
+ -c, --config Path to .toml configuration file [string]
963
+ -h, --help Show help [boolean]
964
+ -v, --version Show version number [boolean]
965
+ --legacy-env Use legacy environments [boolean]"
966
+ `);
967
+ });
968
+ });
969
+ describe("Deprecated commands", () => {
970
+ it("should print a deprecation message for 'generate'", async () => {
971
+ await runWrangler("generate").catch((err) => {
972
+ expect(err.message).toMatchInlineSnapshot(`
973
+ "🦺 DEPRECATION:
974
+ \`wrangler generate\` has been deprecated, please refer to https://github.com/cloudflare/wrangler2/blob/main/docs/deprecations.md#generate for alternatives"
975
+ `);
976
+ });
977
+ });
978
+ it("should print a deprecation message for 'build'", async () => {
979
+ await runWrangler("build").catch((err) => {
980
+ expect(err.message).toMatchInlineSnapshot(`
981
+ "🦺 DEPRECATION:
982
+ \`wrangler build\` has been deprecated, please refer to https://github.com/cloudflare/wrangler2/blob/main/docs/deprecations.md#build for alternatives"
983
+ `);
984
+ });
151
985
  });
152
986
  });
153
987
  });