wrangler 0.0.0-e64812e → 0.0.0-e8e684c7
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 +27 -3
- package/bin/wrangler.js +150 -62
- package/kv-asset-handler.js +1 -0
- package/miniflare-dist/index.mjs +663 -7
- package/package.json +173 -152
- package/src/__tests__/config-cache-without-cache-dir.test.ts +38 -0
- package/src/__tests__/config-cache.test.ts +30 -24
- package/src/__tests__/configuration.test.ts +4015 -3363
- package/src/__tests__/dev.test.tsx +1290 -952
- package/src/__tests__/generate.test.ts +91 -0
- package/src/__tests__/guess-worker-format.test.ts +68 -68
- package/src/__tests__/helpers/cmd-shim.d.ts +6 -6
- package/src/__tests__/helpers/mock-account-id.ts +24 -24
- package/src/__tests__/helpers/mock-bin.ts +20 -20
- package/src/__tests__/helpers/mock-cfetch.ts +179 -94
- package/src/__tests__/helpers/mock-console.ts +49 -39
- package/src/__tests__/helpers/mock-dialogs.ts +94 -71
- package/src/__tests__/helpers/mock-get-zone-from-host.ts +8 -0
- package/src/__tests__/helpers/mock-http-server.ts +30 -30
- package/src/__tests__/helpers/mock-istty.ts +65 -18
- package/src/__tests__/helpers/mock-known-routes.ts +7 -0
- package/src/__tests__/helpers/mock-kv.ts +26 -26
- package/src/__tests__/helpers/mock-oauth-flow.ts +223 -228
- package/src/__tests__/helpers/mock-process.ts +39 -0
- package/src/__tests__/helpers/mock-stdin.ts +82 -77
- package/src/__tests__/helpers/mock-web-socket.ts +21 -21
- package/src/__tests__/helpers/run-in-tmp.ts +27 -28
- package/src/__tests__/helpers/run-wrangler.ts +8 -8
- package/src/__tests__/helpers/write-worker-source.ts +16 -16
- package/src/__tests__/helpers/write-wrangler-toml.ts +9 -9
- package/src/__tests__/https-options.test.ts +142 -109
- package/src/__tests__/index.test.ts +222 -233
- package/src/__tests__/init.test.ts +2139 -1603
- package/src/__tests__/jest.setup.ts +114 -34
- package/src/__tests__/kv.test.ts +1222 -1032
- package/src/__tests__/logger.test.ts +100 -74
- package/src/__tests__/metrics.test.ts +450 -0
- package/src/__tests__/package-manager.test.ts +303 -303
- package/src/__tests__/pages.test.ts +1173 -652
- package/src/__tests__/parse.test.ts +252 -252
- package/src/__tests__/publish.test.ts +6788 -5301
- package/src/__tests__/pubsub.test.ts +367 -0
- package/src/__tests__/r2.test.ts +328 -225
- package/src/__tests__/route.test.ts +18 -18
- package/src/__tests__/secret.test.ts +470 -459
- package/src/__tests__/tail.test.ts +676 -564
- package/src/__tests__/test-old-node-version.js +31 -0
- package/src/__tests__/user.test.ts +136 -112
- package/src/__tests__/validate-dev-props.test.ts +56 -0
- package/src/__tests__/version.test.ts +35 -0
- package/src/__tests__/whoami.test.tsx +267 -83
- package/src/__tests__/worker-namespace.test.ts +329 -0
- package/src/abort.d.ts +1 -1
- package/src/api/dev.ts +93 -0
- package/src/api/index.ts +1 -0
- package/src/bundle-reporter.tsx +29 -0
- package/src/bundle.ts +430 -157
- package/src/cfetch/index.ts +80 -80
- package/src/cfetch/internal.ts +244 -91
- package/src/cli.ts +21 -7
- package/src/config/config.ts +224 -195
- package/src/config/diagnostics.ts +61 -61
- package/src/config/environment.ts +422 -357
- package/src/config/index.ts +219 -193
- package/src/config/validation-helpers.ts +379 -357
- package/src/config/validation.ts +1690 -1367
- package/src/config-cache.ts +81 -41
- package/src/create-worker-preview.ts +208 -136
- package/src/create-worker-upload-form.ts +275 -238
- package/src/dev/dev-vars.ts +13 -13
- package/src/dev/dev.tsx +477 -351
- package/src/dev/local.tsx +426 -295
- package/src/dev/remote.tsx +406 -211
- package/src/dev/use-esbuild.ts +154 -94
- package/src/dev/validate-dev-props.ts +31 -0
- package/src/dev-registry.tsx +160 -0
- package/src/dev.tsx +696 -0
- package/src/dialogs.tsx +97 -97
- package/src/dispatch-namespace.ts +206 -0
- package/src/durable.ts +87 -87
- package/src/entry.ts +234 -228
- package/src/environment-variables.ts +23 -23
- package/src/errors.ts +6 -6
- package/src/faye-websocket.d.ts +6 -0
- package/src/generate.ts +131 -0
- package/src/git-client.ts +42 -0
- package/src/global-wrangler-config-path.ts +26 -0
- package/src/https-options.ts +84 -80
- package/src/index.tsx +2164 -2768
- package/src/init.ts +622 -0
- package/src/inspect.ts +678 -593
- package/src/intl-polyfill.d.ts +123 -123
- package/src/is-ci.ts +14 -0
- package/src/is-interactive.ts +12 -0
- package/src/kv.ts +299 -277
- package/src/logger.ts +46 -39
- package/src/metrics/index.ts +5 -0
- package/src/metrics/metrics-config.ts +239 -0
- package/src/metrics/metrics-dispatcher.ts +96 -0
- package/src/metrics/metrics-usage-headers.ts +24 -0
- package/src/metrics/send-event.ts +92 -0
- package/src/miniflare-cli/assets.ts +554 -0
- package/src/miniflare-cli/enum-keys.ts +8 -8
- package/src/miniflare-cli/index.ts +198 -32
- package/src/miniflare-cli/request-context.ts +18 -18
- package/src/module-collection.ts +212 -212
- package/src/open-in-browser.ts +4 -6
- package/src/package-manager.ts +173 -128
- package/src/pages/build.tsx +238 -0
- package/src/pages/constants.ts +12 -0
- package/src/pages/deployments.tsx +106 -0
- package/src/pages/dev.tsx +528 -0
- package/src/pages/errors.ts +22 -0
- package/src/pages/functions/buildPlugin.ts +109 -0
- package/src/pages/functions/buildWorker.ts +155 -0
- package/{pages → src/pages}/functions/filepath-routing.test.ts +113 -113
- package/src/pages/functions/filepath-routing.ts +189 -0
- package/src/pages/functions/identifiers.ts +78 -0
- package/src/pages/functions/routes-consolidation.test.ts +250 -0
- package/src/pages/functions/routes-consolidation.ts +73 -0
- package/src/pages/functions/routes-transformation.test.ts +271 -0
- package/src/pages/functions/routes-transformation.ts +122 -0
- package/src/pages/functions/routes.ts +151 -0
- package/src/pages/functions.tsx +96 -0
- package/src/pages/index.tsx +94 -0
- package/src/pages/projects.tsx +169 -0
- package/src/pages/publish.tsx +391 -0
- package/src/pages/types.ts +49 -0
- package/src/pages/upload.tsx +413 -0
- package/src/pages/utils.ts +12 -0
- package/src/parse.ts +209 -125
- package/src/paths.ts +6 -6
- package/src/preview.ts +31 -0
- package/src/proxy.ts +410 -389
- package/src/publish.ts +773 -534
- package/src/pubsub/index.ts +286 -0
- package/src/pubsub/pubsub-commands.tsx +623 -0
- package/src/r2.ts +100 -19
- package/src/selfsigned.d.ts +23 -23
- package/src/sites.tsx +278 -201
- package/src/tail/filters.ts +111 -109
- package/src/tail/index.ts +230 -217
- package/src/tail/printing.ts +86 -46
- package/src/update-check.ts +11 -11
- package/src/user/choose-account.tsx +69 -0
- package/src/user/env-vars.ts +46 -0
- package/src/user/generate-auth-url.ts +33 -0
- package/src/user/generate-random-state.ts +16 -0
- package/src/user/index.ts +3 -0
- package/src/user/user.tsx +1191 -0
- package/src/whoami.tsx +141 -42
- package/src/worker.ts +123 -99
- package/src/zones.ts +167 -0
- package/templates/checked-fetch.js +17 -0
- package/templates/first-party-worker-module-facade.ts +18 -0
- package/templates/format-dev-errors.ts +32 -0
- package/templates/new-worker-scheduled.js +3 -3
- package/templates/new-worker-scheduled.ts +15 -15
- package/templates/new-worker.js +3 -3
- package/templates/new-worker.ts +15 -15
- package/templates/no-op-worker.js +10 -0
- package/templates/pages-shim.ts +9 -0
- package/templates/pages-template-plugin.ts +167 -0
- package/templates/pages-template-worker.ts +172 -0
- package/templates/serve-static-assets.ts +63 -0
- package/templates/service-bindings-module-facade.js +54 -0
- package/templates/service-bindings-sw-facade.js +42 -0
- package/templates/tsconfig.json +95 -95
- package/wrangler-dist/cli.d.ts +338 -0
- package/wrangler-dist/cli.js +95449 -67524
- package/pages/functions/buildPlugin.ts +0 -105
- package/pages/functions/buildWorker.ts +0 -151
- package/pages/functions/filepath-routing.ts +0 -189
- package/pages/functions/identifiers.ts +0 -78
- package/pages/functions/routes.ts +0 -156
- package/pages/functions/template-plugin.ts +0 -147
- package/pages/functions/template-worker.ts +0 -143
- package/src/__tests__/helpers/faye-websocket.d.ts +0 -6
- package/src/pages.tsx +0 -2038
- package/src/user.tsx +0 -1203
- package/templates/static-asset-facade.js +0 -47
- package/vendor/@cloudflare/kv-asset-handler/CHANGELOG.md +0 -332
- package/vendor/@cloudflare/kv-asset-handler/LICENSE_APACHE +0 -176
- package/vendor/@cloudflare/kv-asset-handler/LICENSE_MIT +0 -25
- package/vendor/@cloudflare/kv-asset-handler/README.md +0 -245
- package/vendor/@cloudflare/kv-asset-handler/dist/index.d.ts +0 -32
- package/vendor/@cloudflare/kv-asset-handler/dist/index.js +0 -354
- package/vendor/@cloudflare/kv-asset-handler/dist/mocks.d.ts +0 -13
- package/vendor/@cloudflare/kv-asset-handler/dist/mocks.js +0 -148
- package/vendor/@cloudflare/kv-asset-handler/dist/test/getAssetFromKV.d.ts +0 -1
- package/vendor/@cloudflare/kv-asset-handler/dist/test/getAssetFromKV.js +0 -436
- package/vendor/@cloudflare/kv-asset-handler/dist/test/mapRequestToAsset.d.ts +0 -1
- package/vendor/@cloudflare/kv-asset-handler/dist/test/mapRequestToAsset.js +0 -40
- package/vendor/@cloudflare/kv-asset-handler/dist/test/serveSinglePageApp.d.ts +0 -1
- package/vendor/@cloudflare/kv-asset-handler/dist/test/serveSinglePageApp.js +0 -42
- package/vendor/@cloudflare/kv-asset-handler/dist/types.d.ts +0 -26
- package/vendor/@cloudflare/kv-asset-handler/dist/types.js +0 -31
- package/vendor/@cloudflare/kv-asset-handler/package.json +0 -52
- package/vendor/@cloudflare/kv-asset-handler/src/index.ts +0 -296
- package/vendor/@cloudflare/kv-asset-handler/src/mocks.ts +0 -136
- package/vendor/@cloudflare/kv-asset-handler/src/test/getAssetFromKV.ts +0 -464
- package/vendor/@cloudflare/kv-asset-handler/src/test/mapRequestToAsset.ts +0 -33
- package/vendor/@cloudflare/kv-asset-handler/src/test/serveSinglePageApp.ts +0 -42
- package/vendor/@cloudflare/kv-asset-handler/src/types.ts +0 -39
- package/vendor/wrangler-mime/CHANGELOG.md +0 -289
- package/vendor/wrangler-mime/LICENSE +0 -21
- package/vendor/wrangler-mime/Mime.js +0 -97
- package/vendor/wrangler-mime/README.md +0 -187
- package/vendor/wrangler-mime/cli.js +0 -46
- package/vendor/wrangler-mime/index.js +0 -4
- package/vendor/wrangler-mime/lite.js +0 -4
- package/vendor/wrangler-mime/package.json +0 -52
- package/vendor/wrangler-mime/types/other.js +0 -1
- package/vendor/wrangler-mime/types/standard.js +0 -1
package/src/__tests__/kv.test.ts
CHANGED
|
@@ -1,52 +1,58 @@
|
|
|
1
1
|
import { writeFileSync } from "node:fs";
|
|
2
|
-
import { Headers } from "undici";
|
|
2
|
+
import { FormData, Headers } from "undici";
|
|
3
3
|
import { mockAccountId, mockApiToken } from "./helpers/mock-account-id";
|
|
4
4
|
import {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
5
|
+
setMockResponse,
|
|
6
|
+
unsetAllMocks,
|
|
7
|
+
unsetSpecialMockFns,
|
|
8
|
+
setMockFetchKVGetValue,
|
|
9
|
+
setMockRawResponse,
|
|
10
|
+
createFetchResult,
|
|
9
11
|
} from "./helpers/mock-cfetch";
|
|
10
12
|
import { mockConsoleMethods } from "./helpers/mock-console";
|
|
11
13
|
import { clearConfirmMocks, mockConfirm } from "./helpers/mock-dialogs";
|
|
14
|
+
import { useMockIsTTY } from "./helpers/mock-istty";
|
|
12
15
|
import { mockKeyListRequest } from "./helpers/mock-kv";
|
|
16
|
+
import { mockGetMemberships } from "./helpers/mock-oauth-flow";
|
|
17
|
+
import { mockProcess } from "./helpers/mock-process";
|
|
13
18
|
import { runInTempDir } from "./helpers/run-in-tmp";
|
|
14
19
|
import { runWrangler } from "./helpers/run-wrangler";
|
|
15
20
|
import type { KeyValue, KVNamespaceInfo, NamespaceKeyInfo } from "../kv";
|
|
16
21
|
|
|
17
22
|
describe("wrangler", () => {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
23
|
+
mockAccountId();
|
|
24
|
+
mockApiToken();
|
|
25
|
+
runInTempDir();
|
|
26
|
+
const std = mockConsoleMethods();
|
|
27
|
+
const proc = mockProcess();
|
|
28
|
+
|
|
29
|
+
afterEach(() => {
|
|
30
|
+
unsetAllMocks();
|
|
31
|
+
clearConfirmMocks();
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
describe("kv:namespace", () => {
|
|
35
|
+
describe("create", () => {
|
|
36
|
+
function mockCreateRequest(expectedTitle: string) {
|
|
37
|
+
setMockResponse(
|
|
38
|
+
"/accounts/:accountId/storage/kv/namespaces",
|
|
39
|
+
"POST",
|
|
40
|
+
([_url, accountId], { body }) => {
|
|
41
|
+
expect(accountId).toEqual("some-account-id");
|
|
42
|
+
const title = JSON.parse(body as string).title;
|
|
43
|
+
expect(title).toEqual(expectedTitle);
|
|
44
|
+
return { id: "some-namespace-id" };
|
|
45
|
+
}
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
it("should error if no namespace is given", async () => {
|
|
50
|
+
await expect(
|
|
51
|
+
runWrangler("kv:namespace create")
|
|
52
|
+
).rejects.toThrowErrorMatchingInlineSnapshot(
|
|
53
|
+
`"Not enough non-option arguments: got 0, need at least 1"`
|
|
54
|
+
);
|
|
55
|
+
expect(std.out).toMatchInlineSnapshot(`
|
|
50
56
|
"
|
|
51
57
|
wrangler kv:namespace create <namespace>
|
|
52
58
|
|
|
@@ -64,20 +70,20 @@ describe("wrangler", () => {
|
|
|
64
70
|
-e, --env Perform on a specific environment [string]
|
|
65
71
|
--preview Interact with a preview namespace [boolean]"
|
|
66
72
|
`);
|
|
67
|
-
|
|
73
|
+
expect(std.err).toMatchInlineSnapshot(`
|
|
68
74
|
"[31mX [41;31m[[41;97mERROR[41;31m][0m [1mNot enough non-option arguments: got 0, need at least 1[0m
|
|
69
75
|
|
|
70
76
|
"
|
|
71
77
|
`);
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
it("should error if the namespace to create contains spaces", async () => {
|
|
81
|
+
await expect(
|
|
82
|
+
runWrangler("kv:namespace create abc def ghi")
|
|
83
|
+
).rejects.toThrowErrorMatchingInlineSnapshot(
|
|
84
|
+
`"Unknown arguments: def, ghi"`
|
|
85
|
+
);
|
|
86
|
+
expect(std.out).toMatchInlineSnapshot(`
|
|
81
87
|
"
|
|
82
88
|
wrangler kv:namespace create <namespace>
|
|
83
89
|
|
|
@@ -95,21 +101,21 @@ describe("wrangler", () => {
|
|
|
95
101
|
-e, --env Perform on a specific environment [string]
|
|
96
102
|
--preview Interact with a preview namespace [boolean]"
|
|
97
103
|
`);
|
|
98
|
-
|
|
104
|
+
expect(std.err).toMatchInlineSnapshot(`
|
|
99
105
|
"[31mX [41;31m[[41;97mERROR[41;31m][0m [1mUnknown arguments: def, ghi[0m
|
|
100
106
|
|
|
101
107
|
"
|
|
102
108
|
`);
|
|
103
|
-
|
|
109
|
+
});
|
|
104
110
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
+
it("should error if the namespace to create is not valid", async () => {
|
|
112
|
+
await expect(
|
|
113
|
+
runWrangler("kv:namespace create abc-def")
|
|
114
|
+
).rejects.toThrowErrorMatchingInlineSnapshot(
|
|
115
|
+
`"The namespace binding name \\"abc-def\\" is invalid. It can only have alphanumeric and _ characters, and cannot begin with a number."`
|
|
116
|
+
);
|
|
111
117
|
|
|
112
|
-
|
|
118
|
+
expect(std.out).toMatchInlineSnapshot(`
|
|
113
119
|
"
|
|
114
120
|
wrangler kv:namespace create <namespace>
|
|
115
121
|
|
|
@@ -127,350 +133,400 @@ describe("wrangler", () => {
|
|
|
127
133
|
-e, --env Perform on a specific environment [string]
|
|
128
134
|
--preview Interact with a preview namespace [boolean]"
|
|
129
135
|
`);
|
|
130
|
-
|
|
136
|
+
expect(std.err).toMatchInlineSnapshot(`
|
|
131
137
|
"[31mX [41;31m[[41;97mERROR[41;31m][0m [1mThe namespace binding name \\"abc-def\\" is invalid. It can only have alphanumeric and _ characters, and cannot begin with a number.[0m
|
|
132
138
|
|
|
133
139
|
"
|
|
134
140
|
`);
|
|
135
|
-
|
|
141
|
+
});
|
|
136
142
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
143
|
+
it("should create a namespace", async () => {
|
|
144
|
+
mockCreateRequest("worker-UnitTestNamespace");
|
|
145
|
+
await runWrangler("kv:namespace create UnitTestNamespace");
|
|
146
|
+
expect(std.out).toMatchInlineSnapshot(`
|
|
141
147
|
"🌀 Creating namespace with title \\"worker-UnitTestNamespace\\"
|
|
142
148
|
✨ Success!
|
|
143
149
|
Add the following to your configuration file in your kv_namespaces array:
|
|
144
150
|
{ binding = \\"UnitTestNamespace\\", id = \\"some-namespace-id\\" }"
|
|
145
151
|
`);
|
|
146
|
-
|
|
152
|
+
});
|
|
147
153
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
154
|
+
it("should create a preview namespace if configured to do so", async () => {
|
|
155
|
+
mockCreateRequest("worker-UnitTestNamespace_preview");
|
|
156
|
+
await runWrangler("kv:namespace create UnitTestNamespace --preview");
|
|
157
|
+
expect(std.out).toMatchInlineSnapshot(`
|
|
152
158
|
"🌀 Creating namespace with title \\"worker-UnitTestNamespace_preview\\"
|
|
153
159
|
✨ Success!
|
|
154
160
|
Add the following to your configuration file in your kv_namespaces array:
|
|
155
161
|
{ binding = \\"UnitTestNamespace\\", preview_id = \\"some-namespace-id\\" }"
|
|
156
162
|
`);
|
|
157
|
-
|
|
163
|
+
});
|
|
158
164
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
165
|
+
it("should create a namespace using configured worker name", async () => {
|
|
166
|
+
writeFileSync("./wrangler.toml", 'name = "other-worker"', "utf-8");
|
|
167
|
+
mockCreateRequest("other-worker-UnitTestNamespace");
|
|
168
|
+
await runWrangler("kv:namespace create UnitTestNamespace");
|
|
169
|
+
expect(std.out).toMatchInlineSnapshot(`
|
|
164
170
|
"🌀 Creating namespace with title \\"other-worker-UnitTestNamespace\\"
|
|
165
171
|
✨ Success!
|
|
166
172
|
Add the following to your configuration file in your kv_namespaces array:
|
|
167
173
|
{ binding = \\"UnitTestNamespace\\", id = \\"some-namespace-id\\" }"
|
|
168
174
|
`);
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
it("should create a namespace in an environment if configured to do so", async () => {
|
|
178
|
+
mockCreateRequest("worker-customEnv-UnitTestNamespace");
|
|
179
|
+
await runWrangler(
|
|
180
|
+
"kv:namespace create UnitTestNamespace --env customEnv"
|
|
181
|
+
);
|
|
182
|
+
expect(std.out).toMatchInlineSnapshot(`
|
|
177
183
|
"🌀 Creating namespace with title \\"worker-customEnv-UnitTestNamespace\\"
|
|
178
184
|
✨ Success!
|
|
179
185
|
Add the following to your configuration file in your kv_namespaces array under [env.customEnv]:
|
|
180
186
|
{ binding = \\"UnitTestNamespace\\", id = \\"some-namespace-id\\" }"
|
|
181
187
|
`);
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
188
|
+
});
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
describe("list", () => {
|
|
192
|
+
function mockListRequest(namespaces: unknown[]) {
|
|
193
|
+
const requests = { count: 0 };
|
|
194
|
+
setMockResponse(
|
|
195
|
+
"/accounts/:accountId/storage/kv/namespaces",
|
|
196
|
+
([_url, accountId], init, query) => {
|
|
197
|
+
requests.count++;
|
|
198
|
+
expect(accountId).toEqual("some-account-id");
|
|
199
|
+
expect(query.get("per_page")).toEqual("100");
|
|
200
|
+
expect(query.get("order")).toEqual("title");
|
|
201
|
+
expect(query.get("direction")).toEqual("asc");
|
|
202
|
+
expect(query.get("page")).toEqual(`${requests.count}`);
|
|
203
|
+
expect(init).toEqual({});
|
|
204
|
+
const pageSize = Number(query.get("per_page"));
|
|
205
|
+
const page = Number(query.get("page"));
|
|
206
|
+
return namespaces.slice((page - 1) * pageSize, page * pageSize);
|
|
207
|
+
}
|
|
208
|
+
);
|
|
209
|
+
return requests;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
it("should list namespaces", async () => {
|
|
213
|
+
const kvNamespaces: KVNamespaceInfo[] = [
|
|
214
|
+
{ title: "title-1", id: "id-1" },
|
|
215
|
+
{ title: "title-2", id: "id-2" },
|
|
216
|
+
];
|
|
217
|
+
mockListRequest(kvNamespaces);
|
|
218
|
+
await runWrangler("kv:namespace list");
|
|
219
|
+
|
|
220
|
+
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
221
|
+
const namespaces = JSON.parse(std.out);
|
|
222
|
+
expect(namespaces).toEqual(kvNamespaces);
|
|
223
|
+
});
|
|
224
|
+
|
|
225
|
+
it("should make multiple requests for paginated results", async () => {
|
|
226
|
+
// Create a lot of mock namespaces, so that the fetch requests will be paginated
|
|
227
|
+
const kvNamespaces: KVNamespaceInfo[] = [];
|
|
228
|
+
for (let i = 0; i < 550; i++) {
|
|
229
|
+
kvNamespaces.push({ title: "title-" + i, id: "id-" + i });
|
|
230
|
+
}
|
|
231
|
+
const requests = mockListRequest(kvNamespaces);
|
|
232
|
+
await runWrangler("kv:namespace list");
|
|
233
|
+
const namespaces = JSON.parse(std.out);
|
|
234
|
+
expect(namespaces).toEqual(kvNamespaces);
|
|
235
|
+
expect(requests.count).toEqual(6);
|
|
236
|
+
});
|
|
237
|
+
});
|
|
238
|
+
|
|
239
|
+
describe("delete", () => {
|
|
240
|
+
function mockDeleteRequest(expectedNamespaceId: string) {
|
|
241
|
+
const requests = { count: 0 };
|
|
242
|
+
setMockResponse(
|
|
243
|
+
"/accounts/:accountId/storage/kv/namespaces/:namespaceId",
|
|
244
|
+
"DELETE",
|
|
245
|
+
([_url, accountId, namespaceId]) => {
|
|
246
|
+
requests.count++;
|
|
247
|
+
expect(accountId).toEqual("some-account-id");
|
|
248
|
+
expect(namespaceId).toEqual(expectedNamespaceId);
|
|
249
|
+
return null;
|
|
250
|
+
}
|
|
251
|
+
);
|
|
252
|
+
return requests;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
it("should delete a namespace specified by id", async () => {
|
|
256
|
+
const requests = mockDeleteRequest("some-namespace-id");
|
|
257
|
+
await runWrangler(
|
|
258
|
+
`kv:namespace delete --namespace-id some-namespace-id`
|
|
259
|
+
);
|
|
260
|
+
expect(requests.count).toEqual(1);
|
|
261
|
+
});
|
|
262
|
+
|
|
263
|
+
it("should delete a namespace specified by binding name", async () => {
|
|
264
|
+
writeWranglerConfig();
|
|
265
|
+
const requests = mockDeleteRequest("bound-id");
|
|
266
|
+
await runWrangler(
|
|
267
|
+
`kv:namespace delete --binding someBinding --preview false`
|
|
268
|
+
);
|
|
269
|
+
expect(requests.count).toEqual(1);
|
|
270
|
+
});
|
|
271
|
+
|
|
272
|
+
it("should delete a preview namespace specified by binding name", async () => {
|
|
273
|
+
writeWranglerConfig();
|
|
274
|
+
const requests = mockDeleteRequest("preview-bound-id");
|
|
275
|
+
await runWrangler(
|
|
276
|
+
`kv:namespace delete --binding someBinding --preview`
|
|
277
|
+
);
|
|
278
|
+
expect(requests.count).toEqual(1);
|
|
279
|
+
});
|
|
280
|
+
|
|
281
|
+
it("should error if a given binding name is not in the configured kv namespaces", async () => {
|
|
282
|
+
writeWranglerConfig();
|
|
283
|
+
await expect(runWrangler("kv:namespace delete --binding otherBinding"))
|
|
284
|
+
.rejects.toThrowErrorMatchingInlineSnapshot(`
|
|
285
|
+
"Not able to delete namespace.
|
|
286
|
+
A namespace with binding name \\"otherBinding\\" was not found in the configured \\"kv_namespaces\\"."
|
|
287
|
+
`);
|
|
288
|
+
expect(std.err).toMatchInlineSnapshot(`
|
|
283
289
|
"[31mX [41;31m[[41;97mERROR[41;31m][0m [1mNot able to delete namespace.[0m
|
|
284
290
|
|
|
285
291
|
A namespace with binding name \\"otherBinding\\" was not found in the configured \\"kv_namespaces\\".
|
|
286
292
|
|
|
287
293
|
"
|
|
288
294
|
`);
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
295
|
+
});
|
|
296
|
+
|
|
297
|
+
it("should delete a namespace specified by binding name in a given environment", async () => {
|
|
298
|
+
writeWranglerConfig();
|
|
299
|
+
const requests = mockDeleteRequest("env-bound-id");
|
|
300
|
+
await runWrangler(
|
|
301
|
+
"kv:namespace delete --binding someBinding --env some-environment --preview false"
|
|
302
|
+
);
|
|
303
|
+
|
|
304
|
+
expect(std.out).toMatchInlineSnapshot(`
|
|
305
|
+
"Deleting KV namespace env-bound-id.
|
|
306
|
+
Deleted KV namespace env-bound-id."
|
|
307
|
+
`);
|
|
308
|
+
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
309
|
+
expect(requests.count).toEqual(1);
|
|
310
|
+
});
|
|
311
|
+
|
|
312
|
+
it("should delete a preview namespace specified by binding name in a given environment", async () => {
|
|
313
|
+
writeWranglerConfig();
|
|
314
|
+
const requests = mockDeleteRequest("preview-env-bound-id");
|
|
315
|
+
await runWrangler(
|
|
316
|
+
`kv:namespace delete --binding someBinding --env some-environment --preview`
|
|
317
|
+
);
|
|
318
|
+
expect(requests.count).toEqual(1);
|
|
319
|
+
});
|
|
320
|
+
});
|
|
321
|
+
});
|
|
322
|
+
|
|
323
|
+
describe("kv:key", () => {
|
|
324
|
+
describe("put", () => {
|
|
325
|
+
function mockKeyPutRequest(
|
|
326
|
+
expectedNamespaceId: string,
|
|
327
|
+
expectedKV: KeyValue
|
|
328
|
+
) {
|
|
329
|
+
const requests = { count: 0 };
|
|
330
|
+
setMockResponse(
|
|
331
|
+
"/accounts/:accountId/storage/kv/namespaces/:namespaceId/values/:key",
|
|
332
|
+
"PUT",
|
|
333
|
+
([_url, accountId, namespaceId, key], { body }, query) => {
|
|
334
|
+
requests.count++;
|
|
335
|
+
expect(accountId).toEqual("some-account-id");
|
|
336
|
+
expect(namespaceId).toEqual(expectedNamespaceId);
|
|
337
|
+
expect(key).toEqual(expectedKV.key);
|
|
338
|
+
if (expectedKV.metadata) {
|
|
339
|
+
expect(body).toBeInstanceOf(FormData);
|
|
340
|
+
expect((body as FormData).get("value")).toEqual(expectedKV.value);
|
|
341
|
+
expect((body as FormData).get("metadata")).toEqual(
|
|
342
|
+
JSON.stringify(expectedKV.metadata)
|
|
343
|
+
);
|
|
344
|
+
} else {
|
|
345
|
+
expect(body).toEqual(expectedKV.value);
|
|
346
|
+
}
|
|
347
|
+
if (expectedKV.expiration !== undefined) {
|
|
348
|
+
expect(query.get("expiration")).toEqual(
|
|
349
|
+
`${expectedKV.expiration}`
|
|
350
|
+
);
|
|
351
|
+
} else {
|
|
352
|
+
expect(query.has("expiration")).toBe(false);
|
|
353
|
+
}
|
|
354
|
+
if (expectedKV.expiration_ttl) {
|
|
355
|
+
expect(query.get("expiration_ttl")).toEqual(
|
|
356
|
+
`${expectedKV.expiration_ttl}`
|
|
357
|
+
);
|
|
358
|
+
} else {
|
|
359
|
+
expect(query.has("expiration_ttl")).toBe(false);
|
|
360
|
+
}
|
|
361
|
+
return null;
|
|
362
|
+
}
|
|
363
|
+
);
|
|
364
|
+
return requests;
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
it("should put a key in a given namespace specified by namespace-id", async () => {
|
|
368
|
+
const requests = mockKeyPutRequest("some-namespace-id", {
|
|
369
|
+
key: "my-key",
|
|
370
|
+
value: "my-value",
|
|
371
|
+
});
|
|
372
|
+
|
|
373
|
+
await runWrangler(
|
|
374
|
+
"kv:key put my-key my-value --namespace-id some-namespace-id"
|
|
375
|
+
);
|
|
376
|
+
|
|
377
|
+
expect(requests.count).toEqual(1);
|
|
378
|
+
expect(std.out).toMatchInlineSnapshot(
|
|
379
|
+
`"Writing the value \\"my-value\\" to key \\"my-key\\" on namespace some-namespace-id."`
|
|
380
|
+
);
|
|
381
|
+
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
382
|
+
});
|
|
383
|
+
|
|
384
|
+
it("should encode the key in the api request to put a value", async () => {
|
|
385
|
+
const requests = mockKeyPutRequest("DS9", {
|
|
386
|
+
key: "%2Fmy-key",
|
|
387
|
+
value: "my-value",
|
|
388
|
+
});
|
|
389
|
+
|
|
390
|
+
await runWrangler("kv:key put /my-key my-value --namespace-id DS9");
|
|
391
|
+
|
|
392
|
+
expect(requests.count).toEqual(1);
|
|
393
|
+
expect(std.out).toMatchInlineSnapshot(
|
|
394
|
+
`"Writing the value \\"my-value\\" to key \\"/my-key\\" on namespace DS9."`
|
|
395
|
+
);
|
|
396
|
+
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
397
|
+
});
|
|
398
|
+
|
|
399
|
+
it("should put a key in a given namespace specified by binding", async () => {
|
|
400
|
+
writeWranglerConfig();
|
|
401
|
+
const requests = mockKeyPutRequest("bound-id", {
|
|
402
|
+
key: "my-key",
|
|
403
|
+
value: "my-value",
|
|
404
|
+
});
|
|
405
|
+
await runWrangler(
|
|
406
|
+
"kv:key put my-key my-value --binding someBinding --preview false"
|
|
407
|
+
);
|
|
408
|
+
|
|
409
|
+
expect(std.out).toMatchInlineSnapshot(
|
|
410
|
+
`"Writing the value \\"my-value\\" to key \\"my-key\\" on namespace bound-id."`
|
|
411
|
+
);
|
|
412
|
+
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
413
|
+
expect(requests.count).toEqual(1);
|
|
414
|
+
});
|
|
415
|
+
|
|
416
|
+
it("should put a key in a given preview namespace specified by binding", async () => {
|
|
417
|
+
writeWranglerConfig();
|
|
418
|
+
const requests = mockKeyPutRequest("preview-bound-id", {
|
|
419
|
+
key: "my-key",
|
|
420
|
+
value: "my-value",
|
|
421
|
+
});
|
|
422
|
+
|
|
423
|
+
await runWrangler(
|
|
424
|
+
"kv:key put my-key my-value --binding someBinding --preview"
|
|
425
|
+
);
|
|
426
|
+
|
|
427
|
+
expect(std.out).toMatchInlineSnapshot(
|
|
428
|
+
`"Writing the value \\"my-value\\" to key \\"my-key\\" on namespace preview-bound-id."`
|
|
429
|
+
);
|
|
430
|
+
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
431
|
+
expect(requests.count).toEqual(1);
|
|
432
|
+
});
|
|
433
|
+
|
|
434
|
+
it("should add expiration and ttl properties when putting a key", async () => {
|
|
435
|
+
const requests = mockKeyPutRequest("some-namespace-id", {
|
|
436
|
+
key: "my-key",
|
|
437
|
+
value: "my-value",
|
|
438
|
+
expiration: 10,
|
|
439
|
+
expiration_ttl: 20,
|
|
440
|
+
});
|
|
441
|
+
await runWrangler(
|
|
442
|
+
"kv:key put my-key my-value --namespace-id some-namespace-id --expiration 10 --ttl 20"
|
|
443
|
+
);
|
|
444
|
+
expect(requests.count).toEqual(1);
|
|
445
|
+
expect(std.out).toMatchInlineSnapshot(
|
|
446
|
+
`"Writing the value \\"my-value\\" to key \\"my-key\\" on namespace some-namespace-id."`
|
|
447
|
+
);
|
|
448
|
+
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
449
|
+
});
|
|
450
|
+
|
|
451
|
+
it("should put a key to the specified environment in a given namespace", async () => {
|
|
452
|
+
writeWranglerConfig();
|
|
453
|
+
const requests = mockKeyPutRequest("env-bound-id", {
|
|
454
|
+
key: "my-key",
|
|
455
|
+
value: "my-value",
|
|
456
|
+
});
|
|
457
|
+
await runWrangler(
|
|
458
|
+
"kv:key put my-key my-value --binding someBinding --env some-environment --preview false"
|
|
459
|
+
);
|
|
460
|
+
expect(std.out).toMatchInlineSnapshot(
|
|
461
|
+
`"Writing the value \\"my-value\\" to key \\"my-key\\" on namespace env-bound-id."`
|
|
462
|
+
);
|
|
463
|
+
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
464
|
+
expect(requests.count).toEqual(1);
|
|
465
|
+
});
|
|
466
|
+
|
|
467
|
+
it("should put a key with a value loaded from a given path", async () => {
|
|
468
|
+
const buf = Buffer.from("file-contents", "utf-8");
|
|
469
|
+
writeFileSync("foo.txt", buf);
|
|
470
|
+
const requests = mockKeyPutRequest("some-namespace-id", {
|
|
471
|
+
key: "my-key",
|
|
472
|
+
value: buf,
|
|
473
|
+
});
|
|
474
|
+
await runWrangler(
|
|
475
|
+
"kv:key put my-key --namespace-id some-namespace-id --path foo.txt"
|
|
476
|
+
);
|
|
477
|
+
expect(std.out).toMatchInlineSnapshot(
|
|
478
|
+
`"Writing the contents of foo.txt to the key \\"my-key\\" on namespace some-namespace-id."`
|
|
479
|
+
);
|
|
480
|
+
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
481
|
+
expect(requests.count).toEqual(1);
|
|
482
|
+
});
|
|
483
|
+
|
|
484
|
+
it("should put a key with a binary value loaded from a given path", async () => {
|
|
485
|
+
const buf = Buffer.from(
|
|
486
|
+
"iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAiSURBVHgB7coxEQAACMPAgH/PgAM6dGwu49fA/deIBXrgAj2cAhIFT4QxAAAAAElFTkSuQmCC",
|
|
487
|
+
"base64"
|
|
488
|
+
);
|
|
489
|
+
writeFileSync("test.png", buf);
|
|
490
|
+
const requests = mockKeyPutRequest("another-namespace-id", {
|
|
491
|
+
key: "my-key",
|
|
492
|
+
value: buf,
|
|
493
|
+
});
|
|
494
|
+
await runWrangler(
|
|
495
|
+
"kv:key put my-key --namespace-id another-namespace-id --path test.png"
|
|
496
|
+
);
|
|
497
|
+
expect(std.out).toMatchInlineSnapshot(
|
|
498
|
+
`"Writing the contents of test.png to the key \\"my-key\\" on namespace another-namespace-id."`
|
|
499
|
+
);
|
|
500
|
+
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
501
|
+
expect(requests.count).toEqual(1);
|
|
502
|
+
});
|
|
503
|
+
|
|
504
|
+
it("should put a key with metadata", async () => {
|
|
505
|
+
const requests = mockKeyPutRequest("some-namespace-id", {
|
|
506
|
+
key: "dKey",
|
|
507
|
+
value: "dVal",
|
|
508
|
+
metadata: {
|
|
509
|
+
mKey: "mValue",
|
|
510
|
+
},
|
|
511
|
+
});
|
|
512
|
+
await runWrangler(
|
|
513
|
+
`kv:key put dKey dVal --namespace-id some-namespace-id --metadata {"mKey":"mValue"}`
|
|
514
|
+
);
|
|
515
|
+
expect(requests.count).toEqual(1);
|
|
516
|
+
expect(std.out).toMatchInlineSnapshot(
|
|
517
|
+
`"Writing the value \\"dVal\\" to key \\"dKey\\" on namespace some-namespace-id with metadata \\"{\\"mKey\\":\\"mValue\\"}\\"."`
|
|
518
|
+
);
|
|
519
|
+
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
520
|
+
});
|
|
521
|
+
|
|
522
|
+
it("should error if no key is provided", async () => {
|
|
523
|
+
await expect(
|
|
524
|
+
runWrangler("kv:key put")
|
|
525
|
+
).rejects.toThrowErrorMatchingInlineSnapshot(
|
|
526
|
+
`"Not enough non-option arguments: got 0, need at least 1"`
|
|
527
|
+
);
|
|
528
|
+
|
|
529
|
+
expect(std.out).toMatchInlineSnapshot(`
|
|
474
530
|
"
|
|
475
531
|
wrangler kv:key put <key> [value]
|
|
476
532
|
|
|
@@ -492,23 +548,24 @@ describe("wrangler", () => {
|
|
|
492
548
|
--preview Interact with a preview namespace [boolean]
|
|
493
549
|
--ttl Time for which the entries should be visible [number]
|
|
494
550
|
--expiration Time since the UNIX epoch after which the entry expires [number]
|
|
551
|
+
--metadata Arbitrary JSON that is associated with a key [string]
|
|
495
552
|
--path Read value from the file at a given path [string]"
|
|
496
553
|
`);
|
|
497
|
-
|
|
554
|
+
expect(std.err).toMatchInlineSnapshot(`
|
|
498
555
|
"[31mX [41;31m[[41;97mERROR[41;31m][0m [1mNot enough non-option arguments: got 0, need at least 1[0m
|
|
499
556
|
|
|
500
557
|
"
|
|
501
558
|
`);
|
|
502
|
-
|
|
559
|
+
});
|
|
503
560
|
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
561
|
+
it("should error if no binding nor namespace is provided", async () => {
|
|
562
|
+
await expect(
|
|
563
|
+
runWrangler("kv:key put foo bar")
|
|
564
|
+
).rejects.toThrowErrorMatchingInlineSnapshot(
|
|
565
|
+
`"Exactly one of the arguments binding and namespace-id is required"`
|
|
566
|
+
);
|
|
510
567
|
|
|
511
|
-
|
|
568
|
+
expect(std.out).toMatchInlineSnapshot(`
|
|
512
569
|
"
|
|
513
570
|
wrangler kv:key put <key> [value]
|
|
514
571
|
|
|
@@ -530,23 +587,24 @@ describe("wrangler", () => {
|
|
|
530
587
|
--preview Interact with a preview namespace [boolean]
|
|
531
588
|
--ttl Time for which the entries should be visible [number]
|
|
532
589
|
--expiration Time since the UNIX epoch after which the entry expires [number]
|
|
590
|
+
--metadata Arbitrary JSON that is associated with a key [string]
|
|
533
591
|
--path Read value from the file at a given path [string]"
|
|
534
592
|
`);
|
|
535
|
-
|
|
593
|
+
expect(std.err).toMatchInlineSnapshot(`
|
|
536
594
|
"[31mX [41;31m[[41;97mERROR[41;31m][0m [1mExactly one of the arguments binding and namespace-id is required[0m
|
|
537
595
|
|
|
538
596
|
"
|
|
539
597
|
`);
|
|
540
|
-
|
|
598
|
+
});
|
|
541
599
|
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
600
|
+
it("should error if both binding and namespace is provided", async () => {
|
|
601
|
+
await expect(
|
|
602
|
+
runWrangler("kv:key put foo bar --binding x --namespace-id y")
|
|
603
|
+
).rejects.toThrowErrorMatchingInlineSnapshot(
|
|
604
|
+
`"Arguments binding and namespace-id are mutually exclusive"`
|
|
605
|
+
);
|
|
548
606
|
|
|
549
|
-
|
|
607
|
+
expect(std.out).toMatchInlineSnapshot(`
|
|
550
608
|
"
|
|
551
609
|
wrangler kv:key put <key> [value]
|
|
552
610
|
|
|
@@ -568,23 +626,24 @@ describe("wrangler", () => {
|
|
|
568
626
|
--preview Interact with a preview namespace [boolean]
|
|
569
627
|
--ttl Time for which the entries should be visible [number]
|
|
570
628
|
--expiration Time since the UNIX epoch after which the entry expires [number]
|
|
629
|
+
--metadata Arbitrary JSON that is associated with a key [string]
|
|
571
630
|
--path Read value from the file at a given path [string]"
|
|
572
631
|
`);
|
|
573
|
-
|
|
632
|
+
expect(std.err).toMatchInlineSnapshot(`
|
|
574
633
|
"[31mX [41;31m[[41;97mERROR[41;31m][0m [1mArguments binding and namespace-id are mutually exclusive[0m
|
|
575
634
|
|
|
576
635
|
"
|
|
577
636
|
`);
|
|
578
|
-
|
|
637
|
+
});
|
|
579
638
|
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
639
|
+
it("should error if no value nor path is provided", async () => {
|
|
640
|
+
await expect(
|
|
641
|
+
runWrangler("kv:key put key --namespace-id 12345")
|
|
642
|
+
).rejects.toThrowErrorMatchingInlineSnapshot(
|
|
643
|
+
`"Exactly one of the arguments value and path is required"`
|
|
644
|
+
);
|
|
586
645
|
|
|
587
|
-
|
|
646
|
+
expect(std.out).toMatchInlineSnapshot(`
|
|
588
647
|
"
|
|
589
648
|
wrangler kv:key put <key> [value]
|
|
590
649
|
|
|
@@ -606,23 +665,24 @@ describe("wrangler", () => {
|
|
|
606
665
|
--preview Interact with a preview namespace [boolean]
|
|
607
666
|
--ttl Time for which the entries should be visible [number]
|
|
608
667
|
--expiration Time since the UNIX epoch after which the entry expires [number]
|
|
668
|
+
--metadata Arbitrary JSON that is associated with a key [string]
|
|
609
669
|
--path Read value from the file at a given path [string]"
|
|
610
670
|
`);
|
|
611
|
-
|
|
671
|
+
expect(std.err).toMatchInlineSnapshot(`
|
|
612
672
|
"[31mX [41;31m[[41;97mERROR[41;31m][0m [1mExactly one of the arguments value and path is required[0m
|
|
613
673
|
|
|
614
674
|
"
|
|
615
675
|
`);
|
|
616
|
-
|
|
676
|
+
});
|
|
617
677
|
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
678
|
+
it("should error if both value and path is provided", async () => {
|
|
679
|
+
await expect(
|
|
680
|
+
runWrangler("kv:key put key value --path xyz --namespace-id 12345")
|
|
681
|
+
).rejects.toThrowErrorMatchingInlineSnapshot(
|
|
682
|
+
`"Arguments value and path are mutually exclusive"`
|
|
683
|
+
);
|
|
624
684
|
|
|
625
|
-
|
|
685
|
+
expect(std.out).toMatchInlineSnapshot(`
|
|
626
686
|
"
|
|
627
687
|
wrangler kv:key put <key> [value]
|
|
628
688
|
|
|
@@ -644,69 +704,70 @@ describe("wrangler", () => {
|
|
|
644
704
|
--preview Interact with a preview namespace [boolean]
|
|
645
705
|
--ttl Time for which the entries should be visible [number]
|
|
646
706
|
--expiration Time since the UNIX epoch after which the entry expires [number]
|
|
707
|
+
--metadata Arbitrary JSON that is associated with a key [string]
|
|
647
708
|
--path Read value from the file at a given path [string]"
|
|
648
709
|
`);
|
|
649
|
-
|
|
710
|
+
expect(std.err).toMatchInlineSnapshot(`
|
|
650
711
|
"[31mX [41;31m[[41;97mERROR[41;31m][0m [1mArguments value and path are mutually exclusive[0m
|
|
651
712
|
|
|
652
713
|
"
|
|
653
714
|
`);
|
|
654
|
-
|
|
715
|
+
});
|
|
655
716
|
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
717
|
+
it("should error if a given binding name is not in the configured kv namespaces", async () => {
|
|
718
|
+
writeWranglerConfig();
|
|
719
|
+
await expect(
|
|
720
|
+
runWrangler("kv:key put key value --binding otherBinding")
|
|
721
|
+
).rejects.toThrowErrorMatchingInlineSnapshot(
|
|
722
|
+
`"A namespace with binding name \\"otherBinding\\" was not found in the configured \\"kv_namespaces\\"."`
|
|
723
|
+
);
|
|
663
724
|
|
|
664
|
-
|
|
725
|
+
expect(std.out).toMatchInlineSnapshot(`
|
|
665
726
|
"
|
|
666
727
|
[32mIf you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new/choose[0m"
|
|
667
728
|
`);
|
|
668
|
-
|
|
729
|
+
expect(std.err).toMatchInlineSnapshot(`
|
|
669
730
|
"[31mX [41;31m[[41;97mERROR[41;31m][0m [1mA namespace with binding name \\"otherBinding\\" was not found in the configured \\"kv_namespaces\\".[0m
|
|
670
731
|
|
|
671
732
|
"
|
|
672
733
|
`);
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
734
|
+
});
|
|
735
|
+
|
|
736
|
+
it("should error if a given binding has both preview and non-preview and --preview is not specified", async () => {
|
|
737
|
+
writeWranglerConfig();
|
|
738
|
+
const requests = mockKeyPutRequest("preview-bound-id", {
|
|
739
|
+
key: "my-key",
|
|
740
|
+
value: "my-value",
|
|
741
|
+
});
|
|
742
|
+
await expect(
|
|
743
|
+
runWrangler("kv:key put my-key my-value --binding someBinding")
|
|
744
|
+
).rejects.toThrowErrorMatchingInlineSnapshot(
|
|
745
|
+
`"someBinding has both a namespace ID and a preview ID. Specify \\"--preview\\" or \\"--preview false\\" to avoid writing data to the wrong namespace."`
|
|
746
|
+
);
|
|
747
|
+
expect(std.out).toMatchInlineSnapshot(`
|
|
687
748
|
"
|
|
688
749
|
[32mIf you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new/choose[0m"
|
|
689
750
|
`);
|
|
690
|
-
|
|
751
|
+
expect(std.err).toMatchInlineSnapshot(`
|
|
691
752
|
"[31mX [41;31m[[41;97mERROR[41;31m][0m [1msomeBinding has both a namespace ID and a preview ID. Specify \\"--preview\\" or \\"--preview false\\" to avoid writing data to the wrong namespace.[0m
|
|
692
753
|
|
|
693
754
|
"
|
|
694
755
|
`);
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
756
|
+
expect(requests.count).toEqual(0);
|
|
757
|
+
});
|
|
758
|
+
});
|
|
759
|
+
|
|
760
|
+
describe("list", () => {
|
|
761
|
+
it("should list the keys of a namespace specified by namespace-id", async () => {
|
|
762
|
+
const keys = [
|
|
763
|
+
{ name: "key-1" },
|
|
764
|
+
{ name: "key-2", expiration: 123456789 },
|
|
765
|
+
{ name: "key-3", expiration_ttl: 666 },
|
|
766
|
+
];
|
|
767
|
+
mockKeyListRequest("some-namespace-id", keys);
|
|
768
|
+
await runWrangler("kv:key list --namespace-id some-namespace-id");
|
|
769
|
+
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
770
|
+
expect(std.out).toMatchInlineSnapshot(`
|
|
710
771
|
"[
|
|
711
772
|
{
|
|
712
773
|
\\"name\\": \\"key-1\\"
|
|
@@ -721,16 +782,16 @@ describe("wrangler", () => {
|
|
|
721
782
|
}
|
|
722
783
|
]"
|
|
723
784
|
`);
|
|
724
|
-
|
|
785
|
+
});
|
|
725
786
|
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
787
|
+
it("should list the keys of a namespace specified by binding", async () => {
|
|
788
|
+
writeWranglerConfig();
|
|
789
|
+
const keys = [{ name: "key-1" }, { name: "key-2" }, { name: "key-3" }];
|
|
790
|
+
mockKeyListRequest("bound-id", keys);
|
|
730
791
|
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
792
|
+
await runWrangler("kv:key list --binding someBinding");
|
|
793
|
+
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
794
|
+
expect(std.out).toMatchInlineSnapshot(`
|
|
734
795
|
"[
|
|
735
796
|
{
|
|
736
797
|
\\"name\\": \\"key-1\\"
|
|
@@ -743,15 +804,15 @@ describe("wrangler", () => {
|
|
|
743
804
|
}
|
|
744
805
|
]"
|
|
745
806
|
`);
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
807
|
+
});
|
|
808
|
+
|
|
809
|
+
it("should list the keys of a preview namespace specified by binding", async () => {
|
|
810
|
+
writeWranglerConfig();
|
|
811
|
+
const keys = [{ name: "key-1" }, { name: "key-2" }, { name: "key-3" }];
|
|
812
|
+
mockKeyListRequest("preview-bound-id", keys);
|
|
813
|
+
await runWrangler("kv:key list --binding someBinding --preview");
|
|
814
|
+
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
815
|
+
expect(std.out).toMatchInlineSnapshot(`
|
|
755
816
|
"[
|
|
756
817
|
{
|
|
757
818
|
\\"name\\": \\"key-1\\"
|
|
@@ -764,17 +825,17 @@ describe("wrangler", () => {
|
|
|
764
825
|
}
|
|
765
826
|
]"
|
|
766
827
|
`);
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
828
|
+
});
|
|
829
|
+
|
|
830
|
+
it("should list the keys of a namespace specified by binding, in a given environment", async () => {
|
|
831
|
+
writeWranglerConfig();
|
|
832
|
+
const keys = [{ name: "key-1" }, { name: "key-2" }, { name: "key-3" }];
|
|
833
|
+
mockKeyListRequest("env-bound-id", keys);
|
|
834
|
+
await runWrangler(
|
|
835
|
+
"kv:key list --binding someBinding --env some-environment"
|
|
836
|
+
);
|
|
837
|
+
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
838
|
+
expect(std.out).toMatchInlineSnapshot(`
|
|
778
839
|
"[
|
|
779
840
|
{
|
|
780
841
|
\\"name\\": \\"key-1\\"
|
|
@@ -787,17 +848,17 @@ describe("wrangler", () => {
|
|
|
787
848
|
}
|
|
788
849
|
]"
|
|
789
850
|
`);
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
851
|
+
});
|
|
852
|
+
|
|
853
|
+
it("should list the keys of a preview namespace specified by binding, in a given environment", async () => {
|
|
854
|
+
writeWranglerConfig();
|
|
855
|
+
const keys = [{ name: "key-1" }, { name: "key-2" }, { name: "key-3" }];
|
|
856
|
+
mockKeyListRequest("preview-env-bound-id", keys);
|
|
857
|
+
await runWrangler(
|
|
858
|
+
"kv:key list --binding someBinding --preview --env some-environment"
|
|
859
|
+
);
|
|
860
|
+
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
861
|
+
expect(std.out).toMatchInlineSnapshot(`
|
|
801
862
|
"[
|
|
802
863
|
{
|
|
803
864
|
\\"name\\": \\"key-1\\"
|
|
@@ -810,138 +871,195 @@ describe("wrangler", () => {
|
|
|
810
871
|
}
|
|
811
872
|
]"
|
|
812
873
|
`);
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
874
|
+
});
|
|
875
|
+
|
|
876
|
+
// We'll run the next test with variations on the cursor
|
|
877
|
+
// that's returned on cloudflare's API after all results
|
|
878
|
+
// have been drained.
|
|
879
|
+
for (const blankCursorValue of [undefined, null, ""] as [
|
|
880
|
+
undefined,
|
|
881
|
+
null,
|
|
882
|
+
""
|
|
883
|
+
]) {
|
|
884
|
+
describe(`cursor - ${blankCursorValue}`, () => {
|
|
885
|
+
it("should make multiple requests for paginated results", async () => {
|
|
886
|
+
// Create a lot of mock keys, so that the fetch requests will be paginated
|
|
887
|
+
const keys: NamespaceKeyInfo[] = [];
|
|
888
|
+
for (let i = 0; i < 550; i++) {
|
|
889
|
+
keys.push({ name: "key-" + i });
|
|
890
|
+
}
|
|
891
|
+
// Ask for the keys in pages of size 100.
|
|
892
|
+
const requests = mockKeyListRequest(
|
|
893
|
+
"some-namespace-id",
|
|
894
|
+
keys,
|
|
895
|
+
100,
|
|
896
|
+
blankCursorValue
|
|
897
|
+
);
|
|
898
|
+
await runWrangler("kv:key list --namespace-id some-namespace-id");
|
|
899
|
+
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
900
|
+
expect(JSON.parse(std.out)).toEqual(keys);
|
|
901
|
+
expect(requests.count).toEqual(6);
|
|
902
|
+
});
|
|
903
|
+
});
|
|
904
|
+
}
|
|
905
|
+
|
|
906
|
+
it("should error if a given binding name is not in the configured kv namespaces", async () => {
|
|
907
|
+
writeWranglerConfig();
|
|
908
|
+
await expect(
|
|
909
|
+
runWrangler("kv:key list --binding otherBinding")
|
|
910
|
+
).rejects.toThrowErrorMatchingInlineSnapshot(
|
|
911
|
+
`"A namespace with binding name \\"otherBinding\\" was not found in the configured \\"kv_namespaces\\"."`
|
|
912
|
+
);
|
|
913
|
+
expect(std.err).toMatchInlineSnapshot(`
|
|
853
914
|
"[31mX [41;31m[[41;97mERROR[41;31m][0m [1mA namespace with binding name \\"otherBinding\\" was not found in the configured \\"kv_namespaces\\".[0m
|
|
854
915
|
|
|
855
916
|
"
|
|
856
917
|
`);
|
|
857
|
-
|
|
918
|
+
expect(std.out).toMatchInlineSnapshot(`
|
|
858
919
|
"
|
|
859
920
|
[32mIf you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new/choose[0m"
|
|
860
921
|
`);
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
922
|
+
});
|
|
923
|
+
});
|
|
924
|
+
|
|
925
|
+
describe("get", () => {
|
|
926
|
+
afterEach(() => {
|
|
927
|
+
unsetSpecialMockFns();
|
|
928
|
+
});
|
|
929
|
+
|
|
930
|
+
it("should get a key in a given namespace specified by namespace-id", async () => {
|
|
931
|
+
setMockFetchKVGetValue(
|
|
932
|
+
"some-account-id",
|
|
933
|
+
"some-namespace-id",
|
|
934
|
+
"my-key",
|
|
935
|
+
"my-value"
|
|
936
|
+
);
|
|
937
|
+
await runWrangler("kv:key get my-key --namespace-id some-namespace-id");
|
|
938
|
+
expect(proc.write).toEqual(Buffer.from("my-value"));
|
|
939
|
+
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
940
|
+
});
|
|
941
|
+
|
|
942
|
+
it("should get a key and decode the value from the response as a utf8 string if the `--text` flag is passed", async () => {
|
|
943
|
+
setMockFetchKVGetValue(
|
|
944
|
+
"some-account-id",
|
|
945
|
+
"some-namespace-id",
|
|
946
|
+
"my-key",
|
|
947
|
+
"my-value"
|
|
948
|
+
);
|
|
949
|
+
await runWrangler(
|
|
950
|
+
"kv:key get my-key --text --namespace-id some-namespace-id"
|
|
951
|
+
);
|
|
952
|
+
expect(proc.write).not.toEqual(Buffer.from("my-value"));
|
|
953
|
+
expect(std).toMatchInlineSnapshot(`
|
|
954
|
+
Object {
|
|
955
|
+
"debug": "",
|
|
956
|
+
"err": "",
|
|
957
|
+
"out": "my-value",
|
|
958
|
+
"warn": "",
|
|
959
|
+
}
|
|
960
|
+
`);
|
|
961
|
+
});
|
|
962
|
+
|
|
963
|
+
it("should get a binary and decode as utf8 text, resulting in improper decoding", async () => {
|
|
964
|
+
const buf = Buffer.from(
|
|
965
|
+
"iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAiSURBVHgB7coxEQAACMPAgH/PgAM6dGwu49fA/deIBXrgAj2cAhIFT4QxAAAAAElFTkSuQmCC",
|
|
966
|
+
"base64"
|
|
967
|
+
);
|
|
968
|
+
setMockFetchKVGetValue(
|
|
969
|
+
"some-account-id",
|
|
970
|
+
"some-namespace-id",
|
|
971
|
+
"my-key",
|
|
972
|
+
buf
|
|
973
|
+
);
|
|
974
|
+
await runWrangler(
|
|
975
|
+
"kv:key get my-key --text --namespace-id some-namespace-id"
|
|
976
|
+
);
|
|
977
|
+
expect(proc.write).not.toEqual(buf);
|
|
978
|
+
expect(JSON.stringify(std)).toMatchInlineSnapshot(
|
|
979
|
+
`"{\\"debug\\":\\"\\",\\"out\\":\\"�PNG\\\\n\\\\u001a\\\\n\\\\u0000\\\\u0000\\\\u0000\\\\rIHDR\\\\u0000\\\\u0000\\\\u0000\\\\n\\\\u0000\\\\u0000\\\\u0000\\\\n\\\\b\\\\u0006\\\\u0000\\\\u0000\\\\u0000�2Ͻ\\\\u0000\\\\u0000\\\\u0000\\\\tpHYs\\\\u0000\\\\u0000\\\\u000b\\\\u0013\\\\u0000\\\\u0000\\\\u000b\\\\u0013\\\\u0001\\\\u0000��\\\\u0018\\\\u0000\\\\u0000\\\\u0000\\\\u0001sRGB\\\\u0000��\\\\u001c�\\\\u0000\\\\u0000\\\\u0000\\\\u0004gAMA\\\\u0000\\\\u0000��\\\\u000b�a\\\\u0005\\\\u0000\\\\u0000\\\\u0000\\\\\\"IDATx\\\\u0001��1\\\\u0011\\\\u0000\\\\u0000\\\\b���π\\\\u0003:tl.����\\\\u0005z�\\\\u0002=�\\\\u0002\\\\u0012\\\\u0005O�1\\\\u0000\\\\u0000\\\\u0000\\\\u0000IEND�B\`�\\",\\"err\\":\\"\\",\\"warn\\":\\"\\"}"`
|
|
980
|
+
);
|
|
981
|
+
});
|
|
982
|
+
|
|
983
|
+
it("should get a binary file by key in a given namespace specified by namespace-id", async () => {
|
|
984
|
+
const buf = Buffer.from(
|
|
985
|
+
"iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAiSURBVHgB7coxEQAACMPAgH/PgAM6dGwu49fA/deIBXrgAj2cAhIFT4QxAAAAAElFTkSuQmCC",
|
|
986
|
+
"base64"
|
|
987
|
+
);
|
|
988
|
+
setMockFetchKVGetValue(
|
|
989
|
+
"some-account-id",
|
|
990
|
+
"some-namespace-id",
|
|
991
|
+
"my-key",
|
|
992
|
+
buf
|
|
993
|
+
);
|
|
994
|
+
await runWrangler("kv:key get my-key --namespace-id some-namespace-id");
|
|
995
|
+
expect(proc.write).toEqual(buf);
|
|
996
|
+
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
997
|
+
});
|
|
998
|
+
|
|
999
|
+
it("should get a key in a given namespace specified by binding", async () => {
|
|
1000
|
+
writeWranglerConfig();
|
|
1001
|
+
setMockFetchKVGetValue(
|
|
1002
|
+
"some-account-id",
|
|
1003
|
+
"bound-id",
|
|
1004
|
+
"my-key",
|
|
1005
|
+
"my-value"
|
|
1006
|
+
);
|
|
1007
|
+
await runWrangler(
|
|
1008
|
+
"kv:key get my-key --binding someBinding --preview false"
|
|
1009
|
+
);
|
|
1010
|
+
expect(proc.write).toEqual(Buffer.from("my-value"));
|
|
1011
|
+
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
1012
|
+
});
|
|
1013
|
+
|
|
1014
|
+
it("should get a key in a given preview namespace specified by binding", async () => {
|
|
1015
|
+
writeWranglerConfig();
|
|
1016
|
+
setMockFetchKVGetValue(
|
|
1017
|
+
"some-account-id",
|
|
1018
|
+
"preview-bound-id",
|
|
1019
|
+
"my-key",
|
|
1020
|
+
"my-value"
|
|
1021
|
+
);
|
|
1022
|
+
await runWrangler("kv:key get my-key --binding someBinding --preview");
|
|
1023
|
+
expect(proc.write).toEqual(Buffer.from("my-value"));
|
|
1024
|
+
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
1025
|
+
});
|
|
1026
|
+
|
|
1027
|
+
it("should get a key for the specified environment in a given namespace", async () => {
|
|
1028
|
+
writeWranglerConfig();
|
|
1029
|
+
setMockFetchKVGetValue(
|
|
1030
|
+
"some-account-id",
|
|
1031
|
+
"env-bound-id",
|
|
1032
|
+
"my-key",
|
|
1033
|
+
"my-value"
|
|
1034
|
+
);
|
|
1035
|
+
await runWrangler(
|
|
1036
|
+
"kv:key get my-key --binding someBinding --env some-environment --preview false"
|
|
1037
|
+
);
|
|
1038
|
+
expect(proc.write).toEqual(Buffer.from("my-value"));
|
|
1039
|
+
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
1040
|
+
});
|
|
1041
|
+
|
|
1042
|
+
it("should encode the key in the api request to get a value", async () => {
|
|
1043
|
+
setMockFetchKVGetValue(
|
|
1044
|
+
"some-account-id",
|
|
1045
|
+
"some-namespace-id",
|
|
1046
|
+
"%2Fmy%2Ckey",
|
|
1047
|
+
"my-value"
|
|
1048
|
+
);
|
|
1049
|
+
await runWrangler(
|
|
1050
|
+
"kv:key get /my,key --namespace-id some-namespace-id"
|
|
1051
|
+
);
|
|
1052
|
+
expect(proc.write).toEqual(Buffer.from("my-value"));
|
|
1053
|
+
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
1054
|
+
});
|
|
1055
|
+
|
|
1056
|
+
it("should error if no key is provided", async () => {
|
|
1057
|
+
await expect(
|
|
1058
|
+
runWrangler("kv:key get")
|
|
1059
|
+
).rejects.toThrowErrorMatchingInlineSnapshot(
|
|
1060
|
+
`"Not enough non-option arguments: got 0, need at least 1"`
|
|
1061
|
+
);
|
|
1062
|
+
expect(std.out).toMatchInlineSnapshot(`
|
|
945
1063
|
"
|
|
946
1064
|
wrangler kv:key get <key>
|
|
947
1065
|
|
|
@@ -959,22 +1077,23 @@ describe("wrangler", () => {
|
|
|
959
1077
|
--binding The name of the namespace to get from [string]
|
|
960
1078
|
--namespace-id The id of the namespace to get from [string]
|
|
961
1079
|
-e, --env Perform on a specific environment [string]
|
|
962
|
-
--preview Interact with a preview namespace [boolean] [default: false]
|
|
1080
|
+
--preview Interact with a preview namespace [boolean] [default: false]
|
|
1081
|
+
--text Decode the returned value as a utf8 string [boolean] [default: false]"
|
|
963
1082
|
`);
|
|
964
|
-
|
|
1083
|
+
expect(std.err).toMatchInlineSnapshot(`
|
|
965
1084
|
"[31mX [41;31m[[41;97mERROR[41;31m][0m [1mNot enough non-option arguments: got 0, need at least 1[0m
|
|
966
1085
|
|
|
967
1086
|
"
|
|
968
1087
|
`);
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
1088
|
+
});
|
|
1089
|
+
|
|
1090
|
+
it("should error if no binding nor namespace is provided", async () => {
|
|
1091
|
+
await expect(
|
|
1092
|
+
runWrangler("kv:key get foo")
|
|
1093
|
+
).rejects.toThrowErrorMatchingInlineSnapshot(
|
|
1094
|
+
`"Exactly one of the arguments binding and namespace-id is required"`
|
|
1095
|
+
);
|
|
1096
|
+
expect(std.out).toMatchInlineSnapshot(`
|
|
978
1097
|
"
|
|
979
1098
|
wrangler kv:key get <key>
|
|
980
1099
|
|
|
@@ -992,23 +1111,24 @@ describe("wrangler", () => {
|
|
|
992
1111
|
--binding The name of the namespace to get from [string]
|
|
993
1112
|
--namespace-id The id of the namespace to get from [string]
|
|
994
1113
|
-e, --env Perform on a specific environment [string]
|
|
995
|
-
--preview Interact with a preview namespace [boolean] [default: false]
|
|
1114
|
+
--preview Interact with a preview namespace [boolean] [default: false]
|
|
1115
|
+
--text Decode the returned value as a utf8 string [boolean] [default: false]"
|
|
996
1116
|
`);
|
|
997
|
-
|
|
1117
|
+
expect(std.err).toMatchInlineSnapshot(`
|
|
998
1118
|
"[31mX [41;31m[[41;97mERROR[41;31m][0m [1mExactly one of the arguments binding and namespace-id is required[0m
|
|
999
1119
|
|
|
1000
1120
|
"
|
|
1001
1121
|
`);
|
|
1002
|
-
|
|
1122
|
+
});
|
|
1003
1123
|
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1124
|
+
it("should error if both binding and namespace is provided", async () => {
|
|
1125
|
+
await expect(
|
|
1126
|
+
runWrangler("kv:key get foo --binding x --namespace-id y")
|
|
1127
|
+
).rejects.toThrowErrorMatchingInlineSnapshot(
|
|
1128
|
+
`"Arguments binding and namespace-id are mutually exclusive"`
|
|
1129
|
+
);
|
|
1010
1130
|
|
|
1011
|
-
|
|
1131
|
+
expect(std.out).toMatchInlineSnapshot(`
|
|
1012
1132
|
"
|
|
1013
1133
|
wrangler kv:key get <key>
|
|
1014
1134
|
|
|
@@ -1026,456 +1146,526 @@ describe("wrangler", () => {
|
|
|
1026
1146
|
--binding The name of the namespace to get from [string]
|
|
1027
1147
|
--namespace-id The id of the namespace to get from [string]
|
|
1028
1148
|
-e, --env Perform on a specific environment [string]
|
|
1029
|
-
--preview Interact with a preview namespace [boolean] [default: false]
|
|
1149
|
+
--preview Interact with a preview namespace [boolean] [default: false]
|
|
1150
|
+
--text Decode the returned value as a utf8 string [boolean] [default: false]"
|
|
1030
1151
|
`);
|
|
1031
|
-
|
|
1152
|
+
expect(std.err).toMatchInlineSnapshot(`
|
|
1032
1153
|
"[31mX [41;31m[[41;97mERROR[41;31m][0m [1mArguments binding and namespace-id are mutually exclusive[0m
|
|
1033
1154
|
|
|
1034
1155
|
"
|
|
1035
1156
|
`);
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1157
|
+
});
|
|
1158
|
+
|
|
1159
|
+
it("should error if a given binding name is not in the configured kv namespaces", async () => {
|
|
1160
|
+
writeWranglerConfig();
|
|
1161
|
+
await expect(
|
|
1162
|
+
runWrangler("kv:key get key --binding otherBinding")
|
|
1163
|
+
).rejects.toThrowErrorMatchingInlineSnapshot(
|
|
1164
|
+
`"A namespace with binding name \\"otherBinding\\" was not found in the configured \\"kv_namespaces\\"."`
|
|
1165
|
+
);
|
|
1166
|
+
expect(std.out).toMatchInlineSnapshot(`
|
|
1046
1167
|
"
|
|
1047
1168
|
[32mIf you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new/choose[0m"
|
|
1048
1169
|
`);
|
|
1049
|
-
|
|
1170
|
+
expect(std.err).toMatchInlineSnapshot(`
|
|
1050
1171
|
"[31mX [41;31m[[41;97mERROR[41;31m][0m [1mA namespace with binding name \\"otherBinding\\" was not found in the configured \\"kv_namespaces\\".[0m
|
|
1051
1172
|
|
|
1052
1173
|
"
|
|
1053
1174
|
`);
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1175
|
+
});
|
|
1176
|
+
|
|
1177
|
+
describe("non-interactive", () => {
|
|
1178
|
+
const { setIsTTY } = useMockIsTTY();
|
|
1179
|
+
mockAccountId({ accountId: null });
|
|
1180
|
+
|
|
1181
|
+
it("should error if there are multiple accounts available but not interactive on stdin", async () => {
|
|
1182
|
+
mockGetMemberships([
|
|
1183
|
+
{ id: "xxx", account: { id: "1", name: "one" } },
|
|
1184
|
+
{ id: "yyy", account: { id: "2", name: "two" } },
|
|
1185
|
+
]);
|
|
1186
|
+
setIsTTY({ stdin: false, stdout: true });
|
|
1187
|
+
await expect(runWrangler("kv:key get key --namespace-id=xxxx"))
|
|
1188
|
+
.rejects.toThrowErrorMatchingInlineSnapshot(`
|
|
1189
|
+
"More than one account available but unable to select one in non-interactive mode.
|
|
1190
|
+
Please set the appropriate \`account_id\` in your \`wrangler.toml\` file.
|
|
1191
|
+
Available accounts are (\\"<name>\\" - \\"<id>\\"):
|
|
1192
|
+
\\"one\\" - \\"1\\")
|
|
1193
|
+
\\"two\\" - \\"2\\")"
|
|
1194
|
+
`);
|
|
1195
|
+
});
|
|
1196
|
+
|
|
1197
|
+
it("should error if there are multiple accounts available but not interactive on stdout", async () => {
|
|
1198
|
+
mockGetMemberships([
|
|
1199
|
+
{ id: "xxx", account: { id: "1", name: "one" } },
|
|
1200
|
+
{ id: "yyy", account: { id: "2", name: "two" } },
|
|
1201
|
+
]);
|
|
1202
|
+
setIsTTY({ stdin: true, stdout: false });
|
|
1203
|
+
await expect(runWrangler("kv:key get key --namespace-id=xxxx"))
|
|
1204
|
+
.rejects.toThrowErrorMatchingInlineSnapshot(`
|
|
1205
|
+
"More than one account available but unable to select one in non-interactive mode.
|
|
1206
|
+
Please set the appropriate \`account_id\` in your \`wrangler.toml\` file.
|
|
1207
|
+
Available accounts are (\\"<name>\\" - \\"<id>\\"):
|
|
1208
|
+
\\"one\\" - \\"1\\")
|
|
1209
|
+
\\"two\\" - \\"2\\")"
|
|
1210
|
+
`);
|
|
1211
|
+
});
|
|
1212
|
+
|
|
1213
|
+
it("should recommend using a configuration if unable to fetch memberships", async () => {
|
|
1214
|
+
setMockRawResponse("/memberships", () => {
|
|
1215
|
+
return createFetchResult(undefined, false, [
|
|
1216
|
+
{
|
|
1217
|
+
code: 9109,
|
|
1218
|
+
message: "Uauthorized to access requested resource",
|
|
1219
|
+
},
|
|
1220
|
+
]);
|
|
1221
|
+
});
|
|
1222
|
+
await expect(runWrangler("kv:key get key --namespace-id=xxxx"))
|
|
1223
|
+
.rejects.toThrowErrorMatchingInlineSnapshot(`
|
|
1224
|
+
"Failed to automatically retrieve account IDs for the logged in user.
|
|
1225
|
+
You may have incorrect permissions on your API token. You can skip this account check by adding an \`account_id\` in your \`wrangler.toml\`, or by setting the value of CLOUDFLARE_ACCOUNT_ID\\""
|
|
1226
|
+
`);
|
|
1227
|
+
});
|
|
1228
|
+
|
|
1229
|
+
it("should error if there are multiple accounts available but not interactive at all", async () => {
|
|
1230
|
+
mockGetMemberships([
|
|
1231
|
+
{ id: "xxx", account: { id: "1", name: "one" } },
|
|
1232
|
+
{ id: "yyy", account: { id: "2", name: "two" } },
|
|
1233
|
+
]);
|
|
1234
|
+
setIsTTY(false);
|
|
1235
|
+
await expect(runWrangler("kv:key get key --namespace-id=xxxx"))
|
|
1236
|
+
.rejects.toThrowErrorMatchingInlineSnapshot(`
|
|
1237
|
+
"More than one account available but unable to select one in non-interactive mode.
|
|
1238
|
+
Please set the appropriate \`account_id\` in your \`wrangler.toml\` file.
|
|
1239
|
+
Available accounts are (\\"<name>\\" - \\"<id>\\"):
|
|
1240
|
+
\\"one\\" - \\"1\\")
|
|
1241
|
+
\\"two\\" - \\"2\\")"
|
|
1242
|
+
`);
|
|
1243
|
+
});
|
|
1244
|
+
});
|
|
1245
|
+
});
|
|
1246
|
+
|
|
1247
|
+
describe("delete", () => {
|
|
1248
|
+
function mockDeleteRequest(
|
|
1249
|
+
expectedNamespaceId: string,
|
|
1250
|
+
expectedKey: string
|
|
1251
|
+
) {
|
|
1252
|
+
const requests = { count: 0 };
|
|
1253
|
+
setMockResponse(
|
|
1254
|
+
"/accounts/:accountId/storage/kv/namespaces/:namespaceId/values/:key",
|
|
1255
|
+
"DELETE",
|
|
1256
|
+
([_url, accountId, namespaceId, key]) => {
|
|
1257
|
+
requests.count++;
|
|
1258
|
+
expect(accountId).toEqual("some-account-id");
|
|
1259
|
+
expect(namespaceId).toEqual(expectedNamespaceId);
|
|
1260
|
+
expect(key).toEqual(expectedKey);
|
|
1261
|
+
return null;
|
|
1262
|
+
}
|
|
1263
|
+
);
|
|
1264
|
+
return requests;
|
|
1265
|
+
}
|
|
1266
|
+
|
|
1267
|
+
it("should delete a key in a namespace specified by id", async () => {
|
|
1268
|
+
const requests = mockDeleteRequest("some-namespace-id", "someKey");
|
|
1269
|
+
await runWrangler(
|
|
1270
|
+
`kv:key delete --namespace-id some-namespace-id someKey`
|
|
1271
|
+
);
|
|
1272
|
+
expect(requests.count).toEqual(1);
|
|
1273
|
+
});
|
|
1274
|
+
|
|
1275
|
+
it("should encode the key in the api request to delete a value", async () => {
|
|
1276
|
+
const requests = mockDeleteRequest("voyager", "%2FNCC-74656");
|
|
1277
|
+
await runWrangler(`kv:key delete --namespace-id voyager /NCC-74656`);
|
|
1278
|
+
expect(requests.count).toEqual(1);
|
|
1279
|
+
expect(std.out).toMatchInlineSnapshot(
|
|
1280
|
+
`"Deleting the key \\"/NCC-74656\\" on namespace voyager."`
|
|
1281
|
+
);
|
|
1282
|
+
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
1283
|
+
});
|
|
1284
|
+
|
|
1285
|
+
it("should delete a key in a namespace specified by binding name", async () => {
|
|
1286
|
+
writeWranglerConfig();
|
|
1287
|
+
const requests = mockDeleteRequest("bound-id", "someKey");
|
|
1288
|
+
await runWrangler(
|
|
1289
|
+
`kv:key delete --binding someBinding --preview false someKey`
|
|
1290
|
+
);
|
|
1291
|
+
expect(requests.count).toEqual(1);
|
|
1292
|
+
});
|
|
1293
|
+
|
|
1294
|
+
it("should delete a key in a preview namespace specified by binding name", async () => {
|
|
1295
|
+
writeWranglerConfig();
|
|
1296
|
+
const requests = mockDeleteRequest("preview-bound-id", "someKey");
|
|
1297
|
+
await runWrangler(
|
|
1298
|
+
`kv:key delete --binding someBinding --preview someKey`
|
|
1299
|
+
);
|
|
1300
|
+
expect(requests.count).toEqual(1);
|
|
1301
|
+
});
|
|
1302
|
+
|
|
1303
|
+
it("should error if a given binding name is not in the configured kv namespaces", async () => {
|
|
1304
|
+
writeWranglerConfig();
|
|
1305
|
+
await expect(
|
|
1306
|
+
runWrangler(`kv:key delete --binding otherBinding someKey`)
|
|
1307
|
+
).rejects.toThrowErrorMatchingInlineSnapshot(
|
|
1308
|
+
`"A namespace with binding name \\"otherBinding\\" was not found in the configured \\"kv_namespaces\\"."`
|
|
1309
|
+
);
|
|
1310
|
+
|
|
1311
|
+
expect(std.err).toMatchInlineSnapshot(`
|
|
1122
1312
|
"[31mX [41;31m[[41;97mERROR[41;31m][0m [1mA namespace with binding name \\"otherBinding\\" was not found in the configured \\"kv_namespaces\\".[0m
|
|
1123
1313
|
|
|
1124
1314
|
"
|
|
1125
1315
|
`);
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1316
|
+
});
|
|
1317
|
+
|
|
1318
|
+
it("should delete a key in a namespace specified by binding name in a given environment", async () => {
|
|
1319
|
+
writeWranglerConfig();
|
|
1320
|
+
const requests = mockDeleteRequest("env-bound-id", "someKey");
|
|
1321
|
+
await runWrangler(
|
|
1322
|
+
`kv:key delete --binding someBinding --env some-environment --preview false someKey`
|
|
1323
|
+
);
|
|
1324
|
+
expect(std.out).toMatchInlineSnapshot(
|
|
1325
|
+
`"Deleting the key \\"someKey\\" on namespace env-bound-id."`
|
|
1326
|
+
);
|
|
1327
|
+
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
1328
|
+
expect(requests.count).toEqual(1);
|
|
1329
|
+
});
|
|
1330
|
+
|
|
1331
|
+
it("should delete a key in a preview namespace specified by binding name in a given environment", async () => {
|
|
1332
|
+
writeWranglerConfig();
|
|
1333
|
+
const requests = mockDeleteRequest("preview-env-bound-id", "someKey");
|
|
1334
|
+
await runWrangler(
|
|
1335
|
+
`kv:key delete --binding someBinding --env some-environment --preview someKey`
|
|
1336
|
+
);
|
|
1337
|
+
expect(requests.count).toEqual(1);
|
|
1338
|
+
});
|
|
1339
|
+
});
|
|
1340
|
+
});
|
|
1341
|
+
|
|
1342
|
+
describe("kv:bulk", () => {
|
|
1343
|
+
describe("put", () => {
|
|
1344
|
+
function mockPutRequest(
|
|
1345
|
+
expectedNamespaceId: string,
|
|
1346
|
+
expectedKeyValues: KeyValue[]
|
|
1347
|
+
) {
|
|
1348
|
+
const requests = { count: 0 };
|
|
1349
|
+
setMockResponse(
|
|
1350
|
+
"/accounts/:accountId/storage/kv/namespaces/:namespaceId/bulk",
|
|
1351
|
+
"PUT",
|
|
1352
|
+
([_url, accountId, namespaceId], { body }) => {
|
|
1353
|
+
requests.count++;
|
|
1354
|
+
expect(accountId).toEqual("some-account-id");
|
|
1355
|
+
expect(namespaceId).toEqual(expectedNamespaceId);
|
|
1356
|
+
expect(JSON.parse(body as string)).toEqual(
|
|
1357
|
+
expectedKeyValues.slice(
|
|
1358
|
+
(requests.count - 1) * 5000,
|
|
1359
|
+
requests.count * 5000
|
|
1360
|
+
)
|
|
1361
|
+
);
|
|
1362
|
+
return null;
|
|
1363
|
+
}
|
|
1364
|
+
);
|
|
1365
|
+
return requests;
|
|
1366
|
+
}
|
|
1367
|
+
|
|
1368
|
+
it("should put the key-values parsed from a file", async () => {
|
|
1369
|
+
const keyValues: KeyValue[] = [
|
|
1370
|
+
{ key: "someKey1", value: "someValue1" },
|
|
1371
|
+
{ key: "ns:someKey2", value: "123", base64: true },
|
|
1372
|
+
{ key: "someKey3", value: "someValue3", expiration: 100 },
|
|
1373
|
+
{ key: "someKey4", value: "someValue4", expiration_ttl: 500 },
|
|
1374
|
+
];
|
|
1375
|
+
writeFileSync("./keys.json", JSON.stringify(keyValues));
|
|
1376
|
+
const requests = mockPutRequest("some-namespace-id", keyValues);
|
|
1377
|
+
await runWrangler(
|
|
1378
|
+
`kv:bulk put --namespace-id some-namespace-id keys.json`
|
|
1379
|
+
);
|
|
1380
|
+
expect(requests.count).toEqual(1);
|
|
1381
|
+
expect(std.out).toMatchInlineSnapshot(`"Success!"`);
|
|
1382
|
+
expect(std.warn).toMatchInlineSnapshot(`""`);
|
|
1383
|
+
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
1384
|
+
});
|
|
1385
|
+
|
|
1386
|
+
it("should put the key-values in batches of 5000 parsed from a file", async () => {
|
|
1387
|
+
const keyValues: KeyValue[] = new Array(12000).fill({
|
|
1388
|
+
key: "someKey1",
|
|
1389
|
+
value: "someValue1",
|
|
1390
|
+
});
|
|
1391
|
+
writeFileSync("./keys.json", JSON.stringify(keyValues));
|
|
1392
|
+
const requests = mockPutRequest("some-namespace-id", keyValues);
|
|
1393
|
+
await runWrangler(
|
|
1394
|
+
`kv:bulk put --namespace-id some-namespace-id keys.json`
|
|
1395
|
+
);
|
|
1396
|
+
expect(requests.count).toEqual(3);
|
|
1397
|
+
expect(std.out).toMatchInlineSnapshot(`
|
|
1208
1398
|
"Uploaded 0% (0 out of 12,000)
|
|
1209
1399
|
Uploaded 41% (5,000 out of 12,000)
|
|
1210
1400
|
Uploaded 83% (10,000 out of 12,000)
|
|
1211
1401
|
Uploaded 100% (12,000 out of 12,000)
|
|
1212
1402
|
Success!"
|
|
1213
1403
|
`);
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1404
|
+
expect(std.warn).toMatchInlineSnapshot(`""`);
|
|
1405
|
+
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
1406
|
+
});
|
|
1407
|
+
|
|
1408
|
+
it("should error if the file is not a JSON array", async () => {
|
|
1409
|
+
const keyValues = { key: "someKey1", value: "someValue1" };
|
|
1410
|
+
writeFileSync("./keys.json", JSON.stringify(keyValues));
|
|
1411
|
+
await expect(
|
|
1412
|
+
runWrangler(`kv:bulk put --namespace-id some-namespace-id keys.json`)
|
|
1413
|
+
).rejects.toThrowErrorMatchingInlineSnapshot(`
|
|
1414
|
+
"Unexpected JSON input from \\"keys.json\\".
|
|
1415
|
+
Expected an array of key-value objects but got type \\"object\\"."
|
|
1416
|
+
`);
|
|
1417
|
+
expect(std.out).toMatchInlineSnapshot(`
|
|
1228
1418
|
"
|
|
1229
1419
|
[32mIf you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new/choose[0m"
|
|
1230
1420
|
`);
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1421
|
+
expect(std.warn).toMatchInlineSnapshot(`""`);
|
|
1422
|
+
});
|
|
1423
|
+
|
|
1424
|
+
it("should error if the array contains items that are not key-value objects", async () => {
|
|
1425
|
+
const keyValues = [
|
|
1426
|
+
123,
|
|
1427
|
+
"a string",
|
|
1428
|
+
{ key: "someKey" },
|
|
1429
|
+
{ value: "someValue" },
|
|
1430
|
+
// add a valid object here to make sure it's not included
|
|
1431
|
+
{ key: "someKey1", value: "someValue1" },
|
|
1432
|
+
// this one will only add a warning
|
|
1433
|
+
{ key: "someKey1", value: "someValue1", invalid: true },
|
|
1434
|
+
// back to the invalid ones
|
|
1435
|
+
{ key: 123, value: "somevalue" },
|
|
1436
|
+
{ key: "somekey", value: 123 },
|
|
1437
|
+
{ key: "someKey1", value: "someValue1", expiration: "string" },
|
|
1438
|
+
{ key: "someKey1", value: "someValue1", expiration_ttl: "string" },
|
|
1439
|
+
{
|
|
1440
|
+
key: 123,
|
|
1441
|
+
value: {
|
|
1442
|
+
a: {
|
|
1443
|
+
nested: "object",
|
|
1444
|
+
},
|
|
1445
|
+
},
|
|
1446
|
+
},
|
|
1447
|
+
{ key: "someKey1", value: "someValue1", metadata: 123 },
|
|
1448
|
+
{ key: "someKey1", value: "someValue1", base64: "string" },
|
|
1449
|
+
];
|
|
1450
|
+
writeFileSync("./keys.json", JSON.stringify(keyValues));
|
|
1451
|
+
await expect(
|
|
1452
|
+
runWrangler(`kv:bulk put --namespace-id some-namespace-id keys.json`)
|
|
1453
|
+
).rejects.toThrowErrorMatchingInlineSnapshot(`
|
|
1454
|
+
"Unexpected JSON input from \\"keys.json\\".
|
|
1455
|
+
Each item in the array should be an object that matches:
|
|
1456
|
+
|
|
1457
|
+
interface KeyValue {
|
|
1458
|
+
key: string;
|
|
1459
|
+
value: string;
|
|
1460
|
+
expiration?: number;
|
|
1461
|
+
expiration_ttl?: number;
|
|
1462
|
+
metadata?: object;
|
|
1463
|
+
base64?: boolean;
|
|
1464
|
+
}
|
|
1465
|
+
|
|
1466
|
+
The item at index 0 is 123
|
|
1467
|
+
The item at index 1 is \\"a string\\"
|
|
1468
|
+
The item at index 2 is {\\"key\\":\\"someKey\\"}
|
|
1469
|
+
The item at index 3 is {\\"value\\":\\"someValue\\"}
|
|
1470
|
+
The item at index 6 is {\\"key\\":123,\\"value\\":\\"somevalue\\"}
|
|
1471
|
+
The item at index 7 is {\\"key\\":\\"somekey\\",\\"value\\":123}
|
|
1472
|
+
The item at index 8 is {\\"key\\":\\"someKey1\\",\\"value\\":\\"someValue1\\",\\"expiration\\":\\"string\\"}
|
|
1473
|
+
The item at index 9 is {\\"key\\":\\"someKey1\\",\\"value\\":\\"someValue1\\",\\"expiration_ttl\\":\\"string\\"}
|
|
1474
|
+
The item at index 10 is {\\"key\\":123,\\"value\\":{\\"a\\":{\\"nested\\":\\"object\\"}}}
|
|
1475
|
+
The item at index 11 is {\\"key\\":\\"someKey1\\",\\"value\\":\\"someValue1\\",\\"metadata\\":123}
|
|
1476
|
+
The item at index 12 is {\\"key\\":\\"someKey1\\",\\"value\\":\\"someValue1\\",\\"base64\\":\\"string\\"}"
|
|
1477
|
+
`);
|
|
1478
|
+
|
|
1479
|
+
expect(std.out).toMatchInlineSnapshot(`
|
|
1290
1480
|
"
|
|
1291
1481
|
[32mIf you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new/choose[0m"
|
|
1292
1482
|
`);
|
|
1293
|
-
|
|
1483
|
+
expect(std.warn).toMatchInlineSnapshot(`
|
|
1294
1484
|
"[33m▲ [43;33m[[43;30mWARNING[43;33m][0m [1mUnexpected key-value properties in \\"keys.json\\".[0m
|
|
1295
1485
|
|
|
1296
1486
|
The item at index 5 contains unexpected properties: [\\"invalid\\"].
|
|
1297
1487
|
|
|
1298
1488
|
"
|
|
1299
1489
|
`);
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1490
|
+
});
|
|
1491
|
+
});
|
|
1492
|
+
|
|
1493
|
+
describe("delete", () => {
|
|
1494
|
+
function mockDeleteRequest(
|
|
1495
|
+
expectedNamespaceId: string,
|
|
1496
|
+
expectedKeys: string[]
|
|
1497
|
+
) {
|
|
1498
|
+
const requests = { count: 0 };
|
|
1499
|
+
setMockResponse(
|
|
1500
|
+
"/accounts/:accountId/storage/kv/namespaces/:namespaceId/bulk",
|
|
1501
|
+
"DELETE",
|
|
1502
|
+
([_url, accountId, namespaceId], { headers, body }) => {
|
|
1503
|
+
requests.count++;
|
|
1504
|
+
expect(accountId).toEqual("some-account-id");
|
|
1505
|
+
expect(namespaceId).toEqual(expectedNamespaceId);
|
|
1506
|
+
expect(new Headers(headers ?? []).get("Content-Type")).toEqual(
|
|
1507
|
+
"application/json"
|
|
1508
|
+
);
|
|
1509
|
+
expect(JSON.parse(body as string)).toEqual(
|
|
1510
|
+
expectedKeys.slice(
|
|
1511
|
+
(requests.count - 1) * 5000,
|
|
1512
|
+
requests.count * 5000
|
|
1513
|
+
)
|
|
1514
|
+
);
|
|
1515
|
+
return null;
|
|
1516
|
+
}
|
|
1517
|
+
);
|
|
1518
|
+
return requests;
|
|
1519
|
+
}
|
|
1520
|
+
|
|
1521
|
+
it("should delete the keys parsed from a file", async () => {
|
|
1522
|
+
const keys = ["someKey1", "ns:someKey2"];
|
|
1523
|
+
writeFileSync("./keys.json", JSON.stringify(keys));
|
|
1524
|
+
mockConfirm({
|
|
1525
|
+
text: `Are you sure you want to delete all the keys read from "keys.json" from kv-namespace with id "some-namespace-id"?`,
|
|
1526
|
+
result: true,
|
|
1527
|
+
});
|
|
1528
|
+
const requests = mockDeleteRequest("some-namespace-id", keys);
|
|
1529
|
+
await runWrangler(
|
|
1530
|
+
`kv:bulk delete --namespace-id some-namespace-id keys.json`
|
|
1531
|
+
);
|
|
1532
|
+
expect(requests.count).toEqual(1);
|
|
1533
|
+
expect(std.out).toMatchInlineSnapshot(`"Success!"`);
|
|
1534
|
+
expect(std.warn).toMatchInlineSnapshot(`""`);
|
|
1535
|
+
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
1536
|
+
});
|
|
1537
|
+
|
|
1538
|
+
it("should delete the keys in batches of 5000 parsed from a file", async () => {
|
|
1539
|
+
const keys = new Array(12000).fill("some-key");
|
|
1540
|
+
writeFileSync("./keys.json", JSON.stringify(keys));
|
|
1541
|
+
mockConfirm({
|
|
1542
|
+
text: `Are you sure you want to delete all the keys read from "keys.json" from kv-namespace with id "some-namespace-id"?`,
|
|
1543
|
+
result: true,
|
|
1544
|
+
});
|
|
1545
|
+
const requests = mockDeleteRequest("some-namespace-id", keys);
|
|
1546
|
+
await runWrangler(
|
|
1547
|
+
`kv:bulk delete --namespace-id some-namespace-id keys.json`
|
|
1548
|
+
);
|
|
1549
|
+
expect(requests.count).toEqual(3);
|
|
1550
|
+
expect(std.out).toMatchInlineSnapshot(`
|
|
1361
1551
|
"Deleted 0% (0 out of 12,000)
|
|
1362
1552
|
Deleted 41% (5,000 out of 12,000)
|
|
1363
1553
|
Deleted 83% (10,000 out of 12,000)
|
|
1364
1554
|
Deleted 100% (12,000 out of 12,000)
|
|
1365
1555
|
Success!"
|
|
1366
1556
|
`);
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1557
|
+
expect(std.warn).toMatchInlineSnapshot(`""`);
|
|
1558
|
+
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
1559
|
+
});
|
|
1560
|
+
|
|
1561
|
+
it("should not delete the keys if the user confirms no", async () => {
|
|
1562
|
+
const keys = ["someKey1", "ns:someKey2"];
|
|
1563
|
+
writeFileSync("./keys.json", JSON.stringify(keys));
|
|
1564
|
+
mockConfirm({
|
|
1565
|
+
text: `Are you sure you want to delete all the keys read from "keys.json" from kv-namespace with id "some-namespace-id"?`,
|
|
1566
|
+
result: false,
|
|
1567
|
+
});
|
|
1568
|
+
await runWrangler(
|
|
1569
|
+
`kv:bulk delete --namespace-id some-namespace-id keys.json`
|
|
1570
|
+
);
|
|
1571
|
+
expect(std.out).toMatchInlineSnapshot(
|
|
1572
|
+
`"Not deleting keys read from \\"keys.json\\"."`
|
|
1573
|
+
);
|
|
1574
|
+
expect(std.warn).toMatchInlineSnapshot(`""`);
|
|
1575
|
+
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
1576
|
+
});
|
|
1577
|
+
|
|
1578
|
+
it("should delete the keys without asking if --force is provided", async () => {
|
|
1579
|
+
const keys = ["someKey1", "ns:someKey2"];
|
|
1580
|
+
writeFileSync("./keys.json", JSON.stringify(keys));
|
|
1581
|
+
const requests = mockDeleteRequest("some-namespace-id", keys);
|
|
1582
|
+
await runWrangler(
|
|
1583
|
+
`kv:bulk delete --namespace-id some-namespace-id keys.json --force`
|
|
1584
|
+
);
|
|
1585
|
+
expect(requests.count).toEqual(1);
|
|
1586
|
+
expect(std.out).toMatchInlineSnapshot(`"Success!"`);
|
|
1587
|
+
expect(std.warn).toMatchInlineSnapshot(`""`);
|
|
1588
|
+
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
1589
|
+
});
|
|
1590
|
+
|
|
1591
|
+
it("should delete the keys without asking if -f is provided", async () => {
|
|
1592
|
+
const keys = ["someKey1", "ns:someKey2"];
|
|
1593
|
+
writeFileSync("./keys.json", JSON.stringify(keys));
|
|
1594
|
+
const requests = mockDeleteRequest("some-namespace-id", keys);
|
|
1595
|
+
await runWrangler(
|
|
1596
|
+
`kv:bulk delete --namespace-id some-namespace-id keys.json -f`
|
|
1597
|
+
);
|
|
1598
|
+
expect(requests.count).toEqual(1);
|
|
1599
|
+
expect(std.out).toMatchInlineSnapshot(`"Success!"`);
|
|
1600
|
+
expect(std.warn).toMatchInlineSnapshot(`""`);
|
|
1601
|
+
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
1602
|
+
});
|
|
1603
|
+
|
|
1604
|
+
it("should error if the file is not a JSON array", async () => {
|
|
1605
|
+
const keys = 12354;
|
|
1606
|
+
writeFileSync("./keys.json", JSON.stringify(keys));
|
|
1607
|
+
mockConfirm({
|
|
1608
|
+
text: `Are you sure you want to delete all the keys read from "keys.json" from kv-namespace with id "some-namespace-id"?`,
|
|
1609
|
+
result: true,
|
|
1610
|
+
});
|
|
1611
|
+
await expect(
|
|
1612
|
+
runWrangler(
|
|
1613
|
+
`kv:bulk delete --namespace-id some-namespace-id keys.json`
|
|
1614
|
+
)
|
|
1615
|
+
).rejects.toThrowErrorMatchingInlineSnapshot(`
|
|
1616
|
+
"Unexpected JSON input from \\"keys.json\\".
|
|
1617
|
+
Expected an array of strings but got:
|
|
1618
|
+
12354"
|
|
1619
|
+
`);
|
|
1620
|
+
expect(std.out).toMatchInlineSnapshot(`
|
|
1431
1621
|
"
|
|
1432
1622
|
[32mIf you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new/choose[0m"
|
|
1433
1623
|
`);
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1624
|
+
expect(std.warn).toMatchInlineSnapshot(`""`);
|
|
1625
|
+
});
|
|
1626
|
+
|
|
1627
|
+
it("should error if the file contains non-string items", async () => {
|
|
1628
|
+
const keys = ["good", 12354, { key: "someKey" }, null];
|
|
1629
|
+
writeFileSync("./keys.json", JSON.stringify(keys));
|
|
1630
|
+
mockConfirm({
|
|
1631
|
+
text: `Are you sure you want to delete all the keys read from "keys.json" from kv-namespace with id "some-namespace-id"?`,
|
|
1632
|
+
result: true,
|
|
1633
|
+
});
|
|
1634
|
+
await expect(
|
|
1635
|
+
runWrangler(
|
|
1636
|
+
`kv:bulk delete --namespace-id some-namespace-id keys.json`
|
|
1637
|
+
)
|
|
1638
|
+
).rejects.toThrowErrorMatchingInlineSnapshot(`
|
|
1639
|
+
"Unexpected JSON input from \\"keys.json\\".
|
|
1640
|
+
Expected an array of strings.
|
|
1641
|
+
The item at index 1 is type: \\"number\\" - 12354
|
|
1642
|
+
The item at index 2 is type: \\"object\\" - {\\"key\\":\\"someKey\\"}
|
|
1643
|
+
The item at index 3 is type: \\"object\\" - null"
|
|
1644
|
+
`);
|
|
1645
|
+
expect(std.out).toMatchInlineSnapshot(`
|
|
1456
1646
|
"
|
|
1457
1647
|
[32mIf you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new/choose[0m"
|
|
1458
1648
|
`);
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1649
|
+
expect(std.warn).toMatchInlineSnapshot(`""`);
|
|
1650
|
+
});
|
|
1651
|
+
});
|
|
1652
|
+
});
|
|
1463
1653
|
});
|
|
1464
1654
|
|
|
1465
1655
|
function writeWranglerConfig() {
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1656
|
+
writeFileSync(
|
|
1657
|
+
"./wrangler.toml",
|
|
1658
|
+
[
|
|
1659
|
+
'name = "other-worker"',
|
|
1660
|
+
"kv_namespaces = [",
|
|
1661
|
+
' { binding = "someBinding", id = "bound-id", preview_id = "preview-bound-id" }',
|
|
1662
|
+
"]",
|
|
1663
|
+
"",
|
|
1664
|
+
"[env.some-environment]",
|
|
1665
|
+
"kv_namespaces = [",
|
|
1666
|
+
' { binding = "someBinding", id = "env-bound-id", preview_id = "preview-env-bound-id" }',
|
|
1667
|
+
"]",
|
|
1668
|
+
].join("\n"),
|
|
1669
|
+
"utf-8"
|
|
1670
|
+
);
|
|
1481
1671
|
}
|