wrangler 2.0.26 → 2.0.29

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 (62) hide show
  1. package/bin/wrangler.js +1 -1
  2. package/miniflare-dist/index.mjs +54 -46
  3. package/package.json +6 -4
  4. package/src/__tests__/api-dev.test.ts +19 -0
  5. package/src/__tests__/configuration.test.ts +33 -29
  6. package/src/__tests__/dev.test.tsx +8 -6
  7. package/src/__tests__/generate.test.ts +2 -4
  8. package/src/__tests__/helpers/hello-world-worker.js +5 -0
  9. package/src/__tests__/helpers/mock-get-zone-from-host.ts +8 -0
  10. package/src/__tests__/helpers/mock-known-routes.ts +7 -0
  11. package/src/__tests__/index.test.ts +30 -30
  12. package/src/__tests__/jest.setup.ts +17 -0
  13. package/src/__tests__/metrics.test.ts +1 -1
  14. package/src/__tests__/pages.test.ts +829 -103
  15. package/src/__tests__/paths.test.ts +17 -0
  16. package/src/__tests__/publish.test.ts +59 -18
  17. package/src/__tests__/r2.test.ts +4 -3
  18. package/src/__tests__/tail.test.ts +34 -0
  19. package/src/__tests__/test-old-node-version.js +3 -3
  20. package/src/__tests__/user.test.ts +11 -0
  21. package/src/__tests__/worker-namespace.test.ts +37 -35
  22. package/src/api/dev.ts +74 -28
  23. package/src/bundle.ts +14 -11
  24. package/src/cfetch/internal.ts +81 -3
  25. package/src/cli.ts +1 -1
  26. package/src/config/environment.ts +1 -1
  27. package/src/config/index.ts +4 -4
  28. package/src/config/validation-helpers.ts +19 -6
  29. package/src/config/validation.ts +11 -5
  30. package/src/config-cache.ts +2 -1
  31. package/src/create-worker-upload-form.ts +29 -26
  32. package/src/dev/local.tsx +317 -169
  33. package/src/dev/remote.tsx +10 -1
  34. package/src/dev/start-server.ts +412 -0
  35. package/src/dev.tsx +341 -157
  36. package/src/{worker-namespace.ts → dispatch-namespace.ts} +18 -18
  37. package/src/entry.ts +2 -1
  38. package/src/generate.ts +1 -1
  39. package/src/index.tsx +54 -8
  40. package/src/init.ts +5 -5
  41. package/src/{metrics/is-ci.ts → is-ci.ts} +0 -0
  42. package/src/metrics/metrics-config.ts +1 -1
  43. package/src/metrics/send-event.ts +6 -5
  44. package/src/miniflare-cli/assets.ts +4 -65
  45. package/src/miniflare-cli/index.ts +36 -32
  46. package/src/pages/constants.ts +3 -0
  47. package/src/pages/dev.tsx +10 -15
  48. package/src/pages/functions/buildPlugin.ts +2 -1
  49. package/src/pages/functions/buildWorker.ts +2 -1
  50. package/src/pages/functions/routes-transformation.test.ts +12 -1
  51. package/src/pages/functions/routes-transformation.ts +7 -1
  52. package/src/pages/publish.tsx +82 -38
  53. package/src/paths.ts +20 -1
  54. package/src/proxy.ts +10 -0
  55. package/src/publish.ts +19 -4
  56. package/src/r2.ts +4 -4
  57. package/src/user/user.tsx +6 -4
  58. package/src/whoami.tsx +5 -5
  59. package/src/worker.ts +10 -9
  60. package/src/zones.ts +91 -0
  61. package/wrangler-dist/cli.d.ts +22 -8
  62. package/wrangler-dist/cli.js +7757 -2315
package/bin/wrangler.js CHANGED
@@ -4,7 +4,7 @@ const path = require("path");
4
4
  const fs = require("fs");
5
5
  const os = require("os");
6
6
 
7
- const MIN_NODE_VERSION = "16.7.0";
7
+ const MIN_NODE_VERSION = "16.13.0";
8
8
  const debug =
9
9
  process.env["WRANGLER_LOG"] === "debug"
10
10
  ? (...args) => console.log(...args)
@@ -4934,9 +4934,57 @@ var FatalError = class extends Error {
4934
4934
  };
4935
4935
 
4936
4936
  // src/miniflare-cli/assets.ts
4937
- var import_mime = __toESM(require_mime());
4938
4937
  import { existsSync, lstatSync, readFileSync as readFileSync4 } from "node:fs";
4939
4938
  import { join } from "node:path";
4939
+
4940
+ // ../pages-shared/src/asset-server/rulesEngine.ts
4941
+ var ESCAPE_REGEX_CHARACTERS = /[-/\\^$*+?.()|[\]{}]/g;
4942
+ var escapeRegex = (str) => {
4943
+ return str.replace(ESCAPE_REGEX_CHARACTERS, "\\$&");
4944
+ };
4945
+ var HOST_PLACEHOLDER_REGEX = /(?<=^https:\\\/\\\/[^/]*?):([^\\]+)(?=\\)/g;
4946
+ var PLACEHOLDER_REGEX = /:(\w+)/g;
4947
+ var replacer = (str, replacements) => {
4948
+ for (const [replacement, value] of Object.entries(replacements)) {
4949
+ str = str.replaceAll(`:${replacement}`, value);
4950
+ }
4951
+ return str;
4952
+ };
4953
+ var generateRulesMatcher = (rules, replacerFn = (match) => match) => {
4954
+ if (!rules)
4955
+ return () => [];
4956
+ const compiledRules = Object.entries(rules).map(([rule, match]) => {
4957
+ const crossHost = rule.startsWith("https://");
4958
+ rule = rule.split("*").map(escapeRegex).join("(?<splat>.*)");
4959
+ const host_matches = rule.matchAll(HOST_PLACEHOLDER_REGEX);
4960
+ for (const host_match of host_matches) {
4961
+ rule = rule.split(host_match[0]).join(`(?<${host_match[1]}>[^/.]+)`);
4962
+ }
4963
+ const path_matches = rule.matchAll(PLACEHOLDER_REGEX);
4964
+ for (const path_match of path_matches) {
4965
+ rule = rule.split(path_match[0]).join(`(?<${path_match[1]}>[^/]+)`);
4966
+ }
4967
+ rule = "^" + rule + "$";
4968
+ try {
4969
+ const regExp = new RegExp(rule);
4970
+ return [{ crossHost, regExp }, match];
4971
+ } catch {
4972
+ }
4973
+ }).filter((value) => value !== void 0);
4974
+ return ({ request }) => {
4975
+ const { pathname, host } = new URL(request.url);
4976
+ return compiledRules.map(([{ crossHost, regExp }, match]) => {
4977
+ const test = crossHost ? `https://${host}${pathname}` : pathname;
4978
+ const result = regExp.exec(test);
4979
+ if (result) {
4980
+ return replacerFn(match, result.groups || {});
4981
+ }
4982
+ }).filter((value) => value !== void 0);
4983
+ };
4984
+ };
4985
+
4986
+ // src/miniflare-cli/assets.ts
4987
+ var import_mime = __toESM(require_mime());
4940
4988
  import { fetch as miniflareFetch } from "@miniflare/core";
4941
4989
  import { watch } from "chokidar";
4942
4990
  import { Response } from "miniflare";
@@ -4967,49 +5015,6 @@ async function generateASSETSBinding(options) {
4967
5015
  }
4968
5016
  };
4969
5017
  }
4970
- function escapeRegex(str) {
4971
- return str.replace(/[-/\\^$*+?.()|[]{}]/g, "\\$&");
4972
- }
4973
- function replacer(str, replacements) {
4974
- for (const [replacement, value] of Object.entries(replacements)) {
4975
- str = str.replace(`:${replacement}`, value);
4976
- }
4977
- return str;
4978
- }
4979
- function generateRulesMatcher(rules, replacerFn = (match) => match) {
4980
- if (!rules)
4981
- return () => [];
4982
- const compiledRules = Object.entries(rules).map(([rule, match]) => {
4983
- const crossHost = rule.startsWith("https://");
4984
- rule = rule.split("*").map(escapeRegex).join("(?<splat>.*)");
4985
- const host_matches = rule.matchAll(
4986
- /(?<=^https:\\\/\\\/[^/]*?):([^\\]+)(?=\\)/g
4987
- );
4988
- for (const hostMatch of host_matches) {
4989
- rule = rule.split(hostMatch[0]).join(`(?<${hostMatch[1]}>[^/.]+)`);
4990
- }
4991
- const path_matches = rule.matchAll(/:(\w+)/g);
4992
- for (const pathMatch of path_matches) {
4993
- rule = rule.split(pathMatch[0]).join(`(?<${pathMatch[1]}>[^/]+)`);
4994
- }
4995
- rule = "^" + rule + "$";
4996
- try {
4997
- const regExp = new RegExp(rule);
4998
- return [{ crossHost, regExp }, match];
4999
- } catch {
5000
- }
5001
- }).filter((value) => value !== void 0);
5002
- return ({ request }) => {
5003
- const { pathname, host } = new URL(request.url);
5004
- return compiledRules.map(([{ crossHost, regExp }, match]) => {
5005
- const test = crossHost ? `https://${host}${pathname}` : pathname;
5006
- const result = regExp.exec(test);
5007
- if (result) {
5008
- return replacerFn(match, result.groups || {});
5009
- }
5010
- }).filter((value) => value !== void 0);
5011
- };
5012
- }
5013
5018
  function generateHeadersMatcher(headersFile) {
5014
5019
  if (existsSync(headersFile)) {
5015
5020
  const contents = readFileSync4(headersFile).toString();
@@ -5403,7 +5408,7 @@ async function main() {
5403
5408
  }
5404
5409
  config.bindings = {
5405
5410
  ...config.bindings,
5406
- ...Object.fromEntries(
5411
+ ...config.externalDurableObjects && Object.fromEntries(
5407
5412
  Object.entries(
5408
5413
  config.externalDurableObjects
5409
5414
  ).map(([binding, { name, host, port }]) => {
@@ -5427,7 +5432,10 @@ async function main() {
5427
5432
  requestFromArgs
5428
5433
  );
5429
5434
  request.headers.set("x-miniflare-durable-object-name", name);
5430
- request.headers.set("x-miniflare-durable-object-id", id.toString());
5435
+ request.headers.set(
5436
+ "x-miniflare-durable-object-id",
5437
+ id.toString()
5438
+ );
5431
5439
  return fetch(request);
5432
5440
  };
5433
5441
  return stub;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wrangler",
3
- "version": "2.0.26",
3
+ "version": "2.0.29",
4
4
  "description": "Command-line interface for all things Cloudflare Workers",
5
5
  "keywords": [
6
6
  "wrangler",
@@ -97,7 +97,7 @@
97
97
  "blake3-wasm": "^2.1.5",
98
98
  "chokidar": "^3.5.3",
99
99
  "esbuild": "0.14.51",
100
- "miniflare": "^2.6.0",
100
+ "miniflare": "^2.7.1",
101
101
  "nanoid": "^3.3.3",
102
102
  "path-to-regexp": "^6.2.0",
103
103
  "selfsigned": "^2.0.1",
@@ -107,6 +107,7 @@
107
107
  "devDependencies": {
108
108
  "@iarna/toml": "^3.0.0",
109
109
  "@microsoft/api-extractor": "^7.28.3",
110
+ "@types/busboy": "^1.5.0",
110
111
  "@types/command-exists": "^1.2.0",
111
112
  "@types/express": "^4.17.13",
112
113
  "@types/glob-to-regexp": "0.4.1",
@@ -120,6 +121,7 @@
120
121
  "@types/yargs": "^17.0.10",
121
122
  "@webcontainer/env": "^1.0.1",
122
123
  "body-parser": "^1.20.0",
124
+ "busboy": "^1.6.0",
123
125
  "clipboardy": "^3.0.0",
124
126
  "cmd-shim": "^4.1.0",
125
127
  "command-exists": "^1.2.9",
@@ -158,7 +160,7 @@
158
160
  "timeago.js": "^4.0.2",
159
161
  "tmp-promise": "^3.0.3",
160
162
  "ts-dedent": "^2.2.0",
161
- "undici": "^5.5.1",
163
+ "undici": "^5.9.1",
162
164
  "update-check": "^1.5.4",
163
165
  "ws": "^8.5.0",
164
166
  "xdg-app-paths": "^7.3.0",
@@ -168,6 +170,6 @@
168
170
  "fsevents": "~2.3.2"
169
171
  },
170
172
  "engines": {
171
- "node": ">=16.7.0"
173
+ "node": ">=16.13.0"
172
174
  }
173
175
  }
@@ -0,0 +1,19 @@
1
+ import { unstable_dev } from "../api";
2
+
3
+ jest.unmock("undici");
4
+
5
+ describe("unstable_dev", () => {
6
+ it("should return Hello World", async () => {
7
+ const worker = await unstable_dev(
8
+ "src/__tests__/helpers/hello-world-worker.js",
9
+ {},
10
+ { disableExperimentalWarning: true }
11
+ );
12
+ const resp = await worker.fetch();
13
+ if (resp) {
14
+ const text = await resp.text();
15
+ expect(text).toMatchInlineSnapshot(`"Hello World!"`);
16
+ }
17
+ await worker.stop();
18
+ });
19
+ });
@@ -61,7 +61,7 @@ describe("normalizeAndValidateConfig()", () => {
61
61
  unsafe: {
62
62
  bindings: [],
63
63
  },
64
- worker_namespaces: [],
64
+ dispatch_namespaces: [],
65
65
  usage_model: undefined,
66
66
  vars: {},
67
67
  define: {},
@@ -1635,6 +1635,7 @@ describe("normalizeAndValidateConfig()", () => {
1635
1635
  id: "KV_ID_2",
1636
1636
  preview_id: 2222,
1637
1637
  },
1638
+ { binding: "VALID", id: "" },
1638
1639
  ],
1639
1640
  } as unknown as RawConfig,
1640
1641
  undefined,
@@ -1654,7 +1655,8 @@ describe("normalizeAndValidateConfig()", () => {
1654
1655
  - \\"kv_namespaces[1]\\" bindings should have a string \\"id\\" field but got {\\"binding\\":\\"VALID\\"}.
1655
1656
  - \\"kv_namespaces[2]\\" bindings should have a string \\"binding\\" field but got {\\"binding\\":2000,\\"id\\":2111}.
1656
1657
  - \\"kv_namespaces[2]\\" bindings should have a string \\"id\\" field but got {\\"binding\\":2000,\\"id\\":2111}.
1657
- - \\"kv_namespaces[3]\\" bindings should, optionally, have a string \\"preview_id\\" field but got {\\"binding\\":\\"KV_BINDING_2\\",\\"id\\":\\"KV_ID_2\\",\\"preview_id\\":2222}."
1658
+ - \\"kv_namespaces[3]\\" bindings should, optionally, have a string \\"preview_id\\" field but got {\\"binding\\":\\"KV_BINDING_2\\",\\"id\\":\\"KV_ID_2\\",\\"preview_id\\":2222}.
1659
+ - \\"kv_namespaces[4]\\" bindings should have a string \\"id\\" field but got {\\"binding\\":\\"VALID\\",\\"id\\":\\"\\"}."
1658
1660
  `);
1659
1661
  });
1660
1662
  });
@@ -1740,6 +1742,7 @@ describe("normalizeAndValidateConfig()", () => {
1740
1742
  bucket_name: "R2_BUCKET_2",
1741
1743
  preview_bucket_name: 2555,
1742
1744
  },
1745
+ { binding: "R2_BINDING_1", bucket_name: "" },
1743
1746
  ],
1744
1747
  } as unknown as RawConfig,
1745
1748
  undefined,
@@ -1759,7 +1762,8 @@ describe("normalizeAndValidateConfig()", () => {
1759
1762
  - \\"r2_buckets[1]\\" bindings should have a string \\"bucket_name\\" field but got {\\"binding\\":\\"R2_BINDING_1\\"}.
1760
1763
  - \\"r2_buckets[2]\\" bindings should have a string \\"binding\\" field but got {\\"binding\\":2333,\\"bucket_name\\":2444}.
1761
1764
  - \\"r2_buckets[2]\\" bindings should have a string \\"bucket_name\\" field but got {\\"binding\\":2333,\\"bucket_name\\":2444}.
1762
- - \\"r2_buckets[3]\\" bindings should, optionally, have a string \\"preview_bucket_name\\" field but got {\\"binding\\":\\"R2_BINDING_2\\",\\"bucket_name\\":\\"R2_BUCKET_2\\",\\"preview_bucket_name\\":2555}."
1765
+ - \\"r2_buckets[3]\\" bindings should, optionally, have a string \\"preview_bucket_name\\" field but got {\\"binding\\":\\"R2_BINDING_2\\",\\"bucket_name\\":\\"R2_BUCKET_2\\",\\"preview_bucket_name\\":2555}.
1766
+ - \\"r2_buckets[4]\\" bindings should have a string \\"bucket_name\\" field but got {\\"binding\\":\\"R2_BINDING_1\\",\\"bucket_name\\":\\"\\"}."
1763
1767
  `);
1764
1768
  });
1765
1769
  });
@@ -1909,11 +1913,11 @@ describe("normalizeAndValidateConfig()", () => {
1909
1913
  });
1910
1914
  });
1911
1915
 
1912
- describe("[worker_namespaces]", () => {
1913
- it("should log an experimental warning when worker_namespaces is used", () => {
1916
+ describe("[dispatch_namespaces]", () => {
1917
+ it("should log an experimental warning when dispatch_namespaces is used", () => {
1914
1918
  const { config, diagnostics } = normalizeAndValidateConfig(
1915
1919
  {
1916
- worker_namespaces: [
1920
+ dispatch_namespaces: [
1917
1921
  {
1918
1922
  binding: "BINDING_1",
1919
1923
  namespace: "NAMESPACE_1",
@@ -1924,44 +1928,44 @@ describe("normalizeAndValidateConfig()", () => {
1924
1928
  { env: undefined }
1925
1929
  );
1926
1930
  expect(config).toEqual(
1927
- expect.not.objectContaining({ worker_namespaces: expect.anything })
1931
+ expect.not.objectContaining({ dispatch_namespaces: expect.anything })
1928
1932
  );
1929
1933
  expect(diagnostics.hasWarnings()).toBe(true);
1930
1934
  expect(diagnostics.hasErrors()).toBe(false);
1931
1935
  expect(diagnostics.renderWarnings()).toMatchInlineSnapshot(`
1932
1936
  "Processing wrangler configuration:
1933
- - \\"worker_namespaces\\" fields are experimental and may change or break at any time."
1937
+ - \\"dispatch_namespaces\\" fields are experimental and may change or break at any time."
1934
1938
  `);
1935
1939
  });
1936
1940
 
1937
- it("should error if worker_namespaces is not an array", () => {
1941
+ it("should error if dispatch_namespaces is not an array", () => {
1938
1942
  const { config, diagnostics } = normalizeAndValidateConfig(
1939
1943
  {
1940
- worker_namespaces: "just a string",
1944
+ dispatch_namespaces: "just a string",
1941
1945
  } as unknown as RawConfig,
1942
1946
  undefined,
1943
1947
  { env: undefined }
1944
1948
  );
1945
1949
 
1946
1950
  expect(config).toEqual(
1947
- expect.not.objectContaining({ worker_namespaces: expect.anything })
1951
+ expect.not.objectContaining({ dispatch_namespaces: expect.anything })
1948
1952
  );
1949
1953
  expect(diagnostics.hasWarnings()).toBe(true);
1950
1954
  expect(diagnostics.hasErrors()).toBe(true);
1951
1955
  expect(diagnostics.renderWarnings()).toMatchInlineSnapshot(`
1952
1956
  "Processing wrangler configuration:
1953
- - \\"worker_namespaces\\" fields are experimental and may change or break at any time."
1957
+ - \\"dispatch_namespaces\\" fields are experimental and may change or break at any time."
1954
1958
  `);
1955
1959
  expect(diagnostics.renderErrors()).toMatchInlineSnapshot(`
1956
1960
  "Processing wrangler configuration:
1957
- - The field \\"worker_namespaces\\" should be an array but got \\"just a string\\"."
1961
+ - The field \\"dispatch_namespaces\\" should be an array but got \\"just a string\\"."
1958
1962
  `);
1959
1963
  });
1960
1964
 
1961
- it("should error on non valid worker_namespaces", () => {
1965
+ it("should error on non valid dispatch_namespaces", () => {
1962
1966
  const { config, diagnostics } = normalizeAndValidateConfig(
1963
1967
  {
1964
- worker_namespaces: [
1968
+ dispatch_namespaces: [
1965
1969
  "a string",
1966
1970
  123,
1967
1971
  {
@@ -1969,17 +1973,17 @@ describe("normalizeAndValidateConfig()", () => {
1969
1973
  namespace: 456,
1970
1974
  },
1971
1975
  {
1972
- binding: "WORKER_NAMESPACE_BINDING_1",
1976
+ binding: "DISPATCH_NAMESPACE_BINDING_1",
1973
1977
  namespace: 456,
1974
1978
  },
1975
1979
  // this one is valid
1976
1980
  {
1977
- binding: "WORKER_NAMESPACE_BINDING_1",
1978
- namespace: "WORKER_NAMESPACE_BINDING_NAMESPACE_1",
1981
+ binding: "DISPATCH_NAMESPACE_BINDING_1",
1982
+ namespace: "DISPATCH_NAMESPACE_BINDING_NAMESPACE_1",
1979
1983
  },
1980
1984
  {
1981
1985
  binding: 123,
1982
- namespace: "WORKER_NAMESPACE_BINDING_SERVICE_1",
1986
+ namespace: "DISPATCH_NAMESPACE_BINDING_SERVICE_1",
1983
1987
  },
1984
1988
  {
1985
1989
  binding: 123,
@@ -1992,25 +1996,25 @@ describe("normalizeAndValidateConfig()", () => {
1992
1996
  );
1993
1997
  expect(config).toEqual(
1994
1998
  expect.not.objectContaining({
1995
- worker_namespaces: expect.anything,
1999
+ dispatch_namespaces: expect.anything,
1996
2000
  })
1997
2001
  );
1998
2002
  expect(diagnostics.hasWarnings()).toBe(true);
1999
2003
  expect(diagnostics.hasErrors()).toBe(true);
2000
2004
  expect(diagnostics.renderWarnings()).toMatchInlineSnapshot(`
2001
2005
  "Processing wrangler configuration:
2002
- - \\"worker_namespaces\\" fields are experimental and may change or break at any time."
2006
+ - \\"dispatch_namespaces\\" fields are experimental and may change or break at any time."
2003
2007
  `);
2004
2008
  expect(diagnostics.renderErrors()).toMatchInlineSnapshot(`
2005
2009
  "Processing wrangler configuration:
2006
- - \\"worker_namespaces[0]\\" binding should be objects, but got \\"a string\\"
2007
- - \\"worker_namespaces[1]\\" binding should be objects, but got 123
2008
- - \\"worker_namespaces[2]\\" should have a string \\"binding\\" field but got {\\"binding\\":123,\\"namespace\\":456}.
2009
- - \\"worker_namespaces[2]\\" should have a string \\"namespace\\" field but got {\\"binding\\":123,\\"namespace\\":456}.
2010
- - \\"worker_namespaces[3]\\" should have a string \\"namespace\\" field but got {\\"binding\\":\\"WORKER_NAMESPACE_BINDING_1\\",\\"namespace\\":456}.
2011
- - \\"worker_namespaces[5]\\" should have a string \\"binding\\" field but got {\\"binding\\":123,\\"namespace\\":\\"WORKER_NAMESPACE_BINDING_SERVICE_1\\"}.
2012
- - \\"worker_namespaces[6]\\" should have a string \\"binding\\" field but got {\\"binding\\":123,\\"service\\":456}.
2013
- - \\"worker_namespaces[6]\\" should have a string \\"namespace\\" field but got {\\"binding\\":123,\\"service\\":456}."
2010
+ - \\"dispatch_namespaces[0]\\" binding should be objects, but got \\"a string\\"
2011
+ - \\"dispatch_namespaces[1]\\" binding should be objects, but got 123
2012
+ - \\"dispatch_namespaces[2]\\" should have a string \\"binding\\" field but got {\\"binding\\":123,\\"namespace\\":456}.
2013
+ - \\"dispatch_namespaces[2]\\" should have a string \\"namespace\\" field but got {\\"binding\\":123,\\"namespace\\":456}.
2014
+ - \\"dispatch_namespaces[3]\\" should have a string \\"namespace\\" field but got {\\"binding\\":\\"DISPATCH_NAMESPACE_BINDING_1\\",\\"namespace\\":456}.
2015
+ - \\"dispatch_namespaces[5]\\" should have a string \\"binding\\" field but got {\\"binding\\":123,\\"namespace\\":\\"DISPATCH_NAMESPACE_BINDING_SERVICE_1\\"}.
2016
+ - \\"dispatch_namespaces[6]\\" should have a string \\"binding\\" field but got {\\"binding\\":123,\\"service\\":456}.
2017
+ - \\"dispatch_namespaces[6]\\" should have a string \\"namespace\\" field but got {\\"binding\\":123,\\"service\\":456}."
2014
2018
  `);
2015
2019
  });
2016
2020
  });
@@ -668,12 +668,12 @@ describe("wrangler dev", () => {
668
668
  writeWranglerToml({
669
669
  main: "index.js",
670
670
  dev: {
671
- ip: "0.0.0.0",
671
+ ip: "1.2.3.4",
672
672
  },
673
673
  });
674
674
  fs.writeFileSync("index.js", `export default {};`);
675
675
  await runWrangler("dev");
676
- expect((Dev as jest.Mock).mock.calls[0][0].ip).toEqual("0.0.0.0");
676
+ expect((Dev as jest.Mock).mock.calls[0][0].ip).toEqual("1.2.3.4");
677
677
  expect(std.out).toMatchInlineSnapshot(`""`);
678
678
  expect(std.warn).toMatchInlineSnapshot(`""`);
679
679
  expect(std.err).toMatchInlineSnapshot(`""`);
@@ -683,12 +683,12 @@ describe("wrangler dev", () => {
683
683
  writeWranglerToml({
684
684
  main: "index.js",
685
685
  dev: {
686
- ip: "1.1.1.1",
686
+ ip: "1.2.3.4",
687
687
  },
688
688
  });
689
689
  fs.writeFileSync("index.js", `export default {};`);
690
- await runWrangler("dev --ip=0.0.0.0");
691
- expect((Dev as jest.Mock).mock.calls[0][0].ip).toEqual("0.0.0.0");
690
+ await runWrangler("dev --ip=5.6.7.8");
691
+ expect((Dev as jest.Mock).mock.calls[0][0].ip).toEqual("5.6.7.8");
692
692
  expect(std.out).toMatchInlineSnapshot(`""`);
693
693
  expect(std.warn).toMatchInlineSnapshot(`""`);
694
694
  expect(std.err).toMatchInlineSnapshot(`""`);
@@ -1005,7 +1005,7 @@ describe("wrangler dev", () => {
1005
1005
  --compatibility-date Date to use for compatibility checks [string]
1006
1006
  --compatibility-flags, --compatibility-flag Flags to use for compatibility checks [array]
1007
1007
  --latest Use the latest version of the worker runtime [boolean] [default: true]
1008
- --ip IP address to listen on [string] [default: \\"0.0.0.0\\"]
1008
+ --ip IP address to listen on [string]
1009
1009
  --port Port to listen on [number]
1010
1010
  --inspector-port Port for devtools to connect to [number]
1011
1011
  --routes, --route Routes to upload [array]
@@ -1017,6 +1017,8 @@ describe("wrangler dev", () => {
1017
1017
  --site-include Array of .gitignore-style patterns that match file or directory names from the sites directory. Only matched items will be uploaded. [array]
1018
1018
  --site-exclude Array of .gitignore-style patterns that match file or directory names from the sites directory. Matched items will not be uploaded. [array]
1019
1019
  --upstream-protocol Protocol to forward requests to host on, defaults to https. [choices: \\"http\\", \\"https\\"]
1020
+ --var A key-value pair to be injected into the script as a variable [array]
1021
+ --define A key-value pair to be substituted in the script [array]
1020
1022
  --jsx-factory The function that is called for each JSX element [string]
1021
1023
  --jsx-fragment The function that is called for each JSX fragment [string]
1022
1024
  --tsconfig Path to a custom tsconfig.json file [string]
@@ -1,6 +1,4 @@
1
1
  import fs from "node:fs";
2
- import path from "node:path";
3
- import process from "node:process";
4
2
  import { setup } from "create-cloudflare";
5
3
  import { mockConsoleMethods } from "./helpers/mock-console";
6
4
  import { mockConfirm, clearConfirmMocks } from "./helpers/mock-dialogs";
@@ -73,7 +71,7 @@ describe("generate", () => {
73
71
  ).resolves.toBeUndefined();
74
72
 
75
73
  expect(createCloudflareMock).lastCalledWith(
76
- path.resolve(process.cwd(), "my-worker-1"),
74
+ "my-worker-1",
77
75
  "some-template",
78
76
  { debug: false, force: false, init: true }
79
77
  );
@@ -85,7 +83,7 @@ describe("generate", () => {
85
83
  ).resolves.toBeUndefined();
86
84
 
87
85
  expect(createCloudflareMock).lastCalledWith(
88
- path.resolve(process.cwd(), "my-worker-2"),
86
+ "my-worker-2",
89
87
  "some-template",
90
88
  { debug: false, force: false, init: true }
91
89
  );
@@ -0,0 +1,5 @@
1
+ export default {
2
+ async fetch() {
3
+ return new Response("Hello World!");
4
+ },
5
+ };
@@ -0,0 +1,8 @@
1
+ import { setMockResponse } from "./mock-cfetch";
2
+
3
+ export function mockGetZoneFromHostRequest(host: string, zone?: string) {
4
+ setMockResponse("/zones", (_uri, _init, queryParams) => {
5
+ expect(queryParams.get("name")).toEqual(host);
6
+ return zone ? [{ id: zone }] : [];
7
+ });
8
+ }
@@ -0,0 +1,7 @@
1
+ import { setMockResponse } from "./mock-cfetch";
2
+
3
+ export function mockCollectKnownRoutesRequest(
4
+ routes: { pattern: string; script: string }[]
5
+ ) {
6
+ setMockResponse(`/zones/:zoneId/workers/routes`, "GET", () => routes);
7
+ }
@@ -31,21 +31,21 @@ describe("wrangler", () => {
31
31
  "wrangler
32
32
 
33
33
  Commands:
34
- wrangler init [name] 📥 Create a wrangler.toml configuration file
35
- wrangler dev [script] 👂 Start a local server for developing your worker
36
- wrangler publish [script] 🆙 Publish your Worker to Cloudflare.
37
- wrangler tail [name] 🦚 Starts a log tailing session for a published Worker.
38
- wrangler secret 🤫 Generate a secret that can be referenced in a Worker
39
- wrangler kv:namespace 🗂️ Interact with your Workers KV Namespaces
40
- wrangler kv:key 🔑 Individually manage Workers KV key-value pairs
41
- wrangler kv:bulk 💪 Interact with multiple Workers KV key-value pairs at once
42
- wrangler pages ⚡️ Configure Cloudflare Pages
43
- wrangler r2 📦 Interact with an R2 store
44
- wrangler worker-namespace 📦 Interact with a worker namespace
45
- wrangler pubsub 📮 Interact and manage Pub/Sub Brokers
46
- wrangler login 🔓 Login to Cloudflare
47
- wrangler logout 🚪 Logout from Cloudflare
48
- wrangler whoami 🕵️ Retrieve your user info and test your auth config
34
+ wrangler init [name] 📥 Create a wrangler.toml configuration file
35
+ wrangler dev [script] 👂 Start a local server for developing your worker
36
+ wrangler publish [script] 🆙 Publish your Worker to Cloudflare.
37
+ wrangler tail [worker] 🦚 Starts a log tailing session for a published Worker.
38
+ wrangler secret 🤫 Generate a secret that can be referenced in a Worker
39
+ wrangler kv:namespace 🗂️ Interact with your Workers KV Namespaces
40
+ wrangler kv:key 🔑 Individually manage Workers KV key-value pairs
41
+ wrangler kv:bulk 💪 Interact with multiple Workers KV key-value pairs at once
42
+ wrangler pages ⚡️ Configure Cloudflare Pages
43
+ wrangler r2 📦 Interact with an R2 store
44
+ wrangler dispatch-namespace 📦 Interact with a dispatch namespace
45
+ wrangler pubsub 📮 Interact and manage Pub/Sub Brokers
46
+ wrangler login 🔓 Login to Cloudflare
47
+ wrangler logout 🚪 Logout from Cloudflare
48
+ wrangler whoami 🕵️ Retrieve your user info and test your auth config
49
49
 
50
50
  Flags:
51
51
  -c, --config Path to .toml configuration file [string]
@@ -70,21 +70,21 @@ describe("wrangler", () => {
70
70
  wrangler
71
71
 
72
72
  Commands:
73
- wrangler init [name] 📥 Create a wrangler.toml configuration file
74
- wrangler dev [script] 👂 Start a local server for developing your worker
75
- wrangler publish [script] 🆙 Publish your Worker to Cloudflare.
76
- wrangler tail [name] 🦚 Starts a log tailing session for a published Worker.
77
- wrangler secret 🤫 Generate a secret that can be referenced in a Worker
78
- wrangler kv:namespace 🗂️ Interact with your Workers KV Namespaces
79
- wrangler kv:key 🔑 Individually manage Workers KV key-value pairs
80
- wrangler kv:bulk 💪 Interact with multiple Workers KV key-value pairs at once
81
- wrangler pages ⚡️ Configure Cloudflare Pages
82
- wrangler r2 📦 Interact with an R2 store
83
- wrangler worker-namespace 📦 Interact with a worker namespace
84
- wrangler pubsub 📮 Interact and manage Pub/Sub Brokers
85
- wrangler login 🔓 Login to Cloudflare
86
- wrangler logout 🚪 Logout from Cloudflare
87
- wrangler whoami 🕵️ Retrieve your user info and test your auth config
73
+ wrangler init [name] 📥 Create a wrangler.toml configuration file
74
+ wrangler dev [script] 👂 Start a local server for developing your worker
75
+ wrangler publish [script] 🆙 Publish your Worker to Cloudflare.
76
+ wrangler tail [worker] 🦚 Starts a log tailing session for a published Worker.
77
+ wrangler secret 🤫 Generate a secret that can be referenced in a Worker
78
+ wrangler kv:namespace 🗂️ Interact with your Workers KV Namespaces
79
+ wrangler kv:key 🔑 Individually manage Workers KV key-value pairs
80
+ wrangler kv:bulk 💪 Interact with multiple Workers KV key-value pairs at once
81
+ wrangler pages ⚡️ Configure Cloudflare Pages
82
+ wrangler r2 📦 Interact with an R2 store
83
+ wrangler dispatch-namespace 📦 Interact with a dispatch namespace
84
+ wrangler pubsub 📮 Interact and manage Pub/Sub Brokers
85
+ wrangler login 🔓 Login to Cloudflare
86
+ wrangler logout 🚪 Logout from Cloudflare
87
+ wrangler whoami 🕵️ Retrieve your user info and test your auth config
88
88
 
89
89
  Flags:
90
90
  -c, --config Path to .toml configuration file [string]
@@ -15,6 +15,19 @@ import {
15
15
  } from "./helpers/mock-cfetch";
16
16
  import { MockWebSocket } from "./helpers/mock-web-socket";
17
17
 
18
+ /**
19
+ * The relative path between the bundled code and the Wrangler package.
20
+ * This is used as a reliable way to compute paths relative to the Wrangler package
21
+ * in the source files, rather than relying upon `__dirname` which can change depending
22
+ * on whether the source files have been bundled and the location of the outdir.
23
+ *
24
+ * This is exposed in the source via the `getBasePath()` function, which should be used
25
+ * in place of `__dirname` and similar Node.js constants.
26
+ */
27
+ (
28
+ global as unknown as { __RELATIVE_PACKAGE_PATH__: string }
29
+ ).__RELATIVE_PACKAGE_PATH__ = "..";
30
+
18
31
  // Mock out getPort since we don't actually care about what ports are open in unit tests.
19
32
  jest.mock("get-port", () => {
20
33
  return {
@@ -109,6 +122,10 @@ jest.mock("../user/generate-auth-url", () => {
109
122
  };
110
123
  });
111
124
 
125
+ jest.mock("../is-ci", () => {
126
+ return { CI: { isCI: jest.fn().mockImplementation(() => false) } };
127
+ });
128
+
112
129
  jest.mock("../user/generate-random-state", () => {
113
130
  return {
114
131
  generateRandomState: jest.fn().mockImplementation(() => "MOCK_STATE_PARAM"),
@@ -2,9 +2,9 @@ import { mkdirSync } from "node:fs";
2
2
  import fetchMock from "jest-fetch-mock";
3
3
  import { version as wranglerVersion } from "../../package.json";
4
4
  import { purgeConfigCaches, saveToConfigCache } from "../config-cache";
5
+ import { CI } from "../is-ci";
5
6
  import { logger } from "../logger";
6
7
  import { getMetricsDispatcher, getMetricsConfig } from "../metrics";
7
- import { CI } from "../metrics/is-ci";
8
8
  import {
9
9
  CURRENT_METRICS_DATE,
10
10
  readMetricsConfig,