wrangler 0.0.0-e1c615f → 0.0.0-e3cab74

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 (85) hide show
  1. package/bin/wrangler.js +2 -2
  2. package/package.json +28 -13
  3. package/pages/functions/buildWorker.ts +6 -1
  4. package/pages/functions/filepath-routing.test.ts +112 -28
  5. package/pages/functions/filepath-routing.ts +88 -131
  6. package/pages/functions/routes.ts +11 -18
  7. package/pages/functions/template-worker.ts +21 -28
  8. package/src/__tests__/configuration.test.ts +2185 -0
  9. package/src/__tests__/dev.test.tsx +56 -9
  10. package/src/__tests__/guess-worker-format.test.ts +66 -0
  11. package/src/__tests__/{clipboardy-mock.js → helpers/clipboardy-mock.js} +0 -0
  12. package/src/__tests__/helpers/cmd-shim.d.ts +11 -0
  13. package/src/__tests__/helpers/faye-websocket.d.ts +6 -0
  14. package/src/__tests__/helpers/mock-account-id.ts +30 -0
  15. package/src/__tests__/helpers/mock-bin.ts +36 -0
  16. package/src/__tests__/{mock-cfetch.ts → helpers/mock-cfetch.ts} +53 -17
  17. package/src/__tests__/helpers/mock-console.ts +62 -0
  18. package/src/__tests__/{mock-dialogs.ts → helpers/mock-dialogs.ts} +1 -1
  19. package/src/__tests__/helpers/mock-kv.ts +40 -0
  20. package/src/__tests__/helpers/mock-user.ts +27 -0
  21. package/src/__tests__/helpers/mock-web-socket.ts +29 -0
  22. package/src/__tests__/helpers/run-in-tmp.ts +29 -0
  23. package/src/__tests__/helpers/run-wrangler.ts +16 -0
  24. package/src/__tests__/helpers/write-wrangler-toml.ts +17 -0
  25. package/src/__tests__/index.test.ts +655 -76
  26. package/src/__tests__/jest.setup.ts +37 -2
  27. package/src/__tests__/kv.test.ts +441 -398
  28. package/src/__tests__/logout.test.ts +50 -0
  29. package/src/__tests__/package-manager.test.ts +206 -0
  30. package/src/__tests__/parse.test.ts +322 -0
  31. package/src/__tests__/publish.test.ts +2406 -0
  32. package/src/__tests__/r2.test.ts +198 -0
  33. package/src/__tests__/secret.test.ts +326 -0
  34. package/src/__tests__/sentry.test.ts +146 -0
  35. package/src/__tests__/tail.test.ts +564 -0
  36. package/src/__tests__/whoami.test.tsx +86 -0
  37. package/src/api/form_data.ts +112 -26
  38. package/src/api/preview.ts +34 -15
  39. package/src/api/worker.ts +58 -27
  40. package/src/bundle.ts +133 -0
  41. package/src/cfetch/index.ts +21 -19
  42. package/src/cfetch/internal.ts +85 -21
  43. package/src/cli.ts +10 -0
  44. package/src/config/README.md +107 -0
  45. package/src/config/config.ts +265 -0
  46. package/src/config/diagnostics.ts +80 -0
  47. package/src/config/environment.ts +305 -0
  48. package/src/config/index.ts +52 -0
  49. package/src/config/validation-helpers.ts +370 -0
  50. package/src/config/validation.ts +1017 -0
  51. package/src/dev.tsx +455 -368
  52. package/src/dialogs.tsx +2 -2
  53. package/src/entry.ts +57 -0
  54. package/src/environment-variables.ts +33 -0
  55. package/src/guess-worker-format.ts +68 -0
  56. package/src/index.tsx +1044 -646
  57. package/src/inspect.ts +609 -0
  58. package/src/kv.tsx +47 -39
  59. package/src/module-collection.ts +142 -36
  60. package/src/open-in-browser.ts +13 -0
  61. package/src/package-manager.ts +126 -0
  62. package/src/pages.tsx +139 -62
  63. package/src/parse.ts +183 -0
  64. package/src/paths.ts +26 -0
  65. package/src/proxy.ts +350 -77
  66. package/src/publish.ts +307 -289
  67. package/src/r2.ts +50 -0
  68. package/src/reporting.ts +115 -0
  69. package/src/sites.tsx +183 -56
  70. package/src/tail/filters.ts +279 -0
  71. package/src/tail/index.ts +299 -0
  72. package/src/tail/printing.ts +62 -0
  73. package/src/user.tsx +137 -110
  74. package/src/whoami.tsx +69 -0
  75. package/templates/new-worker.js +15 -0
  76. package/templates/new-worker.ts +15 -0
  77. package/{static-asset-facade.js → templates/static-asset-facade.js} +0 -0
  78. package/templates/tsconfig.json +105 -0
  79. package/wrangler-dist/cli.js +127861 -111486
  80. package/wrangler-dist/cli.js.map +3 -3
  81. package/src/__tests__/run-in-tmp.ts +0 -19
  82. package/src/__tests__/run-wrangler.ts +0 -32
  83. package/src/api/inspect.ts +0 -430
  84. package/src/config.ts +0 -131
  85. package/src/tail.tsx +0 -73
@@ -1,15 +1,22 @@
1
- import { writeFileSync } from "fs";
1
+ import { writeFileSync } from "node:fs";
2
+ import { mockAccountId, mockApiToken } from "./helpers/mock-account-id";
2
3
  import {
3
4
  setMockResponse,
4
- setMockRawResponse,
5
5
  unsetAllMocks,
6
- createFetchResult,
7
- } from "./mock-cfetch";
8
- import { runWrangler } from "./run-wrangler";
9
- import { runInTempDir } from "./run-in-tmp";
6
+ unsetMockFetchKVGetValues,
7
+ setMockFetchKVGetValue,
8
+ } from "./helpers/mock-cfetch";
9
+ import { mockConsoleMethods } from "./helpers/mock-console";
10
+ import { mockKeyListRequest } from "./helpers/mock-kv";
11
+ import { runInTempDir } from "./helpers/run-in-tmp";
12
+ import { runWrangler } from "./helpers/run-wrangler";
13
+ import type { KVNamespaceInfo, NamespaceKeyInfo } from "../kv";
10
14
 
11
15
  describe("wrangler", () => {
16
+ mockAccountId();
17
+ mockApiToken();
12
18
  runInTempDir();
19
+ const std = mockConsoleMethods();
13
20
 
14
21
  afterEach(() => {
15
22
  unsetAllMocks();
@@ -31,11 +38,13 @@ describe("wrangler", () => {
31
38
  }
32
39
 
33
40
  it("should error if no namespace is given", async () => {
34
- const { error, stdout, stderr } = await runWrangler(
35
- "kv:namespace create"
41
+ await expect(
42
+ runWrangler("kv:namespace create")
43
+ ).rejects.toThrowErrorMatchingInlineSnapshot(
44
+ `"Not enough non-option arguments: got 0, need at least 1"`
36
45
  );
37
- expect(stdout).toMatchInlineSnapshot(`""`);
38
- expect(stderr).toMatchInlineSnapshot(`
46
+ expect(std.out).toMatchInlineSnapshot(`""`);
47
+ expect(std.err).toMatchInlineSnapshot(`
39
48
  "wrangler kv:namespace create <namespace>
40
49
 
41
50
  Create a new namespace
@@ -44,28 +53,27 @@ describe("wrangler", () => {
44
53
  namespace The name of the new namespace [string] [required]
45
54
 
46
55
  Flags:
47
- -c, --config Path to .toml configuration file [string]
48
- -h, --help Show help [boolean]
49
- -v, --version Show version number [boolean]
56
+ -c, --config Path to .toml configuration file [string]
57
+ -h, --help Show help [boolean]
58
+ -v, --version Show version number [boolean]
59
+ --legacy-env Use legacy environments [boolean]
50
60
 
51
61
  Options:
52
- -l, --local Run on my machine [boolean] [default: false]
53
62
  --env Perform on a specific environment [string]
54
63
  --preview Interact with a preview namespace [boolean]
55
64
 
56
65
  Not enough non-option arguments: got 0, need at least 1"
57
66
  `);
58
- expect(error).toMatchInlineSnapshot(
59
- `[Error: Not enough non-option arguments: got 0, need at least 1]`
60
- );
61
67
  });
62
68
 
63
69
  it("should error if the namespace to create contains spaces", async () => {
64
- const { error, stdout, stderr } = await runWrangler(
65
- "kv:namespace create abc def ghi"
70
+ await expect(
71
+ runWrangler("kv:namespace create abc def ghi")
72
+ ).rejects.toThrowErrorMatchingInlineSnapshot(
73
+ `"Unexpected additional positional arguments \\"def ghi\\"."`
66
74
  );
67
- expect(stdout).toMatchInlineSnapshot(`""`);
68
- expect(stderr).toMatchInlineSnapshot(`
75
+ expect(std.out).toMatchInlineSnapshot(`""`);
76
+ expect(std.err).toMatchInlineSnapshot(`
69
77
  "wrangler kv:namespace create <namespace>
70
78
 
71
79
  Create a new namespace
@@ -74,28 +82,28 @@ describe("wrangler", () => {
74
82
  namespace The name of the new namespace [string] [required]
75
83
 
76
84
  Flags:
77
- -c, --config Path to .toml configuration file [string]
78
- -h, --help Show help [boolean]
79
- -v, --version Show version number [boolean]
85
+ -c, --config Path to .toml configuration file [string]
86
+ -h, --help Show help [boolean]
87
+ -v, --version Show version number [boolean]
88
+ --legacy-env Use legacy environments [boolean]
80
89
 
81
90
  Options:
82
- -l, --local Run on my machine [boolean] [default: false]
83
91
  --env Perform on a specific environment [string]
84
92
  --preview Interact with a preview namespace [boolean]
85
93
 
86
94
  Unexpected additional positional arguments \\"def ghi\\"."
87
95
  `);
88
- expect(error).toMatchInlineSnapshot(
89
- `[Error: Unexpected additional positional arguments "def ghi".]`
90
- );
91
96
  });
92
97
 
93
98
  it("should error if the namespace to create is not valid", async () => {
94
- const { error, stdout, stderr } = await runWrangler(
95
- "kv:namespace create abc-def"
99
+ await expect(
100
+ runWrangler("kv:namespace create abc-def")
101
+ ).rejects.toThrowErrorMatchingInlineSnapshot(
102
+ `"The namespace binding name \\"abc-def\\" is invalid. It can only have alphanumeric and _ characters, and cannot begin with a number."`
96
103
  );
97
- expect(stdout).toMatchInlineSnapshot(`""`);
98
- expect(stderr).toMatchInlineSnapshot(`
104
+
105
+ expect(std.out).toMatchInlineSnapshot(`""`);
106
+ expect(std.err).toMatchInlineSnapshot(`
99
107
  "wrangler kv:namespace create <namespace>
100
108
 
101
109
  Create a new namespace
@@ -104,28 +112,23 @@ describe("wrangler", () => {
104
112
  namespace The name of the new namespace [string] [required]
105
113
 
106
114
  Flags:
107
- -c, --config Path to .toml configuration file [string]
108
- -h, --help Show help [boolean]
109
- -v, --version Show version number [boolean]
115
+ -c, --config Path to .toml configuration file [string]
116
+ -h, --help Show help [boolean]
117
+ -v, --version Show version number [boolean]
118
+ --legacy-env Use legacy environments [boolean]
110
119
 
111
120
  Options:
112
- -l, --local Run on my machine [boolean] [default: false]
113
121
  --env Perform on a specific environment [string]
114
122
  --preview Interact with a preview namespace [boolean]
115
123
 
116
124
  The namespace binding name \\"abc-def\\" is invalid. It can only have alphanumeric and _ characters, and cannot begin with a number."
117
125
  `);
118
- expect(error).toMatchInlineSnapshot(
119
- `[Error: The namespace binding name "abc-def" is invalid. It can only have alphanumeric and _ characters, and cannot begin with a number.]`
120
- );
121
126
  });
122
127
 
123
128
  it("should create a namespace", async () => {
124
129
  mockCreateRequest("worker-UnitTestNamespace");
125
- const { stdout } = await runWrangler(
126
- "kv:namespace create UnitTestNamespace"
127
- );
128
- expect(stdout).toMatchInlineSnapshot(`
130
+ await runWrangler("kv:namespace create UnitTestNamespace");
131
+ expect(std.out).toMatchInlineSnapshot(`
129
132
  "🌀 Creating namespace with title \\"worker-UnitTestNamespace\\"
130
133
  ✨ Success!
131
134
  Add the following to your configuration file in your kv_namespaces array:
@@ -135,10 +138,8 @@ describe("wrangler", () => {
135
138
 
136
139
  it("should create a preview namespace if configured to do so", async () => {
137
140
  mockCreateRequest("worker-UnitTestNamespace_preview");
138
- const { stdout } = await runWrangler(
139
- "kv:namespace create UnitTestNamespace --preview"
140
- );
141
- expect(stdout).toMatchInlineSnapshot(`
141
+ await runWrangler("kv:namespace create UnitTestNamespace --preview");
142
+ expect(std.out).toMatchInlineSnapshot(`
142
143
  "🌀 Creating namespace with title \\"worker-UnitTestNamespace_preview\\"
143
144
  ✨ Success!
144
145
  Add the following to your configuration file in your kv_namespaces array:
@@ -149,10 +150,8 @@ describe("wrangler", () => {
149
150
  it("should create a namespace using configured worker name", async () => {
150
151
  writeFileSync("./wrangler.toml", 'name = "otherWorker"', "utf-8");
151
152
  mockCreateRequest("otherWorker-UnitTestNamespace");
152
- const { stdout } = await runWrangler(
153
- "kv:namespace create UnitTestNamespace"
154
- );
155
- expect(stdout).toMatchInlineSnapshot(`
153
+ await runWrangler("kv:namespace create UnitTestNamespace");
154
+ expect(std.out).toMatchInlineSnapshot(`
156
155
  "🌀 Creating namespace with title \\"otherWorker-UnitTestNamespace\\"
157
156
  ✨ Success!
158
157
  Add the following to your configuration file in your kv_namespaces array:
@@ -162,10 +161,10 @@ describe("wrangler", () => {
162
161
 
163
162
  it("should create a namespace in an environment if configured to do so", async () => {
164
163
  mockCreateRequest("worker-customEnv-UnitTestNamespace");
165
- const { stdout } = await runWrangler(
164
+ await runWrangler(
166
165
  "kv:namespace create UnitTestNamespace --env customEnv"
167
166
  );
168
- expect(stdout).toMatchInlineSnapshot(`
167
+ expect(std.out).toMatchInlineSnapshot(`
169
168
  "🌀 Creating namespace with title \\"worker-customEnv-UnitTestNamespace\\"
170
169
  ✨ Success!
171
170
  Add the following to your configuration file in your kv_namespaces array under [env.customEnv]:
@@ -196,30 +195,28 @@ describe("wrangler", () => {
196
195
  }
197
196
 
198
197
  it("should list namespaces", async () => {
199
- const KVNamespaces = [
198
+ const kvNamespaces: KVNamespaceInfo[] = [
200
199
  { title: "title-1", id: "id-1" },
201
200
  { title: "title-2", id: "id-2" },
202
201
  ];
203
- mockListRequest(KVNamespaces);
204
- const { error, stdout, stderr } = await runWrangler(
205
- "kv:namespace list"
206
- );
207
- expect(error).toMatchInlineSnapshot(`undefined`);
208
- expect(stderr).toMatchInlineSnapshot(`""`);
209
- const namespaces = JSON.parse(stdout);
210
- expect(namespaces).toEqual(KVNamespaces);
202
+ mockListRequest(kvNamespaces);
203
+ await runWrangler("kv:namespace list");
204
+
205
+ expect(std.err).toMatchInlineSnapshot(`""`);
206
+ const namespaces = JSON.parse(std.out);
207
+ expect(namespaces).toEqual(kvNamespaces);
211
208
  });
212
209
 
213
210
  it("should make multiple requests for paginated results", async () => {
214
211
  // Create a lot of mock namespaces, so that the fetch requests will be paginated
215
- const KVNamespaces = [];
212
+ const kvNamespaces: KVNamespaceInfo[] = [];
216
213
  for (let i = 0; i < 550; i++) {
217
- KVNamespaces.push({ title: "title-" + i, id: "id-" + i });
214
+ kvNamespaces.push({ title: "title-" + i, id: "id-" + i });
218
215
  }
219
- const requests = mockListRequest(KVNamespaces);
220
- const { stdout } = await runWrangler("kv:namespace list");
221
- const namespaces = JSON.parse(stdout);
222
- expect(namespaces).toEqual(KVNamespaces);
216
+ const requests = mockListRequest(kvNamespaces);
217
+ await runWrangler("kv:namespace list");
218
+ const namespaces = JSON.parse(std.out);
219
+ expect(namespaces).toEqual(kvNamespaces);
223
220
  expect(requests.count).toEqual(6);
224
221
  });
225
222
  });
@@ -268,21 +265,23 @@ describe("wrangler", () => {
268
265
 
269
266
  it("should error if a given binding name is not in the configured kv namespaces", async () => {
270
267
  writeWranglerConfig();
271
- const { stderr } = await runWrangler(
272
- `kv:namespace delete --binding otherBinding`
273
- );
274
- expect(stderr).toMatchInlineSnapshot(`
268
+ await expect(runWrangler("kv:namespace delete --binding otherBinding"))
269
+ .rejects.toThrowErrorMatchingInlineSnapshot(`
270
+ "Not able to delete namespace.
271
+ A namespace with binding name \\"otherBinding\\" was not found in the configured \\"kv_namespaces\\"."
272
+ `);
273
+ expect(std.err).toMatchInlineSnapshot(`
275
274
  "wrangler kv:namespace delete
276
275
 
277
276
  Deletes a given namespace.
278
277
 
279
278
  Flags:
280
- -c, --config Path to .toml configuration file [string]
281
- -h, --help Show help [boolean]
282
- -v, --version Show version number [boolean]
279
+ -c, --config Path to .toml configuration file [string]
280
+ -h, --help Show help [boolean]
281
+ -v, --version Show version number [boolean]
282
+ --legacy-env Use legacy environments [boolean]
283
283
 
284
284
  Options:
285
- -l, --local Run on my machine [boolean] [default: false]
286
285
  --binding The name of the namespace to delete [string]
287
286
  --namespace-id The id of the namespace to delete [string]
288
287
  --env Perform on a specific environment [string]
@@ -296,12 +295,12 @@ describe("wrangler", () => {
296
295
  it("should delete a namespace specified by binding name in a given environment", async () => {
297
296
  writeWranglerConfig();
298
297
  const requests = mockDeleteRequest("env-bound-id");
299
- const { stdout, stderr, error } = await runWrangler(
300
- `kv:namespace delete --binding someBinding --env some-environment --preview false`
298
+ await runWrangler(
299
+ "kv:namespace delete --binding someBinding --env some-environment --preview false"
301
300
  );
302
- expect(stdout).toMatchInlineSnapshot(`""`);
303
- expect(stderr).toMatchInlineSnapshot(`""`);
304
- expect(error).toMatchInlineSnapshot(`undefined`);
301
+
302
+ expect(std.out).toMatchInlineSnapshot(`""`);
303
+ expect(std.err).toMatchInlineSnapshot(`""`);
305
304
  expect(requests.count).toEqual(1);
306
305
  });
307
306
 
@@ -335,8 +334,16 @@ describe("wrangler", () => {
335
334
  expect(namespaceId).toEqual(expectedNamespaceId);
336
335
  expect(key).toEqual(expectedKey);
337
336
  expect(body).toEqual(expectedValue);
338
- expect(query.get("expiration")).toEqual(`${expiration}`);
339
- expect(query.get("expiration_ttl")).toEqual(`${expirationTtl}`);
337
+ if (expiration !== undefined) {
338
+ expect(query.get("expiration")).toEqual(`${expiration}`);
339
+ } else {
340
+ expect(query.has("expiration")).toBe(false);
341
+ }
342
+ if (expirationTtl) {
343
+ expect(query.get("expiration_ttl")).toEqual(`${expirationTtl}`);
344
+ } else {
345
+ expect(query.has("expiration_ttl")).toBe(false);
346
+ }
340
347
  return null;
341
348
  }
342
349
  );
@@ -349,28 +356,29 @@ describe("wrangler", () => {
349
356
  "my-key",
350
357
  "my-value"
351
358
  );
352
- const { error, stderr, stdout } = await runWrangler(
359
+
360
+ await runWrangler(
353
361
  "kv:key put my-key my-value --namespace-id some-namespace-id"
354
362
  );
363
+
355
364
  expect(requests.count).toEqual(1);
356
- expect(stdout).toMatchInlineSnapshot(
365
+ expect(std.out).toMatchInlineSnapshot(
357
366
  `"writing the value \\"my-value\\" to key \\"my-key\\" on namespace some-namespace-id"`
358
367
  );
359
- expect(stderr).toMatchInlineSnapshot(`""`);
360
- expect(error).toMatchInlineSnapshot(`undefined`);
368
+ expect(std.err).toMatchInlineSnapshot(`""`);
361
369
  });
362
370
 
363
371
  it("should put a key in a given namespace specified by binding", async () => {
364
372
  writeWranglerConfig();
365
373
  const requests = mockKeyPutRequest("bound-id", "my-key", "my-value");
366
- const { error, stderr, stdout } = await runWrangler(
374
+ await runWrangler(
367
375
  "kv:key put my-key my-value --binding someBinding --preview false"
368
376
  );
369
- expect(stdout).toMatchInlineSnapshot(
377
+
378
+ expect(std.out).toMatchInlineSnapshot(
370
379
  `"writing the value \\"my-value\\" to key \\"my-key\\" on namespace bound-id"`
371
380
  );
372
- expect(stderr).toMatchInlineSnapshot(`""`);
373
- expect(error).toMatchInlineSnapshot(`undefined`);
381
+ expect(std.err).toMatchInlineSnapshot(`""`);
374
382
  expect(requests.count).toEqual(1);
375
383
  });
376
384
 
@@ -381,14 +389,15 @@ describe("wrangler", () => {
381
389
  "my-key",
382
390
  "my-value"
383
391
  );
384
- const { error, stderr, stdout } = await runWrangler(
392
+
393
+ await runWrangler(
385
394
  "kv:key put my-key my-value --binding someBinding --preview"
386
395
  );
387
- expect(stdout).toMatchInlineSnapshot(
396
+
397
+ expect(std.out).toMatchInlineSnapshot(
388
398
  `"writing the value \\"my-value\\" to key \\"my-key\\" on namespace preview-bound-id"`
389
399
  );
390
- expect(stderr).toMatchInlineSnapshot(`""`);
391
- expect(error).toMatchInlineSnapshot(`undefined`);
400
+ expect(std.err).toMatchInlineSnapshot(`""`);
392
401
  expect(requests.count).toEqual(1);
393
402
  });
394
403
 
@@ -400,15 +409,14 @@ describe("wrangler", () => {
400
409
  10,
401
410
  20
402
411
  );
403
- const { error, stderr, stdout } = await runWrangler(
412
+ await runWrangler(
404
413
  "kv:key put my-key my-value --namespace-id some-namespace-id --expiration 10 --ttl 20"
405
414
  );
406
415
  expect(requests.count).toEqual(1);
407
- expect(stdout).toMatchInlineSnapshot(
416
+ expect(std.out).toMatchInlineSnapshot(
408
417
  `"writing the value \\"my-value\\" to key \\"my-key\\" on namespace some-namespace-id"`
409
418
  );
410
- expect(stderr).toMatchInlineSnapshot(`""`);
411
- expect(error).toMatchInlineSnapshot(`undefined`);
419
+ expect(std.err).toMatchInlineSnapshot(`""`);
412
420
  });
413
421
 
414
422
  it("should put a key to the specified environment in a given namespace", async () => {
@@ -418,14 +426,13 @@ describe("wrangler", () => {
418
426
  "my-key",
419
427
  "my-value"
420
428
  );
421
- const { error, stderr, stdout } = await runWrangler(
429
+ await runWrangler(
422
430
  "kv:key put my-key my-value --binding someBinding --env some-environment --preview false"
423
431
  );
424
- expect(stdout).toMatchInlineSnapshot(
432
+ expect(std.out).toMatchInlineSnapshot(
425
433
  `"writing the value \\"my-value\\" to key \\"my-key\\" on namespace env-bound-id"`
426
434
  );
427
- expect(stderr).toMatchInlineSnapshot(`""`);
428
- expect(error).toMatchInlineSnapshot(`undefined`);
435
+ expect(std.err).toMatchInlineSnapshot(`""`);
429
436
  expect(requests.count).toEqual(1);
430
437
  });
431
438
 
@@ -436,212 +443,211 @@ describe("wrangler", () => {
436
443
  "my-key",
437
444
  "file-contents"
438
445
  );
439
- const { error, stderr, stdout } = await runWrangler(
446
+ await runWrangler(
440
447
  "kv:key put my-key --namespace-id some-namespace-id --path foo.txt"
441
448
  );
442
- expect(stdout).toMatchInlineSnapshot(
449
+ expect(std.out).toMatchInlineSnapshot(
443
450
  `"writing the contents of foo.txt to the key \\"my-key\\" on namespace some-namespace-id"`
444
451
  );
445
- expect(stderr).toMatchInlineSnapshot(`""`);
446
- expect(error).toMatchInlineSnapshot(`undefined`);
452
+ expect(std.err).toMatchInlineSnapshot(`""`);
447
453
  expect(requests.count).toEqual(1);
448
454
  });
449
455
 
450
456
  it("should error if no key is provided", async () => {
451
- const { error, stdout, stderr } = await runWrangler("kv:key put");
457
+ await expect(
458
+ runWrangler("kv:key put")
459
+ ).rejects.toThrowErrorMatchingInlineSnapshot(
460
+ `"Not enough non-option arguments: got 0, need at least 1"`
461
+ );
452
462
 
453
- expect(stdout).toMatchInlineSnapshot(`""`);
454
- expect(stderr).toMatchInlineSnapshot(`
463
+ expect(std.out).toMatchInlineSnapshot(`""`);
464
+ expect(std.err).toMatchInlineSnapshot(`
455
465
  "wrangler kv:key put <key> [value]
456
466
 
457
467
  Writes a single key/value pair to the given namespace.
458
468
 
459
469
  Positionals:
460
- key The key to write to. [string] [required]
461
- value The value to write. [string]
470
+ key The key to write to [string] [required]
471
+ value The value to write [string]
462
472
 
463
473
  Flags:
464
- -c, --config Path to .toml configuration file [string]
465
- -h, --help Show help [boolean]
466
- -v, --version Show version number [boolean]
474
+ -c, --config Path to .toml configuration file [string]
475
+ -h, --help Show help [boolean]
476
+ -v, --version Show version number [boolean]
477
+ --legacy-env Use legacy environments [boolean]
467
478
 
468
479
  Options:
469
- -l, --local Run on my machine [boolean] [default: false]
470
- --binding The binding of the namespace to write to. [string]
471
- --namespace-id The id of the namespace to write to. [string]
480
+ --binding The binding of the namespace to write to [string]
481
+ --namespace-id The id of the namespace to write to [string]
472
482
  --env Perform on a specific environment [string]
473
483
  --preview Interact with a preview namespace [boolean]
474
- --ttl Time for which the entries should be visible. [number]
484
+ --ttl Time for which the entries should be visible [number]
475
485
  --expiration Time since the UNIX epoch after which the entry expires [number]
476
- --path Read value from the file at a given path. [string]
486
+ --path Read value from the file at a given path [string]
477
487
 
478
488
  Not enough non-option arguments: got 0, need at least 1"
479
489
  `);
480
- expect(error).toMatchInlineSnapshot(
481
- `[Error: Not enough non-option arguments: got 0, need at least 1]`
482
- );
483
490
  });
484
491
 
485
492
  it("should error if no binding nor namespace is provided", async () => {
486
- const { error, stdout, stderr } = await runWrangler(
487
- "kv:key put foo bar"
493
+ await expect(
494
+ runWrangler("kv:key put foo bar")
495
+ ).rejects.toThrowErrorMatchingInlineSnapshot(
496
+ `"Exactly one of the arguments binding and namespace-id is required"`
488
497
  );
489
498
 
490
- expect(stdout).toMatchInlineSnapshot(`""`);
491
- expect(stderr).toMatchInlineSnapshot(`
499
+ expect(std.out).toMatchInlineSnapshot(`""`);
500
+ expect(std.err).toMatchInlineSnapshot(`
492
501
  "wrangler kv:key put <key> [value]
493
502
 
494
503
  Writes a single key/value pair to the given namespace.
495
504
 
496
505
  Positionals:
497
- key The key to write to. [string] [required]
498
- value The value to write. [string]
506
+ key The key to write to [string] [required]
507
+ value The value to write [string]
499
508
 
500
509
  Flags:
501
- -c, --config Path to .toml configuration file [string]
502
- -h, --help Show help [boolean]
503
- -v, --version Show version number [boolean]
510
+ -c, --config Path to .toml configuration file [string]
511
+ -h, --help Show help [boolean]
512
+ -v, --version Show version number [boolean]
513
+ --legacy-env Use legacy environments [boolean]
504
514
 
505
515
  Options:
506
- -l, --local Run on my machine [boolean] [default: false]
507
- --binding The binding of the namespace to write to. [string]
508
- --namespace-id The id of the namespace to write to. [string]
516
+ --binding The binding of the namespace to write to [string]
517
+ --namespace-id The id of the namespace to write to [string]
509
518
  --env Perform on a specific environment [string]
510
519
  --preview Interact with a preview namespace [boolean]
511
- --ttl Time for which the entries should be visible. [number]
520
+ --ttl Time for which the entries should be visible [number]
512
521
  --expiration Time since the UNIX epoch after which the entry expires [number]
513
- --path Read value from the file at a given path. [string]
522
+ --path Read value from the file at a given path [string]
514
523
 
515
524
  Exactly one of the arguments binding and namespace-id is required"
516
525
  `);
517
- expect(error).toMatchInlineSnapshot(
518
- `[Error: Exactly one of the arguments binding and namespace-id is required]`
519
- );
520
526
  });
521
527
 
522
528
  it("should error if both binding and namespace is provided", async () => {
523
- const { error, stdout, stderr } = await runWrangler(
524
- "kv:key put foo bar --binding x --namespace-id y"
529
+ await expect(
530
+ runWrangler("kv:key put foo bar --binding x --namespace-id y")
531
+ ).rejects.toThrowErrorMatchingInlineSnapshot(
532
+ `"Arguments binding and namespace-id are mutually exclusive"`
525
533
  );
526
534
 
527
- expect(stdout).toMatchInlineSnapshot(`""`);
528
- expect(stderr).toMatchInlineSnapshot(`
535
+ expect(std.out).toMatchInlineSnapshot(`""`);
536
+ expect(std.err).toMatchInlineSnapshot(`
529
537
  "wrangler kv:key put <key> [value]
530
538
 
531
539
  Writes a single key/value pair to the given namespace.
532
540
 
533
541
  Positionals:
534
- key The key to write to. [string] [required]
535
- value The value to write. [string]
542
+ key The key to write to [string] [required]
543
+ value The value to write [string]
536
544
 
537
545
  Flags:
538
- -c, --config Path to .toml configuration file [string]
539
- -h, --help Show help [boolean]
540
- -v, --version Show version number [boolean]
546
+ -c, --config Path to .toml configuration file [string]
547
+ -h, --help Show help [boolean]
548
+ -v, --version Show version number [boolean]
549
+ --legacy-env Use legacy environments [boolean]
541
550
 
542
551
  Options:
543
- -l, --local Run on my machine [boolean] [default: false]
544
- --binding The binding of the namespace to write to. [string]
545
- --namespace-id The id of the namespace to write to. [string]
552
+ --binding The binding of the namespace to write to [string]
553
+ --namespace-id The id of the namespace to write to [string]
546
554
  --env Perform on a specific environment [string]
547
555
  --preview Interact with a preview namespace [boolean]
548
- --ttl Time for which the entries should be visible. [number]
556
+ --ttl Time for which the entries should be visible [number]
549
557
  --expiration Time since the UNIX epoch after which the entry expires [number]
550
- --path Read value from the file at a given path. [string]
558
+ --path Read value from the file at a given path [string]
551
559
 
552
560
  Arguments binding and namespace-id are mutually exclusive"
553
561
  `);
554
- expect(error).toMatchInlineSnapshot(
555
- `[Error: Arguments binding and namespace-id are mutually exclusive]`
556
- );
557
562
  });
558
563
 
559
564
  it("should error if no value nor path is provided", async () => {
560
- const { error, stdout, stderr } = await runWrangler(
561
- "kv:key put key --namespace-id 12345"
565
+ await expect(
566
+ runWrangler("kv:key put key --namespace-id 12345")
567
+ ).rejects.toThrowErrorMatchingInlineSnapshot(
568
+ `"Exactly one of the arguments value and path is required"`
562
569
  );
563
570
 
564
- expect(stdout).toMatchInlineSnapshot(`""`);
565
- expect(stderr).toMatchInlineSnapshot(`
571
+ expect(std.out).toMatchInlineSnapshot(`""`);
572
+ expect(std.err).toMatchInlineSnapshot(`
566
573
  "wrangler kv:key put <key> [value]
567
574
 
568
575
  Writes a single key/value pair to the given namespace.
569
576
 
570
577
  Positionals:
571
- key The key to write to. [string] [required]
572
- value The value to write. [string]
578
+ key The key to write to [string] [required]
579
+ value The value to write [string]
573
580
 
574
581
  Flags:
575
- -c, --config Path to .toml configuration file [string]
576
- -h, --help Show help [boolean]
577
- -v, --version Show version number [boolean]
582
+ -c, --config Path to .toml configuration file [string]
583
+ -h, --help Show help [boolean]
584
+ -v, --version Show version number [boolean]
585
+ --legacy-env Use legacy environments [boolean]
578
586
 
579
587
  Options:
580
- -l, --local Run on my machine [boolean] [default: false]
581
- --binding The binding of the namespace to write to. [string]
582
- --namespace-id The id of the namespace to write to. [string]
588
+ --binding The binding of the namespace to write to [string]
589
+ --namespace-id The id of the namespace to write to [string]
583
590
  --env Perform on a specific environment [string]
584
591
  --preview Interact with a preview namespace [boolean]
585
- --ttl Time for which the entries should be visible. [number]
592
+ --ttl Time for which the entries should be visible [number]
586
593
  --expiration Time since the UNIX epoch after which the entry expires [number]
587
- --path Read value from the file at a given path. [string]
594
+ --path Read value from the file at a given path [string]
588
595
 
589
596
  Exactly one of the arguments value and path is required"
590
597
  `);
591
- expect(error).toMatchInlineSnapshot(
592
- `[Error: Exactly one of the arguments value and path is required]`
593
- );
594
598
  });
595
599
 
596
600
  it("should error if both value and path is provided", async () => {
597
- const { error, stdout, stderr } = await runWrangler(
598
- "kv:key put key value --path xyz --namespace-id 12345"
601
+ await expect(
602
+ runWrangler("kv:key put key value --path xyz --namespace-id 12345")
603
+ ).rejects.toThrowErrorMatchingInlineSnapshot(
604
+ `"Arguments value and path are mutually exclusive"`
599
605
  );
600
606
 
601
- expect(stdout).toMatchInlineSnapshot(`""`);
602
- expect(stderr).toMatchInlineSnapshot(`
607
+ expect(std.out).toMatchInlineSnapshot(`""`);
608
+ expect(std.err).toMatchInlineSnapshot(`
603
609
  "wrangler kv:key put <key> [value]
604
610
 
605
611
  Writes a single key/value pair to the given namespace.
606
612
 
607
613
  Positionals:
608
- key The key to write to. [string] [required]
609
- value The value to write. [string]
614
+ key The key to write to [string] [required]
615
+ value The value to write [string]
610
616
 
611
617
  Flags:
612
- -c, --config Path to .toml configuration file [string]
613
- -h, --help Show help [boolean]
614
- -v, --version Show version number [boolean]
618
+ -c, --config Path to .toml configuration file [string]
619
+ -h, --help Show help [boolean]
620
+ -v, --version Show version number [boolean]
621
+ --legacy-env Use legacy environments [boolean]
615
622
 
616
623
  Options:
617
- -l, --local Run on my machine [boolean] [default: false]
618
- --binding The binding of the namespace to write to. [string]
619
- --namespace-id The id of the namespace to write to. [string]
624
+ --binding The binding of the namespace to write to [string]
625
+ --namespace-id The id of the namespace to write to [string]
620
626
  --env Perform on a specific environment [string]
621
627
  --preview Interact with a preview namespace [boolean]
622
- --ttl Time for which the entries should be visible. [number]
628
+ --ttl Time for which the entries should be visible [number]
623
629
  --expiration Time since the UNIX epoch after which the entry expires [number]
624
- --path Read value from the file at a given path. [string]
630
+ --path Read value from the file at a given path [string]
625
631
 
626
632
  Arguments value and path are mutually exclusive"
627
633
  `);
628
- expect(error).toMatchInlineSnapshot(
629
- `[Error: Arguments value and path are mutually exclusive]`
630
- );
631
634
  });
632
635
 
633
636
  it("should error if a given binding name is not in the configured kv namespaces", async () => {
634
637
  writeWranglerConfig();
635
- const { error, stdout, stderr } = await runWrangler(
636
- `kv:key put key value --binding otherBinding`
637
- );
638
- expect(stdout).toMatchInlineSnapshot(`""`);
639
- expect(stderr).toMatchInlineSnapshot(
638
+ await expect(
639
+ runWrangler("kv:key put key value --binding otherBinding")
640
+ ).rejects.toThrowErrorMatchingInlineSnapshot(
640
641
  `"A namespace with binding name \\"otherBinding\\" was not found in the configured \\"kv_namespaces\\"."`
641
642
  );
642
- expect(error).toMatchInlineSnapshot(
643
- `[Error: A namespace with binding name "otherBinding" was not found in the configured "kv_namespaces".]`
644
- );
643
+
644
+ expect(std.out).toMatchInlineSnapshot(`""`);
645
+ expect(std.err).toMatchInlineSnapshot(`
646
+ "A namespace with binding name \\"otherBinding\\" was not found in the configured \\"kv_namespaces\\".
647
+
648
+ %s
649
+ If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new."
650
+ `);
645
651
  });
646
652
 
647
653
  it("should error if a given binding has both preview and non-preview and --preview is not specified", async () => {
@@ -651,64 +657,46 @@ describe("wrangler", () => {
651
657
  "my-key",
652
658
  "my-value"
653
659
  );
654
- const { error, stderr, stdout } = await runWrangler(
655
- "kv:key put my-key my-value --binding someBinding"
656
- );
657
- expect(stdout).toMatchInlineSnapshot(`""`);
658
- expect(stderr).toMatchInlineSnapshot(
660
+ await expect(
661
+ runWrangler("kv:key put my-key my-value --binding someBinding")
662
+ ).rejects.toThrowErrorMatchingInlineSnapshot(
659
663
  `"someBinding has both a namespace ID and a preview ID. Specify \\"--preview\\" or \\"--preview false\\" to avoid writing data to the wrong namespace."`
660
664
  );
661
- expect(error).toMatchInlineSnapshot(
662
- `[Error: someBinding has both a namespace ID and a preview ID. Specify "--preview" or "--preview false" to avoid writing data to the wrong namespace.]`
663
- );
665
+ expect(std.out).toMatchInlineSnapshot(`""`);
666
+ expect(std.err).toMatchInlineSnapshot(`
667
+ "someBinding has both a namespace ID and a preview ID. Specify \\"--preview\\" or \\"--preview false\\" to avoid writing data to the wrong namespace.
668
+
669
+ %s
670
+ If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new."
671
+ `);
664
672
  expect(requests.count).toEqual(0);
665
673
  });
666
674
  });
667
675
 
668
676
  describe("list", () => {
669
- function mockKeyListRequest(
670
- expectedNamespaceId: string,
671
- expectedKeys: string[],
672
- keysPerRequest = 1000
673
- ) {
674
- const requests = { count: 0 };
675
- setMockRawResponse(
676
- "/accounts/:accountId/storage/kv/namespaces/:namespaceId/keys",
677
- ([_url, accountId, namespaceId], _init, query) => {
678
- requests.count++;
679
- expect(accountId).toEqual("some-account-id");
680
- expect(namespaceId).toEqual(expectedNamespaceId);
681
- if (expectedKeys.length <= keysPerRequest) {
682
- return createFetchResult(expectedKeys);
683
- } else {
684
- const start = parseInt(query.get("cursor")) || 0;
685
- const end = start + keysPerRequest;
686
- const cursor = end < expectedKeys.length ? end : undefined;
687
- return createFetchResult(
688
- expectedKeys.slice(start, end),
689
- true,
690
- [],
691
- [],
692
- { cursor }
693
- );
694
- }
695
- }
696
- );
697
- return requests;
698
- }
699
-
700
677
  it("should list the keys of a namespace specified by namespace-id", async () => {
701
678
  const keys = ["key-1", "key-2", "key-3"];
702
679
  mockKeyListRequest("some-namespace-id", keys);
703
- const { error, stdout, stderr } = await runWrangler(
704
- "kv:key list --namespace-id some-namespace-id"
705
- );
706
- expect(error).toMatchInlineSnapshot(`undefined`);
707
- expect(stderr).toMatchInlineSnapshot(`""`);
708
- expect(stdout).toMatchInlineSnapshot(`
709
- "key-1
710
- key-2
711
- key-3"
680
+ await runWrangler("kv:key list --namespace-id some-namespace-id");
681
+ expect(std.err).toMatchInlineSnapshot(`""`);
682
+ expect(std.out).toMatchInlineSnapshot(`
683
+ "[
684
+ {
685
+ \\"name\\": \\"key-1\\",
686
+ \\"expiration\\": 123456789,
687
+ \\"metadata\\": {}
688
+ },
689
+ {
690
+ \\"name\\": \\"key-2\\",
691
+ \\"expiration\\": 123456789,
692
+ \\"metadata\\": {}
693
+ },
694
+ {
695
+ \\"name\\": \\"key-3\\",
696
+ \\"expiration\\": 123456789,
697
+ \\"metadata\\": {}
698
+ }
699
+ ]"
712
700
  `);
713
701
  });
714
702
 
@@ -716,15 +704,27 @@ describe("wrangler", () => {
716
704
  writeWranglerConfig();
717
705
  const keys = ["key-1", "key-2", "key-3"];
718
706
  mockKeyListRequest("bound-id", keys);
719
- const { error, stdout, stderr } = await runWrangler(
720
- "kv:key list --binding someBinding"
721
- );
722
- expect(error).toMatchInlineSnapshot(`undefined`);
723
- expect(stderr).toMatchInlineSnapshot(`""`);
724
- expect(stdout).toMatchInlineSnapshot(`
725
- "key-1
726
- key-2
727
- key-3"
707
+
708
+ await runWrangler("kv:key list --binding someBinding");
709
+ expect(std.err).toMatchInlineSnapshot(`""`);
710
+ expect(std.out).toMatchInlineSnapshot(`
711
+ "[
712
+ {
713
+ \\"name\\": \\"key-1\\",
714
+ \\"expiration\\": 123456789,
715
+ \\"metadata\\": {}
716
+ },
717
+ {
718
+ \\"name\\": \\"key-2\\",
719
+ \\"expiration\\": 123456789,
720
+ \\"metadata\\": {}
721
+ },
722
+ {
723
+ \\"name\\": \\"key-3\\",
724
+ \\"expiration\\": 123456789,
725
+ \\"metadata\\": {}
726
+ }
727
+ ]"
728
728
  `);
729
729
  });
730
730
 
@@ -732,15 +732,26 @@ describe("wrangler", () => {
732
732
  writeWranglerConfig();
733
733
  const keys = ["key-1", "key-2", "key-3"];
734
734
  mockKeyListRequest("preview-bound-id", keys);
735
- const { error, stdout, stderr } = await runWrangler(
736
- "kv:key list --binding someBinding --preview"
737
- );
738
- expect(error).toMatchInlineSnapshot(`undefined`);
739
- expect(stderr).toMatchInlineSnapshot(`""`);
740
- expect(stdout).toMatchInlineSnapshot(`
741
- "key-1
742
- key-2
743
- key-3"
735
+ await runWrangler("kv:key list --binding someBinding --preview");
736
+ expect(std.err).toMatchInlineSnapshot(`""`);
737
+ expect(std.out).toMatchInlineSnapshot(`
738
+ "[
739
+ {
740
+ \\"name\\": \\"key-1\\",
741
+ \\"expiration\\": 123456789,
742
+ \\"metadata\\": {}
743
+ },
744
+ {
745
+ \\"name\\": \\"key-2\\",
746
+ \\"expiration\\": 123456789,
747
+ \\"metadata\\": {}
748
+ },
749
+ {
750
+ \\"name\\": \\"key-3\\",
751
+ \\"expiration\\": 123456789,
752
+ \\"metadata\\": {}
753
+ }
754
+ ]"
744
755
  `);
745
756
  });
746
757
 
@@ -748,15 +759,28 @@ describe("wrangler", () => {
748
759
  writeWranglerConfig();
749
760
  const keys = ["key-1", "key-2", "key-3"];
750
761
  mockKeyListRequest("env-bound-id", keys);
751
- const { error, stdout, stderr } = await runWrangler(
762
+ await runWrangler(
752
763
  "kv:key list --binding someBinding --env some-environment"
753
764
  );
754
- expect(error).toMatchInlineSnapshot(`undefined`);
755
- expect(stderr).toMatchInlineSnapshot(`""`);
756
- expect(stdout).toMatchInlineSnapshot(`
757
- "key-1
758
- key-2
759
- key-3"
765
+ expect(std.err).toMatchInlineSnapshot(`""`);
766
+ expect(std.out).toMatchInlineSnapshot(`
767
+ "[
768
+ {
769
+ \\"name\\": \\"key-1\\",
770
+ \\"expiration\\": 123456789,
771
+ \\"metadata\\": {}
772
+ },
773
+ {
774
+ \\"name\\": \\"key-2\\",
775
+ \\"expiration\\": 123456789,
776
+ \\"metadata\\": {}
777
+ },
778
+ {
779
+ \\"name\\": \\"key-3\\",
780
+ \\"expiration\\": 123456789,
781
+ \\"metadata\\": {}
782
+ }
783
+ ]"
760
784
  `);
761
785
  });
762
786
 
@@ -764,134 +788,150 @@ describe("wrangler", () => {
764
788
  writeWranglerConfig();
765
789
  const keys = ["key-1", "key-2", "key-3"];
766
790
  mockKeyListRequest("preview-env-bound-id", keys);
767
- const { error, stdout, stderr } = await runWrangler(
791
+ await runWrangler(
768
792
  "kv:key list --binding someBinding --preview --env some-environment"
769
793
  );
770
- expect(error).toMatchInlineSnapshot(`undefined`);
771
- expect(stderr).toMatchInlineSnapshot(`""`);
772
- expect(stdout).toMatchInlineSnapshot(`
773
- "key-1
774
- key-2
775
- key-3"
794
+ expect(std.err).toMatchInlineSnapshot(`""`);
795
+ expect(std.out).toMatchInlineSnapshot(`
796
+ "[
797
+ {
798
+ \\"name\\": \\"key-1\\",
799
+ \\"expiration\\": 123456789,
800
+ \\"metadata\\": {}
801
+ },
802
+ {
803
+ \\"name\\": \\"key-2\\",
804
+ \\"expiration\\": 123456789,
805
+ \\"metadata\\": {}
806
+ },
807
+ {
808
+ \\"name\\": \\"key-3\\",
809
+ \\"expiration\\": 123456789,
810
+ \\"metadata\\": {}
811
+ }
812
+ ]"
776
813
  `);
777
814
  });
778
815
 
779
- it("should make multiple requests for paginated results", async () => {
780
- // Create a lot of mock keys, so that the fetch requests will be paginated
781
- const keys = [];
782
- for (let i = 0; i < 550; i++) {
783
- keys.push("key-" + i);
784
- }
785
- // Ask for the keys in pages of size 100.
786
- const requests = mockKeyListRequest("some-namespace-id", keys, 100);
787
- const { stdout, stderr, error } = await runWrangler(
788
- "kv:key list --namespace-id some-namespace-id --limit 100"
789
- );
790
- expect(error).toMatchInlineSnapshot(`undefined`);
791
- expect(stderr).toMatchInlineSnapshot(`""`);
792
- expect(stdout).toEqual(keys.join("\n"));
793
- expect(requests.count).toEqual(6);
794
- });
816
+ // We'll run the next test with variations on the cursor
817
+ // that's returned on cloudflare's API after all results
818
+ // have been drained.
819
+ for (const blankCursorValue of [undefined, null, ""] as [
820
+ undefined,
821
+ null,
822
+ ""
823
+ ]) {
824
+ describe(`cursor - ${blankCursorValue}`, () => {
825
+ it("should make multiple requests for paginated results", async () => {
826
+ // Create a lot of mock keys, so that the fetch requests will be paginated
827
+ const keys: string[] = [];
828
+ for (let i = 0; i < 550; i++) {
829
+ keys.push("key-" + i);
830
+ }
831
+ // Ask for the keys in pages of size 100.
832
+ const requests = mockKeyListRequest(
833
+ "some-namespace-id",
834
+ keys,
835
+ 100,
836
+ blankCursorValue
837
+ );
838
+ await runWrangler(
839
+ "kv:key list --namespace-id some-namespace-id --limit 100"
840
+ );
841
+ expect(std.err).toMatchInlineSnapshot(`""`);
842
+ expect(
843
+ JSON.parse(std.out).map((k: NamespaceKeyInfo) => k.name)
844
+ ).toEqual(keys);
845
+ expect(requests.count).toEqual(6);
846
+ });
847
+ });
848
+ }
795
849
 
796
850
  it("should error if a given binding name is not in the configured kv namespaces", async () => {
797
851
  writeWranglerConfig();
798
- const { error, stdout, stderr } = await runWrangler(
799
- "kv:key list --binding otherBinding"
800
- );
801
- expect(error).toMatchInlineSnapshot(
802
- `[Error: A namespace with binding name "otherBinding" was not found in the configured "kv_namespaces".]`
803
- );
804
- expect(stderr).toMatchInlineSnapshot(
852
+ await expect(
853
+ runWrangler("kv:key list --binding otherBinding")
854
+ ).rejects.toThrowErrorMatchingInlineSnapshot(
805
855
  `"A namespace with binding name \\"otherBinding\\" was not found in the configured \\"kv_namespaces\\"."`
806
856
  );
807
- expect(stdout).toMatchInlineSnapshot(`""`);
857
+ expect(std.err).toMatchInlineSnapshot(`
858
+ "A namespace with binding name \\"otherBinding\\" was not found in the configured \\"kv_namespaces\\".
859
+
860
+ %s
861
+ If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new."
862
+ `);
863
+ expect(std.out).toMatchInlineSnapshot(`""`);
808
864
  });
809
865
  });
810
866
 
811
867
  describe("get", () => {
812
- function mockKeyGetRequest(
813
- expectedNamespaceId: string,
814
- expectedKey: string,
815
- expectedValue: string
816
- ) {
817
- const requests = { count: 0 };
818
- setMockRawResponse(
819
- "/accounts/:accountId/storage/kv/namespaces/:namespaceId/values/:key",
820
- ([_url, accountId, namespaceId, key]) => {
821
- requests.count++;
822
- expect(accountId).toEqual("some-account-id");
823
- expect(namespaceId).toEqual(expectedNamespaceId);
824
- expect(key).toEqual(expectedKey);
825
- return expectedValue;
826
- }
827
- );
828
- return requests;
829
- }
868
+ afterEach(() => {
869
+ unsetMockFetchKVGetValues();
870
+ });
830
871
 
831
872
  it("should get a key in a given namespace specified by namespace-id", async () => {
832
- const requests = mockKeyGetRequest(
873
+ setMockFetchKVGetValue(
874
+ "some-account-id",
833
875
  "some-namespace-id",
834
876
  "my-key",
835
877
  "my-value"
836
878
  );
837
- const { error, stderr, stdout } = await runWrangler(
838
- "kv:key get my-key --namespace-id some-namespace-id"
839
- );
840
- expect(stdout).toMatchInlineSnapshot(`"my-value"`);
841
- expect(stderr).toMatchInlineSnapshot(`""`);
842
- expect(error).toMatchInlineSnapshot(`undefined`);
843
- expect(requests.count).toEqual(1);
879
+ await runWrangler("kv:key get my-key --namespace-id some-namespace-id");
880
+ expect(std.out).toMatchInlineSnapshot(`"my-value"`);
881
+ expect(std.err).toMatchInlineSnapshot(`""`);
844
882
  });
845
883
 
846
884
  it("should get a key in a given namespace specified by binding", async () => {
847
885
  writeWranglerConfig();
848
- const requests = mockKeyGetRequest("bound-id", "my-key", "my-value");
849
- const { error, stderr, stdout } = await runWrangler(
886
+ setMockFetchKVGetValue(
887
+ "some-account-id",
888
+ "bound-id",
889
+ "my-key",
890
+ "my-value"
891
+ );
892
+ await runWrangler(
850
893
  "kv:key get my-key --binding someBinding --preview false"
851
894
  );
852
- expect(stdout).toMatchInlineSnapshot(`"my-value"`);
853
- expect(stderr).toMatchInlineSnapshot(`""`);
854
- expect(error).toMatchInlineSnapshot(`undefined`);
855
- expect(requests.count).toEqual(1);
895
+ expect(std.out).toMatchInlineSnapshot(`"my-value"`);
896
+ expect(std.err).toMatchInlineSnapshot(`""`);
856
897
  });
857
898
 
858
899
  it("should get a key in a given preview namespace specified by binding", async () => {
859
900
  writeWranglerConfig();
860
- const requests = mockKeyGetRequest(
901
+ setMockFetchKVGetValue(
902
+ "some-account-id",
861
903
  "preview-bound-id",
862
904
  "my-key",
863
905
  "my-value"
864
906
  );
865
- const { error, stderr, stdout } = await runWrangler(
866
- "kv:key get my-key --binding someBinding --preview"
867
- );
868
- expect(stdout).toMatchInlineSnapshot(`"my-value"`);
869
- expect(stderr).toMatchInlineSnapshot(`""`);
870
- expect(error).toMatchInlineSnapshot(`undefined`);
871
- expect(requests.count).toEqual(1);
907
+ await runWrangler("kv:key get my-key --binding someBinding --preview");
908
+ expect(std.out).toMatchInlineSnapshot(`"my-value"`);
909
+ expect(std.err).toMatchInlineSnapshot(`""`);
872
910
  });
873
911
 
874
912
  it("should get a key for the specified environment in a given namespace", async () => {
875
913
  writeWranglerConfig();
876
- const requests = mockKeyGetRequest(
914
+ setMockFetchKVGetValue(
915
+ "some-account-id",
877
916
  "env-bound-id",
878
917
  "my-key",
879
918
  "my-value"
880
919
  );
881
- const { error, stderr, stdout } = await runWrangler(
920
+ await runWrangler(
882
921
  "kv:key get my-key my-value --binding someBinding --env some-environment --preview false"
883
922
  );
884
- expect(stdout).toMatchInlineSnapshot(`"my-value"`);
885
- expect(stderr).toMatchInlineSnapshot(`""`);
886
- expect(error).toMatchInlineSnapshot(`undefined`);
887
- expect(requests.count).toEqual(1);
923
+ expect(std.out).toMatchInlineSnapshot(`"my-value"`);
924
+ expect(std.err).toMatchInlineSnapshot(`""`);
888
925
  });
889
926
 
890
927
  it("should error if no key is provided", async () => {
891
- const { error, stdout, stderr } = await runWrangler("kv:key get");
892
-
893
- expect(stdout).toMatchInlineSnapshot(`""`);
894
- expect(stderr).toMatchInlineSnapshot(`
928
+ await expect(
929
+ runWrangler("kv:key get")
930
+ ).rejects.toThrowErrorMatchingInlineSnapshot(
931
+ `"Not enough non-option arguments: got 0, need at least 1"`
932
+ );
933
+ expect(std.out).toMatchInlineSnapshot(`""`);
934
+ expect(std.err).toMatchInlineSnapshot(`
895
935
  "wrangler kv:key get <key>
896
936
 
897
937
  Reads a single value by key from the given namespace.
@@ -900,12 +940,12 @@ describe("wrangler", () => {
900
940
  key The key value to get. [string] [required]
901
941
 
902
942
  Flags:
903
- -c, --config Path to .toml configuration file [string]
904
- -h, --help Show help [boolean]
905
- -v, --version Show version number [boolean]
943
+ -c, --config Path to .toml configuration file [string]
944
+ -h, --help Show help [boolean]
945
+ -v, --version Show version number [boolean]
946
+ --legacy-env Use legacy environments [boolean]
906
947
 
907
948
  Options:
908
- -l, --local Run on my machine [boolean] [default: false]
909
949
  --binding The name of the namespace to get from [string]
910
950
  --namespace-id The id of the namespace to get from [string]
911
951
  --env Perform on a specific environment [string]
@@ -913,16 +953,16 @@ describe("wrangler", () => {
913
953
 
914
954
  Not enough non-option arguments: got 0, need at least 1"
915
955
  `);
916
- expect(error).toMatchInlineSnapshot(
917
- `[Error: Not enough non-option arguments: got 0, need at least 1]`
918
- );
919
956
  });
920
957
 
921
958
  it("should error if no binding nor namespace is provided", async () => {
922
- const { error, stdout, stderr } = await runWrangler("kv:key get foo");
923
-
924
- expect(stdout).toMatchInlineSnapshot(`""`);
925
- expect(stderr).toMatchInlineSnapshot(`
959
+ await expect(
960
+ runWrangler("kv:key get foo")
961
+ ).rejects.toThrowErrorMatchingInlineSnapshot(
962
+ `"Exactly one of the arguments binding and namespace-id is required"`
963
+ );
964
+ expect(std.out).toMatchInlineSnapshot(`""`);
965
+ expect(std.err).toMatchInlineSnapshot(`
926
966
  "wrangler kv:key get <key>
927
967
 
928
968
  Reads a single value by key from the given namespace.
@@ -931,12 +971,12 @@ describe("wrangler", () => {
931
971
  key The key value to get. [string] [required]
932
972
 
933
973
  Flags:
934
- -c, --config Path to .toml configuration file [string]
935
- -h, --help Show help [boolean]
936
- -v, --version Show version number [boolean]
974
+ -c, --config Path to .toml configuration file [string]
975
+ -h, --help Show help [boolean]
976
+ -v, --version Show version number [boolean]
977
+ --legacy-env Use legacy environments [boolean]
937
978
 
938
979
  Options:
939
- -l, --local Run on my machine [boolean] [default: false]
940
980
  --binding The name of the namespace to get from [string]
941
981
  --namespace-id The id of the namespace to get from [string]
942
982
  --env Perform on a specific environment [string]
@@ -944,18 +984,17 @@ describe("wrangler", () => {
944
984
 
945
985
  Exactly one of the arguments binding and namespace-id is required"
946
986
  `);
947
- expect(error).toMatchInlineSnapshot(
948
- `[Error: Exactly one of the arguments binding and namespace-id is required]`
949
- );
950
987
  });
951
988
 
952
989
  it("should error if both binding and namespace is provided", async () => {
953
- const { error, stdout, stderr } = await runWrangler(
954
- "kv:key get foo --binding x --namespace-id y"
990
+ await expect(
991
+ runWrangler("kv:key get foo --binding x --namespace-id y")
992
+ ).rejects.toThrowErrorMatchingInlineSnapshot(
993
+ `"Arguments binding and namespace-id are mutually exclusive"`
955
994
  );
956
995
 
957
- expect(stdout).toMatchInlineSnapshot(`""`);
958
- expect(stderr).toMatchInlineSnapshot(`
996
+ expect(std.out).toMatchInlineSnapshot(`""`);
997
+ expect(std.err).toMatchInlineSnapshot(`
959
998
  "wrangler kv:key get <key>
960
999
 
961
1000
  Reads a single value by key from the given namespace.
@@ -964,12 +1003,12 @@ describe("wrangler", () => {
964
1003
  key The key value to get. [string] [required]
965
1004
 
966
1005
  Flags:
967
- -c, --config Path to .toml configuration file [string]
968
- -h, --help Show help [boolean]
969
- -v, --version Show version number [boolean]
1006
+ -c, --config Path to .toml configuration file [string]
1007
+ -h, --help Show help [boolean]
1008
+ -v, --version Show version number [boolean]
1009
+ --legacy-env Use legacy environments [boolean]
970
1010
 
971
1011
  Options:
972
- -l, --local Run on my machine [boolean] [default: false]
973
1012
  --binding The name of the namespace to get from [string]
974
1013
  --namespace-id The id of the namespace to get from [string]
975
1014
  --env Perform on a specific environment [string]
@@ -977,23 +1016,22 @@ describe("wrangler", () => {
977
1016
 
978
1017
  Arguments binding and namespace-id are mutually exclusive"
979
1018
  `);
980
- expect(error).toMatchInlineSnapshot(
981
- `[Error: Arguments binding and namespace-id are mutually exclusive]`
982
- );
983
1019
  });
984
1020
 
985
1021
  it("should error if a given binding name is not in the configured kv namespaces", async () => {
986
1022
  writeWranglerConfig();
987
- const { error, stdout, stderr } = await runWrangler(
988
- `kv:key get key --binding otherBinding`
989
- );
990
- expect(stdout).toMatchInlineSnapshot(`""`);
991
- expect(stderr).toMatchInlineSnapshot(
1023
+ await expect(
1024
+ runWrangler("kv:key get key --binding otherBinding")
1025
+ ).rejects.toThrowErrorMatchingInlineSnapshot(
992
1026
  `"A namespace with binding name \\"otherBinding\\" was not found in the configured \\"kv_namespaces\\"."`
993
1027
  );
994
- expect(error).toMatchInlineSnapshot(
995
- `[Error: A namespace with binding name "otherBinding" was not found in the configured "kv_namespaces".]`
996
- );
1028
+ expect(std.out).toMatchInlineSnapshot(`""`);
1029
+ expect(std.err).toMatchInlineSnapshot(`
1030
+ "A namespace with binding name \\"otherBinding\\" was not found in the configured \\"kv_namespaces\\".
1031
+
1032
+ %s
1033
+ If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new."
1034
+ `);
997
1035
  });
998
1036
  });
999
1037
 
@@ -1045,25 +1083,30 @@ describe("wrangler", () => {
1045
1083
 
1046
1084
  it("should error if a given binding name is not in the configured kv namespaces", async () => {
1047
1085
  writeWranglerConfig();
1048
- const { stderr } = await runWrangler(
1049
- `kv:key delete --binding otherBinding someKey`
1050
- );
1051
- expect(stderr).toMatchInlineSnapshot(
1086
+ await expect(
1087
+ runWrangler(`kv:key delete --binding otherBinding someKey`)
1088
+ ).rejects.toThrowErrorMatchingInlineSnapshot(
1052
1089
  `"A namespace with binding name \\"otherBinding\\" was not found in the configured \\"kv_namespaces\\"."`
1053
1090
  );
1091
+
1092
+ expect(std.err).toMatchInlineSnapshot(`
1093
+ "A namespace with binding name \\"otherBinding\\" was not found in the configured \\"kv_namespaces\\".
1094
+
1095
+ %s
1096
+ If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new."
1097
+ `);
1054
1098
  });
1055
1099
 
1056
1100
  it("should delete a key in a namespace specified by binding name in a given environment", async () => {
1057
1101
  writeWranglerConfig();
1058
1102
  const requests = mockDeleteRequest("env-bound-id", "someKey");
1059
- const { stdout, stderr, error } = await runWrangler(
1103
+ await runWrangler(
1060
1104
  `kv:key delete --binding someBinding --env some-environment --preview false someKey`
1061
1105
  );
1062
- expect(stdout).toMatchInlineSnapshot(
1106
+ expect(std.out).toMatchInlineSnapshot(
1063
1107
  `"deleting the key \\"someKey\\" on namespace env-bound-id"`
1064
1108
  );
1065
- expect(stderr).toMatchInlineSnapshot(`""`);
1066
- expect(error).toMatchInlineSnapshot(`undefined`);
1109
+ expect(std.err).toMatchInlineSnapshot(`""`);
1067
1110
  expect(requests.count).toEqual(1);
1068
1111
  });
1069
1112