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