wrangler 0.0.0-fe5dcfd → 0.0.0-ff53f4e
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/wrangler.js +2 -2
- package/package.json +28 -15
- package/pages/functions/buildWorker.ts +1 -1
- package/pages/functions/filepath-routing.test.ts +212 -28
- package/pages/functions/filepath-routing.ts +83 -130
- package/pages/functions/routes.ts +11 -18
- package/pages/functions/template-worker.ts +3 -9
- package/src/__tests__/configuration.test.ts +2237 -0
- package/src/__tests__/dev.test.tsx +397 -59
- package/src/__tests__/dev2.test.tsx +152 -0
- package/src/__tests__/guess-worker-format.test.ts +58 -0
- package/src/__tests__/{clipboardy-mock.js → helpers/clipboardy-mock.js} +0 -0
- package/src/__tests__/helpers/cmd-shim.d.ts +11 -0
- package/src/__tests__/helpers/faye-websocket.d.ts +6 -0
- package/src/__tests__/helpers/mock-account-id.ts +44 -0
- package/src/__tests__/helpers/mock-bin.ts +36 -0
- package/src/__tests__/{mock-cfetch.ts → helpers/mock-cfetch.ts} +46 -12
- package/src/__tests__/helpers/mock-console.ts +70 -0
- package/src/__tests__/{mock-dialogs.ts → helpers/mock-dialogs.ts} +1 -1
- package/src/__tests__/helpers/mock-kv.ts +33 -0
- package/src/__tests__/helpers/mock-stdin.ts +103 -0
- package/src/__tests__/helpers/mock-user.ts +27 -0
- package/src/__tests__/helpers/mock-web-socket.ts +29 -0
- package/src/__tests__/helpers/run-in-tmp.ts +29 -0
- package/src/__tests__/helpers/run-wrangler.ts +16 -0
- package/src/__tests__/helpers/write-wrangler-toml.ts +17 -0
- package/src/__tests__/https-options.test.ts +127 -0
- package/src/__tests__/index.test.ts +777 -75
- package/src/__tests__/jest.setup.ts +53 -6
- package/src/__tests__/kv.test.ts +662 -480
- package/src/__tests__/logout.test.ts +50 -0
- package/src/__tests__/package-manager.test.ts +206 -0
- package/src/__tests__/pages.test.ts +44 -0
- package/src/__tests__/parse.test.ts +322 -0
- package/src/__tests__/publish.test.ts +2218 -338
- package/src/__tests__/r2.test.ts +198 -0
- package/src/__tests__/route.test.ts +45 -0
- package/src/__tests__/secret.test.ts +425 -0
- package/src/__tests__/sentry.test.ts +146 -0
- package/src/__tests__/tail.test.ts +564 -0
- package/src/__tests__/whoami.test.tsx +7 -51
- package/src/bundle.ts +142 -0
- package/src/cfetch/index.ts +13 -19
- package/src/cfetch/internal.ts +88 -20
- package/src/cli.ts +10 -0
- package/src/config/README.md +107 -0
- package/src/config/config.ts +279 -0
- package/src/config/diagnostics.ts +80 -0
- package/src/config/environment.ts +305 -0
- package/src/config/index.ts +52 -0
- package/src/config/validation-helpers.ts +388 -0
- package/src/config/validation.ts +1027 -0
- package/src/{api/preview.ts → create-worker-preview.ts} +61 -23
- package/src/create-worker-upload-form.ts +217 -0
- package/src/dev/dev.tsx +357 -0
- package/src/dev/local.tsx +241 -0
- package/src/dev/remote.tsx +201 -0
- package/src/dev/use-esbuild.ts +100 -0
- package/src/dialogs.tsx +2 -2
- package/src/entry.ts +159 -0
- package/src/environment-variables.ts +33 -0
- package/src/https-options.ts +122 -0
- package/src/index.tsx +1122 -768
- package/src/inspect.ts +95 -21
- package/src/{kv.tsx → kv.ts} +119 -56
- package/src/module-collection.ts +215 -26
- package/src/open-in-browser.ts +25 -0
- package/src/package-manager.ts +126 -0
- package/src/pages.tsx +30 -25
- package/src/parse.ts +183 -0
- package/src/paths.ts +26 -0
- package/src/proxy.ts +175 -39
- package/src/publish.ts +282 -310
- package/src/r2.ts +50 -0
- package/src/reporting.ts +131 -0
- package/src/selfsigned.d.ts +29 -0
- package/src/sites.tsx +77 -48
- package/src/tail/filters.ts +279 -0
- package/src/tail/index.ts +299 -0
- package/src/tail/printing.ts +62 -0
- package/src/user.tsx +106 -60
- package/src/{api/worker.ts → worker.ts} +45 -37
- package/templates/new-worker.js +15 -0
- package/templates/new-worker.ts +15 -0
- package/{static-asset-facade.js → templates/static-asset-facade.js} +0 -0
- package/templates/tsconfig.json +105 -0
- package/wrangler-dist/cli.js +128970 -113025
- package/wrangler-dist/cli.js.map +3 -3
- package/src/__tests__/run-in-tmp.ts +0 -19
- package/src/__tests__/run-wrangler.ts +0 -32
- package/src/api/form_data.ts +0 -131
- package/src/config.ts +0 -646
- package/src/dev.tsx +0 -779
- package/src/tail.tsx +0 -73
package/src/__tests__/kv.test.ts
CHANGED
|
@@ -1,16 +1,24 @@
|
|
|
1
|
-
import { writeFileSync } from "fs";
|
|
2
|
-
import
|
|
1
|
+
import { writeFileSync } from "node:fs";
|
|
2
|
+
import { Headers } from "undici";
|
|
3
|
+
import { mockAccountId, mockApiToken } from "./helpers/mock-account-id";
|
|
3
4
|
import {
|
|
4
5
|
setMockResponse,
|
|
5
|
-
setMockRawResponse,
|
|
6
6
|
unsetAllMocks,
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
import {
|
|
7
|
+
unsetMockFetchKVGetValues,
|
|
8
|
+
setMockFetchKVGetValue,
|
|
9
|
+
} from "./helpers/mock-cfetch";
|
|
10
|
+
import { mockConsoleMethods } from "./helpers/mock-console";
|
|
11
|
+
import { mockConfirm } from "./helpers/mock-dialogs";
|
|
12
|
+
import { mockKeyListRequest } from "./helpers/mock-kv";
|
|
13
|
+
import { runInTempDir } from "./helpers/run-in-tmp";
|
|
14
|
+
import { runWrangler } from "./helpers/run-wrangler";
|
|
15
|
+
import type { KeyValue, KVNamespaceInfo, NamespaceKeyInfo } from "../kv";
|
|
11
16
|
|
|
12
17
|
describe("wrangler", () => {
|
|
18
|
+
mockAccountId();
|
|
19
|
+
mockApiToken();
|
|
13
20
|
runInTempDir();
|
|
21
|
+
const std = mockConsoleMethods();
|
|
14
22
|
|
|
15
23
|
afterEach(() => {
|
|
16
24
|
unsetAllMocks();
|
|
@@ -32,11 +40,13 @@ describe("wrangler", () => {
|
|
|
32
40
|
}
|
|
33
41
|
|
|
34
42
|
it("should error if no namespace is given", async () => {
|
|
35
|
-
|
|
36
|
-
"kv:namespace create"
|
|
43
|
+
await expect(
|
|
44
|
+
runWrangler("kv:namespace create")
|
|
45
|
+
).rejects.toThrowErrorMatchingInlineSnapshot(
|
|
46
|
+
`"Not enough non-option arguments: got 0, need at least 1"`
|
|
37
47
|
);
|
|
38
|
-
expect(
|
|
39
|
-
expect(
|
|
48
|
+
expect(std.out).toMatchInlineSnapshot(`""`);
|
|
49
|
+
expect(std.err).toMatchInlineSnapshot(`
|
|
40
50
|
"wrangler kv:namespace create <namespace>
|
|
41
51
|
|
|
42
52
|
Create a new namespace
|
|
@@ -45,28 +55,27 @@ describe("wrangler", () => {
|
|
|
45
55
|
namespace The name of the new namespace [string] [required]
|
|
46
56
|
|
|
47
57
|
Flags:
|
|
48
|
-
-c, --config
|
|
49
|
-
-h, --help
|
|
50
|
-
-v, --version
|
|
58
|
+
-c, --config Path to .toml configuration file [string]
|
|
59
|
+
-h, --help Show help [boolean]
|
|
60
|
+
-v, --version Show version number [boolean]
|
|
61
|
+
--legacy-env Use legacy environments [boolean]
|
|
51
62
|
|
|
52
63
|
Options:
|
|
53
|
-
-l, --local Run on my machine [boolean] [default: false]
|
|
54
64
|
--env Perform on a specific environment [string]
|
|
55
65
|
--preview Interact with a preview namespace [boolean]
|
|
56
66
|
|
|
57
67
|
Not enough non-option arguments: got 0, need at least 1"
|
|
58
68
|
`);
|
|
59
|
-
expect(error).toMatchInlineSnapshot(
|
|
60
|
-
`[Error: Not enough non-option arguments: got 0, need at least 1]`
|
|
61
|
-
);
|
|
62
69
|
});
|
|
63
70
|
|
|
64
71
|
it("should error if the namespace to create contains spaces", async () => {
|
|
65
|
-
|
|
66
|
-
"kv:namespace create abc def ghi"
|
|
72
|
+
await expect(
|
|
73
|
+
runWrangler("kv:namespace create abc def ghi")
|
|
74
|
+
).rejects.toThrowErrorMatchingInlineSnapshot(
|
|
75
|
+
`"Unexpected additional positional arguments \\"def ghi\\"."`
|
|
67
76
|
);
|
|
68
|
-
expect(
|
|
69
|
-
expect(
|
|
77
|
+
expect(std.out).toMatchInlineSnapshot(`""`);
|
|
78
|
+
expect(std.err).toMatchInlineSnapshot(`
|
|
70
79
|
"wrangler kv:namespace create <namespace>
|
|
71
80
|
|
|
72
81
|
Create a new namespace
|
|
@@ -75,28 +84,28 @@ describe("wrangler", () => {
|
|
|
75
84
|
namespace The name of the new namespace [string] [required]
|
|
76
85
|
|
|
77
86
|
Flags:
|
|
78
|
-
-c, --config
|
|
79
|
-
-h, --help
|
|
80
|
-
-v, --version
|
|
87
|
+
-c, --config Path to .toml configuration file [string]
|
|
88
|
+
-h, --help Show help [boolean]
|
|
89
|
+
-v, --version Show version number [boolean]
|
|
90
|
+
--legacy-env Use legacy environments [boolean]
|
|
81
91
|
|
|
82
92
|
Options:
|
|
83
|
-
-l, --local Run on my machine [boolean] [default: false]
|
|
84
93
|
--env Perform on a specific environment [string]
|
|
85
94
|
--preview Interact with a preview namespace [boolean]
|
|
86
95
|
|
|
87
96
|
Unexpected additional positional arguments \\"def ghi\\"."
|
|
88
97
|
`);
|
|
89
|
-
expect(error).toMatchInlineSnapshot(
|
|
90
|
-
`[Error: Unexpected additional positional arguments "def ghi".]`
|
|
91
|
-
);
|
|
92
98
|
});
|
|
93
99
|
|
|
94
100
|
it("should error if the namespace to create is not valid", async () => {
|
|
95
|
-
|
|
96
|
-
"kv:namespace create abc-def"
|
|
101
|
+
await expect(
|
|
102
|
+
runWrangler("kv:namespace create abc-def")
|
|
103
|
+
).rejects.toThrowErrorMatchingInlineSnapshot(
|
|
104
|
+
`"The namespace binding name \\"abc-def\\" is invalid. It can only have alphanumeric and _ characters, and cannot begin with a number."`
|
|
97
105
|
);
|
|
98
|
-
|
|
99
|
-
expect(
|
|
106
|
+
|
|
107
|
+
expect(std.out).toMatchInlineSnapshot(`""`);
|
|
108
|
+
expect(std.err).toMatchInlineSnapshot(`
|
|
100
109
|
"wrangler kv:namespace create <namespace>
|
|
101
110
|
|
|
102
111
|
Create a new namespace
|
|
@@ -105,28 +114,23 @@ describe("wrangler", () => {
|
|
|
105
114
|
namespace The name of the new namespace [string] [required]
|
|
106
115
|
|
|
107
116
|
Flags:
|
|
108
|
-
-c, --config
|
|
109
|
-
-h, --help
|
|
110
|
-
-v, --version
|
|
117
|
+
-c, --config Path to .toml configuration file [string]
|
|
118
|
+
-h, --help Show help [boolean]
|
|
119
|
+
-v, --version Show version number [boolean]
|
|
120
|
+
--legacy-env Use legacy environments [boolean]
|
|
111
121
|
|
|
112
122
|
Options:
|
|
113
|
-
-l, --local Run on my machine [boolean] [default: false]
|
|
114
123
|
--env Perform on a specific environment [string]
|
|
115
124
|
--preview Interact with a preview namespace [boolean]
|
|
116
125
|
|
|
117
126
|
The namespace binding name \\"abc-def\\" is invalid. It can only have alphanumeric and _ characters, and cannot begin with a number."
|
|
118
127
|
`);
|
|
119
|
-
expect(error).toMatchInlineSnapshot(
|
|
120
|
-
`[Error: The namespace binding name "abc-def" is invalid. It can only have alphanumeric and _ characters, and cannot begin with a number.]`
|
|
121
|
-
);
|
|
122
128
|
});
|
|
123
129
|
|
|
124
130
|
it("should create a namespace", async () => {
|
|
125
131
|
mockCreateRequest("worker-UnitTestNamespace");
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
);
|
|
129
|
-
expect(stdout).toMatchInlineSnapshot(`
|
|
132
|
+
await runWrangler("kv:namespace create UnitTestNamespace");
|
|
133
|
+
expect(std.out).toMatchInlineSnapshot(`
|
|
130
134
|
"🌀 Creating namespace with title \\"worker-UnitTestNamespace\\"
|
|
131
135
|
✨ Success!
|
|
132
136
|
Add the following to your configuration file in your kv_namespaces array:
|
|
@@ -136,10 +140,8 @@ describe("wrangler", () => {
|
|
|
136
140
|
|
|
137
141
|
it("should create a preview namespace if configured to do so", async () => {
|
|
138
142
|
mockCreateRequest("worker-UnitTestNamespace_preview");
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
);
|
|
142
|
-
expect(stdout).toMatchInlineSnapshot(`
|
|
143
|
+
await runWrangler("kv:namespace create UnitTestNamespace --preview");
|
|
144
|
+
expect(std.out).toMatchInlineSnapshot(`
|
|
143
145
|
"🌀 Creating namespace with title \\"worker-UnitTestNamespace_preview\\"
|
|
144
146
|
✨ Success!
|
|
145
147
|
Add the following to your configuration file in your kv_namespaces array:
|
|
@@ -150,10 +152,8 @@ describe("wrangler", () => {
|
|
|
150
152
|
it("should create a namespace using configured worker name", async () => {
|
|
151
153
|
writeFileSync("./wrangler.toml", 'name = "otherWorker"', "utf-8");
|
|
152
154
|
mockCreateRequest("otherWorker-UnitTestNamespace");
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
);
|
|
156
|
-
expect(stdout).toMatchInlineSnapshot(`
|
|
155
|
+
await runWrangler("kv:namespace create UnitTestNamespace");
|
|
156
|
+
expect(std.out).toMatchInlineSnapshot(`
|
|
157
157
|
"🌀 Creating namespace with title \\"otherWorker-UnitTestNamespace\\"
|
|
158
158
|
✨ Success!
|
|
159
159
|
Add the following to your configuration file in your kv_namespaces array:
|
|
@@ -163,10 +163,10 @@ describe("wrangler", () => {
|
|
|
163
163
|
|
|
164
164
|
it("should create a namespace in an environment if configured to do so", async () => {
|
|
165
165
|
mockCreateRequest("worker-customEnv-UnitTestNamespace");
|
|
166
|
-
|
|
166
|
+
await runWrangler(
|
|
167
167
|
"kv:namespace create UnitTestNamespace --env customEnv"
|
|
168
168
|
);
|
|
169
|
-
expect(
|
|
169
|
+
expect(std.out).toMatchInlineSnapshot(`
|
|
170
170
|
"🌀 Creating namespace with title \\"worker-customEnv-UnitTestNamespace\\"
|
|
171
171
|
✨ Success!
|
|
172
172
|
Add the following to your configuration file in your kv_namespaces array under [env.customEnv]:
|
|
@@ -202,12 +202,10 @@ describe("wrangler", () => {
|
|
|
202
202
|
{ title: "title-2", id: "id-2" },
|
|
203
203
|
];
|
|
204
204
|
mockListRequest(kvNamespaces);
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
);
|
|
208
|
-
|
|
209
|
-
expect(stderr).toMatchInlineSnapshot(`""`);
|
|
210
|
-
const namespaces = JSON.parse(stdout);
|
|
205
|
+
await runWrangler("kv:namespace list");
|
|
206
|
+
|
|
207
|
+
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
208
|
+
const namespaces = JSON.parse(std.out);
|
|
211
209
|
expect(namespaces).toEqual(kvNamespaces);
|
|
212
210
|
});
|
|
213
211
|
|
|
@@ -218,8 +216,8 @@ describe("wrangler", () => {
|
|
|
218
216
|
kvNamespaces.push({ title: "title-" + i, id: "id-" + i });
|
|
219
217
|
}
|
|
220
218
|
const requests = mockListRequest(kvNamespaces);
|
|
221
|
-
|
|
222
|
-
const namespaces = JSON.parse(
|
|
219
|
+
await runWrangler("kv:namespace list");
|
|
220
|
+
const namespaces = JSON.parse(std.out);
|
|
223
221
|
expect(namespaces).toEqual(kvNamespaces);
|
|
224
222
|
expect(requests.count).toEqual(6);
|
|
225
223
|
});
|
|
@@ -269,21 +267,23 @@ describe("wrangler", () => {
|
|
|
269
267
|
|
|
270
268
|
it("should error if a given binding name is not in the configured kv namespaces", async () => {
|
|
271
269
|
writeWranglerConfig();
|
|
272
|
-
|
|
273
|
-
`
|
|
274
|
-
|
|
275
|
-
|
|
270
|
+
await expect(runWrangler("kv:namespace delete --binding otherBinding"))
|
|
271
|
+
.rejects.toThrowErrorMatchingInlineSnapshot(`
|
|
272
|
+
"Not able to delete namespace.
|
|
273
|
+
A namespace with binding name \\"otherBinding\\" was not found in the configured \\"kv_namespaces\\"."
|
|
274
|
+
`);
|
|
275
|
+
expect(std.err).toMatchInlineSnapshot(`
|
|
276
276
|
"wrangler kv:namespace delete
|
|
277
277
|
|
|
278
278
|
Deletes a given namespace.
|
|
279
279
|
|
|
280
280
|
Flags:
|
|
281
|
-
-c, --config
|
|
282
|
-
-h, --help
|
|
283
|
-
-v, --version
|
|
281
|
+
-c, --config Path to .toml configuration file [string]
|
|
282
|
+
-h, --help Show help [boolean]
|
|
283
|
+
-v, --version Show version number [boolean]
|
|
284
|
+
--legacy-env Use legacy environments [boolean]
|
|
284
285
|
|
|
285
286
|
Options:
|
|
286
|
-
-l, --local Run on my machine [boolean] [default: false]
|
|
287
287
|
--binding The name of the namespace to delete [string]
|
|
288
288
|
--namespace-id The id of the namespace to delete [string]
|
|
289
289
|
--env Perform on a specific environment [string]
|
|
@@ -297,12 +297,12 @@ describe("wrangler", () => {
|
|
|
297
297
|
it("should delete a namespace specified by binding name in a given environment", async () => {
|
|
298
298
|
writeWranglerConfig();
|
|
299
299
|
const requests = mockDeleteRequest("env-bound-id");
|
|
300
|
-
|
|
301
|
-
|
|
300
|
+
await runWrangler(
|
|
301
|
+
"kv:namespace delete --binding someBinding --env some-environment --preview false"
|
|
302
302
|
);
|
|
303
|
-
|
|
304
|
-
expect(
|
|
305
|
-
expect(
|
|
303
|
+
|
|
304
|
+
expect(std.out).toMatchInlineSnapshot(`""`);
|
|
305
|
+
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
306
306
|
expect(requests.count).toEqual(1);
|
|
307
307
|
});
|
|
308
308
|
|
|
@@ -321,10 +321,7 @@ describe("wrangler", () => {
|
|
|
321
321
|
describe("put", () => {
|
|
322
322
|
function mockKeyPutRequest(
|
|
323
323
|
expectedNamespaceId: string,
|
|
324
|
-
|
|
325
|
-
expectedValue: string,
|
|
326
|
-
expiration?: number,
|
|
327
|
-
expirationTtl?: number
|
|
324
|
+
expectedKV: KeyValue
|
|
328
325
|
) {
|
|
329
326
|
const requests = { count: 0 };
|
|
330
327
|
setMockResponse(
|
|
@@ -334,15 +331,19 @@ describe("wrangler", () => {
|
|
|
334
331
|
requests.count++;
|
|
335
332
|
expect(accountId).toEqual("some-account-id");
|
|
336
333
|
expect(namespaceId).toEqual(expectedNamespaceId);
|
|
337
|
-
expect(key).toEqual(
|
|
338
|
-
expect(body).toEqual(
|
|
339
|
-
if (expiration !== undefined) {
|
|
340
|
-
expect(query.get("expiration")).toEqual(
|
|
334
|
+
expect(key).toEqual(expectedKV.key);
|
|
335
|
+
expect(body).toEqual(expectedKV.value);
|
|
336
|
+
if (expectedKV.expiration !== undefined) {
|
|
337
|
+
expect(query.get("expiration")).toEqual(
|
|
338
|
+
`${expectedKV.expiration}`
|
|
339
|
+
);
|
|
341
340
|
} else {
|
|
342
341
|
expect(query.has("expiration")).toBe(false);
|
|
343
342
|
}
|
|
344
|
-
if (
|
|
345
|
-
expect(query.get("expiration_ttl")).toEqual(
|
|
343
|
+
if (expectedKV.expiration_ttl) {
|
|
344
|
+
expect(query.get("expiration_ttl")).toEqual(
|
|
345
|
+
`${expectedKV.expiration_ttl}`
|
|
346
|
+
);
|
|
346
347
|
} else {
|
|
347
348
|
expect(query.has("expiration_ttl")).toBe(false);
|
|
348
349
|
}
|
|
@@ -353,358 +354,344 @@ describe("wrangler", () => {
|
|
|
353
354
|
}
|
|
354
355
|
|
|
355
356
|
it("should put a key in a given namespace specified by namespace-id", async () => {
|
|
356
|
-
const requests = mockKeyPutRequest(
|
|
357
|
-
"
|
|
358
|
-
"my-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
357
|
+
const requests = mockKeyPutRequest("some-namespace-id", {
|
|
358
|
+
key: "my-key",
|
|
359
|
+
value: "my-value",
|
|
360
|
+
});
|
|
361
|
+
|
|
362
|
+
await runWrangler(
|
|
362
363
|
"kv:key put my-key my-value --namespace-id some-namespace-id"
|
|
363
364
|
);
|
|
365
|
+
|
|
364
366
|
expect(requests.count).toEqual(1);
|
|
365
|
-
expect(
|
|
367
|
+
expect(std.out).toMatchInlineSnapshot(
|
|
366
368
|
`"writing the value \\"my-value\\" to key \\"my-key\\" on namespace some-namespace-id"`
|
|
367
369
|
);
|
|
368
|
-
expect(
|
|
369
|
-
expect(error).toMatchInlineSnapshot(`undefined`);
|
|
370
|
+
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
370
371
|
});
|
|
371
372
|
|
|
372
373
|
it("should put a key in a given namespace specified by binding", async () => {
|
|
373
374
|
writeWranglerConfig();
|
|
374
|
-
const requests = mockKeyPutRequest("bound-id",
|
|
375
|
-
|
|
375
|
+
const requests = mockKeyPutRequest("bound-id", {
|
|
376
|
+
key: "my-key",
|
|
377
|
+
value: "my-value",
|
|
378
|
+
});
|
|
379
|
+
await runWrangler(
|
|
376
380
|
"kv:key put my-key my-value --binding someBinding --preview false"
|
|
377
381
|
);
|
|
378
|
-
|
|
382
|
+
|
|
383
|
+
expect(std.out).toMatchInlineSnapshot(
|
|
379
384
|
`"writing the value \\"my-value\\" to key \\"my-key\\" on namespace bound-id"`
|
|
380
385
|
);
|
|
381
|
-
expect(
|
|
382
|
-
expect(error).toMatchInlineSnapshot(`undefined`);
|
|
386
|
+
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
383
387
|
expect(requests.count).toEqual(1);
|
|
384
388
|
});
|
|
385
389
|
|
|
386
390
|
it("should put a key in a given preview namespace specified by binding", async () => {
|
|
387
391
|
writeWranglerConfig();
|
|
388
|
-
const requests = mockKeyPutRequest(
|
|
389
|
-
"
|
|
390
|
-
"my-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
392
|
+
const requests = mockKeyPutRequest("preview-bound-id", {
|
|
393
|
+
key: "my-key",
|
|
394
|
+
value: "my-value",
|
|
395
|
+
});
|
|
396
|
+
|
|
397
|
+
await runWrangler(
|
|
394
398
|
"kv:key put my-key my-value --binding someBinding --preview"
|
|
395
399
|
);
|
|
396
|
-
|
|
400
|
+
|
|
401
|
+
expect(std.out).toMatchInlineSnapshot(
|
|
397
402
|
`"writing the value \\"my-value\\" to key \\"my-key\\" on namespace preview-bound-id"`
|
|
398
403
|
);
|
|
399
|
-
expect(
|
|
400
|
-
expect(error).toMatchInlineSnapshot(`undefined`);
|
|
404
|
+
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
401
405
|
expect(requests.count).toEqual(1);
|
|
402
406
|
});
|
|
403
407
|
|
|
404
408
|
it("should add expiration and ttl properties when putting a key", async () => {
|
|
405
|
-
const requests = mockKeyPutRequest(
|
|
406
|
-
"
|
|
407
|
-
"my-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
const { error, stderr, stdout } = await runWrangler(
|
|
409
|
+
const requests = mockKeyPutRequest("some-namespace-id", {
|
|
410
|
+
key: "my-key",
|
|
411
|
+
value: "my-value",
|
|
412
|
+
expiration: 10,
|
|
413
|
+
expiration_ttl: 20,
|
|
414
|
+
});
|
|
415
|
+
await runWrangler(
|
|
413
416
|
"kv:key put my-key my-value --namespace-id some-namespace-id --expiration 10 --ttl 20"
|
|
414
417
|
);
|
|
415
418
|
expect(requests.count).toEqual(1);
|
|
416
|
-
expect(
|
|
419
|
+
expect(std.out).toMatchInlineSnapshot(
|
|
417
420
|
`"writing the value \\"my-value\\" to key \\"my-key\\" on namespace some-namespace-id"`
|
|
418
421
|
);
|
|
419
|
-
expect(
|
|
420
|
-
expect(error).toMatchInlineSnapshot(`undefined`);
|
|
422
|
+
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
421
423
|
});
|
|
422
424
|
|
|
423
425
|
it("should put a key to the specified environment in a given namespace", async () => {
|
|
424
426
|
writeWranglerConfig();
|
|
425
|
-
const requests = mockKeyPutRequest(
|
|
426
|
-
"
|
|
427
|
-
"my-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
const { error, stderr, stdout } = await runWrangler(
|
|
427
|
+
const requests = mockKeyPutRequest("env-bound-id", {
|
|
428
|
+
key: "my-key",
|
|
429
|
+
value: "my-value",
|
|
430
|
+
});
|
|
431
|
+
await runWrangler(
|
|
431
432
|
"kv:key put my-key my-value --binding someBinding --env some-environment --preview false"
|
|
432
433
|
);
|
|
433
|
-
expect(
|
|
434
|
+
expect(std.out).toMatchInlineSnapshot(
|
|
434
435
|
`"writing the value \\"my-value\\" to key \\"my-key\\" on namespace env-bound-id"`
|
|
435
436
|
);
|
|
436
|
-
expect(
|
|
437
|
-
expect(error).toMatchInlineSnapshot(`undefined`);
|
|
437
|
+
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
438
438
|
expect(requests.count).toEqual(1);
|
|
439
439
|
});
|
|
440
440
|
|
|
441
441
|
it("should put a key with a value loaded from a given path", async () => {
|
|
442
442
|
writeFileSync("foo.txt", "file-contents", "utf-8");
|
|
443
|
-
const requests = mockKeyPutRequest(
|
|
444
|
-
"
|
|
445
|
-
"
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
const { error, stderr, stdout } = await runWrangler(
|
|
443
|
+
const requests = mockKeyPutRequest("some-namespace-id", {
|
|
444
|
+
key: "my-key",
|
|
445
|
+
value: "file-contents",
|
|
446
|
+
});
|
|
447
|
+
await runWrangler(
|
|
449
448
|
"kv:key put my-key --namespace-id some-namespace-id --path foo.txt"
|
|
450
449
|
);
|
|
451
|
-
expect(
|
|
450
|
+
expect(std.out).toMatchInlineSnapshot(
|
|
452
451
|
`"writing the contents of foo.txt to the key \\"my-key\\" on namespace some-namespace-id"`
|
|
453
452
|
);
|
|
454
|
-
expect(
|
|
455
|
-
expect(error).toMatchInlineSnapshot(`undefined`);
|
|
453
|
+
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
456
454
|
expect(requests.count).toEqual(1);
|
|
457
455
|
});
|
|
458
456
|
|
|
459
457
|
it("should error if no key is provided", async () => {
|
|
460
|
-
|
|
458
|
+
await expect(
|
|
459
|
+
runWrangler("kv:key put")
|
|
460
|
+
).rejects.toThrowErrorMatchingInlineSnapshot(
|
|
461
|
+
`"Not enough non-option arguments: got 0, need at least 1"`
|
|
462
|
+
);
|
|
461
463
|
|
|
462
|
-
expect(
|
|
463
|
-
expect(
|
|
464
|
+
expect(std.out).toMatchInlineSnapshot(`""`);
|
|
465
|
+
expect(std.err).toMatchInlineSnapshot(`
|
|
464
466
|
"wrangler kv:key put <key> [value]
|
|
465
467
|
|
|
466
468
|
Writes a single key/value pair to the given namespace.
|
|
467
469
|
|
|
468
470
|
Positionals:
|
|
469
|
-
key The key to write to
|
|
470
|
-
value The value to write
|
|
471
|
+
key The key to write to [string] [required]
|
|
472
|
+
value The value to write [string]
|
|
471
473
|
|
|
472
474
|
Flags:
|
|
473
|
-
-c, --config
|
|
474
|
-
-h, --help
|
|
475
|
-
-v, --version
|
|
475
|
+
-c, --config Path to .toml configuration file [string]
|
|
476
|
+
-h, --help Show help [boolean]
|
|
477
|
+
-v, --version Show version number [boolean]
|
|
478
|
+
--legacy-env Use legacy environments [boolean]
|
|
476
479
|
|
|
477
480
|
Options:
|
|
478
|
-
|
|
479
|
-
--
|
|
480
|
-
--namespace-id The id of the namespace to write to. [string]
|
|
481
|
+
--binding The binding of the namespace to write to [string]
|
|
482
|
+
--namespace-id The id of the namespace to write to [string]
|
|
481
483
|
--env Perform on a specific environment [string]
|
|
482
484
|
--preview Interact with a preview namespace [boolean]
|
|
483
|
-
--ttl Time for which the entries should be visible
|
|
485
|
+
--ttl Time for which the entries should be visible [number]
|
|
484
486
|
--expiration Time since the UNIX epoch after which the entry expires [number]
|
|
485
|
-
--path Read value from the file at a given path
|
|
487
|
+
--path Read value from the file at a given path [string]
|
|
486
488
|
|
|
487
489
|
Not enough non-option arguments: got 0, need at least 1"
|
|
488
490
|
`);
|
|
489
|
-
expect(error).toMatchInlineSnapshot(
|
|
490
|
-
`[Error: Not enough non-option arguments: got 0, need at least 1]`
|
|
491
|
-
);
|
|
492
491
|
});
|
|
493
492
|
|
|
494
493
|
it("should error if no binding nor namespace is provided", async () => {
|
|
495
|
-
|
|
496
|
-
"kv:key put foo bar"
|
|
494
|
+
await expect(
|
|
495
|
+
runWrangler("kv:key put foo bar")
|
|
496
|
+
).rejects.toThrowErrorMatchingInlineSnapshot(
|
|
497
|
+
`"Exactly one of the arguments binding and namespace-id is required"`
|
|
497
498
|
);
|
|
498
499
|
|
|
499
|
-
expect(
|
|
500
|
-
expect(
|
|
500
|
+
expect(std.out).toMatchInlineSnapshot(`""`);
|
|
501
|
+
expect(std.err).toMatchInlineSnapshot(`
|
|
501
502
|
"wrangler kv:key put <key> [value]
|
|
502
503
|
|
|
503
504
|
Writes a single key/value pair to the given namespace.
|
|
504
505
|
|
|
505
506
|
Positionals:
|
|
506
|
-
key The key to write to
|
|
507
|
-
value The value to write
|
|
507
|
+
key The key to write to [string] [required]
|
|
508
|
+
value The value to write [string]
|
|
508
509
|
|
|
509
510
|
Flags:
|
|
510
|
-
-c, --config
|
|
511
|
-
-h, --help
|
|
512
|
-
-v, --version
|
|
511
|
+
-c, --config Path to .toml configuration file [string]
|
|
512
|
+
-h, --help Show help [boolean]
|
|
513
|
+
-v, --version Show version number [boolean]
|
|
514
|
+
--legacy-env Use legacy environments [boolean]
|
|
513
515
|
|
|
514
516
|
Options:
|
|
515
|
-
|
|
516
|
-
--
|
|
517
|
-
--namespace-id The id of the namespace to write to. [string]
|
|
517
|
+
--binding The binding of the namespace to write to [string]
|
|
518
|
+
--namespace-id The id of the namespace to write to [string]
|
|
518
519
|
--env Perform on a specific environment [string]
|
|
519
520
|
--preview Interact with a preview namespace [boolean]
|
|
520
|
-
--ttl Time for which the entries should be visible
|
|
521
|
+
--ttl Time for which the entries should be visible [number]
|
|
521
522
|
--expiration Time since the UNIX epoch after which the entry expires [number]
|
|
522
|
-
--path Read value from the file at a given path
|
|
523
|
+
--path Read value from the file at a given path [string]
|
|
523
524
|
|
|
524
525
|
Exactly one of the arguments binding and namespace-id is required"
|
|
525
526
|
`);
|
|
526
|
-
expect(error).toMatchInlineSnapshot(
|
|
527
|
-
`[Error: Exactly one of the arguments binding and namespace-id is required]`
|
|
528
|
-
);
|
|
529
527
|
});
|
|
530
528
|
|
|
531
529
|
it("should error if both binding and namespace is provided", async () => {
|
|
532
|
-
|
|
533
|
-
"kv:key put foo bar --binding x --namespace-id y"
|
|
530
|
+
await expect(
|
|
531
|
+
runWrangler("kv:key put foo bar --binding x --namespace-id y")
|
|
532
|
+
).rejects.toThrowErrorMatchingInlineSnapshot(
|
|
533
|
+
`"Arguments binding and namespace-id are mutually exclusive"`
|
|
534
534
|
);
|
|
535
535
|
|
|
536
|
-
expect(
|
|
537
|
-
expect(
|
|
536
|
+
expect(std.out).toMatchInlineSnapshot(`""`);
|
|
537
|
+
expect(std.err).toMatchInlineSnapshot(`
|
|
538
538
|
"wrangler kv:key put <key> [value]
|
|
539
539
|
|
|
540
540
|
Writes a single key/value pair to the given namespace.
|
|
541
541
|
|
|
542
542
|
Positionals:
|
|
543
|
-
key The key to write to
|
|
544
|
-
value The value to write
|
|
543
|
+
key The key to write to [string] [required]
|
|
544
|
+
value The value to write [string]
|
|
545
545
|
|
|
546
546
|
Flags:
|
|
547
|
-
-c, --config
|
|
548
|
-
-h, --help
|
|
549
|
-
-v, --version
|
|
547
|
+
-c, --config Path to .toml configuration file [string]
|
|
548
|
+
-h, --help Show help [boolean]
|
|
549
|
+
-v, --version Show version number [boolean]
|
|
550
|
+
--legacy-env Use legacy environments [boolean]
|
|
550
551
|
|
|
551
552
|
Options:
|
|
552
|
-
|
|
553
|
-
--
|
|
554
|
-
--namespace-id The id of the namespace to write to. [string]
|
|
553
|
+
--binding The binding of the namespace to write to [string]
|
|
554
|
+
--namespace-id The id of the namespace to write to [string]
|
|
555
555
|
--env Perform on a specific environment [string]
|
|
556
556
|
--preview Interact with a preview namespace [boolean]
|
|
557
|
-
--ttl Time for which the entries should be visible
|
|
557
|
+
--ttl Time for which the entries should be visible [number]
|
|
558
558
|
--expiration Time since the UNIX epoch after which the entry expires [number]
|
|
559
|
-
--path Read value from the file at a given path
|
|
559
|
+
--path Read value from the file at a given path [string]
|
|
560
560
|
|
|
561
561
|
Arguments binding and namespace-id are mutually exclusive"
|
|
562
562
|
`);
|
|
563
|
-
expect(error).toMatchInlineSnapshot(
|
|
564
|
-
`[Error: Arguments binding and namespace-id are mutually exclusive]`
|
|
565
|
-
);
|
|
566
563
|
});
|
|
567
564
|
|
|
568
565
|
it("should error if no value nor path is provided", async () => {
|
|
569
|
-
|
|
570
|
-
"kv:key put key --namespace-id 12345"
|
|
566
|
+
await expect(
|
|
567
|
+
runWrangler("kv:key put key --namespace-id 12345")
|
|
568
|
+
).rejects.toThrowErrorMatchingInlineSnapshot(
|
|
569
|
+
`"Exactly one of the arguments value and path is required"`
|
|
571
570
|
);
|
|
572
571
|
|
|
573
|
-
expect(
|
|
574
|
-
expect(
|
|
572
|
+
expect(std.out).toMatchInlineSnapshot(`""`);
|
|
573
|
+
expect(std.err).toMatchInlineSnapshot(`
|
|
575
574
|
"wrangler kv:key put <key> [value]
|
|
576
575
|
|
|
577
576
|
Writes a single key/value pair to the given namespace.
|
|
578
577
|
|
|
579
578
|
Positionals:
|
|
580
|
-
key The key to write to
|
|
581
|
-
value The value to write
|
|
579
|
+
key The key to write to [string] [required]
|
|
580
|
+
value The value to write [string]
|
|
582
581
|
|
|
583
582
|
Flags:
|
|
584
|
-
-c, --config
|
|
585
|
-
-h, --help
|
|
586
|
-
-v, --version
|
|
583
|
+
-c, --config Path to .toml configuration file [string]
|
|
584
|
+
-h, --help Show help [boolean]
|
|
585
|
+
-v, --version Show version number [boolean]
|
|
586
|
+
--legacy-env Use legacy environments [boolean]
|
|
587
587
|
|
|
588
588
|
Options:
|
|
589
|
-
|
|
590
|
-
--
|
|
591
|
-
--namespace-id The id of the namespace to write to. [string]
|
|
589
|
+
--binding The binding of the namespace to write to [string]
|
|
590
|
+
--namespace-id The id of the namespace to write to [string]
|
|
592
591
|
--env Perform on a specific environment [string]
|
|
593
592
|
--preview Interact with a preview namespace [boolean]
|
|
594
|
-
--ttl Time for which the entries should be visible
|
|
593
|
+
--ttl Time for which the entries should be visible [number]
|
|
595
594
|
--expiration Time since the UNIX epoch after which the entry expires [number]
|
|
596
|
-
--path Read value from the file at a given path
|
|
595
|
+
--path Read value from the file at a given path [string]
|
|
597
596
|
|
|
598
597
|
Exactly one of the arguments value and path is required"
|
|
599
598
|
`);
|
|
600
|
-
expect(error).toMatchInlineSnapshot(
|
|
601
|
-
`[Error: Exactly one of the arguments value and path is required]`
|
|
602
|
-
);
|
|
603
599
|
});
|
|
604
600
|
|
|
605
601
|
it("should error if both value and path is provided", async () => {
|
|
606
|
-
|
|
607
|
-
"kv:key put key value --path xyz --namespace-id 12345"
|
|
602
|
+
await expect(
|
|
603
|
+
runWrangler("kv:key put key value --path xyz --namespace-id 12345")
|
|
604
|
+
).rejects.toThrowErrorMatchingInlineSnapshot(
|
|
605
|
+
`"Arguments value and path are mutually exclusive"`
|
|
608
606
|
);
|
|
609
607
|
|
|
610
|
-
expect(
|
|
611
|
-
expect(
|
|
608
|
+
expect(std.out).toMatchInlineSnapshot(`""`);
|
|
609
|
+
expect(std.err).toMatchInlineSnapshot(`
|
|
612
610
|
"wrangler kv:key put <key> [value]
|
|
613
611
|
|
|
614
612
|
Writes a single key/value pair to the given namespace.
|
|
615
613
|
|
|
616
614
|
Positionals:
|
|
617
|
-
key The key to write to
|
|
618
|
-
value The value to write
|
|
615
|
+
key The key to write to [string] [required]
|
|
616
|
+
value The value to write [string]
|
|
619
617
|
|
|
620
618
|
Flags:
|
|
621
|
-
-c, --config
|
|
622
|
-
-h, --help
|
|
623
|
-
-v, --version
|
|
619
|
+
-c, --config Path to .toml configuration file [string]
|
|
620
|
+
-h, --help Show help [boolean]
|
|
621
|
+
-v, --version Show version number [boolean]
|
|
622
|
+
--legacy-env Use legacy environments [boolean]
|
|
624
623
|
|
|
625
624
|
Options:
|
|
626
|
-
|
|
627
|
-
--
|
|
628
|
-
--namespace-id The id of the namespace to write to. [string]
|
|
625
|
+
--binding The binding of the namespace to write to [string]
|
|
626
|
+
--namespace-id The id of the namespace to write to [string]
|
|
629
627
|
--env Perform on a specific environment [string]
|
|
630
628
|
--preview Interact with a preview namespace [boolean]
|
|
631
|
-
--ttl Time for which the entries should be visible
|
|
629
|
+
--ttl Time for which the entries should be visible [number]
|
|
632
630
|
--expiration Time since the UNIX epoch after which the entry expires [number]
|
|
633
|
-
--path Read value from the file at a given path
|
|
631
|
+
--path Read value from the file at a given path [string]
|
|
634
632
|
|
|
635
633
|
Arguments value and path are mutually exclusive"
|
|
636
634
|
`);
|
|
637
|
-
expect(error).toMatchInlineSnapshot(
|
|
638
|
-
`[Error: Arguments value and path are mutually exclusive]`
|
|
639
|
-
);
|
|
640
635
|
});
|
|
641
636
|
|
|
642
637
|
it("should error if a given binding name is not in the configured kv namespaces", async () => {
|
|
643
638
|
writeWranglerConfig();
|
|
644
|
-
|
|
645
|
-
|
|
639
|
+
await expect(
|
|
640
|
+
runWrangler("kv:key put key value --binding otherBinding")
|
|
641
|
+
).rejects.toThrowErrorMatchingInlineSnapshot(
|
|
642
|
+
`"A namespace with binding name \\"otherBinding\\" was not found in the configured \\"kv_namespaces\\"."`
|
|
646
643
|
);
|
|
647
|
-
|
|
648
|
-
expect(
|
|
644
|
+
|
|
645
|
+
expect(std.out).toMatchInlineSnapshot(`""`);
|
|
646
|
+
expect(std.err).toMatchInlineSnapshot(`
|
|
649
647
|
"A namespace with binding name \\"otherBinding\\" was not found in the configured \\"kv_namespaces\\".
|
|
650
648
|
|
|
651
|
-
[32m%s[0m
|
|
652
|
-
If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new."
|
|
649
|
+
[32m%s[0m If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new."
|
|
653
650
|
`);
|
|
654
|
-
expect(error).toMatchInlineSnapshot(
|
|
655
|
-
`[Error: A namespace with binding name "otherBinding" was not found in the configured "kv_namespaces".]`
|
|
656
|
-
);
|
|
657
651
|
});
|
|
658
652
|
|
|
659
653
|
it("should error if a given binding has both preview and non-preview and --preview is not specified", async () => {
|
|
660
654
|
writeWranglerConfig();
|
|
661
|
-
const requests = mockKeyPutRequest(
|
|
662
|
-
"
|
|
663
|
-
"my-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
expect(
|
|
655
|
+
const requests = mockKeyPutRequest("preview-bound-id", {
|
|
656
|
+
key: "my-key",
|
|
657
|
+
value: "my-value",
|
|
658
|
+
});
|
|
659
|
+
await expect(
|
|
660
|
+
runWrangler("kv:key put my-key my-value --binding someBinding")
|
|
661
|
+
).rejects.toThrowErrorMatchingInlineSnapshot(
|
|
662
|
+
`"someBinding has both a namespace ID and a preview ID. Specify \\"--preview\\" or \\"--preview false\\" to avoid writing data to the wrong namespace."`
|
|
663
|
+
);
|
|
664
|
+
expect(std.out).toMatchInlineSnapshot(`""`);
|
|
665
|
+
expect(std.err).toMatchInlineSnapshot(`
|
|
671
666
|
"someBinding has both a namespace ID and a preview ID. Specify \\"--preview\\" or \\"--preview false\\" to avoid writing data to the wrong namespace.
|
|
672
667
|
|
|
673
|
-
[32m%s[0m
|
|
674
|
-
If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new."
|
|
668
|
+
[32m%s[0m If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new."
|
|
675
669
|
`);
|
|
676
|
-
expect(error).toMatchInlineSnapshot(
|
|
677
|
-
`[Error: someBinding has both a namespace ID and a preview ID. Specify "--preview" or "--preview false" to avoid writing data to the wrong namespace.]`
|
|
678
|
-
);
|
|
679
670
|
expect(requests.count).toEqual(0);
|
|
680
671
|
});
|
|
681
672
|
});
|
|
682
673
|
|
|
683
674
|
describe("list", () => {
|
|
684
675
|
it("should list the keys of a namespace specified by namespace-id", async () => {
|
|
685
|
-
const keys = [
|
|
676
|
+
const keys = [
|
|
677
|
+
{ name: "key-1" },
|
|
678
|
+
{ name: "key-2", expiration: 123456789 },
|
|
679
|
+
{ name: "key-3" },
|
|
680
|
+
];
|
|
686
681
|
mockKeyListRequest("some-namespace-id", keys);
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
)
|
|
690
|
-
expect(error).toMatchInlineSnapshot(`undefined`);
|
|
691
|
-
expect(stderr).toMatchInlineSnapshot(`""`);
|
|
692
|
-
expect(stdout).toMatchInlineSnapshot(`
|
|
682
|
+
await runWrangler("kv:key list --namespace-id some-namespace-id");
|
|
683
|
+
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
684
|
+
expect(std.out).toMatchInlineSnapshot(`
|
|
693
685
|
"[
|
|
694
686
|
{
|
|
695
|
-
\\"name\\": \\"key-1\\"
|
|
696
|
-
\\"expiration\\": 123456789,
|
|
697
|
-
\\"metadata\\": {}
|
|
687
|
+
\\"name\\": \\"key-1\\"
|
|
698
688
|
},
|
|
699
689
|
{
|
|
700
690
|
\\"name\\": \\"key-2\\",
|
|
701
|
-
\\"expiration\\": 123456789
|
|
702
|
-
\\"metadata\\": {}
|
|
691
|
+
\\"expiration\\": 123456789
|
|
703
692
|
},
|
|
704
693
|
{
|
|
705
|
-
\\"name\\": \\"key-3\\"
|
|
706
|
-
\\"expiration\\": 123456789,
|
|
707
|
-
\\"metadata\\": {}
|
|
694
|
+
\\"name\\": \\"key-3\\"
|
|
708
695
|
}
|
|
709
696
|
]"
|
|
710
697
|
`);
|
|
@@ -712,29 +699,21 @@ describe("wrangler", () => {
|
|
|
712
699
|
|
|
713
700
|
it("should list the keys of a namespace specified by binding", async () => {
|
|
714
701
|
writeWranglerConfig();
|
|
715
|
-
const keys = ["key-1", "key-2", "key-3"];
|
|
702
|
+
const keys = [{ name: "key-1" }, { name: "key-2" }, { name: "key-3" }];
|
|
716
703
|
mockKeyListRequest("bound-id", keys);
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
);
|
|
720
|
-
expect(
|
|
721
|
-
expect(stderr).toMatchInlineSnapshot(`""`);
|
|
722
|
-
expect(stdout).toMatchInlineSnapshot(`
|
|
704
|
+
|
|
705
|
+
await runWrangler("kv:key list --binding someBinding");
|
|
706
|
+
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
707
|
+
expect(std.out).toMatchInlineSnapshot(`
|
|
723
708
|
"[
|
|
724
709
|
{
|
|
725
|
-
\\"name\\": \\"key-1\\"
|
|
726
|
-
\\"expiration\\": 123456789,
|
|
727
|
-
\\"metadata\\": {}
|
|
710
|
+
\\"name\\": \\"key-1\\"
|
|
728
711
|
},
|
|
729
712
|
{
|
|
730
|
-
\\"name\\": \\"key-2\\"
|
|
731
|
-
\\"expiration\\": 123456789,
|
|
732
|
-
\\"metadata\\": {}
|
|
713
|
+
\\"name\\": \\"key-2\\"
|
|
733
714
|
},
|
|
734
715
|
{
|
|
735
|
-
\\"name\\": \\"key-3\\"
|
|
736
|
-
\\"expiration\\": 123456789,
|
|
737
|
-
\\"metadata\\": {}
|
|
716
|
+
\\"name\\": \\"key-3\\"
|
|
738
717
|
}
|
|
739
718
|
]"
|
|
740
719
|
`);
|
|
@@ -742,29 +721,20 @@ describe("wrangler", () => {
|
|
|
742
721
|
|
|
743
722
|
it("should list the keys of a preview namespace specified by binding", async () => {
|
|
744
723
|
writeWranglerConfig();
|
|
745
|
-
const keys = ["key-1", "key-2", "key-3"];
|
|
724
|
+
const keys = [{ name: "key-1" }, { name: "key-2" }, { name: "key-3" }];
|
|
746
725
|
mockKeyListRequest("preview-bound-id", keys);
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
)
|
|
750
|
-
expect(error).toMatchInlineSnapshot(`undefined`);
|
|
751
|
-
expect(stderr).toMatchInlineSnapshot(`""`);
|
|
752
|
-
expect(stdout).toMatchInlineSnapshot(`
|
|
726
|
+
await runWrangler("kv:key list --binding someBinding --preview");
|
|
727
|
+
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
728
|
+
expect(std.out).toMatchInlineSnapshot(`
|
|
753
729
|
"[
|
|
754
730
|
{
|
|
755
|
-
\\"name\\": \\"key-1\\"
|
|
756
|
-
\\"expiration\\": 123456789,
|
|
757
|
-
\\"metadata\\": {}
|
|
731
|
+
\\"name\\": \\"key-1\\"
|
|
758
732
|
},
|
|
759
733
|
{
|
|
760
|
-
\\"name\\": \\"key-2\\"
|
|
761
|
-
\\"expiration\\": 123456789,
|
|
762
|
-
\\"metadata\\": {}
|
|
734
|
+
\\"name\\": \\"key-2\\"
|
|
763
735
|
},
|
|
764
736
|
{
|
|
765
|
-
\\"name\\": \\"key-3\\"
|
|
766
|
-
\\"expiration\\": 123456789,
|
|
767
|
-
\\"metadata\\": {}
|
|
737
|
+
\\"name\\": \\"key-3\\"
|
|
768
738
|
}
|
|
769
739
|
]"
|
|
770
740
|
`);
|
|
@@ -772,29 +742,22 @@ describe("wrangler", () => {
|
|
|
772
742
|
|
|
773
743
|
it("should list the keys of a namespace specified by binding, in a given environment", async () => {
|
|
774
744
|
writeWranglerConfig();
|
|
775
|
-
const keys = ["key-1", "key-2", "key-3"];
|
|
745
|
+
const keys = [{ name: "key-1" }, { name: "key-2" }, { name: "key-3" }];
|
|
776
746
|
mockKeyListRequest("env-bound-id", keys);
|
|
777
|
-
|
|
747
|
+
await runWrangler(
|
|
778
748
|
"kv:key list --binding someBinding --env some-environment"
|
|
779
749
|
);
|
|
780
|
-
expect(
|
|
781
|
-
expect(
|
|
782
|
-
expect(stdout).toMatchInlineSnapshot(`
|
|
750
|
+
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
751
|
+
expect(std.out).toMatchInlineSnapshot(`
|
|
783
752
|
"[
|
|
784
753
|
{
|
|
785
|
-
\\"name\\": \\"key-1\\"
|
|
786
|
-
\\"expiration\\": 123456789,
|
|
787
|
-
\\"metadata\\": {}
|
|
754
|
+
\\"name\\": \\"key-1\\"
|
|
788
755
|
},
|
|
789
756
|
{
|
|
790
|
-
\\"name\\": \\"key-2\\"
|
|
791
|
-
\\"expiration\\": 123456789,
|
|
792
|
-
\\"metadata\\": {}
|
|
757
|
+
\\"name\\": \\"key-2\\"
|
|
793
758
|
},
|
|
794
759
|
{
|
|
795
|
-
\\"name\\": \\"key-3\\"
|
|
796
|
-
\\"expiration\\": 123456789,
|
|
797
|
-
\\"metadata\\": {}
|
|
760
|
+
\\"name\\": \\"key-3\\"
|
|
798
761
|
}
|
|
799
762
|
]"
|
|
800
763
|
`);
|
|
@@ -802,153 +765,143 @@ describe("wrangler", () => {
|
|
|
802
765
|
|
|
803
766
|
it("should list the keys of a preview namespace specified by binding, in a given environment", async () => {
|
|
804
767
|
writeWranglerConfig();
|
|
805
|
-
const keys = ["key-1", "key-2", "key-3"];
|
|
768
|
+
const keys = [{ name: "key-1" }, { name: "key-2" }, { name: "key-3" }];
|
|
806
769
|
mockKeyListRequest("preview-env-bound-id", keys);
|
|
807
|
-
|
|
770
|
+
await runWrangler(
|
|
808
771
|
"kv:key list --binding someBinding --preview --env some-environment"
|
|
809
772
|
);
|
|
810
|
-
expect(
|
|
811
|
-
expect(
|
|
812
|
-
expect(stdout).toMatchInlineSnapshot(`
|
|
773
|
+
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
774
|
+
expect(std.out).toMatchInlineSnapshot(`
|
|
813
775
|
"[
|
|
814
776
|
{
|
|
815
|
-
\\"name\\": \\"key-1\\"
|
|
816
|
-
\\"expiration\\": 123456789,
|
|
817
|
-
\\"metadata\\": {}
|
|
777
|
+
\\"name\\": \\"key-1\\"
|
|
818
778
|
},
|
|
819
779
|
{
|
|
820
|
-
\\"name\\": \\"key-2\\"
|
|
821
|
-
\\"expiration\\": 123456789,
|
|
822
|
-
\\"metadata\\": {}
|
|
780
|
+
\\"name\\": \\"key-2\\"
|
|
823
781
|
},
|
|
824
782
|
{
|
|
825
|
-
\\"name\\": \\"key-3\\"
|
|
826
|
-
\\"expiration\\": 123456789,
|
|
827
|
-
\\"metadata\\": {}
|
|
783
|
+
\\"name\\": \\"key-3\\"
|
|
828
784
|
}
|
|
829
785
|
]"
|
|
830
786
|
`);
|
|
831
787
|
});
|
|
832
788
|
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
"
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
789
|
+
// We'll run the next test with variations on the cursor
|
|
790
|
+
// that's returned on cloudflare's API after all results
|
|
791
|
+
// have been drained.
|
|
792
|
+
for (const blankCursorValue of [undefined, null, ""] as [
|
|
793
|
+
undefined,
|
|
794
|
+
null,
|
|
795
|
+
""
|
|
796
|
+
]) {
|
|
797
|
+
describe(`cursor - ${blankCursorValue}`, () => {
|
|
798
|
+
it("should make multiple requests for paginated results", async () => {
|
|
799
|
+
// Create a lot of mock keys, so that the fetch requests will be paginated
|
|
800
|
+
const keys: NamespaceKeyInfo[] = [];
|
|
801
|
+
for (let i = 0; i < 550; i++) {
|
|
802
|
+
keys.push({ name: "key-" + i });
|
|
803
|
+
}
|
|
804
|
+
// Ask for the keys in pages of size 100.
|
|
805
|
+
const requests = mockKeyListRequest(
|
|
806
|
+
"some-namespace-id",
|
|
807
|
+
keys,
|
|
808
|
+
100,
|
|
809
|
+
blankCursorValue
|
|
810
|
+
);
|
|
811
|
+
await runWrangler(
|
|
812
|
+
"kv:key list --namespace-id some-namespace-id --limit 100"
|
|
813
|
+
);
|
|
814
|
+
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
815
|
+
expect(JSON.parse(std.out)).toEqual(keys);
|
|
816
|
+
expect(requests.count).toEqual(6);
|
|
817
|
+
});
|
|
818
|
+
});
|
|
819
|
+
}
|
|
849
820
|
|
|
850
821
|
it("should error if a given binding name is not in the configured kv namespaces", async () => {
|
|
851
822
|
writeWranglerConfig();
|
|
852
|
-
|
|
853
|
-
"kv:key list --binding otherBinding"
|
|
854
|
-
)
|
|
855
|
-
|
|
856
|
-
`[Error: A namespace with binding name "otherBinding" was not found in the configured "kv_namespaces".]`
|
|
823
|
+
await expect(
|
|
824
|
+
runWrangler("kv:key list --binding otherBinding")
|
|
825
|
+
).rejects.toThrowErrorMatchingInlineSnapshot(
|
|
826
|
+
`"A namespace with binding name \\"otherBinding\\" was not found in the configured \\"kv_namespaces\\"."`
|
|
857
827
|
);
|
|
858
|
-
expect(
|
|
828
|
+
expect(std.err).toMatchInlineSnapshot(`
|
|
859
829
|
"A namespace with binding name \\"otherBinding\\" was not found in the configured \\"kv_namespaces\\".
|
|
860
830
|
|
|
861
|
-
[32m%s[0m
|
|
862
|
-
If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new."
|
|
831
|
+
[32m%s[0m If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new."
|
|
863
832
|
`);
|
|
864
|
-
expect(
|
|
833
|
+
expect(std.out).toMatchInlineSnapshot(`""`);
|
|
865
834
|
});
|
|
866
835
|
});
|
|
867
836
|
|
|
868
837
|
describe("get", () => {
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
expectedValue: string
|
|
873
|
-
) {
|
|
874
|
-
const requests = { count: 0 };
|
|
875
|
-
setMockRawResponse(
|
|
876
|
-
"/accounts/:accountId/storage/kv/namespaces/:namespaceId/values/:key",
|
|
877
|
-
([_url, accountId, namespaceId, key]) => {
|
|
878
|
-
requests.count++;
|
|
879
|
-
expect(accountId).toEqual("some-account-id");
|
|
880
|
-
expect(namespaceId).toEqual(expectedNamespaceId);
|
|
881
|
-
expect(key).toEqual(expectedKey);
|
|
882
|
-
return expectedValue;
|
|
883
|
-
}
|
|
884
|
-
);
|
|
885
|
-
return requests;
|
|
886
|
-
}
|
|
838
|
+
afterEach(() => {
|
|
839
|
+
unsetMockFetchKVGetValues();
|
|
840
|
+
});
|
|
887
841
|
|
|
888
842
|
it("should get a key in a given namespace specified by namespace-id", async () => {
|
|
889
|
-
|
|
843
|
+
setMockFetchKVGetValue(
|
|
844
|
+
"some-account-id",
|
|
890
845
|
"some-namespace-id",
|
|
891
846
|
"my-key",
|
|
892
847
|
"my-value"
|
|
893
848
|
);
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
);
|
|
897
|
-
expect(stdout).toMatchInlineSnapshot(`"my-value"`);
|
|
898
|
-
expect(stderr).toMatchInlineSnapshot(`""`);
|
|
899
|
-
expect(error).toMatchInlineSnapshot(`undefined`);
|
|
900
|
-
expect(requests.count).toEqual(1);
|
|
849
|
+
await runWrangler("kv:key get my-key --namespace-id some-namespace-id");
|
|
850
|
+
expect(std.out).toMatchInlineSnapshot(`"my-value"`);
|
|
851
|
+
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
901
852
|
});
|
|
902
853
|
|
|
903
854
|
it("should get a key in a given namespace specified by binding", async () => {
|
|
904
855
|
writeWranglerConfig();
|
|
905
|
-
|
|
906
|
-
|
|
856
|
+
setMockFetchKVGetValue(
|
|
857
|
+
"some-account-id",
|
|
858
|
+
"bound-id",
|
|
859
|
+
"my-key",
|
|
860
|
+
"my-value"
|
|
861
|
+
);
|
|
862
|
+
await runWrangler(
|
|
907
863
|
"kv:key get my-key --binding someBinding --preview false"
|
|
908
864
|
);
|
|
909
|
-
expect(
|
|
910
|
-
expect(
|
|
911
|
-
expect(error).toMatchInlineSnapshot(`undefined`);
|
|
912
|
-
expect(requests.count).toEqual(1);
|
|
865
|
+
expect(std.out).toMatchInlineSnapshot(`"my-value"`);
|
|
866
|
+
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
913
867
|
});
|
|
914
868
|
|
|
915
869
|
it("should get a key in a given preview namespace specified by binding", async () => {
|
|
916
870
|
writeWranglerConfig();
|
|
917
|
-
|
|
871
|
+
setMockFetchKVGetValue(
|
|
872
|
+
"some-account-id",
|
|
918
873
|
"preview-bound-id",
|
|
919
874
|
"my-key",
|
|
920
875
|
"my-value"
|
|
921
876
|
);
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
);
|
|
925
|
-
expect(stdout).toMatchInlineSnapshot(`"my-value"`);
|
|
926
|
-
expect(stderr).toMatchInlineSnapshot(`""`);
|
|
927
|
-
expect(error).toMatchInlineSnapshot(`undefined`);
|
|
928
|
-
expect(requests.count).toEqual(1);
|
|
877
|
+
await runWrangler("kv:key get my-key --binding someBinding --preview");
|
|
878
|
+
expect(std.out).toMatchInlineSnapshot(`"my-value"`);
|
|
879
|
+
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
929
880
|
});
|
|
930
881
|
|
|
931
882
|
it("should get a key for the specified environment in a given namespace", async () => {
|
|
932
883
|
writeWranglerConfig();
|
|
933
|
-
|
|
884
|
+
setMockFetchKVGetValue(
|
|
885
|
+
"some-account-id",
|
|
934
886
|
"env-bound-id",
|
|
935
887
|
"my-key",
|
|
936
888
|
"my-value"
|
|
937
889
|
);
|
|
938
|
-
|
|
890
|
+
await runWrangler(
|
|
939
891
|
"kv:key get my-key my-value --binding someBinding --env some-environment --preview false"
|
|
940
892
|
);
|
|
941
|
-
expect(
|
|
942
|
-
expect(
|
|
943
|
-
expect(error).toMatchInlineSnapshot(`undefined`);
|
|
944
|
-
expect(requests.count).toEqual(1);
|
|
893
|
+
expect(std.out).toMatchInlineSnapshot(`"my-value"`);
|
|
894
|
+
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
945
895
|
});
|
|
946
896
|
|
|
947
897
|
it("should error if no key is provided", async () => {
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
898
|
+
await expect(
|
|
899
|
+
runWrangler("kv:key get")
|
|
900
|
+
).rejects.toThrowErrorMatchingInlineSnapshot(
|
|
901
|
+
`"Not enough non-option arguments: got 0, need at least 1"`
|
|
902
|
+
);
|
|
903
|
+
expect(std.out).toMatchInlineSnapshot(`""`);
|
|
904
|
+
expect(std.err).toMatchInlineSnapshot(`
|
|
952
905
|
"wrangler kv:key get <key>
|
|
953
906
|
|
|
954
907
|
Reads a single value by key from the given namespace.
|
|
@@ -957,12 +910,12 @@ describe("wrangler", () => {
|
|
|
957
910
|
key The key value to get. [string] [required]
|
|
958
911
|
|
|
959
912
|
Flags:
|
|
960
|
-
-c, --config
|
|
961
|
-
-h, --help
|
|
962
|
-
-v, --version
|
|
913
|
+
-c, --config Path to .toml configuration file [string]
|
|
914
|
+
-h, --help Show help [boolean]
|
|
915
|
+
-v, --version Show version number [boolean]
|
|
916
|
+
--legacy-env Use legacy environments [boolean]
|
|
963
917
|
|
|
964
918
|
Options:
|
|
965
|
-
-l, --local Run on my machine [boolean] [default: false]
|
|
966
919
|
--binding The name of the namespace to get from [string]
|
|
967
920
|
--namespace-id The id of the namespace to get from [string]
|
|
968
921
|
--env Perform on a specific environment [string]
|
|
@@ -970,16 +923,16 @@ describe("wrangler", () => {
|
|
|
970
923
|
|
|
971
924
|
Not enough non-option arguments: got 0, need at least 1"
|
|
972
925
|
`);
|
|
973
|
-
expect(error).toMatchInlineSnapshot(
|
|
974
|
-
`[Error: Not enough non-option arguments: got 0, need at least 1]`
|
|
975
|
-
);
|
|
976
926
|
});
|
|
977
927
|
|
|
978
928
|
it("should error if no binding nor namespace is provided", async () => {
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
929
|
+
await expect(
|
|
930
|
+
runWrangler("kv:key get foo")
|
|
931
|
+
).rejects.toThrowErrorMatchingInlineSnapshot(
|
|
932
|
+
`"Exactly one of the arguments binding and namespace-id is required"`
|
|
933
|
+
);
|
|
934
|
+
expect(std.out).toMatchInlineSnapshot(`""`);
|
|
935
|
+
expect(std.err).toMatchInlineSnapshot(`
|
|
983
936
|
"wrangler kv:key get <key>
|
|
984
937
|
|
|
985
938
|
Reads a single value by key from the given namespace.
|
|
@@ -988,12 +941,12 @@ describe("wrangler", () => {
|
|
|
988
941
|
key The key value to get. [string] [required]
|
|
989
942
|
|
|
990
943
|
Flags:
|
|
991
|
-
-c, --config
|
|
992
|
-
-h, --help
|
|
993
|
-
-v, --version
|
|
944
|
+
-c, --config Path to .toml configuration file [string]
|
|
945
|
+
-h, --help Show help [boolean]
|
|
946
|
+
-v, --version Show version number [boolean]
|
|
947
|
+
--legacy-env Use legacy environments [boolean]
|
|
994
948
|
|
|
995
949
|
Options:
|
|
996
|
-
-l, --local Run on my machine [boolean] [default: false]
|
|
997
950
|
--binding The name of the namespace to get from [string]
|
|
998
951
|
--namespace-id The id of the namespace to get from [string]
|
|
999
952
|
--env Perform on a specific environment [string]
|
|
@@ -1001,18 +954,17 @@ describe("wrangler", () => {
|
|
|
1001
954
|
|
|
1002
955
|
Exactly one of the arguments binding and namespace-id is required"
|
|
1003
956
|
`);
|
|
1004
|
-
expect(error).toMatchInlineSnapshot(
|
|
1005
|
-
`[Error: Exactly one of the arguments binding and namespace-id is required]`
|
|
1006
|
-
);
|
|
1007
957
|
});
|
|
1008
958
|
|
|
1009
959
|
it("should error if both binding and namespace is provided", async () => {
|
|
1010
|
-
|
|
1011
|
-
"kv:key get foo --binding x --namespace-id y"
|
|
960
|
+
await expect(
|
|
961
|
+
runWrangler("kv:key get foo --binding x --namespace-id y")
|
|
962
|
+
).rejects.toThrowErrorMatchingInlineSnapshot(
|
|
963
|
+
`"Arguments binding and namespace-id are mutually exclusive"`
|
|
1012
964
|
);
|
|
1013
965
|
|
|
1014
|
-
expect(
|
|
1015
|
-
expect(
|
|
966
|
+
expect(std.out).toMatchInlineSnapshot(`""`);
|
|
967
|
+
expect(std.err).toMatchInlineSnapshot(`
|
|
1016
968
|
"wrangler kv:key get <key>
|
|
1017
969
|
|
|
1018
970
|
Reads a single value by key from the given namespace.
|
|
@@ -1021,12 +973,12 @@ describe("wrangler", () => {
|
|
|
1021
973
|
key The key value to get. [string] [required]
|
|
1022
974
|
|
|
1023
975
|
Flags:
|
|
1024
|
-
-c, --config
|
|
1025
|
-
-h, --help
|
|
1026
|
-
-v, --version
|
|
976
|
+
-c, --config Path to .toml configuration file [string]
|
|
977
|
+
-h, --help Show help [boolean]
|
|
978
|
+
-v, --version Show version number [boolean]
|
|
979
|
+
--legacy-env Use legacy environments [boolean]
|
|
1027
980
|
|
|
1028
981
|
Options:
|
|
1029
|
-
-l, --local Run on my machine [boolean] [default: false]
|
|
1030
982
|
--binding The name of the namespace to get from [string]
|
|
1031
983
|
--namespace-id The id of the namespace to get from [string]
|
|
1032
984
|
--env Perform on a specific environment [string]
|
|
@@ -1034,26 +986,21 @@ describe("wrangler", () => {
|
|
|
1034
986
|
|
|
1035
987
|
Arguments binding and namespace-id are mutually exclusive"
|
|
1036
988
|
`);
|
|
1037
|
-
expect(error).toMatchInlineSnapshot(
|
|
1038
|
-
`[Error: Arguments binding and namespace-id are mutually exclusive]`
|
|
1039
|
-
);
|
|
1040
989
|
});
|
|
1041
990
|
|
|
1042
991
|
it("should error if a given binding name is not in the configured kv namespaces", async () => {
|
|
1043
992
|
writeWranglerConfig();
|
|
1044
|
-
|
|
1045
|
-
|
|
993
|
+
await expect(
|
|
994
|
+
runWrangler("kv:key get key --binding otherBinding")
|
|
995
|
+
).rejects.toThrowErrorMatchingInlineSnapshot(
|
|
996
|
+
`"A namespace with binding name \\"otherBinding\\" was not found in the configured \\"kv_namespaces\\"."`
|
|
1046
997
|
);
|
|
1047
|
-
expect(
|
|
1048
|
-
expect(
|
|
998
|
+
expect(std.out).toMatchInlineSnapshot(`""`);
|
|
999
|
+
expect(std.err).toMatchInlineSnapshot(`
|
|
1049
1000
|
"A namespace with binding name \\"otherBinding\\" was not found in the configured \\"kv_namespaces\\".
|
|
1050
1001
|
|
|
1051
|
-
[32m%s[0m
|
|
1052
|
-
If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new."
|
|
1002
|
+
[32m%s[0m If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new."
|
|
1053
1003
|
`);
|
|
1054
|
-
expect(error).toMatchInlineSnapshot(
|
|
1055
|
-
`[Error: A namespace with binding name "otherBinding" was not found in the configured "kv_namespaces".]`
|
|
1056
|
-
);
|
|
1057
1004
|
});
|
|
1058
1005
|
});
|
|
1059
1006
|
|
|
@@ -1105,28 +1052,29 @@ describe("wrangler", () => {
|
|
|
1105
1052
|
|
|
1106
1053
|
it("should error if a given binding name is not in the configured kv namespaces", async () => {
|
|
1107
1054
|
writeWranglerConfig();
|
|
1108
|
-
|
|
1109
|
-
`kv:key delete --binding otherBinding someKey`
|
|
1055
|
+
await expect(
|
|
1056
|
+
runWrangler(`kv:key delete --binding otherBinding someKey`)
|
|
1057
|
+
).rejects.toThrowErrorMatchingInlineSnapshot(
|
|
1058
|
+
`"A namespace with binding name \\"otherBinding\\" was not found in the configured \\"kv_namespaces\\"."`
|
|
1110
1059
|
);
|
|
1111
|
-
|
|
1060
|
+
|
|
1061
|
+
expect(std.err).toMatchInlineSnapshot(`
|
|
1112
1062
|
"A namespace with binding name \\"otherBinding\\" was not found in the configured \\"kv_namespaces\\".
|
|
1113
1063
|
|
|
1114
|
-
[32m%s[0m
|
|
1115
|
-
If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new."
|
|
1064
|
+
[32m%s[0m If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new."
|
|
1116
1065
|
`);
|
|
1117
1066
|
});
|
|
1118
1067
|
|
|
1119
1068
|
it("should delete a key in a namespace specified by binding name in a given environment", async () => {
|
|
1120
1069
|
writeWranglerConfig();
|
|
1121
1070
|
const requests = mockDeleteRequest("env-bound-id", "someKey");
|
|
1122
|
-
|
|
1071
|
+
await runWrangler(
|
|
1123
1072
|
`kv:key delete --binding someBinding --env some-environment --preview false someKey`
|
|
1124
1073
|
);
|
|
1125
|
-
expect(
|
|
1074
|
+
expect(std.out).toMatchInlineSnapshot(
|
|
1126
1075
|
`"deleting the key \\"someKey\\" on namespace env-bound-id"`
|
|
1127
1076
|
);
|
|
1128
|
-
expect(
|
|
1129
|
-
expect(error).toMatchInlineSnapshot(`undefined`);
|
|
1077
|
+
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
1130
1078
|
expect(requests.count).toEqual(1);
|
|
1131
1079
|
});
|
|
1132
1080
|
|
|
@@ -1140,6 +1088,278 @@ describe("wrangler", () => {
|
|
|
1140
1088
|
});
|
|
1141
1089
|
});
|
|
1142
1090
|
});
|
|
1091
|
+
|
|
1092
|
+
describe("kv:bulk", () => {
|
|
1093
|
+
describe("put", () => {
|
|
1094
|
+
function mockPutRequest(
|
|
1095
|
+
expectedNamespaceId: string,
|
|
1096
|
+
expectedKeyValues: KeyValue[]
|
|
1097
|
+
) {
|
|
1098
|
+
const requests = { count: 0 };
|
|
1099
|
+
setMockResponse(
|
|
1100
|
+
"/accounts/:accountId/storage/kv/namespaces/:namespaceId/bulk",
|
|
1101
|
+
"PUT",
|
|
1102
|
+
([_url, accountId, namespaceId], { body }) => {
|
|
1103
|
+
requests.count++;
|
|
1104
|
+
expect(accountId).toEqual("some-account-id");
|
|
1105
|
+
expect(namespaceId).toEqual(expectedNamespaceId);
|
|
1106
|
+
expect(JSON.parse(body as string)).toEqual(
|
|
1107
|
+
expectedKeyValues.slice(
|
|
1108
|
+
(requests.count - 1) * 5000,
|
|
1109
|
+
requests.count * 5000
|
|
1110
|
+
)
|
|
1111
|
+
);
|
|
1112
|
+
return null;
|
|
1113
|
+
}
|
|
1114
|
+
);
|
|
1115
|
+
return requests;
|
|
1116
|
+
}
|
|
1117
|
+
|
|
1118
|
+
it("should put the key-values parsed from a file", async () => {
|
|
1119
|
+
const keyValues: KeyValue[] = [
|
|
1120
|
+
{ key: "someKey1", value: "someValue1" },
|
|
1121
|
+
{ key: "ns:someKey2", value: "123", base64: true },
|
|
1122
|
+
{ key: "someKey3", value: "someValue3", expiration: 100 },
|
|
1123
|
+
{ key: "someKey4", value: "someValue4", expiration_ttl: 500 },
|
|
1124
|
+
];
|
|
1125
|
+
writeFileSync("./keys.json", JSON.stringify(keyValues));
|
|
1126
|
+
const requests = mockPutRequest("some-namespace-id", keyValues);
|
|
1127
|
+
await runWrangler(
|
|
1128
|
+
`kv:bulk put --namespace-id some-namespace-id keys.json`
|
|
1129
|
+
);
|
|
1130
|
+
expect(requests.count).toEqual(1);
|
|
1131
|
+
expect(std.out).toMatchInlineSnapshot(`"Success!"`);
|
|
1132
|
+
expect(std.warn).toMatchInlineSnapshot(`""`);
|
|
1133
|
+
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
1134
|
+
});
|
|
1135
|
+
|
|
1136
|
+
it("should put the key-values in batches of 5000 parsed from a file", async () => {
|
|
1137
|
+
const keyValues: KeyValue[] = new Array(12000).fill({
|
|
1138
|
+
key: "someKey1",
|
|
1139
|
+
value: "someValue1",
|
|
1140
|
+
});
|
|
1141
|
+
writeFileSync("./keys.json", JSON.stringify(keyValues));
|
|
1142
|
+
const requests = mockPutRequest("some-namespace-id", keyValues);
|
|
1143
|
+
await runWrangler(
|
|
1144
|
+
`kv:bulk put --namespace-id some-namespace-id keys.json`
|
|
1145
|
+
);
|
|
1146
|
+
expect(requests.count).toEqual(3);
|
|
1147
|
+
expect(std.out).toMatchInlineSnapshot(`
|
|
1148
|
+
"Uploaded 0 of 12000.
|
|
1149
|
+
Uploaded 5000 of 12000.
|
|
1150
|
+
Uploaded 10000 of 12000.
|
|
1151
|
+
Uploaded 12000 of 12000.
|
|
1152
|
+
Success!"
|
|
1153
|
+
`);
|
|
1154
|
+
expect(std.warn).toMatchInlineSnapshot(`""`);
|
|
1155
|
+
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
1156
|
+
});
|
|
1157
|
+
|
|
1158
|
+
it("should error if the file is not a JSON array", async () => {
|
|
1159
|
+
const keyValues = { key: "someKey1", value: "someValue1" };
|
|
1160
|
+
writeFileSync("./keys.json", JSON.stringify(keyValues));
|
|
1161
|
+
await expect(
|
|
1162
|
+
runWrangler(`kv:bulk put --namespace-id some-namespace-id keys.json`)
|
|
1163
|
+
).rejects.toThrowErrorMatchingInlineSnapshot(`
|
|
1164
|
+
"Unexpected JSON input from \\"keys.json\\".
|
|
1165
|
+
Expected an array of key-value objects but got type \\"object\\"."
|
|
1166
|
+
`);
|
|
1167
|
+
expect(std.out).toMatchInlineSnapshot(`""`);
|
|
1168
|
+
expect(std.warn).toMatchInlineSnapshot(`""`);
|
|
1169
|
+
});
|
|
1170
|
+
|
|
1171
|
+
it("should error if the array contains items that are not key-value objects", async () => {
|
|
1172
|
+
const keyValues = [
|
|
1173
|
+
123,
|
|
1174
|
+
"a string",
|
|
1175
|
+
{ key: "someKey" },
|
|
1176
|
+
{ value: "someValue" },
|
|
1177
|
+
{ key: "someKey1", value: "someValue1", invalid: true },
|
|
1178
|
+
];
|
|
1179
|
+
writeFileSync("./keys.json", JSON.stringify(keyValues));
|
|
1180
|
+
await expect(
|
|
1181
|
+
runWrangler(`kv:bulk put --namespace-id some-namespace-id keys.json`)
|
|
1182
|
+
).rejects.toThrowErrorMatchingInlineSnapshot(`
|
|
1183
|
+
"Unexpected JSON input from \\"keys.json\\".
|
|
1184
|
+
Each item in the array should be an object that matches:
|
|
1185
|
+
|
|
1186
|
+
interface KeyValue {
|
|
1187
|
+
key: string;
|
|
1188
|
+
value: string;
|
|
1189
|
+
expiration?: number;
|
|
1190
|
+
expiration_ttl?: number;
|
|
1191
|
+
metadata?: object;
|
|
1192
|
+
base64?: boolean;
|
|
1193
|
+
}
|
|
1194
|
+
|
|
1195
|
+
The item at index 0 is type: \\"number\\" - 123
|
|
1196
|
+
The item at index 1 is type: \\"string\\" - \\"a string\\"
|
|
1197
|
+
The item at index 2 is {\\"key\\":\\"someKey\\"}
|
|
1198
|
+
The item at index 3 is {\\"value\\":\\"someValue\\"}"
|
|
1199
|
+
`);
|
|
1200
|
+
|
|
1201
|
+
expect(std.out).toMatchInlineSnapshot(`""`);
|
|
1202
|
+
expect(std.warn).toMatchInlineSnapshot(`
|
|
1203
|
+
"Unexpected key-value properties in \\"keys.json\\".
|
|
1204
|
+
The item at index 4 contains unexpected properties: [\\"invalid\\"]."
|
|
1205
|
+
`);
|
|
1206
|
+
});
|
|
1207
|
+
});
|
|
1208
|
+
|
|
1209
|
+
describe("delete", () => {
|
|
1210
|
+
function mockDeleteRequest(
|
|
1211
|
+
expectedNamespaceId: string,
|
|
1212
|
+
expectedKeys: string[]
|
|
1213
|
+
) {
|
|
1214
|
+
const requests = { count: 0 };
|
|
1215
|
+
setMockResponse(
|
|
1216
|
+
"/accounts/:accountId/storage/kv/namespaces/:namespaceId/bulk",
|
|
1217
|
+
"DELETE",
|
|
1218
|
+
([_url, accountId, namespaceId], { headers, body }) => {
|
|
1219
|
+
requests.count++;
|
|
1220
|
+
expect(accountId).toEqual("some-account-id");
|
|
1221
|
+
expect(namespaceId).toEqual(expectedNamespaceId);
|
|
1222
|
+
expect(new Headers(headers ?? []).get("Content-Type")).toEqual(
|
|
1223
|
+
"application/json"
|
|
1224
|
+
);
|
|
1225
|
+
expect(JSON.parse(body as string)).toEqual(
|
|
1226
|
+
expectedKeys.slice(
|
|
1227
|
+
(requests.count - 1) * 5000,
|
|
1228
|
+
requests.count * 5000
|
|
1229
|
+
)
|
|
1230
|
+
);
|
|
1231
|
+
return null;
|
|
1232
|
+
}
|
|
1233
|
+
);
|
|
1234
|
+
return requests;
|
|
1235
|
+
}
|
|
1236
|
+
|
|
1237
|
+
it("should delete the keys parsed from a file", async () => {
|
|
1238
|
+
const keys = ["someKey1", "ns:someKey2"];
|
|
1239
|
+
writeFileSync("./keys.json", JSON.stringify(keys));
|
|
1240
|
+
mockConfirm({
|
|
1241
|
+
text: `Are you sure you want to delete all the keys read from "keys.json" from kv-namespace with id "some-namespace-id"?`,
|
|
1242
|
+
result: true,
|
|
1243
|
+
});
|
|
1244
|
+
const requests = mockDeleteRequest("some-namespace-id", keys);
|
|
1245
|
+
await runWrangler(
|
|
1246
|
+
`kv:bulk delete --namespace-id some-namespace-id keys.json`
|
|
1247
|
+
);
|
|
1248
|
+
expect(requests.count).toEqual(1);
|
|
1249
|
+
expect(std.out).toMatchInlineSnapshot(`"Success!"`);
|
|
1250
|
+
expect(std.warn).toMatchInlineSnapshot(`""`);
|
|
1251
|
+
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
1252
|
+
});
|
|
1253
|
+
|
|
1254
|
+
it("should delete the keys in batches of 5000 parsed from a file", async () => {
|
|
1255
|
+
const keys = new Array(12000).fill("some-key");
|
|
1256
|
+
writeFileSync("./keys.json", JSON.stringify(keys));
|
|
1257
|
+
mockConfirm({
|
|
1258
|
+
text: `Are you sure you want to delete all the keys read from "keys.json" from kv-namespace with id "some-namespace-id"?`,
|
|
1259
|
+
result: true,
|
|
1260
|
+
});
|
|
1261
|
+
const requests = mockDeleteRequest("some-namespace-id", keys);
|
|
1262
|
+
await runWrangler(
|
|
1263
|
+
`kv:bulk delete --namespace-id some-namespace-id keys.json`
|
|
1264
|
+
);
|
|
1265
|
+
expect(requests.count).toEqual(3);
|
|
1266
|
+
expect(std.out).toMatchInlineSnapshot(`
|
|
1267
|
+
"Deleted 0 of 12000.
|
|
1268
|
+
Deleted 5000 of 12000.
|
|
1269
|
+
Deleted 10000 of 12000.
|
|
1270
|
+
Deleted 12000 of 12000.
|
|
1271
|
+
Success!"
|
|
1272
|
+
`);
|
|
1273
|
+
expect(std.warn).toMatchInlineSnapshot(`""`);
|
|
1274
|
+
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
1275
|
+
});
|
|
1276
|
+
|
|
1277
|
+
it("should not delete the keys if the user confirms no", async () => {
|
|
1278
|
+
const keys = ["someKey1", "ns:someKey2"];
|
|
1279
|
+
writeFileSync("./keys.json", JSON.stringify(keys));
|
|
1280
|
+
mockConfirm({
|
|
1281
|
+
text: `Are you sure you want to delete all the keys read from "keys.json" from kv-namespace with id "some-namespace-id"?`,
|
|
1282
|
+
result: false,
|
|
1283
|
+
});
|
|
1284
|
+
await runWrangler(
|
|
1285
|
+
`kv:bulk delete --namespace-id some-namespace-id keys.json`
|
|
1286
|
+
);
|
|
1287
|
+
expect(std.out).toMatchInlineSnapshot(
|
|
1288
|
+
`"Not deleting keys read from \\"keys.json\\"."`
|
|
1289
|
+
);
|
|
1290
|
+
expect(std.warn).toMatchInlineSnapshot(`""`);
|
|
1291
|
+
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
1292
|
+
});
|
|
1293
|
+
|
|
1294
|
+
it("should delete the keys without asking if --force is provided", async () => {
|
|
1295
|
+
const keys = ["someKey1", "ns:someKey2"];
|
|
1296
|
+
writeFileSync("./keys.json", JSON.stringify(keys));
|
|
1297
|
+
const requests = mockDeleteRequest("some-namespace-id", keys);
|
|
1298
|
+
await runWrangler(
|
|
1299
|
+
`kv:bulk delete --namespace-id some-namespace-id keys.json --force`
|
|
1300
|
+
);
|
|
1301
|
+
expect(requests.count).toEqual(1);
|
|
1302
|
+
expect(std.out).toMatchInlineSnapshot(`"Success!"`);
|
|
1303
|
+
expect(std.warn).toMatchInlineSnapshot(`""`);
|
|
1304
|
+
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
1305
|
+
});
|
|
1306
|
+
|
|
1307
|
+
it("should delete the keys without asking if -f is provided", async () => {
|
|
1308
|
+
const keys = ["someKey1", "ns:someKey2"];
|
|
1309
|
+
writeFileSync("./keys.json", JSON.stringify(keys));
|
|
1310
|
+
const requests = mockDeleteRequest("some-namespace-id", keys);
|
|
1311
|
+
await runWrangler(
|
|
1312
|
+
`kv:bulk delete --namespace-id some-namespace-id keys.json -f`
|
|
1313
|
+
);
|
|
1314
|
+
expect(requests.count).toEqual(1);
|
|
1315
|
+
expect(std.out).toMatchInlineSnapshot(`"Success!"`);
|
|
1316
|
+
expect(std.warn).toMatchInlineSnapshot(`""`);
|
|
1317
|
+
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
1318
|
+
});
|
|
1319
|
+
|
|
1320
|
+
it("should error if the file is not a JSON array", async () => {
|
|
1321
|
+
const keys = 12354;
|
|
1322
|
+
writeFileSync("./keys.json", JSON.stringify(keys));
|
|
1323
|
+
mockConfirm({
|
|
1324
|
+
text: `Are you sure you want to delete all the keys read from "keys.json" from kv-namespace with id "some-namespace-id"?`,
|
|
1325
|
+
result: true,
|
|
1326
|
+
});
|
|
1327
|
+
await expect(
|
|
1328
|
+
runWrangler(
|
|
1329
|
+
`kv:bulk delete --namespace-id some-namespace-id keys.json`
|
|
1330
|
+
)
|
|
1331
|
+
).rejects.toThrowErrorMatchingInlineSnapshot(`
|
|
1332
|
+
"Unexpected JSON input from \\"keys.json\\".
|
|
1333
|
+
Expected an array of strings but got:
|
|
1334
|
+
12354"
|
|
1335
|
+
`);
|
|
1336
|
+
expect(std.out).toMatchInlineSnapshot(`""`);
|
|
1337
|
+
expect(std.warn).toMatchInlineSnapshot(`""`);
|
|
1338
|
+
});
|
|
1339
|
+
|
|
1340
|
+
it("should error if the file contains non-string items", async () => {
|
|
1341
|
+
const keys = ["good", 12354, { key: "someKey" }, null];
|
|
1342
|
+
writeFileSync("./keys.json", JSON.stringify(keys));
|
|
1343
|
+
mockConfirm({
|
|
1344
|
+
text: `Are you sure you want to delete all the keys read from "keys.json" from kv-namespace with id "some-namespace-id"?`,
|
|
1345
|
+
result: true,
|
|
1346
|
+
});
|
|
1347
|
+
await expect(
|
|
1348
|
+
runWrangler(
|
|
1349
|
+
`kv:bulk delete --namespace-id some-namespace-id keys.json`
|
|
1350
|
+
)
|
|
1351
|
+
).rejects.toThrowErrorMatchingInlineSnapshot(`
|
|
1352
|
+
"Unexpected JSON input from \\"keys.json\\".
|
|
1353
|
+
Expected an array of strings.
|
|
1354
|
+
The item at index 1 is type: \\"number\\" - 12354
|
|
1355
|
+
The item at index 2 is type: \\"object\\" - {\\"key\\":\\"someKey\\"}
|
|
1356
|
+
The item at index 3 is type: \\"object\\" - null"
|
|
1357
|
+
`);
|
|
1358
|
+
expect(std.out).toMatchInlineSnapshot(`""`);
|
|
1359
|
+
expect(std.warn).toMatchInlineSnapshot(`""`);
|
|
1360
|
+
});
|
|
1361
|
+
});
|
|
1362
|
+
});
|
|
1143
1363
|
});
|
|
1144
1364
|
|
|
1145
1365
|
function writeWranglerConfig() {
|
|
@@ -1159,41 +1379,3 @@ function writeWranglerConfig() {
|
|
|
1159
1379
|
"utf-8"
|
|
1160
1380
|
);
|
|
1161
1381
|
}
|
|
1162
|
-
|
|
1163
|
-
export function mockKeyListRequest(
|
|
1164
|
-
expectedNamespaceId: string,
|
|
1165
|
-
expectedKeys: string[],
|
|
1166
|
-
keysPerRequest = 1000
|
|
1167
|
-
) {
|
|
1168
|
-
const requests = { count: 0 };
|
|
1169
|
-
// See https://api.cloudflare.com/#workers-kv-namespace-list-a-namespace-s-keys
|
|
1170
|
-
const expectedKeyObjects = expectedKeys.map((name) => ({
|
|
1171
|
-
name,
|
|
1172
|
-
expiration: 123456789,
|
|
1173
|
-
metadata: {},
|
|
1174
|
-
}));
|
|
1175
|
-
setMockRawResponse(
|
|
1176
|
-
"/accounts/:accountId/storage/kv/namespaces/:namespaceId/keys",
|
|
1177
|
-
"GET",
|
|
1178
|
-
([_url, accountId, namespaceId], _init, query) => {
|
|
1179
|
-
requests.count++;
|
|
1180
|
-
expect(accountId).toEqual("some-account-id");
|
|
1181
|
-
expect(namespaceId).toEqual(expectedNamespaceId);
|
|
1182
|
-
if (expectedKeyObjects.length <= keysPerRequest) {
|
|
1183
|
-
return createFetchResult(expectedKeyObjects);
|
|
1184
|
-
} else {
|
|
1185
|
-
const start = parseInt(query.get("cursor") ?? "0") || 0;
|
|
1186
|
-
const end = start + keysPerRequest;
|
|
1187
|
-
const cursor = end < expectedKeyObjects.length ? end : undefined;
|
|
1188
|
-
return createFetchResult(
|
|
1189
|
-
expectedKeyObjects.slice(start, end),
|
|
1190
|
-
true,
|
|
1191
|
-
[],
|
|
1192
|
-
[],
|
|
1193
|
-
{ cursor }
|
|
1194
|
-
);
|
|
1195
|
-
}
|
|
1196
|
-
}
|
|
1197
|
-
);
|
|
1198
|
-
return requests;
|
|
1199
|
-
}
|