wrangler 0.0.0-e22f9d7 → 0.0.0-e2b7352
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/README.md +3 -3
- package/bin/wrangler.js +12 -3
- package/miniflare-dist/index.mjs +79 -0
- package/miniflare-dist/index.mjs.map +7 -0
- package/package.json +33 -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 +2820 -0
- package/src/__tests__/dev.test.tsx +535 -61
- package/src/__tests__/guess-worker-format.test.ts +68 -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 +773 -77
- package/src/__tests__/jest.setup.ts +53 -6
- package/src/__tests__/kv.test.ts +725 -456
- package/src/__tests__/logout.test.ts +52 -0
- package/src/__tests__/package-manager.test.ts +206 -0
- package/src/__tests__/pages.test.ts +82 -0
- package/src/__tests__/parse.test.ts +322 -0
- package/src/__tests__/publish.test.ts +3509 -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 +638 -0
- package/src/__tests__/whoami.test.tsx +100 -0
- package/src/bundle.ts +155 -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 +218 -0
- package/src/config/diagnostics.ts +80 -0
- package/src/config/environment.ts +371 -0
- package/src/config/index.ts +62 -0
- package/src/config/validation-helpers.ts +554 -0
- package/src/config/validation.ts +1232 -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 +392 -0
- package/src/dev/local.tsx +232 -0
- package/src/dev/remote.tsx +203 -0
- package/src/dev/use-esbuild.ts +104 -0
- package/src/dialogs.tsx +2 -2
- package/src/entry.ts +240 -0
- package/src/environment-variables.ts +33 -0
- package/src/https-options.ts +122 -0
- package/src/index.tsx +1218 -803
- package/src/inspect.ts +103 -25
- package/src/intl-polyfill.d.ts +139 -0
- 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 +74 -44
- package/src/parse.ts +183 -0
- package/src/paths.ts +26 -0
- package/src/proxy.ts +177 -39
- package/src/publish.ts +286 -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 +278 -178
- 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 +130377 -112126
- 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
|
+
`"Unknown 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
|
+
Unknown 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,553 @@ 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("kv:key list --namespace-id some-namespace-id");
|
|
813
|
+
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
814
|
+
expect(JSON.parse(std.out)).toEqual(keys);
|
|
815
|
+
expect(requests.count).toEqual(6);
|
|
816
|
+
});
|
|
817
|
+
});
|
|
818
|
+
}
|
|
808
819
|
|
|
809
820
|
it("should error if a given binding name is not in the configured kv namespaces", async () => {
|
|
810
821
|
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(
|
|
822
|
+
await expect(
|
|
823
|
+
runWrangler("kv:key list --binding otherBinding")
|
|
824
|
+
).rejects.toThrowErrorMatchingInlineSnapshot(
|
|
818
825
|
`"A namespace with binding name \\"otherBinding\\" was not found in the configured \\"kv_namespaces\\"."`
|
|
819
826
|
);
|
|
820
|
-
expect(
|
|
827
|
+
expect(std.err).toMatchInlineSnapshot(`
|
|
828
|
+
"A namespace with binding name \\"otherBinding\\" was not found in the configured \\"kv_namespaces\\".
|
|
829
|
+
|
|
830
|
+
[32m%s[0m If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new."
|
|
831
|
+
`);
|
|
832
|
+
expect(std.out).toMatchInlineSnapshot(`""`);
|
|
821
833
|
});
|
|
822
834
|
});
|
|
823
835
|
|
|
824
836
|
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
|
-
}
|
|
837
|
+
afterEach(() => {
|
|
838
|
+
unsetMockFetchKVGetValues();
|
|
839
|
+
});
|
|
843
840
|
|
|
844
841
|
it("should get a key in a given namespace specified by namespace-id", async () => {
|
|
845
|
-
|
|
842
|
+
setMockFetchKVGetValue(
|
|
843
|
+
"some-account-id",
|
|
846
844
|
"some-namespace-id",
|
|
847
845
|
"my-key",
|
|
848
846
|
"my-value"
|
|
849
847
|
);
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
);
|
|
853
|
-
expect(stdout).toMatchInlineSnapshot(`"my-value"`);
|
|
854
|
-
expect(stderr).toMatchInlineSnapshot(`""`);
|
|
855
|
-
expect(error).toMatchInlineSnapshot(`undefined`);
|
|
856
|
-
expect(requests.count).toEqual(1);
|
|
848
|
+
await runWrangler("kv:key get my-key --namespace-id some-namespace-id");
|
|
849
|
+
expect(std.out).toMatchInlineSnapshot(`"my-value"`);
|
|
850
|
+
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
857
851
|
});
|
|
858
852
|
|
|
859
853
|
it("should get a key in a given namespace specified by binding", async () => {
|
|
860
854
|
writeWranglerConfig();
|
|
861
|
-
|
|
862
|
-
|
|
855
|
+
setMockFetchKVGetValue(
|
|
856
|
+
"some-account-id",
|
|
857
|
+
"bound-id",
|
|
858
|
+
"my-key",
|
|
859
|
+
"my-value"
|
|
860
|
+
);
|
|
861
|
+
await runWrangler(
|
|
863
862
|
"kv:key get my-key --binding someBinding --preview false"
|
|
864
863
|
);
|
|
865
|
-
expect(
|
|
866
|
-
expect(
|
|
867
|
-
expect(error).toMatchInlineSnapshot(`undefined`);
|
|
868
|
-
expect(requests.count).toEqual(1);
|
|
864
|
+
expect(std.out).toMatchInlineSnapshot(`"my-value"`);
|
|
865
|
+
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
869
866
|
});
|
|
870
867
|
|
|
871
868
|
it("should get a key in a given preview namespace specified by binding", async () => {
|
|
872
869
|
writeWranglerConfig();
|
|
873
|
-
|
|
870
|
+
setMockFetchKVGetValue(
|
|
871
|
+
"some-account-id",
|
|
874
872
|
"preview-bound-id",
|
|
875
873
|
"my-key",
|
|
876
874
|
"my-value"
|
|
877
875
|
);
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
);
|
|
881
|
-
expect(stdout).toMatchInlineSnapshot(`"my-value"`);
|
|
882
|
-
expect(stderr).toMatchInlineSnapshot(`""`);
|
|
883
|
-
expect(error).toMatchInlineSnapshot(`undefined`);
|
|
884
|
-
expect(requests.count).toEqual(1);
|
|
876
|
+
await runWrangler("kv:key get my-key --binding someBinding --preview");
|
|
877
|
+
expect(std.out).toMatchInlineSnapshot(`"my-value"`);
|
|
878
|
+
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
885
879
|
});
|
|
886
880
|
|
|
887
881
|
it("should get a key for the specified environment in a given namespace", async () => {
|
|
888
882
|
writeWranglerConfig();
|
|
889
|
-
|
|
883
|
+
setMockFetchKVGetValue(
|
|
884
|
+
"some-account-id",
|
|
890
885
|
"env-bound-id",
|
|
891
886
|
"my-key",
|
|
892
887
|
"my-value"
|
|
893
888
|
);
|
|
894
|
-
|
|
895
|
-
"kv:key get my-key
|
|
889
|
+
await runWrangler(
|
|
890
|
+
"kv:key get my-key --binding someBinding --env some-environment --preview false"
|
|
896
891
|
);
|
|
897
|
-
expect(
|
|
898
|
-
expect(
|
|
899
|
-
expect(error).toMatchInlineSnapshot(`undefined`);
|
|
900
|
-
expect(requests.count).toEqual(1);
|
|
892
|
+
expect(std.out).toMatchInlineSnapshot(`"my-value"`);
|
|
893
|
+
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
901
894
|
});
|
|
902
895
|
|
|
903
896
|
it("should error if no key is provided", async () => {
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
897
|
+
await expect(
|
|
898
|
+
runWrangler("kv:key get")
|
|
899
|
+
).rejects.toThrowErrorMatchingInlineSnapshot(
|
|
900
|
+
`"Not enough non-option arguments: got 0, need at least 1"`
|
|
901
|
+
);
|
|
902
|
+
expect(std.out).toMatchInlineSnapshot(`""`);
|
|
903
|
+
expect(std.err).toMatchInlineSnapshot(`
|
|
908
904
|
"wrangler kv:key get <key>
|
|
909
905
|
|
|
910
906
|
Reads a single value by key from the given namespace.
|
|
@@ -913,29 +909,29 @@ describe("wrangler", () => {
|
|
|
913
909
|
key The key value to get. [string] [required]
|
|
914
910
|
|
|
915
911
|
Flags:
|
|
916
|
-
-c, --config
|
|
917
|
-
-h, --help
|
|
918
|
-
-v, --version
|
|
912
|
+
-c, --config Path to .toml configuration file [string]
|
|
913
|
+
-h, --help Show help [boolean]
|
|
914
|
+
-v, --version Show version number [boolean]
|
|
915
|
+
--legacy-env Use legacy environments [boolean]
|
|
919
916
|
|
|
920
917
|
Options:
|
|
921
|
-
-l, --local Run on my machine [boolean] [default: false]
|
|
922
918
|
--binding The name of the namespace to get from [string]
|
|
923
919
|
--namespace-id The id of the namespace to get from [string]
|
|
924
|
-
|
|
920
|
+
-e, --env Perform on a specific environment [string]
|
|
925
921
|
--preview Interact with a preview namespace [boolean] [default: false]
|
|
926
922
|
|
|
927
923
|
Not enough non-option arguments: got 0, need at least 1"
|
|
928
924
|
`);
|
|
929
|
-
expect(error).toMatchInlineSnapshot(
|
|
930
|
-
`[Error: Not enough non-option arguments: got 0, need at least 1]`
|
|
931
|
-
);
|
|
932
925
|
});
|
|
933
926
|
|
|
934
927
|
it("should error if no binding nor namespace is provided", async () => {
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
928
|
+
await expect(
|
|
929
|
+
runWrangler("kv:key get foo")
|
|
930
|
+
).rejects.toThrowErrorMatchingInlineSnapshot(
|
|
931
|
+
`"Exactly one of the arguments binding and namespace-id is required"`
|
|
932
|
+
);
|
|
933
|
+
expect(std.out).toMatchInlineSnapshot(`""`);
|
|
934
|
+
expect(std.err).toMatchInlineSnapshot(`
|
|
939
935
|
"wrangler kv:key get <key>
|
|
940
936
|
|
|
941
937
|
Reads a single value by key from the given namespace.
|
|
@@ -944,31 +940,30 @@ describe("wrangler", () => {
|
|
|
944
940
|
key The key value to get. [string] [required]
|
|
945
941
|
|
|
946
942
|
Flags:
|
|
947
|
-
-c, --config
|
|
948
|
-
-h, --help
|
|
949
|
-
-v, --version
|
|
943
|
+
-c, --config Path to .toml configuration file [string]
|
|
944
|
+
-h, --help Show help [boolean]
|
|
945
|
+
-v, --version Show version number [boolean]
|
|
946
|
+
--legacy-env Use legacy environments [boolean]
|
|
950
947
|
|
|
951
948
|
Options:
|
|
952
|
-
-l, --local Run on my machine [boolean] [default: false]
|
|
953
949
|
--binding The name of the namespace to get from [string]
|
|
954
950
|
--namespace-id The id of the namespace to get from [string]
|
|
955
|
-
|
|
951
|
+
-e, --env Perform on a specific environment [string]
|
|
956
952
|
--preview Interact with a preview namespace [boolean] [default: false]
|
|
957
953
|
|
|
958
954
|
Exactly one of the arguments binding and namespace-id is required"
|
|
959
955
|
`);
|
|
960
|
-
expect(error).toMatchInlineSnapshot(
|
|
961
|
-
`[Error: Exactly one of the arguments binding and namespace-id is required]`
|
|
962
|
-
);
|
|
963
956
|
});
|
|
964
957
|
|
|
965
958
|
it("should error if both binding and namespace is provided", async () => {
|
|
966
|
-
|
|
967
|
-
"kv:key get foo --binding x --namespace-id y"
|
|
959
|
+
await expect(
|
|
960
|
+
runWrangler("kv:key get foo --binding x --namespace-id y")
|
|
961
|
+
).rejects.toThrowErrorMatchingInlineSnapshot(
|
|
962
|
+
`"Arguments binding and namespace-id are mutually exclusive"`
|
|
968
963
|
);
|
|
969
964
|
|
|
970
|
-
expect(
|
|
971
|
-
expect(
|
|
965
|
+
expect(std.out).toMatchInlineSnapshot(`""`);
|
|
966
|
+
expect(std.err).toMatchInlineSnapshot(`
|
|
972
967
|
"wrangler kv:key get <key>
|
|
973
968
|
|
|
974
969
|
Reads a single value by key from the given namespace.
|
|
@@ -977,36 +972,34 @@ describe("wrangler", () => {
|
|
|
977
972
|
key The key value to get. [string] [required]
|
|
978
973
|
|
|
979
974
|
Flags:
|
|
980
|
-
-c, --config
|
|
981
|
-
-h, --help
|
|
982
|
-
-v, --version
|
|
975
|
+
-c, --config Path to .toml configuration file [string]
|
|
976
|
+
-h, --help Show help [boolean]
|
|
977
|
+
-v, --version Show version number [boolean]
|
|
978
|
+
--legacy-env Use legacy environments [boolean]
|
|
983
979
|
|
|
984
980
|
Options:
|
|
985
|
-
-l, --local Run on my machine [boolean] [default: false]
|
|
986
981
|
--binding The name of the namespace to get from [string]
|
|
987
982
|
--namespace-id The id of the namespace to get from [string]
|
|
988
|
-
|
|
983
|
+
-e, --env Perform on a specific environment [string]
|
|
989
984
|
--preview Interact with a preview namespace [boolean] [default: false]
|
|
990
985
|
|
|
991
986
|
Arguments binding and namespace-id are mutually exclusive"
|
|
992
987
|
`);
|
|
993
|
-
expect(error).toMatchInlineSnapshot(
|
|
994
|
-
`[Error: Arguments binding and namespace-id are mutually exclusive]`
|
|
995
|
-
);
|
|
996
988
|
});
|
|
997
989
|
|
|
998
990
|
it("should error if a given binding name is not in the configured kv namespaces", async () => {
|
|
999
991
|
writeWranglerConfig();
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
)
|
|
1003
|
-
expect(stdout).toMatchInlineSnapshot(`""`);
|
|
1004
|
-
expect(stderr).toMatchInlineSnapshot(
|
|
992
|
+
await expect(
|
|
993
|
+
runWrangler("kv:key get key --binding otherBinding")
|
|
994
|
+
).rejects.toThrowErrorMatchingInlineSnapshot(
|
|
1005
995
|
`"A namespace with binding name \\"otherBinding\\" was not found in the configured \\"kv_namespaces\\"."`
|
|
1006
996
|
);
|
|
1007
|
-
expect(
|
|
1008
|
-
|
|
1009
|
-
|
|
997
|
+
expect(std.out).toMatchInlineSnapshot(`""`);
|
|
998
|
+
expect(std.err).toMatchInlineSnapshot(`
|
|
999
|
+
"A namespace with binding name \\"otherBinding\\" was not found in the configured \\"kv_namespaces\\".
|
|
1000
|
+
|
|
1001
|
+
[32m%s[0m If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new."
|
|
1002
|
+
`);
|
|
1010
1003
|
});
|
|
1011
1004
|
});
|
|
1012
1005
|
|
|
@@ -1058,25 +1051,29 @@ describe("wrangler", () => {
|
|
|
1058
1051
|
|
|
1059
1052
|
it("should error if a given binding name is not in the configured kv namespaces", async () => {
|
|
1060
1053
|
writeWranglerConfig();
|
|
1061
|
-
|
|
1062
|
-
`kv:key delete --binding otherBinding someKey`
|
|
1063
|
-
)
|
|
1064
|
-
expect(stderr).toMatchInlineSnapshot(
|
|
1054
|
+
await expect(
|
|
1055
|
+
runWrangler(`kv:key delete --binding otherBinding someKey`)
|
|
1056
|
+
).rejects.toThrowErrorMatchingInlineSnapshot(
|
|
1065
1057
|
`"A namespace with binding name \\"otherBinding\\" was not found in the configured \\"kv_namespaces\\"."`
|
|
1066
1058
|
);
|
|
1059
|
+
|
|
1060
|
+
expect(std.err).toMatchInlineSnapshot(`
|
|
1061
|
+
"A namespace with binding name \\"otherBinding\\" was not found in the configured \\"kv_namespaces\\".
|
|
1062
|
+
|
|
1063
|
+
[32m%s[0m If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new."
|
|
1064
|
+
`);
|
|
1067
1065
|
});
|
|
1068
1066
|
|
|
1069
1067
|
it("should delete a key in a namespace specified by binding name in a given environment", async () => {
|
|
1070
1068
|
writeWranglerConfig();
|
|
1071
1069
|
const requests = mockDeleteRequest("env-bound-id", "someKey");
|
|
1072
|
-
|
|
1070
|
+
await runWrangler(
|
|
1073
1071
|
`kv:key delete --binding someBinding --env some-environment --preview false someKey`
|
|
1074
1072
|
);
|
|
1075
|
-
expect(
|
|
1073
|
+
expect(std.out).toMatchInlineSnapshot(
|
|
1076
1074
|
`"deleting the key \\"someKey\\" on namespace env-bound-id"`
|
|
1077
1075
|
);
|
|
1078
|
-
expect(
|
|
1079
|
-
expect(error).toMatchInlineSnapshot(`undefined`);
|
|
1076
|
+
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
1080
1077
|
expect(requests.count).toEqual(1);
|
|
1081
1078
|
});
|
|
1082
1079
|
|
|
@@ -1090,6 +1087,278 @@ describe("wrangler", () => {
|
|
|
1090
1087
|
});
|
|
1091
1088
|
});
|
|
1092
1089
|
});
|
|
1090
|
+
|
|
1091
|
+
describe("kv:bulk", () => {
|
|
1092
|
+
describe("put", () => {
|
|
1093
|
+
function mockPutRequest(
|
|
1094
|
+
expectedNamespaceId: string,
|
|
1095
|
+
expectedKeyValues: KeyValue[]
|
|
1096
|
+
) {
|
|
1097
|
+
const requests = { count: 0 };
|
|
1098
|
+
setMockResponse(
|
|
1099
|
+
"/accounts/:accountId/storage/kv/namespaces/:namespaceId/bulk",
|
|
1100
|
+
"PUT",
|
|
1101
|
+
([_url, accountId, namespaceId], { body }) => {
|
|
1102
|
+
requests.count++;
|
|
1103
|
+
expect(accountId).toEqual("some-account-id");
|
|
1104
|
+
expect(namespaceId).toEqual(expectedNamespaceId);
|
|
1105
|
+
expect(JSON.parse(body as string)).toEqual(
|
|
1106
|
+
expectedKeyValues.slice(
|
|
1107
|
+
(requests.count - 1) * 5000,
|
|
1108
|
+
requests.count * 5000
|
|
1109
|
+
)
|
|
1110
|
+
);
|
|
1111
|
+
return null;
|
|
1112
|
+
}
|
|
1113
|
+
);
|
|
1114
|
+
return requests;
|
|
1115
|
+
}
|
|
1116
|
+
|
|
1117
|
+
it("should put the key-values parsed from a file", async () => {
|
|
1118
|
+
const keyValues: KeyValue[] = [
|
|
1119
|
+
{ key: "someKey1", value: "someValue1" },
|
|
1120
|
+
{ key: "ns:someKey2", value: "123", base64: true },
|
|
1121
|
+
{ key: "someKey3", value: "someValue3", expiration: 100 },
|
|
1122
|
+
{ key: "someKey4", value: "someValue4", expiration_ttl: 500 },
|
|
1123
|
+
];
|
|
1124
|
+
writeFileSync("./keys.json", JSON.stringify(keyValues));
|
|
1125
|
+
const requests = mockPutRequest("some-namespace-id", keyValues);
|
|
1126
|
+
await runWrangler(
|
|
1127
|
+
`kv:bulk put --namespace-id some-namespace-id keys.json`
|
|
1128
|
+
);
|
|
1129
|
+
expect(requests.count).toEqual(1);
|
|
1130
|
+
expect(std.out).toMatchInlineSnapshot(`"Success!"`);
|
|
1131
|
+
expect(std.warn).toMatchInlineSnapshot(`""`);
|
|
1132
|
+
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
1133
|
+
});
|
|
1134
|
+
|
|
1135
|
+
it("should put the key-values in batches of 5000 parsed from a file", async () => {
|
|
1136
|
+
const keyValues: KeyValue[] = new Array(12000).fill({
|
|
1137
|
+
key: "someKey1",
|
|
1138
|
+
value: "someValue1",
|
|
1139
|
+
});
|
|
1140
|
+
writeFileSync("./keys.json", JSON.stringify(keyValues));
|
|
1141
|
+
const requests = mockPutRequest("some-namespace-id", keyValues);
|
|
1142
|
+
await runWrangler(
|
|
1143
|
+
`kv:bulk put --namespace-id some-namespace-id keys.json`
|
|
1144
|
+
);
|
|
1145
|
+
expect(requests.count).toEqual(3);
|
|
1146
|
+
expect(std.out).toMatchInlineSnapshot(`
|
|
1147
|
+
"Uploaded 0 of 12000.
|
|
1148
|
+
Uploaded 5000 of 12000.
|
|
1149
|
+
Uploaded 10000 of 12000.
|
|
1150
|
+
Uploaded 12000 of 12000.
|
|
1151
|
+
Success!"
|
|
1152
|
+
`);
|
|
1153
|
+
expect(std.warn).toMatchInlineSnapshot(`""`);
|
|
1154
|
+
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
1155
|
+
});
|
|
1156
|
+
|
|
1157
|
+
it("should error if the file is not a JSON array", async () => {
|
|
1158
|
+
const keyValues = { key: "someKey1", value: "someValue1" };
|
|
1159
|
+
writeFileSync("./keys.json", JSON.stringify(keyValues));
|
|
1160
|
+
await expect(
|
|
1161
|
+
runWrangler(`kv:bulk put --namespace-id some-namespace-id keys.json`)
|
|
1162
|
+
).rejects.toThrowErrorMatchingInlineSnapshot(`
|
|
1163
|
+
"Unexpected JSON input from \\"keys.json\\".
|
|
1164
|
+
Expected an array of key-value objects but got type \\"object\\"."
|
|
1165
|
+
`);
|
|
1166
|
+
expect(std.out).toMatchInlineSnapshot(`""`);
|
|
1167
|
+
expect(std.warn).toMatchInlineSnapshot(`""`);
|
|
1168
|
+
});
|
|
1169
|
+
|
|
1170
|
+
it("should error if the array contains items that are not key-value objects", async () => {
|
|
1171
|
+
const keyValues = [
|
|
1172
|
+
123,
|
|
1173
|
+
"a string",
|
|
1174
|
+
{ key: "someKey" },
|
|
1175
|
+
{ value: "someValue" },
|
|
1176
|
+
{ key: "someKey1", value: "someValue1", invalid: true },
|
|
1177
|
+
];
|
|
1178
|
+
writeFileSync("./keys.json", JSON.stringify(keyValues));
|
|
1179
|
+
await expect(
|
|
1180
|
+
runWrangler(`kv:bulk put --namespace-id some-namespace-id keys.json`)
|
|
1181
|
+
).rejects.toThrowErrorMatchingInlineSnapshot(`
|
|
1182
|
+
"Unexpected JSON input from \\"keys.json\\".
|
|
1183
|
+
Each item in the array should be an object that matches:
|
|
1184
|
+
|
|
1185
|
+
interface KeyValue {
|
|
1186
|
+
key: string;
|
|
1187
|
+
value: string;
|
|
1188
|
+
expiration?: number;
|
|
1189
|
+
expiration_ttl?: number;
|
|
1190
|
+
metadata?: object;
|
|
1191
|
+
base64?: boolean;
|
|
1192
|
+
}
|
|
1193
|
+
|
|
1194
|
+
The item at index 0 is type: \\"number\\" - 123
|
|
1195
|
+
The item at index 1 is type: \\"string\\" - \\"a string\\"
|
|
1196
|
+
The item at index 2 is {\\"key\\":\\"someKey\\"}
|
|
1197
|
+
The item at index 3 is {\\"value\\":\\"someValue\\"}"
|
|
1198
|
+
`);
|
|
1199
|
+
|
|
1200
|
+
expect(std.out).toMatchInlineSnapshot(`""`);
|
|
1201
|
+
expect(std.warn).toMatchInlineSnapshot(`
|
|
1202
|
+
"Unexpected key-value properties in \\"keys.json\\".
|
|
1203
|
+
The item at index 4 contains unexpected properties: [\\"invalid\\"]."
|
|
1204
|
+
`);
|
|
1205
|
+
});
|
|
1206
|
+
});
|
|
1207
|
+
|
|
1208
|
+
describe("delete", () => {
|
|
1209
|
+
function mockDeleteRequest(
|
|
1210
|
+
expectedNamespaceId: string,
|
|
1211
|
+
expectedKeys: string[]
|
|
1212
|
+
) {
|
|
1213
|
+
const requests = { count: 0 };
|
|
1214
|
+
setMockResponse(
|
|
1215
|
+
"/accounts/:accountId/storage/kv/namespaces/:namespaceId/bulk",
|
|
1216
|
+
"DELETE",
|
|
1217
|
+
([_url, accountId, namespaceId], { headers, body }) => {
|
|
1218
|
+
requests.count++;
|
|
1219
|
+
expect(accountId).toEqual("some-account-id");
|
|
1220
|
+
expect(namespaceId).toEqual(expectedNamespaceId);
|
|
1221
|
+
expect(new Headers(headers ?? []).get("Content-Type")).toEqual(
|
|
1222
|
+
"application/json"
|
|
1223
|
+
);
|
|
1224
|
+
expect(JSON.parse(body as string)).toEqual(
|
|
1225
|
+
expectedKeys.slice(
|
|
1226
|
+
(requests.count - 1) * 5000,
|
|
1227
|
+
requests.count * 5000
|
|
1228
|
+
)
|
|
1229
|
+
);
|
|
1230
|
+
return null;
|
|
1231
|
+
}
|
|
1232
|
+
);
|
|
1233
|
+
return requests;
|
|
1234
|
+
}
|
|
1235
|
+
|
|
1236
|
+
it("should delete the keys parsed from a file", async () => {
|
|
1237
|
+
const keys = ["someKey1", "ns:someKey2"];
|
|
1238
|
+
writeFileSync("./keys.json", JSON.stringify(keys));
|
|
1239
|
+
mockConfirm({
|
|
1240
|
+
text: `Are you sure you want to delete all the keys read from "keys.json" from kv-namespace with id "some-namespace-id"?`,
|
|
1241
|
+
result: true,
|
|
1242
|
+
});
|
|
1243
|
+
const requests = mockDeleteRequest("some-namespace-id", keys);
|
|
1244
|
+
await runWrangler(
|
|
1245
|
+
`kv:bulk delete --namespace-id some-namespace-id keys.json`
|
|
1246
|
+
);
|
|
1247
|
+
expect(requests.count).toEqual(1);
|
|
1248
|
+
expect(std.out).toMatchInlineSnapshot(`"Success!"`);
|
|
1249
|
+
expect(std.warn).toMatchInlineSnapshot(`""`);
|
|
1250
|
+
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
1251
|
+
});
|
|
1252
|
+
|
|
1253
|
+
it("should delete the keys in batches of 5000 parsed from a file", async () => {
|
|
1254
|
+
const keys = new Array(12000).fill("some-key");
|
|
1255
|
+
writeFileSync("./keys.json", JSON.stringify(keys));
|
|
1256
|
+
mockConfirm({
|
|
1257
|
+
text: `Are you sure you want to delete all the keys read from "keys.json" from kv-namespace with id "some-namespace-id"?`,
|
|
1258
|
+
result: true,
|
|
1259
|
+
});
|
|
1260
|
+
const requests = mockDeleteRequest("some-namespace-id", keys);
|
|
1261
|
+
await runWrangler(
|
|
1262
|
+
`kv:bulk delete --namespace-id some-namespace-id keys.json`
|
|
1263
|
+
);
|
|
1264
|
+
expect(requests.count).toEqual(3);
|
|
1265
|
+
expect(std.out).toMatchInlineSnapshot(`
|
|
1266
|
+
"Deleted 0 of 12000.
|
|
1267
|
+
Deleted 5000 of 12000.
|
|
1268
|
+
Deleted 10000 of 12000.
|
|
1269
|
+
Deleted 12000 of 12000.
|
|
1270
|
+
Success!"
|
|
1271
|
+
`);
|
|
1272
|
+
expect(std.warn).toMatchInlineSnapshot(`""`);
|
|
1273
|
+
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
1274
|
+
});
|
|
1275
|
+
|
|
1276
|
+
it("should not delete the keys if the user confirms no", async () => {
|
|
1277
|
+
const keys = ["someKey1", "ns:someKey2"];
|
|
1278
|
+
writeFileSync("./keys.json", JSON.stringify(keys));
|
|
1279
|
+
mockConfirm({
|
|
1280
|
+
text: `Are you sure you want to delete all the keys read from "keys.json" from kv-namespace with id "some-namespace-id"?`,
|
|
1281
|
+
result: false,
|
|
1282
|
+
});
|
|
1283
|
+
await runWrangler(
|
|
1284
|
+
`kv:bulk delete --namespace-id some-namespace-id keys.json`
|
|
1285
|
+
);
|
|
1286
|
+
expect(std.out).toMatchInlineSnapshot(
|
|
1287
|
+
`"Not deleting keys read from \\"keys.json\\"."`
|
|
1288
|
+
);
|
|
1289
|
+
expect(std.warn).toMatchInlineSnapshot(`""`);
|
|
1290
|
+
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
1291
|
+
});
|
|
1292
|
+
|
|
1293
|
+
it("should delete the keys without asking if --force is provided", async () => {
|
|
1294
|
+
const keys = ["someKey1", "ns:someKey2"];
|
|
1295
|
+
writeFileSync("./keys.json", JSON.stringify(keys));
|
|
1296
|
+
const requests = mockDeleteRequest("some-namespace-id", keys);
|
|
1297
|
+
await runWrangler(
|
|
1298
|
+
`kv:bulk delete --namespace-id some-namespace-id keys.json --force`
|
|
1299
|
+
);
|
|
1300
|
+
expect(requests.count).toEqual(1);
|
|
1301
|
+
expect(std.out).toMatchInlineSnapshot(`"Success!"`);
|
|
1302
|
+
expect(std.warn).toMatchInlineSnapshot(`""`);
|
|
1303
|
+
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
1304
|
+
});
|
|
1305
|
+
|
|
1306
|
+
it("should delete the keys without asking if -f is provided", async () => {
|
|
1307
|
+
const keys = ["someKey1", "ns:someKey2"];
|
|
1308
|
+
writeFileSync("./keys.json", JSON.stringify(keys));
|
|
1309
|
+
const requests = mockDeleteRequest("some-namespace-id", keys);
|
|
1310
|
+
await runWrangler(
|
|
1311
|
+
`kv:bulk delete --namespace-id some-namespace-id keys.json -f`
|
|
1312
|
+
);
|
|
1313
|
+
expect(requests.count).toEqual(1);
|
|
1314
|
+
expect(std.out).toMatchInlineSnapshot(`"Success!"`);
|
|
1315
|
+
expect(std.warn).toMatchInlineSnapshot(`""`);
|
|
1316
|
+
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
1317
|
+
});
|
|
1318
|
+
|
|
1319
|
+
it("should error if the file is not a JSON array", async () => {
|
|
1320
|
+
const keys = 12354;
|
|
1321
|
+
writeFileSync("./keys.json", JSON.stringify(keys));
|
|
1322
|
+
mockConfirm({
|
|
1323
|
+
text: `Are you sure you want to delete all the keys read from "keys.json" from kv-namespace with id "some-namespace-id"?`,
|
|
1324
|
+
result: true,
|
|
1325
|
+
});
|
|
1326
|
+
await expect(
|
|
1327
|
+
runWrangler(
|
|
1328
|
+
`kv:bulk delete --namespace-id some-namespace-id keys.json`
|
|
1329
|
+
)
|
|
1330
|
+
).rejects.toThrowErrorMatchingInlineSnapshot(`
|
|
1331
|
+
"Unexpected JSON input from \\"keys.json\\".
|
|
1332
|
+
Expected an array of strings but got:
|
|
1333
|
+
12354"
|
|
1334
|
+
`);
|
|
1335
|
+
expect(std.out).toMatchInlineSnapshot(`""`);
|
|
1336
|
+
expect(std.warn).toMatchInlineSnapshot(`""`);
|
|
1337
|
+
});
|
|
1338
|
+
|
|
1339
|
+
it("should error if the file contains non-string items", async () => {
|
|
1340
|
+
const keys = ["good", 12354, { key: "someKey" }, null];
|
|
1341
|
+
writeFileSync("./keys.json", JSON.stringify(keys));
|
|
1342
|
+
mockConfirm({
|
|
1343
|
+
text: `Are you sure you want to delete all the keys read from "keys.json" from kv-namespace with id "some-namespace-id"?`,
|
|
1344
|
+
result: true,
|
|
1345
|
+
});
|
|
1346
|
+
await expect(
|
|
1347
|
+
runWrangler(
|
|
1348
|
+
`kv:bulk delete --namespace-id some-namespace-id keys.json`
|
|
1349
|
+
)
|
|
1350
|
+
).rejects.toThrowErrorMatchingInlineSnapshot(`
|
|
1351
|
+
"Unexpected JSON input from \\"keys.json\\".
|
|
1352
|
+
Expected an array of strings.
|
|
1353
|
+
The item at index 1 is type: \\"number\\" - 12354
|
|
1354
|
+
The item at index 2 is type: \\"object\\" - {\\"key\\":\\"someKey\\"}
|
|
1355
|
+
The item at index 3 is type: \\"object\\" - null"
|
|
1356
|
+
`);
|
|
1357
|
+
expect(std.out).toMatchInlineSnapshot(`""`);
|
|
1358
|
+
expect(std.warn).toMatchInlineSnapshot(`""`);
|
|
1359
|
+
});
|
|
1360
|
+
});
|
|
1361
|
+
});
|
|
1093
1362
|
});
|
|
1094
1363
|
|
|
1095
1364
|
function writeWranglerConfig() {
|