wrangler 2.1.11 → 2.1.13

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 (47) hide show
  1. package/miniflare-dist/index.mjs +1 -1
  2. package/package.json +7 -6
  3. package/src/__tests__/d1.test.ts +70 -0
  4. package/src/__tests__/delete.test.ts +116 -0
  5. package/src/__tests__/dev.test.tsx +5 -2
  6. package/src/__tests__/get-host-from-url.test.ts +16 -0
  7. package/src/__tests__/helpers/mock-kv.ts +1 -1
  8. package/src/__tests__/helpers/msw/handlers/script.ts +75 -0
  9. package/src/__tests__/helpers/msw/index.ts +2 -1
  10. package/src/__tests__/index.test.ts +2 -0
  11. package/src/__tests__/kv.test.ts +5 -1
  12. package/src/__tests__/publish.test.ts +81 -52
  13. package/src/__tests__/r2.test.ts +1 -1
  14. package/src/__tests__/secret.test.ts +6 -6
  15. package/src/__tests__/tail.test.ts +39 -14
  16. package/src/__tests__/utils-collectKeyValues.test.ts +47 -0
  17. package/src/api/dev.ts +2 -1
  18. package/src/cfetch/index.ts +40 -1
  19. package/src/cli.ts +1 -1
  20. package/src/d1/index.ts +1 -1
  21. package/src/delete.ts +86 -0
  22. package/src/{generate.ts → deprecated/index.ts} +167 -6
  23. package/src/dev/remote.tsx +12 -1
  24. package/src/dev-registry.tsx +11 -0
  25. package/src/dev.tsx +3 -12
  26. package/src/dialogs.tsx +5 -0
  27. package/src/index.tsx +99 -1887
  28. package/src/{kv.ts → kv/helpers.ts} +3 -3
  29. package/src/kv/index.ts +645 -0
  30. package/src/metrics/send-event.ts +1 -0
  31. package/src/pages/dev.tsx +14 -12
  32. package/src/publish/index.ts +267 -0
  33. package/src/{publish.ts → publish/publish.ts} +90 -55
  34. package/src/{r2.ts → r2/helpers.ts} +2 -2
  35. package/src/r2/index.ts +277 -0
  36. package/src/routes.ts +140 -0
  37. package/src/secret/index.ts +403 -0
  38. package/src/sites.tsx +2 -2
  39. package/src/tail/createTail.ts +315 -0
  40. package/src/tail/index.ts +202 -300
  41. package/src/tail/printing.ts +2 -2
  42. package/src/utils/collectKeyValues.ts +14 -0
  43. package/src/yargs-types.ts +7 -0
  44. package/src/zones.ts +3 -5
  45. package/wrangler-dist/cli.d.ts +1 -0
  46. package/wrangler-dist/cli.js +3030 -2736
  47. package/src/preview.ts +0 -31
@@ -509,7 +509,7 @@ async function generateHandler({
509
509
  (async () => {
510
510
  try {
511
511
  const links = [];
512
- const transformedResponse = new HTMLRewriter().on("link[rel=preconnect],link[rel=preload]", {
512
+ const transformedResponse = new HTMLRewriter().on("link[rel~=preconnect],link[rel~=preload]", {
513
513
  element(element) {
514
514
  for (const [attributeName] of element.attributes) {
515
515
  if (!ALLOWED_EARLY_HINT_LINK_ATTRIBUTES.includes(
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wrangler",
3
- "version": "2.1.11",
3
+ "version": "2.1.13",
4
4
  "description": "Command-line interface for all things Cloudflare Workers",
5
5
  "keywords": [
6
6
  "wrangler",
@@ -54,6 +54,7 @@
54
54
  "Cloudflare_CA.pem"
55
55
  ],
56
56
  "scripts": {
57
+ "assert-git-version": "node -r esbuild-register scripts/assert-git-version.ts",
57
58
  "build": "npm run clean && npm run bundle && npm run emit-types",
58
59
  "bundle": "node -r esbuild-register scripts/bundle.ts",
59
60
  "check:type": "tsc",
@@ -62,7 +63,7 @@
62
63
  "emit-types": "tsc -p tsconfig.emit.json && node -r esbuild-register scripts/emit-types.ts",
63
64
  "prepublishOnly": "SOURCEMAPS=false npm run build",
64
65
  "start": "npm run bundle && cross-env NODE_OPTIONS=--enable-source-maps ./bin/wrangler.js",
65
- "test": "jest --silent=false --verbose=true",
66
+ "test": "npm run assert-git-version && jest --silent=false --verbose=true",
66
67
  "test-watch": "npm run test -- --runInBand --testTimeout=50000 --watch",
67
68
  "test:ci": "npm run test -- --verbose=true --coverage"
68
69
  },
@@ -99,13 +100,13 @@
99
100
  "@cloudflare/kv-asset-handler": "^0.2.0",
100
101
  "@esbuild-plugins/node-globals-polyfill": "^0.1.1",
101
102
  "@esbuild-plugins/node-modules-polyfill": "^0.1.4",
102
- "@miniflare/core": "2.9.0",
103
- "@miniflare/d1": "2.9.0",
104
- "@miniflare/durable-objects": "2.9.0",
103
+ "@miniflare/core": "2.10.0",
104
+ "@miniflare/d1": "2.10.0",
105
+ "@miniflare/durable-objects": "2.10.0",
105
106
  "blake3-wasm": "^2.1.5",
106
107
  "chokidar": "^3.5.3",
107
108
  "esbuild": "0.14.51",
108
- "miniflare": "2.9.0",
109
+ "miniflare": "2.10.0",
109
110
  "nanoid": "^3.3.3",
110
111
  "path-to-regexp": "^6.2.0",
111
112
  "selfsigned": "^2.0.1",
@@ -0,0 +1,70 @@
1
+ import { mockAccountId } from "./helpers/mock-account-id";
2
+ import { mockConsoleMethods } from "./helpers/mock-console";
3
+ import { runWrangler } from "./helpers/run-wrangler";
4
+
5
+ function endEventLoop() {
6
+ return new Promise((resolve) => setImmediate(resolve));
7
+ }
8
+
9
+ describe("d1", () => {
10
+ const std = mockConsoleMethods();
11
+
12
+ mockAccountId();
13
+
14
+ it("should show help when no argument is passed", async () => {
15
+ await runWrangler("d1");
16
+ await endEventLoop();
17
+
18
+ expect(std.out).toMatchInlineSnapshot(`
19
+ "wrangler d1
20
+
21
+ 🗄 Interact with a D1 database
22
+
23
+ Commands:
24
+ wrangler d1 list List D1 databases
25
+ wrangler d1 create <name> Create D1 database
26
+ wrangler d1 delete <name> Delete D1 database
27
+ wrangler d1 backup Interact with D1 Backups
28
+ wrangler d1 execute <name> Executed command or SQL file
29
+
30
+ Flags:
31
+ -c, --config Path to .toml configuration file [string]
32
+ -h, --help Show help [boolean]
33
+ -v, --version Show version number [boolean]
34
+
35
+ 🚧 'wrangler d1 <command>' is a beta command. Please report any issues to https://github.com/cloudflare/wrangler2/issues/new/choose"
36
+ `);
37
+ });
38
+
39
+ it("should show help when an invalid argument is passed", async () => {
40
+ await expect(() => runWrangler("d1 asdf")).rejects.toThrow(
41
+ "Unknown argument: asdf"
42
+ );
43
+
44
+ expect(std.err).toMatchInlineSnapshot(`
45
+ "X [ERROR] Unknown argument: asdf
46
+
47
+ "
48
+ `);
49
+ expect(std.out).toMatchInlineSnapshot(`
50
+ "
51
+ wrangler d1
52
+
53
+ 🗄 Interact with a D1 database
54
+
55
+ Commands:
56
+ wrangler d1 list List D1 databases
57
+ wrangler d1 create <name> Create D1 database
58
+ wrangler d1 delete <name> Delete D1 database
59
+ wrangler d1 backup Interact with D1 Backups
60
+ wrangler d1 execute <name> Executed command or SQL file
61
+
62
+ Flags:
63
+ -c, --config Path to .toml configuration file [string]
64
+ -h, --help Show help [boolean]
65
+ -v, --version Show version number [boolean]
66
+
67
+ 🚧 'wrangler d1 <command>' is a beta command. Please report any issues to https://github.com/cloudflare/wrangler2/issues/new/choose"
68
+ `);
69
+ });
70
+ });
@@ -0,0 +1,116 @@
1
+ import { mockAccountId, mockApiToken } from "./helpers/mock-account-id";
2
+ import { setMockResponse, unsetAllMocks } from "./helpers/mock-cfetch";
3
+ import { mockConsoleMethods } from "./helpers/mock-console";
4
+ import { mockConfirm } from "./helpers/mock-dialogs";
5
+ import { runInTempDir } from "./helpers/run-in-tmp";
6
+ import { runWrangler } from "./helpers/run-wrangler";
7
+ import writeWranglerToml from "./helpers/write-wrangler-toml";
8
+
9
+ describe("delete", () => {
10
+ mockAccountId();
11
+ mockApiToken();
12
+ runInTempDir();
13
+
14
+ afterEach(() => {
15
+ unsetAllMocks();
16
+ });
17
+
18
+ const std = mockConsoleMethods();
19
+
20
+ it("should delete an entire service by name", async () => {
21
+ mockConfirm({
22
+ text: `Are you sure you want to delete my-script? This action cannot be undone.`,
23
+ result: true,
24
+ });
25
+ mockDeleteWorkerRequest({ name: "my-script" });
26
+ await runWrangler("delete --name my-script");
27
+
28
+ expect(std).toMatchInlineSnapshot(`
29
+ Object {
30
+ "debug": "",
31
+ "err": "",
32
+ "out": "Successfully deleted my-script",
33
+ "warn": "",
34
+ }
35
+ `);
36
+ });
37
+
38
+ it("should delete a script by configuration", async () => {
39
+ mockConfirm({
40
+ text: `Are you sure you want to delete test-name? This action cannot be undone.`,
41
+ result: true,
42
+ });
43
+ writeWranglerToml();
44
+ mockDeleteWorkerRequest();
45
+ await runWrangler("delete");
46
+
47
+ expect(std).toMatchInlineSnapshot(`
48
+ Object {
49
+ "debug": "",
50
+ "err": "",
51
+ "out": "Successfully deleted test-name",
52
+ "warn": "",
53
+ }
54
+ `);
55
+ });
56
+
57
+ it("shouldn't delete a service when doing a --dry-run", async () => {
58
+ await runWrangler("delete --name xyz --dry-run");
59
+
60
+ expect(std).toMatchInlineSnapshot(`
61
+ Object {
62
+ "debug": "",
63
+ "err": "",
64
+ "out": "--dry-run: exiting now.",
65
+ "warn": "",
66
+ }
67
+ `);
68
+ });
69
+
70
+ it('shouldn\'t delete when the user says "no"', async () => {
71
+ mockConfirm({
72
+ text: `Are you sure you want to delete xyz? This action cannot be undone.`,
73
+ result: false,
74
+ });
75
+
76
+ await runWrangler("delete --name xyz");
77
+
78
+ expect(std).toMatchInlineSnapshot(`
79
+ Object {
80
+ "debug": "",
81
+ "err": "",
82
+ "out": "",
83
+ "warn": "",
84
+ }
85
+ `);
86
+ });
87
+ });
88
+
89
+ /** Create a mock handler for the request to upload a worker script. */
90
+ function mockDeleteWorkerRequest(
91
+ options: {
92
+ name?: string;
93
+ env?: string;
94
+ legacyEnv?: boolean;
95
+ } = {}
96
+ ) {
97
+ const { env, legacyEnv, name } = options;
98
+ setMockResponse(
99
+ // there's no special handling for environments yet
100
+ "/accounts/:accountId/workers/services/:scriptName",
101
+ "DELETE",
102
+ async ([_url, accountId, scriptName], { method }, queryParams) => {
103
+ expect(accountId).toEqual("some-account-id");
104
+ expect(method).toEqual("DELETE");
105
+ expect(scriptName).toEqual(
106
+ legacyEnv && env
107
+ ? `${name || "test-name"}-${env}`
108
+ : `${name || "test-name"}`
109
+ );
110
+
111
+ expect(queryParams.get("force")).toEqual("true");
112
+
113
+ return null;
114
+ }
115
+ );
116
+ }
@@ -48,7 +48,7 @@ describe("wrangler dev", () => {
48
48
  \`\`\`
49
49
  --compatibility-date=<current-date>
50
50
  \`\`\`
51
- See https://developers.cloudflare.com/workers/platform/compatibility-dates for more information.
51
+ See https://developers.cloudflare.com/workers/platform/compatibility-dates/ for more information.
52
52
 
53
53
  "
54
54
  `);
@@ -301,7 +301,10 @@ describe("wrangler dev", () => {
301
301
  writeWranglerToml({
302
302
  main: "index.js",
303
303
  routes: [
304
- { pattern: "https://some-domain.com/*", zone_name: "some-zone.com" },
304
+ {
305
+ pattern: "https://some-zone.com/*",
306
+ zone_name: "some-zone.com",
307
+ },
305
308
  ],
306
309
  });
307
310
  fs.writeFileSync("index.js", `export default {};`);
@@ -0,0 +1,16 @@
1
+ import { getHostFromUrl } from "../zones";
2
+
3
+ //return the host given a url-like string
4
+ describe("getHostFromUrl", () => {
5
+ it("should return the host from a url", () => {
6
+ expect(getHostFromUrl("https://www.example.com")).toBe("www.example.com");
7
+ });
8
+
9
+ it("should return the host from a url using wildcard *.", () => {
10
+ expect(getHostFromUrl("*.example.com")).toBe("example.com");
11
+ });
12
+
13
+ it("should return the host from a url using wildcard *", () => {
14
+ expect(getHostFromUrl("*example.com")).toBe("example.com");
15
+ });
16
+ });
@@ -1,5 +1,5 @@
1
1
  import { createFetchResult, setMockRawResponse } from "./mock-cfetch";
2
- import type { NamespaceKeyInfo } from "../../kv";
2
+ import type { NamespaceKeyInfo } from "../../kv/helpers";
3
3
 
4
4
  export function mockKeyListRequest(
5
5
  expectedNamespaceId: string,
@@ -0,0 +1,75 @@
1
+ import { rest } from "msw";
2
+ import type { WorkerMetadata } from "../../../../create-worker-upload-form";
3
+
4
+ const bindings: Record<string, WorkerMetadata["bindings"]> = {
5
+ "durable-object": [
6
+ {
7
+ type: "durable_object_namespace",
8
+ name: "TestDO",
9
+ class_name: "TestDO",
10
+ },
11
+ ],
12
+ };
13
+ const scripts: Record<string, string> = {
14
+ websocket: `new WebSocket("ws://dummy")`,
15
+ response: `return new Response("ok")`,
16
+ };
17
+ function getBindings(scriptName: string) {
18
+ return scriptName.split("--").flatMap((part) => bindings[part] ?? []);
19
+ }
20
+ function getScript(scriptName: string) {
21
+ return `export default {fetch(request){
22
+ ${scriptName
23
+ .split("--")
24
+ .map((part) => scripts[part] ?? "")
25
+ .join(";\n")}
26
+ }}`;
27
+ }
28
+ export default [
29
+ rest.get(
30
+ "*/accounts/:accountId/workers/services/:scriptName/environments/:env/content",
31
+ ({ params: { scriptName } }, res, context) => {
32
+ return res(
33
+ context.status(200),
34
+ context.text(getScript(scriptName as string))
35
+ );
36
+ }
37
+ ),
38
+ rest.get(
39
+ "*/accounts/:accountId/workers/scripts/:scriptName",
40
+ ({ params: { scriptName } }, res, context) => {
41
+ return res(
42
+ context.status(200),
43
+ context.text(getScript(scriptName as string))
44
+ );
45
+ }
46
+ ),
47
+ rest.get(
48
+ "*/accounts/:accountId/workers/services/:scriptName/environments/:env/bindings",
49
+ ({ params: { scriptName } }, res, context) => {
50
+ return res(
51
+ context.status(200),
52
+ context.json({
53
+ success: true,
54
+ errors: [],
55
+ messages: [],
56
+ result: getBindings(scriptName as string),
57
+ })
58
+ );
59
+ }
60
+ ),
61
+ rest.get(
62
+ "*/accounts/:accountId/workers/scripts/:scriptName/bindings",
63
+ ({ params: { scriptName } }, res, context) => {
64
+ return res(
65
+ context.status(200),
66
+ context.json({
67
+ success: true,
68
+ errors: [],
69
+ messages: [],
70
+ result: getBindings(scriptName as string),
71
+ })
72
+ );
73
+ }
74
+ ),
75
+ ];
@@ -2,8 +2,8 @@ import { setupServer } from "msw/node";
2
2
  import { mswSuccessNamespacesHandlers } from "./handlers/namespaces";
3
3
  import { mswSuccessOauthHandlers } from "./handlers/oauth";
4
4
  import { mswSuccessR2handlers } from "./handlers/r2";
5
+ import { default as mswScriptHandlers } from "./handlers/script";
5
6
  import { mswSuccessUserHandlers } from "./handlers/user";
6
-
7
7
  export const msw = setupServer();
8
8
 
9
9
  export {
@@ -11,4 +11,5 @@ export {
11
11
  mswSuccessR2handlers,
12
12
  mswSuccessOauthHandlers,
13
13
  mswSuccessNamespacesHandlers,
14
+ mswScriptHandlers,
14
15
  };
@@ -34,6 +34,7 @@ describe("wrangler", () => {
34
34
  wrangler init [name] 📥 Create a wrangler.toml configuration file
35
35
  wrangler dev [script] 👂 Start a local server for developing your worker
36
36
  wrangler publish [script] 🆙 Publish your Worker to Cloudflare.
37
+ wrangler delete [script] 🗑 Delete your Worker from Cloudflare.
37
38
  wrangler tail [worker] 🦚 Starts a log tailing session for a published Worker.
38
39
  wrangler secret 🤫 Generate a secret that can be referenced in a Worker
39
40
  wrangler secret:bulk <json> 🗄️ Bulk upload secrets for a Worker
@@ -75,6 +76,7 @@ describe("wrangler", () => {
75
76
  wrangler init [name] 📥 Create a wrangler.toml configuration file
76
77
  wrangler dev [script] 👂 Start a local server for developing your worker
77
78
  wrangler publish [script] 🆙 Publish your Worker to Cloudflare.
79
+ wrangler delete [script] 🗑 Delete your Worker from Cloudflare.
78
80
  wrangler tail [worker] 🦚 Starts a log tailing session for a published Worker.
79
81
  wrangler secret 🤫 Generate a secret that can be referenced in a Worker
80
82
  wrangler secret:bulk <json> 🗄️ Bulk upload secrets for a Worker
@@ -17,7 +17,11 @@ import { mockGetMemberships } from "./helpers/mock-oauth-flow";
17
17
  import { mockProcess } from "./helpers/mock-process";
18
18
  import { runInTempDir } from "./helpers/run-in-tmp";
19
19
  import { runWrangler } from "./helpers/run-wrangler";
20
- import type { KeyValue, KVNamespaceInfo, NamespaceKeyInfo } from "../kv";
20
+ import type {
21
+ KeyValue,
22
+ KVNamespaceInfo,
23
+ NamespaceKeyInfo,
24
+ } from "../kv/helpers";
21
25
 
22
26
  describe("wrangler", () => {
23
27
  mockAccountId();
@@ -28,8 +28,8 @@ import { writeWorkerSource } from "./helpers/write-worker-source";
28
28
  import writeWranglerToml from "./helpers/write-wrangler-toml";
29
29
  import type { Config } from "../config";
30
30
  import type { WorkerMetadata } from "../create-worker-upload-form";
31
- import type { KVNamespaceInfo } from "../kv";
32
- import type { CustomDomainChangeset, CustomDomain } from "../publish";
31
+ import type { KVNamespaceInfo } from "../kv/helpers";
32
+ import type { CustomDomainChangeset, CustomDomain } from "../publish/publish";
33
33
  import type { CfWorkerInit } from "../worker";
34
34
  import type { FormData, File } from "undici";
35
35
 
@@ -400,17 +400,17 @@ describe("publish", () => {
400
400
  await expect(
401
401
  runWrangler("publish index.js --env some-env --legacy-env true")
402
402
  ).rejects.toThrowErrorMatchingInlineSnapshot(`
403
- "Processing wrangler.toml configuration:
404
- - No environment found in configuration with name \\"some-env\\".
405
- Before using \`--env=some-env\` there should be an equivalent environment section in the configuration.
406
- The available configured environment names are: [\\"other-env\\"]
403
+ "Processing wrangler.toml configuration:
404
+ - No environment found in configuration with name \\"some-env\\".
405
+ Before using \`--env=some-env\` there should be an equivalent environment section in the configuration.
406
+ The available configured environment names are: [\\"other-env\\"]
407
407
 
408
- Consider adding an environment configuration section to the wrangler.toml file:
409
- \`\`\`
410
- [env.some-env]
411
- \`\`\`
412
- "
413
- `);
408
+ Consider adding an environment configuration section to the wrangler.toml file:
409
+ \`\`\`
410
+ [env.some-env]
411
+ \`\`\`
412
+ "
413
+ `);
414
414
  });
415
415
 
416
416
  it("should throw an error w/ helpful message when using --env --name", async () => {
@@ -790,9 +790,9 @@ describe("publish", () => {
790
790
  });
791
791
  await expect(runWrangler("publish ./index --env=staging")).rejects
792
792
  .toThrowErrorMatchingInlineSnapshot(`
793
- "Service environments combined with an API token that doesn't have 'All Zones' permissions is not supported.
794
- Either turn off service environments by setting \`legacy_env = true\`, creating an API token with 'All Zones' permissions, or logging in via OAuth"
795
- `);
793
+ "Service environments combined with an API token that doesn't have 'All Zones' permissions is not supported.
794
+ Either turn off service environments by setting \`legacy_env = true\`, creating an API token with 'All Zones' permissions, or logging in via OAuth"
795
+ `);
796
796
  });
797
797
 
798
798
  describe("custom domains", () => {
@@ -1180,11 +1180,11 @@ Update them to point to this script instead?`,
1180
1180
  });
1181
1181
  await expect(runWrangler("publish")).rejects
1182
1182
  .toThrowErrorMatchingInlineSnapshot(`
1183
- "Processing wrangler.toml configuration:
1184
- - Don't define both the \`main\` and \`build.upload.main\` fields in your configuration.
1185
- They serve the same purpose: to point to the entry-point of your worker.
1186
- Delete the \`build.upload.main\` and \`build.upload.dir\` field from your config."
1187
- `);
1183
+ "Processing wrangler.toml configuration:
1184
+ - Don't define both the \`main\` and \`build.upload.main\` fields in your configuration.
1185
+ They serve the same purpose: to point to the entry-point of your worker.
1186
+ Delete the \`build.upload.main\` and \`build.upload.dir\` field from your config."
1187
+ `);
1188
1188
  });
1189
1189
 
1190
1190
  it("should be able to transpile TypeScript (esm)", async () => {
@@ -1375,9 +1375,9 @@ addEventListener('fetch', event => {});`
1375
1375
 
1376
1376
  await expect(runWrangler("publish ./index.js")).rejects
1377
1377
  .toThrowErrorMatchingInlineSnapshot(`
1378
- "Processing wrangler.toml configuration:
1379
- - \\"site.bucket\\" is a required field."
1380
- `);
1378
+ "Processing wrangler.toml configuration:
1379
+ - \\"site.bucket\\" is a required field."
1380
+ `);
1381
1381
 
1382
1382
  expect(std.out).toMatchInlineSnapshot(`
1383
1383
  "
@@ -1521,11 +1521,11 @@ addEventListener('fetch', event => {});`
1521
1521
 
1522
1522
  await expect(runWrangler("publish")).rejects
1523
1523
  .toThrowErrorMatchingInlineSnapshot(`
1524
- "Processing wrangler.toml configuration:
1525
- - Don't define both the \`main\` and \`site.entry-point\` fields in your configuration.
1526
- They serve the same purpose: to point to the entry-point of your worker.
1527
- Delete the deprecated \`site.entry-point\` field from your config."
1528
- `);
1524
+ "Processing wrangler.toml configuration:
1525
+ - Don't define both the \`main\` and \`site.entry-point\` fields in your configuration.
1526
+ They serve the same purpose: to point to the entry-point of your worker.
1527
+ Delete the deprecated \`site.entry-point\` field from your config."
1528
+ `);
1529
1529
  });
1530
1530
 
1531
1531
  it("should error if there is no entry-point specified", async () => {
@@ -3301,7 +3301,7 @@ addEventListener('fetch', event => {});`
3301
3301
  expect(std.err).toMatchInlineSnapshot(`""`);
3302
3302
  });
3303
3303
 
3304
- it("should error politely when publishing to workers_dev when there is no workers.dev subdomain", async () => {
3304
+ it("should offer to create a new workers.dev subdomain when publishing to workers_dev without one", async () => {
3305
3305
  writeWranglerToml({
3306
3306
  workers_dev: true,
3307
3307
  });
@@ -3309,12 +3309,16 @@ addEventListener('fetch', event => {});`
3309
3309
  mockUploadWorkerRequest();
3310
3310
  mockSubDomainRequest("does-not-exist", false);
3311
3311
 
3312
+ mockConfirm({
3313
+ text: `Would you like to register a workers.dev subdomain now?`,
3314
+ result: false,
3315
+ });
3316
+
3312
3317
  await expect(runWrangler("publish ./index")).rejects
3313
3318
  .toThrowErrorMatchingInlineSnapshot(`
3314
- "Error: You need to register a workers.dev subdomain before publishing to workers.dev
3315
- You can either publish your worker to one or more routes by specifying them in wrangler.toml, or register a workers.dev subdomain here:
3316
- https://dash.cloudflare.com/some-account-id/workers/onboarding"
3317
- `);
3319
+ "You can either publish your worker to one or more routes by specifying them in wrangler.toml, or register a workers.dev subdomain here:
3320
+ https://dash.cloudflare.com/some-account-id/workers/onboarding"
3321
+ `);
3318
3322
  });
3319
3323
 
3320
3324
  it("should not deploy to workers.dev if there are any routes defined", async () => {
@@ -3667,6 +3671,31 @@ addEventListener('fetch', event => {});`
3667
3671
  `console.log(789);`
3668
3672
  );
3669
3673
  });
3674
+
3675
+ it("can be overridden with cli args containing colons", async () => {
3676
+ writeWranglerToml({
3677
+ main: "index.js",
3678
+ define: {
3679
+ abc: "123",
3680
+ },
3681
+ });
3682
+ fs.writeFileSync(
3683
+ "index.js",
3684
+ `
3685
+ console.log(abc);
3686
+ `
3687
+ );
3688
+ mockSubDomainRequest();
3689
+ mockUploadWorkerRequest();
3690
+ await runWrangler(
3691
+ "publish --dry-run --outdir dist --define abc:'https://www.abc.net.au/news/'"
3692
+ );
3693
+
3694
+ expect(fs.readFileSync("dist/index.js", "utf-8")).toContain(
3695
+ // eslint-disable-next-line no-useless-escape
3696
+ `console.log(\"https://www.abc.net.au/news/\");`
3697
+ );
3698
+ });
3670
3699
  });
3671
3700
  describe("custom builds", () => {
3672
3701
  beforeEach(() => {
@@ -3734,9 +3763,9 @@ addEventListener('fetch', event => {});`
3734
3763
 
3735
3764
  await expect(runWrangler("publish index.js")).rejects
3736
3765
  .toThrowErrorMatchingInlineSnapshot(`
3737
- "The expected output file at \\"index.js\\" was not found after running custom build: node -e \\"console.log('custom build');\\".
3738
- The \`main\` property in wrangler.toml should point to the file generated by the custom build."
3739
- `);
3766
+ "The expected output file at \\"index.js\\" was not found after running custom build: node -e \\"console.log('custom build');\\".
3767
+ The \`main\` property in wrangler.toml should point to the file generated by the custom build."
3768
+ `);
3740
3769
  expect(std.out).toMatchInlineSnapshot(`
3741
3770
  "Running custom build: node -e \\"console.log('custom build');\\"
3742
3771
 
@@ -3766,16 +3795,16 @@ addEventListener('fetch', event => {});`
3766
3795
 
3767
3796
  await expect(runWrangler("publish")).rejects
3768
3797
  .toThrowErrorMatchingInlineSnapshot(`
3769
- "The expected output file at \\".\\" was not found after running custom build: node -e \\"console.log('custom build');\\".
3770
- The \`main\` property in wrangler.toml should point to the file generated by the custom build.
3771
- The provided entry-point path, \\".\\", points to a directory, rather than a file.
3772
-
3773
- Did you mean to set the main field to one of:
3774
- \`\`\`
3775
- main = \\"./worker.js\\"
3776
- main = \\"./dist/index.ts\\"
3777
- \`\`\`"
3778
- `);
3798
+ "The expected output file at \\".\\" was not found after running custom build: node -e \\"console.log('custom build');\\".
3799
+ The \`main\` property in wrangler.toml should point to the file generated by the custom build.
3800
+ The provided entry-point path, \\".\\", points to a directory, rather than a file.
3801
+
3802
+ Did you mean to set the main field to one of:
3803
+ \`\`\`
3804
+ main = \\"./worker.js\\"
3805
+ main = \\"./dist/index.ts\\"
3806
+ \`\`\`"
3807
+ `);
3779
3808
  expect(std.out).toMatchInlineSnapshot(`
3780
3809
  "Running custom build: node -e \\"console.log('custom build');\\"
3781
3810
 
@@ -5538,12 +5567,12 @@ addEventListener('fetch', event => {});`
5538
5567
 
5539
5568
  await expect(runWrangler("publish index.js")).rejects
5540
5569
  .toThrowErrorMatchingInlineSnapshot(`
5541
- "You seem to be trying to use Durable Objects in a Worker written as a service-worker.
5542
- You can use Durable Objects defined in other Workers by specifying a \`script_name\` in your wrangler.toml, where \`script_name\` is the name of the Worker that implements that Durable Object. For example:
5543
- { name = EXAMPLE_DO_BINDING, class_name = ExampleDurableObject } ==> { name = EXAMPLE_DO_BINDING, class_name = ExampleDurableObject, script_name = example-do-binding-worker }
5544
- Alternatively, migrate your worker to ES Module syntax to implement a Durable Object in this Worker:
5545
- https://developers.cloudflare.com/workers/learning/migrating-to-module-workers/"
5546
- `);
5570
+ "You seem to be trying to use Durable Objects in a Worker written as a service-worker.
5571
+ You can use Durable Objects defined in other Workers by specifying a \`script_name\` in your wrangler.toml, where \`script_name\` is the name of the Worker that implements that Durable Object. For example:
5572
+ { name = EXAMPLE_DO_BINDING, class_name = ExampleDurableObject } ==> { name = EXAMPLE_DO_BINDING, class_name = ExampleDurableObject, script_name = example-do-binding-worker }
5573
+ Alternatively, migrate your worker to ES Module syntax to implement a Durable Object in this Worker:
5574
+ https://developers.cloudflare.com/workers/learning/migrating-to-module-workers/"
5575
+ `);
5547
5576
  });
5548
5577
  });
5549
5578
 
@@ -5,7 +5,7 @@ import { mockConsoleMethods } from "./helpers/mock-console";
5
5
  import { msw, mswSuccessR2handlers } from "./helpers/msw";
6
6
  import { runInTempDir } from "./helpers/run-in-tmp";
7
7
  import { runWrangler } from "./helpers/run-wrangler";
8
- import type { R2BucketInfo } from "../r2";
8
+ import type { R2BucketInfo } from "../r2/helpers";
9
9
 
10
10
  describe("r2", () => {
11
11
  const std = mockConsoleMethods();