wrangler 2.0.2 → 2.0.6

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.
@@ -0,0 +1,18 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIIC6zCCAkygAwIBAgIUI7b68p0pPrCBoW4ptlyvVcPItscwCgYIKoZIzj0EAwQw
3
+ gY0xCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1T
4
+ YW4gRnJhbmNpc2NvMRgwFgYDVQQKEw9DbG91ZGZsYXJlLCBJbmMxNzA1BgNVBAMT
5
+ LkNsb3VkZmxhcmUgZm9yIFRlYW1zIEVDQyBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkw
6
+ HhcNMjAwMjA0MTYwNTAwWhcNMjUwMjAyMTYwNTAwWjCBjTELMAkGA1UEBhMCVVMx
7
+ EzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBGcmFuY2lzY28xGDAW
8
+ BgNVBAoTD0Nsb3VkZmxhcmUsIEluYzE3MDUGA1UEAxMuQ2xvdWRmbGFyZSBmb3Ig
9
+ VGVhbXMgRUNDIENlcnRpZmljYXRlIEF1dGhvcml0eTCBmzAQBgcqhkjOPQIBBgUr
10
+ gQQAIwOBhgAEAVdXsX8tpA9NAQeEQalvUIcVaFNDvGsR69ysZxOraRWNGHLfq1mi
11
+ P6o3wtmtx/C2OXG01Cw7UFJbKl5MEDxnT2KoAdFSynSJOF2NDoe5LoZHbUW+yR3X
12
+ FDl+MF6JzZ590VLGo6dPBf06UsXbH7PvHH2XKtFt8bBXVNMa5a21RdmpD0Pho0Uw
13
+ QzAOBgNVHQ8BAf8EBAMCAQYwEgYDVR0TAQH/BAgwBgEB/wIBAjAdBgNVHQ4EFgQU
14
+ YBcQng1AEMMNteuRDAMG0/vgFe0wCgYIKoZIzj0EAwQDgYwAMIGIAkIBQU5OTA2h
15
+ YqmFk8paan5ezHVLcmcucsfYw4L/wmeEjCkczRmCVNm6L86LjhWU0v0wER0e+lHO
16
+ 3efvjbsu8gIGSagCQgEBnyYMP9gwg8l96QnQ1khFA1ljFlnqc2XgJHDSaAJC0gdz
17
+ +NV3JMeWaD2Rb32jc9r6/a7xY0u0ByqxBQ1OQ0dt7A==
18
+ -----END CERTIFICATE-----
package/bin/wrangler.js CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
- const { spawn } = require("node:child_process");
3
- const { join } = require("node:path");
2
+ const { spawn } = require("child_process");
3
+ const { join } = require("path");
4
4
  const semiver = require("semiver");
5
5
 
6
6
  const MIN_NODE_VERSION = "16.7.0";
@@ -20,6 +20,20 @@ Consider using a Node.js version manager such as https://volta.sh/ or https://gi
20
20
  return;
21
21
  }
22
22
 
23
+ let pathToCACerts = process.env.NODE_EXTRA_CA_CERTS;
24
+ if (pathToCACerts) {
25
+ // TODO:
26
+ // - should we log a warning here?
27
+ // - maybe we can generate a certificate that concatenates with ours?
28
+ // - is there a security concern/should we cleanup after we exit?
29
+ //
30
+ // I do think it'll be rare that someone wants to add a cert AND
31
+ // use cloudflare WARP, but let's wait till the situation actually
32
+ // arises before we do anything about it
33
+ } else {
34
+ pathToCACerts = join(__dirname, "../Cloudflare_CA.pem");
35
+ }
36
+
23
37
  wranglerProcess = spawn(
24
38
  process.execPath,
25
39
  [
@@ -32,7 +46,13 @@ Consider using a Node.js version manager such as https://volta.sh/ or https://gi
32
46
  join(__dirname, "../wrangler-dist/cli.js"),
33
47
  ...process.argv.slice(2),
34
48
  ],
35
- { stdio: "inherit" }
49
+ {
50
+ stdio: "inherit",
51
+ env: {
52
+ ...process.env,
53
+ NODE_EXTRA_CA_CERTS: pathToCACerts,
54
+ },
55
+ }
36
56
  ).on("exit", (code) =>
37
57
  process.exit(code === undefined || code === null ? 0 : code)
38
58
  );
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wrangler",
3
- "version": "2.0.2",
3
+ "version": "2.0.6",
4
4
  "author": "wrangler@cloudflare.com",
5
5
  "description": "Command-line interface for all things Cloudflare Workers",
6
6
  "bin": {
@@ -62,6 +62,7 @@
62
62
  "@types/supports-color": "^8.1.1",
63
63
  "@types/ws": "^8.5.3",
64
64
  "@types/yargs": "^17.0.10",
65
+ "@webcontainer/env": "^1.0.1",
65
66
  "chokidar": "^3.5.3",
66
67
  "clipboardy": "^3.0.0",
67
68
  "cmd-shim": "^4.1.0",
@@ -109,7 +110,8 @@
109
110
  "wrangler-dist",
110
111
  "templates",
111
112
  "vendor",
112
- "import_meta_url.js"
113
+ "import_meta_url.js",
114
+ "Cloudflare_CA.pem"
113
115
  ],
114
116
  "scripts": {
115
117
  "clean": "rm -rf wrangler-dist miniflare-dist",
@@ -122,7 +122,7 @@ export function buildWorker({
122
122
  // TODO: Watch args.path for changes and re-copy when updated
123
123
  contents: `export const onRequest = ({ request, env, functionPath }) => {
124
124
  const url = new URL(request.url)
125
- const relativePathname = url.pathname.split(functionPath)[1] || "/";
125
+ const relativePathname = \`/\${url.pathname.split(functionPath)[1] || ''}\`.replace(/^\\/\\//, '/');
126
126
  url.pathname = '/cdn-cgi/pages-plugins/${identifier}' + relativePathname
127
127
  request = new Request(url.toString(), request)
128
128
  return env.ASSETS.fetch(request)
@@ -103,8 +103,9 @@ export default function (pluginArgs) {
103
103
  const { env, next, data } = workerContext;
104
104
 
105
105
  const url = new URL(request.url);
106
- const relativePathname =
107
- url.pathname.split(workerContext.functionPath)[1] || "/";
106
+ const relativePathname = `/${
107
+ url.pathname.split(workerContext.functionPath)[1] || ""
108
+ }`.replace(/^\/\//, "/");
108
109
 
109
110
  const handlerIterator = executeRequest(request, relativePathname);
110
111
  const pluginNext = async (input?: RequestInfo, init?: RequestInit) => {
@@ -27,7 +27,7 @@ describe("normalizeAndValidateConfig()", () => {
27
27
  dev: {
28
28
  ip: "localhost",
29
29
  local_protocol: "http",
30
- port: 8787,
30
+ port: undefined, // the default of 8787 is set at runtime
31
31
  upstream_protocol: "https",
32
32
  host: undefined,
33
33
  },
@@ -43,6 +43,7 @@ describe("normalizeAndValidateConfig()", () => {
43
43
  migrations: [],
44
44
  name: undefined,
45
45
  r2_buckets: [],
46
+ services: [],
46
47
  route: undefined,
47
48
  routes: undefined,
48
49
  rules: [],
@@ -620,6 +621,12 @@ describe("normalizeAndValidateConfig()", () => {
620
621
  class_name: "CLASS2",
621
622
  script_name: "SCRIPT2",
622
623
  },
624
+ {
625
+ name: "DO_BINDING_3",
626
+ class_name: "CLASS3",
627
+ script_name: "SCRIPT3",
628
+ environment: "ENV3",
629
+ },
623
630
  ],
624
631
  },
625
632
  kv_namespaces: [
@@ -638,6 +645,13 @@ describe("normalizeAndValidateConfig()", () => {
638
645
  preview_bucket_name: "R2_PREVIEW_2",
639
646
  },
640
647
  ],
648
+ services: [
649
+ {
650
+ binding: "SERVICE_BINDING_1",
651
+ service: "SERVICE_TYPE_1",
652
+ environment: "SERVICE_BINDING_ENVIRONMENT_1",
653
+ },
654
+ ],
641
655
  unsafe: {
642
656
  bindings: [
643
657
  { name: "UNSAFE_BINDING_1", type: "UNSAFE_TYPE_1" },
@@ -661,9 +675,10 @@ describe("normalizeAndValidateConfig()", () => {
661
675
  );
662
676
  expect(diagnostics.hasErrors()).toBe(false);
663
677
  expect(diagnostics.renderWarnings()).toMatchInlineSnapshot(`
664
- "Processing wrangler configuration:
665
- - \\"unsafe\\" fields are experimental and may change or break at any time."
666
- `);
678
+ "Processing wrangler configuration:
679
+ - \\"unsafe\\" fields are experimental and may change or break at any time.
680
+ - \\"services\\" fields are experimental and may change or break at any time."
681
+ `);
667
682
  });
668
683
 
669
684
  it("should error on invalid environment values", () => {
@@ -717,8 +732,8 @@ describe("normalizeAndValidateConfig()", () => {
717
732
  expect(diagnostics.hasWarnings()).toBe(false);
718
733
  expect(diagnostics.renderErrors()).toMatchInlineSnapshot(`
719
734
  "Processing wrangler configuration:
720
- - Expected \\"route\\" to be either a string, or an object with shape { pattern, zone_id | zone_name }, but got 888.
721
- - Expected \\"routes\\" to be an array of either strings or objects with the shape { pattern, zone_id | zone_name }, but these weren't valid: [
735
+ - Expected \\"route\\" to be either a string, or an object with shape { pattern, custom_domain, zone_id | zone_name }, but got 888.
736
+ - Expected \\"routes\\" to be an array of either strings or objects with the shape { pattern, custom_domain, zone_id | zone_name }, but these weren't valid: [
722
737
  666,
723
738
  777,
724
739
  {
@@ -1106,13 +1121,29 @@ describe("normalizeAndValidateConfig()", () => {
1106
1121
  durable_objects: {
1107
1122
  bindings: [
1108
1123
  {},
1109
- { name: "VALID" },
1124
+ { name: "MISSING_CLASS" },
1110
1125
  { name: 1555, class_name: 1666 },
1111
1126
  {
1112
1127
  name: 1777,
1113
1128
  class_name: 1888,
1114
1129
  script_name: 1999,
1115
1130
  },
1131
+ {
1132
+ name: "SOMENAME",
1133
+ class_name: "SomeClass",
1134
+ environment: "staging",
1135
+ },
1136
+ {
1137
+ name: 1778,
1138
+ class_name: 1889,
1139
+ script_name: 1992,
1140
+ environment: 2111,
1141
+ },
1142
+ {
1143
+ name: 1772,
1144
+ class_name: 1883,
1145
+ environment: 2112,
1146
+ },
1116
1147
  ],
1117
1148
  },
1118
1149
  } as unknown as RawConfig,
@@ -1133,7 +1164,7 @@ describe("normalizeAndValidateConfig()", () => {
1133
1164
  - binding should have a string \\"name\\" field.
1134
1165
  - binding should have a string \\"class_name\\" field.
1135
1166
 
1136
- - \\"durable_objects.bindings[1]\\": {\\"name\\":\\"VALID\\"}
1167
+ - \\"durable_objects.bindings[1]\\": {\\"name\\":\\"MISSING_CLASS\\"}
1137
1168
  - binding should have a string \\"class_name\\" field.
1138
1169
 
1139
1170
  - \\"durable_objects.bindings[2]\\": {\\"name\\":1555,\\"class_name\\":1666}
@@ -1143,7 +1174,22 @@ describe("normalizeAndValidateConfig()", () => {
1143
1174
  - \\"durable_objects.bindings[3]\\": {\\"name\\":1777,\\"class_name\\":1888,\\"script_name\\":1999}
1144
1175
  - binding should have a string \\"name\\" field.
1145
1176
  - binding should have a string \\"class_name\\" field.
1146
- - binding should, optionally, have a string \\"script_name\\" field."
1177
+ - the field \\"script_name\\", when present, should be a string.
1178
+
1179
+ - \\"durable_objects.bindings[4]\\": {\\"name\\":\\"SOMENAME\\",\\"class_name\\":\\"SomeClass\\",\\"environment\\":\\"staging\\"}
1180
+ - binding should have a \\"script_name\\" field if \\"environment\\" is present.
1181
+
1182
+ - \\"durable_objects.bindings[5]\\": {\\"name\\":1778,\\"class_name\\":1889,\\"script_name\\":1992,\\"environment\\":2111}
1183
+ - binding should have a string \\"name\\" field.
1184
+ - binding should have a string \\"class_name\\" field.
1185
+ - the field \\"script_name\\", when present, should be a string.
1186
+ - the field \\"environment\\", when present, should be a string.
1187
+
1188
+ - \\"durable_objects.bindings[6]\\": {\\"name\\":1772,\\"class_name\\":1883,\\"environment\\":2112}
1189
+ - binding should have a string \\"name\\" field.
1190
+ - binding should have a string \\"class_name\\" field.
1191
+ - the field \\"environment\\", when present, should be a string.
1192
+ - binding should have a \\"script_name\\" field if \\"environment\\" is present."
1147
1193
  `);
1148
1194
  });
1149
1195
  });
@@ -1358,6 +1404,151 @@ describe("normalizeAndValidateConfig()", () => {
1358
1404
  });
1359
1405
  });
1360
1406
 
1407
+ describe("services field", () => {
1408
+ it("should error if services is an object", () => {
1409
+ const { config, diagnostics } = normalizeAndValidateConfig(
1410
+ { services: {} } as unknown as RawConfig,
1411
+ undefined,
1412
+ { env: undefined }
1413
+ );
1414
+
1415
+ expect(config).toEqual(
1416
+ expect.not.objectContaining({ services: expect.anything })
1417
+ );
1418
+ expect(diagnostics.hasWarnings()).toBe(true);
1419
+ expect(diagnostics.hasErrors()).toBe(true);
1420
+ expect(diagnostics.renderWarnings()).toMatchInlineSnapshot(`
1421
+ "Processing wrangler configuration:
1422
+ - \\"services\\" fields are experimental and may change or break at any time."
1423
+ `);
1424
+ expect(diagnostics.renderErrors()).toMatchInlineSnapshot(`
1425
+ "Processing wrangler configuration:
1426
+ - The field \\"services\\" should be an array but got {}."
1427
+ `);
1428
+ });
1429
+
1430
+ it("should error if services is a string", () => {
1431
+ const { config, diagnostics } = normalizeAndValidateConfig(
1432
+ { services: "BAD" } as unknown as RawConfig,
1433
+ undefined,
1434
+ { env: undefined }
1435
+ );
1436
+
1437
+ expect(config).toEqual(
1438
+ expect.not.objectContaining({ services: expect.anything })
1439
+ );
1440
+ expect(diagnostics.hasWarnings()).toBe(true);
1441
+ expect(diagnostics.hasErrors()).toBe(true);
1442
+ expect(diagnostics.renderWarnings()).toMatchInlineSnapshot(`
1443
+ "Processing wrangler configuration:
1444
+ - \\"services\\" fields are experimental and may change or break at any time."
1445
+ `);
1446
+ expect(diagnostics.renderErrors()).toMatchInlineSnapshot(`
1447
+ "Processing wrangler configuration:
1448
+ - The field \\"services\\" should be an array but got \\"BAD\\"."
1449
+ `);
1450
+ });
1451
+
1452
+ it("should error if services is a number", () => {
1453
+ const { config, diagnostics } = normalizeAndValidateConfig(
1454
+ { services: 999 } as unknown as RawConfig,
1455
+ undefined,
1456
+ { env: undefined }
1457
+ );
1458
+
1459
+ expect(config).toEqual(
1460
+ expect.not.objectContaining({ services: expect.anything })
1461
+ );
1462
+ expect(diagnostics.hasWarnings()).toBe(true);
1463
+ expect(diagnostics.hasErrors()).toBe(true);
1464
+ expect(diagnostics.renderWarnings()).toMatchInlineSnapshot(`
1465
+ "Processing wrangler configuration:
1466
+ - \\"services\\" fields are experimental and may change or break at any time."
1467
+ `);
1468
+ expect(diagnostics.renderErrors()).toMatchInlineSnapshot(`
1469
+ "Processing wrangler configuration:
1470
+ - The field \\"services\\" should be an array but got 999."
1471
+ `);
1472
+ });
1473
+
1474
+ it("should error if services is null", () => {
1475
+ const { config, diagnostics } = normalizeAndValidateConfig(
1476
+ { services: null } as unknown as RawConfig,
1477
+ undefined,
1478
+ { env: undefined }
1479
+ );
1480
+
1481
+ expect(config).toEqual(
1482
+ expect.not.objectContaining({ services: expect.anything })
1483
+ );
1484
+ expect(diagnostics.hasWarnings()).toBe(true);
1485
+ expect(diagnostics.hasErrors()).toBe(true);
1486
+ expect(diagnostics.renderWarnings()).toMatchInlineSnapshot(`
1487
+ "Processing wrangler configuration:
1488
+ - \\"services\\" fields are experimental and may change or break at any time."
1489
+ `);
1490
+ expect(diagnostics.renderErrors()).toMatchInlineSnapshot(`
1491
+ "Processing wrangler configuration:
1492
+ - The field \\"services\\" should be an array but got null."
1493
+ `);
1494
+ });
1495
+
1496
+ it("should error if services bindings are not valid", () => {
1497
+ const { config, diagnostics } = normalizeAndValidateConfig(
1498
+ {
1499
+ services: [
1500
+ {},
1501
+ { binding: "SERVICE_BINDING_1" },
1502
+ { binding: 123, service: 456 },
1503
+ { binding: 123, service: 456, environment: 789 },
1504
+ { binding: "SERVICE_BINDING_1", service: 456, environment: 789 },
1505
+ {
1506
+ binding: 123,
1507
+ service: "SERVICE_BINDING_SERVICE_1",
1508
+ environment: 789,
1509
+ },
1510
+ {
1511
+ binding: 123,
1512
+ service: 456,
1513
+ environment: "SERVICE_BINDING_ENVIRONMENT_1",
1514
+ },
1515
+ ],
1516
+ } as unknown as RawConfig,
1517
+ undefined,
1518
+ { env: undefined }
1519
+ );
1520
+
1521
+ expect(config).toEqual(
1522
+ expect.not.objectContaining({
1523
+ services: { bindings: expect.anything },
1524
+ })
1525
+ );
1526
+ expect(diagnostics.hasWarnings()).toBe(true);
1527
+ expect(diagnostics.hasErrors()).toBe(true);
1528
+ expect(diagnostics.renderWarnings()).toMatchInlineSnapshot(`
1529
+ "Processing wrangler configuration:
1530
+ - \\"services\\" fields are experimental and may change or break at any time."
1531
+ `);
1532
+ expect(diagnostics.renderErrors()).toMatchInlineSnapshot(`
1533
+ "Processing wrangler configuration:
1534
+ - \\"services[0]\\" bindings should have a string \\"binding\\" field but got {}.
1535
+ - \\"services[0]\\" bindings should have a string \\"service\\" field but got {}.
1536
+ - \\"services[1]\\" bindings should have a string \\"service\\" field but got {\\"binding\\":\\"SERVICE_BINDING_1\\"}.
1537
+ - \\"services[2]\\" bindings should have a string \\"binding\\" field but got {\\"binding\\":123,\\"service\\":456}.
1538
+ - \\"services[2]\\" bindings should have a string \\"service\\" field but got {\\"binding\\":123,\\"service\\":456}.
1539
+ - \\"services[3]\\" bindings should have a string \\"binding\\" field but got {\\"binding\\":123,\\"service\\":456,\\"environment\\":789}.
1540
+ - \\"services[3]\\" bindings should have a string \\"service\\" field but got {\\"binding\\":123,\\"service\\":456,\\"environment\\":789}.
1541
+ - \\"services[3]\\" bindings should have a string \\"environment\\" field but got {\\"binding\\":123,\\"service\\":456,\\"environment\\":789}.
1542
+ - \\"services[4]\\" bindings should have a string \\"service\\" field but got {\\"binding\\":\\"SERVICE_BINDING_1\\",\\"service\\":456,\\"environment\\":789}.
1543
+ - \\"services[4]\\" bindings should have a string \\"environment\\" field but got {\\"binding\\":\\"SERVICE_BINDING_1\\",\\"service\\":456,\\"environment\\":789}.
1544
+ - \\"services[5]\\" bindings should have a string \\"binding\\" field but got {\\"binding\\":123,\\"service\\":\\"SERVICE_BINDING_SERVICE_1\\",\\"environment\\":789}.
1545
+ - \\"services[5]\\" bindings should have a string \\"environment\\" field but got {\\"binding\\":123,\\"service\\":\\"SERVICE_BINDING_SERVICE_1\\",\\"environment\\":789}.
1546
+ - \\"services[6]\\" bindings should have a string \\"binding\\" field but got {\\"binding\\":123,\\"service\\":456,\\"environment\\":\\"SERVICE_BINDING_ENVIRONMENT_1\\"}.
1547
+ - \\"services[6]\\" bindings should have a string \\"service\\" field but got {\\"binding\\":123,\\"service\\":456,\\"environment\\":\\"SERVICE_BINDING_ENVIRONMENT_1\\"}."
1548
+ `);
1549
+ });
1550
+ });
1551
+
1361
1552
  describe("unsafe field", () => {
1362
1553
  it("should error if unsafe is an array", () => {
1363
1554
  const { config, diagnostics } = normalizeAndValidateConfig(
@@ -1622,14 +1813,7 @@ describe("normalizeAndValidateConfig()", () => {
1622
1813
  - Deprecation: \\"zone_id\\":
1623
1814
  This is unnecessary since we can deduce this from routes directly.
1624
1815
  - Deprecation: \\"experimental_services\\":
1625
- The \\"experimental_services\\" field is no longer supported. Instead, use [[unsafe.bindings]] to enable experimental features. Add this to your wrangler.toml:
1626
- \`\`\`
1627
- [[unsafe.bindings]]
1628
- name = \\"mock-name\\"
1629
- type = \\"service\\"
1630
- service = \\"SERVICE\\"
1631
- environment = \\"ENV\\"
1632
- \`\`\`"
1816
+ The \\"experimental_services\\" field is no longer supported. Simply rename the [experimental_services] field to [services]."
1633
1817
  `);
1634
1818
  });
1635
1819
  });
@@ -2045,8 +2229,8 @@ describe("normalizeAndValidateConfig()", () => {
2045
2229
  "Processing wrangler configuration:
2046
2230
 
2047
2231
  - \\"env.ENV1\\" environment configuration
2048
- - Expected \\"route\\" to be either a string, or an object with shape { pattern, zone_id | zone_name }, but got 888.
2049
- - Expected \\"routes\\" to be an array of either strings or objects with the shape { pattern, zone_id | zone_name }, but these weren't valid: [
2232
+ - Expected \\"route\\" to be either a string, or an object with shape { pattern, custom_domain, zone_id | zone_name }, but got 888.
2233
+ - Expected \\"routes\\" to be an array of either strings or objects with the shape { pattern, custom_domain, zone_id | zone_name }, but these weren't valid: [
2050
2234
  666,
2051
2235
  777
2052
2236
  ].
@@ -2304,7 +2488,7 @@ describe("normalizeAndValidateConfig()", () => {
2304
2488
  - \\"env.ENV1.durable_objects.bindings[3]\\": {\\"name\\":1777,\\"class_name\\":1888,\\"script_name\\":1999}
2305
2489
  - binding should have a string \\"name\\" field.
2306
2490
  - binding should have a string \\"class_name\\" field.
2307
- - binding should, optionally, have a string \\"script_name\\" field."
2491
+ - the field \\"script_name\\", when present, should be a string."
2308
2492
  `);
2309
2493
  });
2310
2494
  });
@@ -2869,14 +3053,7 @@ describe("normalizeAndValidateConfig()", () => {
2869
3053
  - Deprecation: \\"zone_id\\":
2870
3054
  This is unnecessary since we can deduce this from routes directly.
2871
3055
  - Deprecation: \\"experimental_services\\":
2872
- The \\"experimental_services\\" field is no longer supported. Instead, use [[unsafe.bindings]] to enable experimental features. Add this to your wrangler.toml:
2873
- \`\`\`
2874
- [[unsafe.bindings]]
2875
- name = \\"mock-name\\"
2876
- type = \\"service\\"
2877
- service = \\"SERVICE\\"
2878
- environment = \\"ENV\\"
2879
- \`\`\`"
3056
+ The \\"experimental_services\\" field is no longer supported. Simply rename the [experimental_services] field to [services]."
2880
3057
  `);
2881
3058
  });
2882
3059
  });
@@ -1,4 +1,5 @@
1
1
  import * as fs from "node:fs";
2
+ import getPort from "get-port";
2
3
  import patchConsole from "patch-console";
3
4
  import dedent from "ts-dedent";
4
5
  import Dev from "../dev/dev";
@@ -224,6 +225,32 @@ describe("wrangler dev", () => {
224
225
  );
225
226
  });
226
227
 
228
+ it("should strip leading `*` from given host when deducing a zone id", async () => {
229
+ writeWranglerToml({
230
+ main: "index.js",
231
+ route: "*some-host.com/some/path/*",
232
+ });
233
+ fs.writeFileSync("index.js", `export default {};`);
234
+ mockGetZones("some-host.com", [{ id: "some-zone-id" }]);
235
+ await runWrangler("dev");
236
+ expect((Dev as jest.Mock).mock.calls[0][0].zone.host).toEqual(
237
+ "some-host.com"
238
+ );
239
+ });
240
+
241
+ it("should strip leading `*.` from given host when deducing a zone id", async () => {
242
+ writeWranglerToml({
243
+ main: "index.js",
244
+ route: "*.some-host.com/some/path/*",
245
+ });
246
+ fs.writeFileSync("index.js", `export default {};`);
247
+ mockGetZones("some-host.com", [{ id: "some-zone-id" }]);
248
+ await runWrangler("dev");
249
+ expect((Dev as jest.Mock).mock.calls[0][0].zone.host).toEqual(
250
+ "some-host.com"
251
+ );
252
+ });
253
+
227
254
  it("should, when provided, use a configured zone_id", async () => {
228
255
  writeWranglerToml({
229
256
  main: "index.js",
@@ -432,18 +459,20 @@ describe("wrangler dev", () => {
432
459
  },
433
460
  });
434
461
 
435
- await expect(
436
- runWrangler("dev")
437
- ).rejects.toThrowErrorMatchingInlineSnapshot(
438
- `"Could not resolve \\"index.js\\" after running custom build: node -e \\"console.log('custom build');\\""`
439
- );
462
+ await expect(runWrangler("dev")).rejects
463
+ .toThrowErrorMatchingInlineSnapshot(`
464
+ "The expected output file at \\"index.js\\" was not found after running custom build: node -e \\"console.log('custom build');\\".
465
+ The \`main\` property in wrangler.toml should point to the file generated by the custom build."
466
+ `);
440
467
  expect(std.out).toMatchInlineSnapshot(`
441
468
  "Running custom build: node -e \\"console.log('custom build');\\"
442
469
 
443
470
  If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new."
444
471
  `);
445
472
  expect(std.err).toMatchInlineSnapshot(`
446
- "X [ERROR] Could not resolve \\"index.js\\" after running custom build: node -e \\"console.log('custom build');\\"
473
+ "X [ERROR] The expected output file at \\"index.js\\" was not found after running custom build: node -e \\"console.log('custom build');\\".
474
+
475
+ The \`main\` property in wrangler.toml should point to the file generated by the custom build.
447
476
 
448
477
  "
449
478
  `);
@@ -580,6 +609,71 @@ describe("wrangler dev", () => {
580
609
  });
581
610
  });
582
611
 
612
+ describe("port", () => {
613
+ it("should default port to 8787 if it is not in use", async () => {
614
+ writeWranglerToml({
615
+ main: "index.js",
616
+ });
617
+ fs.writeFileSync("index.js", `export default {};`);
618
+ await runWrangler("dev");
619
+ expect((Dev as jest.Mock).mock.calls[0][0].port).toEqual(8787);
620
+ expect(std.out).toMatchInlineSnapshot(`""`);
621
+ expect(std.warn).toMatchInlineSnapshot(`""`);
622
+ expect(std.err).toMatchInlineSnapshot(`""`);
623
+ });
624
+
625
+ it("should use to `port` from `wrangler.toml`, if available", async () => {
626
+ writeWranglerToml({
627
+ main: "index.js",
628
+ dev: {
629
+ port: 8888,
630
+ },
631
+ });
632
+ fs.writeFileSync("index.js", `export default {};`);
633
+ // Mock `getPort()` to resolve to a completely different port.
634
+ (getPort as jest.Mock).mockResolvedValue(98765);
635
+
636
+ await runWrangler("dev");
637
+ expect((Dev as jest.Mock).mock.calls[0][0].port).toEqual(8888);
638
+ expect(std.out).toMatchInlineSnapshot(`""`);
639
+ expect(std.warn).toMatchInlineSnapshot(`""`);
640
+ expect(std.err).toMatchInlineSnapshot(`""`);
641
+ });
642
+
643
+ it("should use --port command line arg, if provided", async () => {
644
+ writeWranglerToml({
645
+ main: "index.js",
646
+ dev: {
647
+ port: 8888,
648
+ },
649
+ });
650
+ fs.writeFileSync("index.js", `export default {};`);
651
+ // Mock `getPort()` to resolve to a completely different port.
652
+ (getPort as jest.Mock).mockResolvedValue(98765);
653
+
654
+ await runWrangler("dev --port=9999");
655
+ expect((Dev as jest.Mock).mock.calls[0][0].port).toEqual(9999);
656
+ expect(std.out).toMatchInlineSnapshot(`""`);
657
+ expect(std.warn).toMatchInlineSnapshot(`""`);
658
+ expect(std.err).toMatchInlineSnapshot(`""`);
659
+ });
660
+
661
+ it("should use a different port to the default if it is in use", async () => {
662
+ writeWranglerToml({
663
+ main: "index.js",
664
+ });
665
+ fs.writeFileSync("index.js", `export default {};`);
666
+ // Mock `getPort()` to resolve to a completely different port.
667
+ (getPort as jest.Mock).mockResolvedValue(98765);
668
+
669
+ await runWrangler("dev");
670
+ expect((Dev as jest.Mock).mock.calls[0][0].port).toEqual(98765);
671
+ expect(std.out).toMatchInlineSnapshot(`""`);
672
+ expect(std.warn).toMatchInlineSnapshot(`""`);
673
+ expect(std.err).toMatchInlineSnapshot(`""`);
674
+ });
675
+ });
676
+
583
677
  describe("durable_objects", () => {
584
678
  it("should warn if there is one or more remote Durable Object", async () => {
585
679
  writeWranglerToml({
@@ -680,7 +774,11 @@ describe("wrangler dev", () => {
680
774
  expect(std).toMatchInlineSnapshot(`
681
775
  Object {
682
776
  "debug": "",
683
- "err": "wrangler dev [script]
777
+ "err": "X [ERROR] Not enough arguments following: site
778
+
779
+ ",
780
+ "out": "
781
+ wrangler dev [script]
684
782
 
685
783
  👂 Start a local server for developing your worker
686
784
 
@@ -688,10 +786,9 @@ describe("wrangler dev", () => {
688
786
  script The path to an entry point for your worker [string]
689
787
 
690
788
  Flags:
691
- -c, --config Path to .toml configuration file [string]
692
- -h, --help Show help [boolean]
693
- -v, --version Show version number [boolean]
694
- --legacy-env Use legacy environments [boolean]
789
+ -c, --config Path to .toml configuration file [string]
790
+ -h, --help Show help [boolean]
791
+ -v, --version Show version number [boolean]
695
792
 
696
793
  Options:
697
794
  --name Name of the worker [string]
@@ -718,12 +815,7 @@ describe("wrangler dev", () => {
718
815
  --minify Minify the script [boolean]
719
816
  --node-compat Enable node.js compatibility [boolean]
720
817
  --experimental-enable-local-persistence Enable persistence for this session (only for local mode) [boolean]
721
- --inspect Enable dev tools [deprecated] [boolean]
722
- X [ERROR] Not enough arguments following: site
723
-
724
- ",
725
- "out": "
726
- ",
818
+ --inspect Enable dev tools [deprecated] [boolean]",
727
819
  "warn": "",
728
820
  }
729
821
  `);
@@ -746,6 +838,34 @@ describe("wrangler dev", () => {
746
838
  `);
747
839
  });
748
840
  });
841
+
842
+ describe("service bindings", () => {
843
+ it("should warn when using service bindings", async () => {
844
+ writeWranglerToml({
845
+ services: [
846
+ { binding: "WorkerA", service: "A" },
847
+ { binding: "WorkerB", service: "B", environment: "staging" },
848
+ ],
849
+ });
850
+ fs.writeFileSync("index.js", `export default {};`);
851
+ await runWrangler("dev index.js");
852
+ expect(std).toMatchInlineSnapshot(`
853
+ Object {
854
+ "debug": "",
855
+ "err": "",
856
+ "out": "",
857
+ "warn": "â–² [WARNING] Processing wrangler.toml configuration:
858
+
859
+ - \\"services\\" fields are experimental and may change or break at any time.
860
+
861
+
862
+ â–² [WARNING] This worker is bound to live services: WorkerA (A), WorkerB (B@staging)
863
+
864
+ ",
865
+ }
866
+ `);
867
+ });
868
+ });
749
869
  });
750
870
 
751
871
  function mockGetZones(domain: string, zones: { id: string }[] = []) {