wrangler 2.1.11 → 2.1.12

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.
@@ -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.12",
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
+ });
@@ -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 {};`);
@@ -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,
@@ -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();
@@ -167,12 +167,12 @@ describe("wrangler secret", () => {
167
167
  expect(std.err).toMatchInlineSnapshot(`
168
168
  "X [ERROR] 🚨 Error uploading secret for key: secret-name-1:
169
169
 
170
- Failed to create secret 1
170
+ Failed to create secret 1
171
171
 
172
172
 
173
173
  X [ERROR] 🚨 Error uploading secret for key: secret-name-2:
174
174
 
175
- Failed to create secret 2
175
+ Failed to create secret 2
176
176
 
177
177
  "
178
178
  `);
@@ -226,22 +226,22 @@ describe("wrangler secret", () => {
226
226
  expect(std.err).toMatchInlineSnapshot(`
227
227
  "X [ERROR] 🚨 Error uploading secret for key: secret-name-1:
228
228
 
229
- Failed to create secret 1
229
+ Failed to create secret 1
230
230
 
231
231
 
232
232
  X [ERROR] 🚨 Error uploading secret for key: secret-name-3:
233
233
 
234
- Failed to create secret 3
234
+ Failed to create secret 3
235
235
 
236
236
 
237
237
  X [ERROR] 🚨 Error uploading secret for key: secret-name-5:
238
238
 
239
- Failed to create secret 5
239
+ Failed to create secret 5
240
240
 
241
241
 
242
242
  X [ERROR] 🚨 Error uploading secret for key: secret-name-7:
243
243
 
244
- Failed to create secret 7
244
+ Failed to create secret 7
245
245
 
246
246
  "
247
247
  `);
@@ -13,7 +13,7 @@ import type {
13
13
  RequestEvent,
14
14
  ScheduledEvent,
15
15
  AlarmEvent,
16
- } from "../tail";
16
+ } from "../tail/createTail";
17
17
  import type { RequestInit } from "undici";
18
18
  import type WebSocket from "ws";
19
19
 
@@ -0,0 +1,47 @@
1
+ import { collectKeyValues } from "../utils/collectKeyValues";
2
+
3
+ describe("collectKeyValues()", () => {
4
+ it("should return an empty object when passed undefined", () => {
5
+ expect(collectKeyValues(undefined)).toEqual({});
6
+ });
7
+
8
+ it("should return an empty object when passed an empty array", () => {
9
+ expect(collectKeyValues([])).toEqual({});
10
+ });
11
+
12
+ it("should parse a key:value string with no value by returning an empty string for the value", () => {
13
+ expect(collectKeyValues(["some-string-with-no-colon"])).toEqual({
14
+ "some-string-with-no-colon": "",
15
+ });
16
+ });
17
+
18
+ it("should return an object with a single key/value pair when passed an array with a single string", () => {
19
+ expect(collectKeyValues(["some-key:some-value"])).toEqual({
20
+ "some-key": "some-value",
21
+ });
22
+ });
23
+
24
+ it("should return an object with multiple key/value pairs when passed an array with multiple strings", () => {
25
+ expect(
26
+ collectKeyValues([
27
+ "some-key:some-value",
28
+ "some-other-key:some-other-value",
29
+ ])
30
+ ).toEqual({
31
+ "some-key": "some-value",
32
+ "some-other-key": "some-other-value",
33
+ });
34
+ });
35
+
36
+ it("should return an object with multiple key/value pairs when passed an array with multiple strings with multiple colons", () => {
37
+ expect(
38
+ collectKeyValues([
39
+ "some-key:https://some-value.com",
40
+ "some-other-key:https://some-other-value.com",
41
+ ])
42
+ ).toEqual({
43
+ "some-key": "https://some-value.com",
44
+ "some-other-key": "https://some-other-value.com",
45
+ });
46
+ });
47
+ });
package/src/d1/index.ts CHANGED
@@ -6,7 +6,7 @@ import * as List from "./list";
6
6
  import { d1BetaWarning } from "./utils";
7
7
  import type { Argv } from "yargs";
8
8
 
9
- export const d1api = (yargs: Argv) => {
9
+ export const d1 = (yargs: Argv) => {
10
10
  return (
11
11
  yargs
12
12
  .command("list", "List D1 databases", List.Options, List.Handler)