wrangler 0.0.28 → 0.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.
package/README.md CHANGED
@@ -2,24 +2,29 @@
2
2
 
3
3
  `wrangler` is a command line tool for building [Cloudflare Workers](https://workers.cloudflare.com/).
4
4
 
5
- [(Read the full stack week launch blog post.)](https://blog.cloudflare.com/wrangler-v2-beta/)
6
-
7
- **DISCLAIMER**: This is a work in progress, and is NOT recommended for use in production. We are opening this preview for feedback from the community, and to openly share our [roadmap](https://github.com/cloudflare/wrangler2/milestones) for the future. As such, expect APIs and documentation to change before the end of the preview.
8
-
9
- Further, we will NOT do a general release until we are both feature complete, and have a full backward compatibility and incremental migration plan in place. For more details, follow the [2.0 milestone](https://github.com/cloudflare/wrangler2/milestone/1).
10
-
11
5
  ## Quick Start
12
6
 
13
7
  ```bash
14
8
  # Make a javascript file
15
- $ echo "export default { fetch() { return new Response('hello world') } }" > index.js
9
+ echo "export default { fetch() { return new Response('hello world') } }" > index.js
16
10
  # try it out
17
- $ npx wrangler dev index.js
11
+ npx wrangler dev index.js
18
12
  # and then publish it
19
- $ npx wrangler publish index.js --name my-worker
13
+ npx wrangler publish index.js --name my-worker
20
14
  # visit https://my-worker.<your workers subdomain>.workers.dev
21
15
  ```
22
16
 
17
+ ## Create a Project
18
+
19
+ ```bash
20
+ # Generate a new project
21
+ npx wrangler init my-worker
22
+ # try it out
23
+ cd my-worker && npm run start
24
+ # and then publish it
25
+ npx wrangler publish
26
+ ```
27
+
23
28
  ## Installation:
24
29
 
25
30
  ```bash
@@ -30,18 +35,20 @@ $ npm install wrangler --save-dev
30
35
 
31
36
  ### `wrangler init [name]`
32
37
 
33
- Creates a `wrangler.toml` configuration file. For more details on the configuration keys and values, refer to the [documentation](https://developers.cloudflare.com/workers/cli-wrangler/configuration).
38
+ Creates a Worker project. For details on configuration keys and values, refer to the [documentation](https://developers.cloudflare.com/workers/cli-wrangler/configuration).
34
39
 
35
- ### `wrangler dev [script]`
40
+ ### `wrangler dev`
36
41
 
37
42
  Start a local development server, with live reloading and devtools.
38
43
 
39
- ### `wrangler publish [script] --name [name]`
44
+ ### `wrangler publish`
40
45
 
41
46
  Publish the given script to the worldwide Cloudflare network.
42
47
 
43
48
  For more commands and options, refer to the [documentation](https://developers.cloudflare.com/workers/cli-wrangler/commands).
44
49
 
50
+ ## Pages
51
+
45
52
  ### `wrangler pages dev [directory] [-- command]`
46
53
 
47
54
  Either serves a static build asset directory, or proxies itself in front of a command.
@@ -49,3 +56,7 @@ Either serves a static build asset directory, or proxies itself in front of a co
49
56
  Builds and runs functions from a `./functions` directory or uses a `_worker.js` file inside the static build asset directory.
50
57
 
51
58
  For more commands and options, refer to the [documentation](https://developers.cloudflare.com/pages/platform/functions#develop-and-preview-locally) or run `wrangler pages dev --help`.
59
+
60
+ ## Documentation
61
+
62
+ For the latest Wrangler documentation, [click here](https://6b05b6e1.cloudflare-docs-7ou.pages.dev/workers/wrangler/).
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wrangler",
3
- "version": "0.0.28",
3
+ "version": "0.0.29",
4
4
  "author": "wrangler@cloudflare.com",
5
5
  "description": "Command-line interface for all things Cloudflare Workers",
6
6
  "bin": {
@@ -69,6 +69,7 @@
69
69
  "cmd-shim": "^4.1.0",
70
70
  "command-exists": "^1.2.9",
71
71
  "devtools-protocol": "^0.0.955664",
72
+ "dotenv": "^16.0.0",
72
73
  "execa": "^6.1.0",
73
74
  "faye-websocket": "^0.11.4",
74
75
  "finalhandler": "^1.2.0",
@@ -95,6 +96,7 @@
95
96
  "supports-color": "^9.2.2",
96
97
  "timeago.js": "^4.0.2",
97
98
  "tmp-promise": "^3.0.3",
99
+ "ts-dedent": "^2.2.0",
98
100
  "undici": "^4.15.1",
99
101
  "update-check": "^1.5.4",
100
102
  "ws": "^8.5.0",
@@ -132,7 +132,7 @@ export default function (pluginArgs) {
132
132
  // https://fetch.spec.whatwg.org/#null-body-status
133
133
  return new Response(
134
134
  [101, 204, 205, 304].includes(response.status) ? null : response.body,
135
- response
135
+ { ...response, headers: new Headers(response.headers) }
136
136
  );
137
137
  } else {
138
138
  return next();
@@ -123,7 +123,7 @@ export default {
123
123
  // https://fetch.spec.whatwg.org/#null-body-status
124
124
  return new Response(
125
125
  [101, 204, 205, 304].includes(response.status) ? null : response.body,
126
- { ...response, headers: new Headers([...response.headers.entries()]) }
126
+ { ...response, headers: new Headers(response.headers) }
127
127
  );
128
128
  } else if (__FALLBACK_SERVICE__) {
129
129
  // There are no more handlers so finish with the fallback service (`env.ASSETS.fetch` in Pages' case)
@@ -0,0 +1,36 @@
1
+ import { getConfigCache, saveToConfigCache } from "../config-cache";
2
+ import { runInTempDir } from "./helpers/run-in-tmp";
3
+
4
+ interface PagesConfigCache {
5
+ account_id: string;
6
+ pages_project_name: string;
7
+ }
8
+
9
+ describe("config cache", () => {
10
+ runInTempDir();
11
+
12
+ const pagesConfigCacheFilename = "pages-config-cache.json";
13
+
14
+ it("should return an empty config if no file exists", () => {
15
+ expect(
16
+ getConfigCache<PagesConfigCache>(pagesConfigCacheFilename)
17
+ ).toMatchInlineSnapshot(`Object {}`);
18
+ });
19
+
20
+ it("should read and write values without overriding old ones", () => {
21
+ saveToConfigCache<PagesConfigCache>(pagesConfigCacheFilename, {
22
+ account_id: "some-account-id",
23
+ pages_project_name: "foo",
24
+ });
25
+ expect(
26
+ getConfigCache<PagesConfigCache>(pagesConfigCacheFilename).account_id
27
+ ).toEqual("some-account-id");
28
+
29
+ saveToConfigCache<PagesConfigCache>(pagesConfigCacheFilename, {
30
+ pages_project_name: "bar",
31
+ });
32
+ expect(
33
+ getConfigCache<PagesConfigCache>(pagesConfigCacheFilename).account_id
34
+ ).toEqual("some-account-id");
35
+ });
36
+ });
@@ -157,7 +157,7 @@ describe("normalizeAndValidateConfig()", () => {
157
157
  expect(diagnostics.hasErrors()).toBe(false);
158
158
  expect(diagnostics.renderWarnings()).toMatchInlineSnapshot(`
159
159
  "Processing wrangler configuration:
160
- - 😶 UNUSED: \\"miniflare\\":
160
+ - 😶 Ignored: \\"miniflare\\":
161
161
  Wrangler does not use configuration in the \`miniflare\` section. Unless you are using Miniflare directly you can remove this section."
162
162
  `);
163
163
  });
@@ -250,7 +250,7 @@ describe("normalizeAndValidateConfig()", () => {
250
250
  expect(normalizeSlashes(diagnostics.renderWarnings()))
251
251
  .toMatchInlineSnapshot(`
252
252
  "Processing wrangler configuration:
253
- - DEPRECATION: \\"site.entry-point\\":
253
+ - Deprecation: \\"site.entry-point\\":
254
254
  Delete the \`site.entry-point\` field, then add the top level \`main\` field to your configuration file:
255
255
  \`\`\`
256
256
  main = \\"my-site/index.js\\"
@@ -281,7 +281,7 @@ describe("normalizeAndValidateConfig()", () => {
281
281
  expect(normalizeSlashes(diagnostics.renderWarnings()))
282
282
  .toMatchInlineSnapshot(`
283
283
  "Processing wrangler configuration:
284
- - DEPRECATION: \\"site.entry-point\\":
284
+ - Deprecation: \\"site.entry-point\\":
285
285
  Delete the \`site.entry-point\` field, then add the top level \`main\` field to your configuration file:
286
286
  \`\`\`
287
287
  main = \\"workers-site/index.js\\"
@@ -324,7 +324,7 @@ describe("normalizeAndValidateConfig()", () => {
324
324
  expect(normalizeSlashes(diagnostics.renderWarnings()))
325
325
  .toMatchInlineSnapshot(`
326
326
  "Processing wrangler configuration:
327
- - DEPRECATION: \\"site.entry-point\\":
327
+ - Deprecation: \\"site.entry-point\\":
328
328
  Delete the \`site.entry-point\` field, then add the top level \`main\` field to your configuration file:
329
329
  \`\`\`
330
330
  main = \\"111/index.js\\"
@@ -358,7 +358,7 @@ describe("normalizeAndValidateConfig()", () => {
358
358
  expect(normalizeSlashes(diagnostics.renderWarnings()))
359
359
  .toMatchInlineSnapshot(`
360
360
  "Processing wrangler configuration:
361
- - DEPRECATION: \\"site.entry-point\\":
361
+ - Deprecation: \\"site.entry-point\\":
362
362
  Delete the \`site.entry-point\` field, then add the top level \`main\` field to your configuration file:
363
363
  \`\`\`
364
364
  main = \\"some/other/script.js\\"
@@ -571,10 +571,10 @@ describe("normalizeAndValidateConfig()", () => {
571
571
  expect(diagnostics.hasWarnings()).toBe(true);
572
572
  expect(diagnostics.renderWarnings()).toMatchInlineSnapshot(`
573
573
  "Processing wrangler configuration:
574
- - DEPRECATION: \\"type\\":
575
- DO NOT USE THIS. Most common features now work out of the box with wrangler, including modules, jsx, typescript, etc. If you need anything more, use a custom build.
576
- - DEPRECATION: \\"webpack_config\\":
577
- DO NOT USE THIS. Most common features now work out of the box with wrangler, including modules, jsx, typescript, etc. If you need anything more, use a custom build."
574
+ - 😶 Ignored: \\"type\\":
575
+ Most common features now work out of the box with wrangler, including modules, jsx, typescript, etc. If you need anything more, use a custom build.
576
+ - 😶 Ignored: \\"webpack_config\\":
577
+ Most common features now work out of the box with wrangler, including modules, jsx, typescript, etc. If you need anything more, use a custom build."
578
578
  `);
579
579
  });
580
580
  });
@@ -869,17 +869,17 @@ describe("normalizeAndValidateConfig()", () => {
869
869
  expect(normalizePath(diagnostics.renderWarnings()))
870
870
  .toMatchInlineSnapshot(`
871
871
  "Processing project/wrangler.toml configuration:
872
- - DEPRECATION: \\"build.upload.format\\":
872
+ - Deprecation: \\"build.upload.format\\":
873
873
  The format is inferred automatically from the code.
874
- - DEPRECATION: \\"build.upload.main\\":
874
+ - Deprecation: \\"build.upload.main\\":
875
875
  Delete the \`build.upload.main\` and \`build.upload.dir\` fields.
876
876
  Then add the top level \`main\` field to your configuration file:
877
877
  \`\`\`
878
878
  main = \\"src/index.ts\\"
879
879
  \`\`\`
880
- - DEPRECATION: \\"build.upload.dir\\":
880
+ - Deprecation: \\"build.upload.dir\\":
881
881
  Use the top level \\"main\\" field or a command-line argument to specify the entry-point for the Worker.
882
- - DEPRECATION: The \`build.upload.rules\` config field is no longer used, the rules should be specified via the \`rules\` config field. Delete the \`build.upload\` field from the configuration file, and add this:
882
+ - Deprecation: The \`build.upload.rules\` config field is no longer used, the rules should be specified via the \`rules\` config field. Delete the \`build.upload\` field from the configuration file, and add this:
883
883
  \`\`\`
884
884
  [[rules]]
885
885
  type = \\"Text\\"
@@ -1619,9 +1619,9 @@ describe("normalizeAndValidateConfig()", () => {
1619
1619
  expect(diagnostics.hasWarnings()).toBe(true);
1620
1620
  expect(diagnostics.renderWarnings()).toMatchInlineSnapshot(`
1621
1621
  "Processing wrangler configuration:
1622
- - DEPRECATION: \\"zone_id\\":
1622
+ - Deprecation: \\"zone_id\\":
1623
1623
  This is unnecessary since we can deduce this from routes directly.
1624
- - DEPRECATION: \\"experimental_services\\":
1624
+ - Deprecation: \\"experimental_services\\":
1625
1625
  The \\"experimental_services\\" field is no longer supported. Instead, use [[unsafe.bindings]] to enable experimental features. Add this to your wrangler.toml:
1626
1626
  \`\`\`
1627
1627
  [[unsafe.bindings]]
@@ -1815,7 +1815,11 @@ describe("normalizeAndValidateConfig()", () => {
1815
1815
 
1816
1816
  expect(config.name).toEqual("mock-name");
1817
1817
  expect(diagnostics.hasErrors()).toBe(false);
1818
- expect(diagnostics.hasWarnings()).toBe(false);
1818
+ expect(diagnostics.hasWarnings()).toBe(true);
1819
+ expect(diagnostics.renderWarnings()).toMatchInlineSnapshot(`
1820
+ "Processing wrangler configuration:
1821
+ - Experimental: Service environments are in beta, and their behaviour is guaranteed to change in the future. DO NOT USE IN PRODUCTION."
1822
+ `);
1819
1823
  });
1820
1824
 
1821
1825
  it("should error if named environment contains a `name` field, even if there is no top-level name", () => {
@@ -1835,6 +1839,12 @@ describe("normalizeAndValidateConfig()", () => {
1835
1839
  );
1836
1840
 
1837
1841
  expect(config.name).toBeUndefined();
1842
+ expect(diagnostics.hasWarnings()).toBe(true);
1843
+ expect(diagnostics.hasErrors()).toBe(true);
1844
+ expect(diagnostics.renderWarnings()).toMatchInlineSnapshot(`
1845
+ "Processing wrangler configuration:
1846
+ - Experimental: Service environments are in beta, and their behaviour is guaranteed to change in the future. DO NOT USE IN PRODUCTION."
1847
+ `);
1838
1848
  expect(diagnostics.renderErrors()).toMatchInlineSnapshot(`
1839
1849
  "Processing wrangler configuration:
1840
1850
 
@@ -1842,7 +1852,6 @@ describe("normalizeAndValidateConfig()", () => {
1842
1852
  - The \\"name\\" field is not allowed in named service environments.
1843
1853
  Please remove the field from this environment."
1844
1854
  `);
1845
- expect(diagnostics.hasWarnings()).toBe(false);
1846
1855
  });
1847
1856
 
1848
1857
  it("should error if top-level config and a named environment both contain a `name` field", () => {
@@ -1863,6 +1872,12 @@ describe("normalizeAndValidateConfig()", () => {
1863
1872
  );
1864
1873
 
1865
1874
  expect(config.name).toEqual("mock-name");
1875
+ expect(diagnostics.hasWarnings()).toBe(true);
1876
+ expect(diagnostics.hasErrors()).toBe(true);
1877
+ expect(diagnostics.renderWarnings()).toMatchInlineSnapshot(`
1878
+ "Processing wrangler configuration:
1879
+ - Experimental: Service environments are in beta, and their behaviour is guaranteed to change in the future. DO NOT USE IN PRODUCTION."
1880
+ `);
1866
1881
  expect(diagnostics.renderErrors()).toMatchInlineSnapshot(`
1867
1882
  "Processing wrangler configuration:
1868
1883
 
@@ -1870,7 +1885,6 @@ describe("normalizeAndValidateConfig()", () => {
1870
1885
  - The \\"name\\" field is not allowed in named service environments.
1871
1886
  Please remove the field from this environment."
1872
1887
  `);
1873
- expect(diagnostics.hasWarnings()).toBe(false);
1874
1888
  });
1875
1889
  });
1876
1890
 
@@ -1890,7 +1904,12 @@ describe("normalizeAndValidateConfig()", () => {
1890
1904
  { env: "DEV" }
1891
1905
  );
1892
1906
 
1907
+ expect(diagnostics.hasWarnings()).toBe(true);
1893
1908
  expect(config.account_id).toBeUndefined();
1909
+ expect(diagnostics.renderWarnings()).toMatchInlineSnapshot(`
1910
+ "Processing wrangler configuration:
1911
+ - Experimental: Service environments are in beta, and their behaviour is guaranteed to change in the future. DO NOT USE IN PRODUCTION."
1912
+ `);
1894
1913
  expect(diagnostics.renderErrors()).toMatchInlineSnapshot(`
1895
1914
  "Processing wrangler configuration:
1896
1915
 
@@ -1898,7 +1917,6 @@ describe("normalizeAndValidateConfig()", () => {
1898
1917
  - The \\"account_id\\" field is not allowed in named service environments.
1899
1918
  Please remove the field from this environment."
1900
1919
  `);
1901
- expect(diagnostics.hasWarnings()).toBe(false);
1902
1920
  });
1903
1921
 
1904
1922
  it("should error if top-level config and a named environment both contain a `account_id` field", () => {
@@ -1919,6 +1937,12 @@ describe("normalizeAndValidateConfig()", () => {
1919
1937
  );
1920
1938
 
1921
1939
  expect(config.account_id).toEqual("ACCOUNT_ID");
1940
+ expect(diagnostics.hasErrors()).toBe(true);
1941
+ expect(diagnostics.hasWarnings()).toBe(true);
1942
+ expect(diagnostics.renderWarnings()).toMatchInlineSnapshot(`
1943
+ "Processing wrangler configuration:
1944
+ - Experimental: Service environments are in beta, and their behaviour is guaranteed to change in the future. DO NOT USE IN PRODUCTION."
1945
+ `);
1922
1946
  expect(diagnostics.renderErrors()).toMatchInlineSnapshot(`
1923
1947
  "Processing wrangler configuration:
1924
1948
 
@@ -1926,7 +1950,6 @@ describe("normalizeAndValidateConfig()", () => {
1926
1950
  - The \\"account_id\\" field is not allowed in named service environments.
1927
1951
  Please remove the field from this environment."
1928
1952
  `);
1929
- expect(diagnostics.hasWarnings()).toBe(false);
1930
1953
  });
1931
1954
 
1932
1955
  it("should warn for non-inherited fields that are missing in environments", () => {
@@ -2843,9 +2866,9 @@ describe("normalizeAndValidateConfig()", () => {
2843
2866
  "Processing wrangler configuration:
2844
2867
 
2845
2868
  - \\"env.ENV1\\" environment configuration
2846
- - DEPRECATION: \\"zone_id\\":
2869
+ - Deprecation: \\"zone_id\\":
2847
2870
  This is unnecessary since we can deduce this from routes directly.
2848
- - DEPRECATION: \\"experimental_services\\":
2871
+ - Deprecation: \\"experimental_services\\":
2849
2872
  The \\"experimental_services\\" field is no longer supported. Instead, use [[unsafe.bindings]] to enable experimental features. Add this to your wrangler.toml:
2850
2873
  \`\`\`
2851
2874
  [[unsafe.bindings]]
@@ -1,6 +1,6 @@
1
1
  import * as fs from "node:fs";
2
- import { readFileSync } from "node:fs";
3
2
  import patchConsole from "patch-console";
3
+ import dedent from "ts-dedent";
4
4
  import Dev from "../dev/dev";
5
5
  import { mockAccountId, mockApiToken } from "./helpers/mock-account-id";
6
6
  import { setMockResponse, unsetAllMocks } from "./helpers/mock-cfetch";
@@ -40,16 +40,17 @@ describe("wrangler dev", () => {
40
40
  expect(std.out).toMatchInlineSnapshot(`""`);
41
41
  expect(std.warn.replaceAll(currentDate, "<current-date>"))
42
42
  .toMatchInlineSnapshot(`
43
- "▲ [WARNING] No compatibility_date was specified. Using today's date: <current-date>.
44
- Add one to your wrangler.toml file:
45
- \`\`\`
46
- compatibility_date = \\"<current-date>\\"
47
- \`\`\`
48
- or pass it in your terminal:
49
- \`\`\`
50
- --compatibility-date=<current-date>
51
- \`\`\`
52
- See https://developers.cloudflare.com/workers/platform/compatibility-dates for more information.
43
+ "▲ [WARNING] No compatibility_date was specified. Using today's date: <current-date>.
44
+
45
+ Add one to your wrangler.toml file:
46
+ \`\`\`
47
+ compatibility_date = \\"<current-date>\\"
48
+ \`\`\`
49
+ or pass it in your terminal:
50
+ \`\`\`
51
+ --compatibility-date=<current-date>
52
+ \`\`\`
53
+ See https://developers.cloudflare.com/workers/platform/compatibility-dates for more information.
53
54
 
54
55
  "
55
56
  `);
@@ -382,7 +383,7 @@ describe("wrangler dev", () => {
382
383
 
383
384
  await runWrangler("dev index.js");
384
385
 
385
- expect(readFileSync("index.js", "utf-8")).toMatchInlineSnapshot(
386
+ expect(fs.readFileSync("index.js", "utf-8")).toMatchInlineSnapshot(
386
387
  `"export default { fetch(){ return new Response(123) } }"`
387
388
  );
388
389
 
@@ -410,7 +411,7 @@ describe("wrangler dev", () => {
410
411
 
411
412
  await runWrangler("dev index.js");
412
413
 
413
- expect(readFileSync("index.js", "utf-8")).toMatchInlineSnapshot(`
414
+ expect(fs.readFileSync("index.js", "utf-8")).toMatchInlineSnapshot(`
414
415
  "export default { fetch(){ return new Response(123) } }
415
416
  "
416
417
  `);
@@ -476,9 +477,10 @@ describe("wrangler dev", () => {
476
477
  );
477
478
  expect(std.out).toMatchInlineSnapshot(`""`);
478
479
  expect(std.warn).toMatchInlineSnapshot(`
479
- "▲ [WARNING] Setting upstream-protocol to http is not currently implemented.
480
- If this is required in your project, please add your use case to the following issue:
481
- https://github.com/cloudflare/wrangler2/issues/583.
480
+ "▲ [WARNING] Setting upstream-protocol to http is not currently implemented.
481
+
482
+ If this is required in your project, please add your use case to the following issue:
483
+ https://github.com/cloudflare/wrangler2/issues/583.
482
484
 
483
485
  "
484
486
  `);
@@ -604,17 +606,68 @@ describe("wrangler dev", () => {
604
606
  expect((Dev as jest.Mock).mock.calls[0][0].ip).toEqual("localhost");
605
607
  expect(std.out).toMatchInlineSnapshot(`""`);
606
608
  expect(std.warn).toMatchInlineSnapshot(`
607
- "▲ [WARNING] WARNING: You have Durable Object bindings that are not defined locally in the worker being developed.
608
- Be aware that changes to the data stored in these Durable Objects will be permanent and affect the live instances.
609
- Remote Durable Objects that are affected:
610
- - {\\"name\\":\\"NAME_2\\",\\"class_name\\":\\"CLASS_2\\",\\"script_name\\":\\"SCRIPT_A\\"}
611
- - {\\"name\\":\\"NAME_4\\",\\"class_name\\":\\"CLASS_4\\",\\"script_name\\":\\"SCRIPT_B\\"}
609
+ "▲ [WARNING] WARNING: You have Durable Object bindings that are not defined locally in the worker being developed.
610
+
611
+ Be aware that changes to the data stored in these Durable Objects will be permanent and affect the
612
+ live instances.
613
+ Remote Durable Objects that are affected:
614
+ - {\\"name\\":\\"NAME_2\\",\\"class_name\\":\\"CLASS_2\\",\\"script_name\\":\\"SCRIPT_A\\"}
615
+ - {\\"name\\":\\"NAME_4\\",\\"class_name\\":\\"CLASS_4\\",\\"script_name\\":\\"SCRIPT_B\\"}
612
616
 
613
617
  "
614
618
  `);
615
619
  expect(std.err).toMatchInlineSnapshot(`""`);
616
620
  });
617
621
  });
622
+
623
+ describe(".dev.vars", () => {
624
+ it("should override `vars` bindings from `wrangler.toml` with values in `.dev.vars`", async () => {
625
+ fs.writeFileSync("index.js", `export default {};`);
626
+
627
+ const localVarsEnvContent = dedent`
628
+ # Preceding comment
629
+ VAR_1="var #1 value" # End of line comment
630
+ VAR_3="var #3 value"
631
+ VAR_MULTI_LINE_1="A: line 1
632
+ line 2"
633
+ VAR_MULTI_LINE_2="B: line 1\\nline 2"
634
+ EMPTY=
635
+ UNQUOTED= unquoted value
636
+ `;
637
+ fs.writeFileSync(".dev.vars", localVarsEnvContent, "utf8");
638
+
639
+ writeWranglerToml({
640
+ main: "index.js",
641
+ vars: {
642
+ VAR_1: "original value 1",
643
+ VAR_2: "original value 2", // should not get overridden
644
+ VAR_3: "original value 3",
645
+ VAR_MULTI_LINE_1: "original multi-line 1",
646
+ VAR_MULTI_LINE_2: "original multi-line 2",
647
+ EMPTY: "original empty",
648
+ UNQUOTED: "original unquoted",
649
+ },
650
+ });
651
+ await runWrangler("dev");
652
+ const varBindings: Record<string, unknown> = (Dev as jest.Mock).mock
653
+ .calls[0][0].bindings.vars;
654
+
655
+ expect(varBindings).toEqual({
656
+ VAR_1: "var #1 value",
657
+ VAR_2: "original value 2",
658
+ VAR_3: "var #3 value",
659
+ VAR_MULTI_LINE_1: "A: line 1\nline 2",
660
+ VAR_MULTI_LINE_2: "B: line 1\nline 2",
661
+ EMPTY: "",
662
+ UNQUOTED: "unquoted value", // Note that whitespace is trimmed
663
+ });
664
+ expect(std.out).toMatchInlineSnapshot(
665
+ `"Using vars defined in .dev.vars"`
666
+ );
667
+ expect(std.warn).toMatchInlineSnapshot(`""`);
668
+ expect(std.err).toMatchInlineSnapshot(`""`);
669
+ });
670
+ });
618
671
  });
619
672
 
620
673
  function mockGetZones(domain: string, zones: { id: string }[] = []) {
@@ -1,4 +1,5 @@
1
1
  import * as util from "node:util";
2
+ import { logger } from "../../logger";
2
3
 
3
4
  /**
4
5
  * We use this module to mock console methods, and optionally
@@ -39,6 +40,7 @@ function captureCalls(spy: jest.SpyInstance): string {
39
40
 
40
41
  export function mockConsoleMethods() {
41
42
  beforeEach(() => {
43
+ logger.columns = 100;
42
44
  debugSpy = jest.spyOn(console, "debug").mockImplementation();
43
45
  logSpy = jest.spyOn(console, "log").mockImplementation();
44
46
  errorSpy = jest.spyOn(console, "error").mockImplementation();
@@ -1,4 +1,5 @@
1
- const ORIGINAL_ISTTY = process.stdout.isTTY;
1
+ const ORIGINAL_STDOUT_ISTTY = process.stdout.isTTY;
2
+ const ORIGINAL_STDIN_ISTTY = process.stdin.isTTY;
2
3
 
3
4
  /**
4
5
  * Mock `process.stdout.isTTY`
@@ -9,14 +10,17 @@ export function useMockIsTTY() {
9
10
  */
10
11
  const setIsTTY = (isTTY: boolean) => {
11
12
  process.stdout.isTTY = isTTY;
13
+ process.stdin.isTTY = isTTY;
12
14
  };
13
15
 
14
16
  beforeEach(() => {
15
- process.stdout.isTTY = ORIGINAL_ISTTY;
17
+ process.stdout.isTTY = ORIGINAL_STDOUT_ISTTY;
18
+ process.stdin.isTTY = ORIGINAL_STDIN_ISTTY;
16
19
  });
17
20
 
18
21
  afterEach(() => {
19
- process.stdout.isTTY = ORIGINAL_ISTTY;
22
+ process.stdout.isTTY = ORIGINAL_STDOUT_ISTTY;
23
+ process.stdin.isTTY = ORIGINAL_STDIN_ISTTY;
20
24
  });
21
25
 
22
26
  return { setIsTTY };
@@ -1,5 +1,6 @@
1
1
  import fetchMock from "jest-fetch-mock";
2
2
  import { Request } from "undici";
3
+ import { getCloudflareApiBaseUrl } from "../../cfetch";
3
4
  import openInBrowser from "../../open-in-browser";
4
5
  import { mockHttpServer } from "./mock-http-server";
5
6
 
@@ -85,6 +86,28 @@ export const mockOAuthFlow = () => {
85
86
  return outcome;
86
87
  };
87
88
 
89
+ const mockGetMemberships = (args: {
90
+ success: boolean;
91
+ result: { id: string; account: { id: string; name: string } }[];
92
+ }) => {
93
+ const outcome = {
94
+ actual: new Request("https://example.org"),
95
+ expected: new Request(`${getCloudflareApiBaseUrl()}/memberships`, {
96
+ method: "GET",
97
+ }),
98
+ };
99
+
100
+ fetchMock.mockIf(outcome.expected.url, async (req) => {
101
+ outcome.actual = req;
102
+ return {
103
+ status: 200,
104
+ body: JSON.stringify(args),
105
+ };
106
+ });
107
+
108
+ return outcome;
109
+ };
110
+
88
111
  const mockGrantAccessToken = ({
89
112
  respondWith,
90
113
  }: {
@@ -150,10 +173,11 @@ export const mockOAuthFlow = () => {
150
173
  };
151
174
 
152
175
  return {
153
- mockOAuthServerCallback,
176
+ mockGetMemberships,
177
+ mockGrantAccessToken,
154
178
  mockGrantAuthorization,
179
+ mockOAuthServerCallback,
155
180
  mockRevokeAuthorization,
156
- mockGrantAccessToken,
157
181
  mockExchangeRefreshTokenForAccessToken,
158
182
  };
159
183
  };
@@ -97,8 +97,9 @@ describe("getHttpsOptions()", () => {
97
97
  `"Generating new self-signed certificate..."`
98
98
  );
99
99
  expect(std.warn).toMatchInlineSnapshot(`
100
- "▲ [WARNING] Unable to cache generated self-signed certificate in home/.wrangler/local-cert.
101
- ERROR: Cannot write file
100
+ "▲ [WARNING] Unable to cache generated self-signed certificate in home/.wrangler/local-cert.
101
+
102
+ ERROR: Cannot write file
102
103
 
103
104
  "
104
105
  `);
@@ -97,14 +97,14 @@ describe("wrangler", () => {
97
97
  it("should throw an error if the deprecated command is used with positional arguments", async () => {
98
98
  await expect(runWrangler("preview GET")).rejects
99
99
  .toThrowErrorMatchingInlineSnapshot(`
100
- "DEPRECATION:
100
+ "Deprecation:
101
101
  The \`wrangler preview\` command has been deprecated.
102
102
  Try using \`wrangler dev\` to to try out a worker during development.
103
103
  "
104
104
  `);
105
105
  await expect(runWrangler(`preview GET "SomeBody"`)).rejects
106
106
  .toThrowErrorMatchingInlineSnapshot(`
107
- "DEPRECATION:
107
+ "Deprecation:
108
108
  The \`wrangler preview\` command has been deprecated.
109
109
  Try using \`wrangler dev\` to to try out a worker during development.
110
110
  "
@@ -222,7 +222,7 @@ describe("wrangler", () => {
222
222
  it("should print a deprecation message for 'generate'", async () => {
223
223
  await runWrangler("generate").catch((err) => {
224
224
  expect(err.message).toMatchInlineSnapshot(`
225
- "DEPRECATION:
225
+ "Deprecation:
226
226
  \`wrangler generate\` has been deprecated, please refer to https://github.com/cloudflare/wrangler2/blob/main/docs/deprecations.md#generate for alternatives"
227
227
  `);
228
228
  });
@@ -230,7 +230,7 @@ describe("wrangler", () => {
230
230
  it("should print a deprecation message for 'build'", async () => {
231
231
  await runWrangler("build").catch((err) => {
232
232
  expect(err.message).toMatchInlineSnapshot(`
233
- "DEPRECATION:
233
+ "Deprecation:
234
234
  \`wrangler build\` has been deprecated, please refer to https://github.com/cloudflare/wrangler2/blob/main/docs/deprecations.md#build for alternatives"
235
235
  `);
236
236
  });
@@ -291,8 +291,9 @@ describe("wrangler", () => {
291
291
  --namespace-id The id of the namespace to delete [string]
292
292
  -e, --env Perform on a specific environment [string]
293
293
  --preview Interact with a preview namespace [boolean]
294
- X [ERROR] Not able to delete namespace.
295
- A namespace with binding name \\"otherBinding\\" was not found in the configured \\"kv_namespaces\\".
294
+ X [ERROR] Not able to delete namespace.
295
+
296
+ A namespace with binding name \\"otherBinding\\" was not found in the configured \\"kv_namespaces\\".
296
297
 
297
298
  "
298
299
  `);
@@ -1229,8 +1230,9 @@ describe("wrangler", () => {
1229
1230
  If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new."
1230
1231
  `);
1231
1232
  expect(std.warn).toMatchInlineSnapshot(`
1232
- "▲ [WARNING] Unexpected key-value properties in \\"keys.json\\".
1233
- The item at index 4 contains unexpected properties: [\\"invalid\\"].
1233
+ "▲ [WARNING] Unexpected key-value properties in \\"keys.json\\".
1234
+
1235
+ The item at index 4 contains unexpected properties: [\\"invalid\\"].
1234
1236
 
1235
1237
  "
1236
1238
  `);