wrangler 0.0.0-e7a0cd5b → 0.0.0-e87ad068

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (255) hide show
  1. package/README.md +3 -3
  2. package/bin/wrangler.js +30 -10
  3. package/miniflare-dist/index.mjs +254 -128
  4. package/package.json +27 -19
  5. package/src/__tests__/api-dev.test.ts +65 -36
  6. package/src/__tests__/api-devregistry.test.ts +121 -0
  7. package/src/__tests__/api.test.ts +27 -5
  8. package/src/__tests__/configuration.test.ts +797 -98
  9. package/src/__tests__/constellation.test.ts +371 -0
  10. package/src/__tests__/d1/d1.test.ts +82 -0
  11. package/src/__tests__/d1/execute.test.ts +66 -0
  12. package/src/__tests__/d1/migrate.test.ts +257 -0
  13. package/src/__tests__/d1/splitter.test.ts +255 -0
  14. package/src/__tests__/delete.test.ts +91 -49
  15. package/src/__tests__/deployments.test.ts +330 -56
  16. package/src/__tests__/dev.test.tsx +198 -90
  17. package/src/__tests__/generate.test.ts +12 -10
  18. package/src/__tests__/guess-worker-format.test.ts +35 -0
  19. package/src/__tests__/helpers/end-event-loop.ts +6 -0
  20. package/src/__tests__/helpers/mock-auth-domain.ts +20 -0
  21. package/src/__tests__/helpers/mock-console.ts +6 -0
  22. package/src/__tests__/helpers/mock-dialogs.ts +71 -85
  23. package/src/__tests__/helpers/mock-get-pages-upload-token.ts +25 -0
  24. package/src/__tests__/helpers/mock-get-zone-from-host.ts +8 -5
  25. package/src/__tests__/helpers/mock-known-routes.ts +7 -2
  26. package/src/__tests__/helpers/mock-kv.ts +29 -16
  27. package/src/__tests__/helpers/mock-oauth-flow.ts +103 -92
  28. package/src/__tests__/helpers/mock-process.ts +8 -13
  29. package/src/__tests__/helpers/mock-set-timeout.ts +16 -0
  30. package/src/__tests__/helpers/msw/blob-worker.cjs +19 -0
  31. package/src/__tests__/helpers/msw/handlers/deployments.ts +128 -27
  32. package/src/__tests__/helpers/msw/handlers/namespaces.ts +18 -41
  33. package/src/__tests__/helpers/msw/handlers/oauth.ts +13 -18
  34. package/src/__tests__/helpers/msw/handlers/r2.ts +14 -34
  35. package/src/__tests__/helpers/msw/handlers/script.ts +9 -28
  36. package/src/__tests__/helpers/msw/handlers/user.ts +13 -24
  37. package/src/__tests__/helpers/msw/handlers/zones.ts +6 -8
  38. package/src/__tests__/helpers/msw/index.ts +32 -1
  39. package/src/__tests__/helpers/msw/read-file-sync.js +61 -0
  40. package/src/__tests__/helpers/string-dynamic-values-matcher.ts +28 -0
  41. package/src/__tests__/helpers/worker-scripts/parent-worker.js +4 -1
  42. package/src/__tests__/index.test.ts +92 -72
  43. package/src/__tests__/init.test.ts +1033 -631
  44. package/src/__tests__/jest.setup.ts +19 -42
  45. package/src/__tests__/kv.test.ts +355 -231
  46. package/src/__tests__/logger.test.ts +68 -2
  47. package/src/__tests__/logout.test.ts +47 -0
  48. package/src/__tests__/metrics.test.ts +94 -51
  49. package/src/__tests__/middleware.scheduled.test.ts +42 -32
  50. package/src/__tests__/middleware.test.ts +212 -122
  51. package/src/__tests__/mtls-certificates.test.ts +589 -0
  52. package/src/__tests__/pages/deployment-list.test.ts +80 -0
  53. package/src/__tests__/pages/functions-build.test.ts +529 -0
  54. package/src/__tests__/pages/pages.test.ts +81 -0
  55. package/src/__tests__/pages/project-create.test.ts +63 -0
  56. package/src/__tests__/pages/project-list.test.ts +110 -0
  57. package/src/__tests__/pages/project-upload.test.ts +500 -0
  58. package/src/__tests__/pages/publish.test.ts +2864 -0
  59. package/src/__tests__/pages-deployment-tail.test.ts +957 -0
  60. package/src/__tests__/parse.test.ts +106 -0
  61. package/src/__tests__/publish.test.ts +2227 -1005
  62. package/src/__tests__/pubsub.test.ts +226 -100
  63. package/src/__tests__/queues.test.ts +238 -77
  64. package/src/__tests__/r2.test.ts +55 -57
  65. package/src/__tests__/secret.test.ts +179 -130
  66. package/src/__tests__/tail.test.ts +313 -113
  67. package/src/__tests__/test-old-node-version.js +3 -3
  68. package/src/__tests__/traverse-module-graph.test.ts +220 -0
  69. package/src/__tests__/tsconfig-sanity.ts +12 -0
  70. package/src/__tests__/tsconfig.json +8 -0
  71. package/src/__tests__/tsconfig.tsbuildinfo +1 -0
  72. package/src/__tests__/type-generation.test.ts +43 -26
  73. package/src/__tests__/unstableDev.test.ts +61 -0
  74. package/src/__tests__/user.test.ts +35 -72
  75. package/src/__tests__/whoami.test.tsx +8 -114
  76. package/src/__tests__/worker-namespace.test.ts +83 -69
  77. package/src/api/dev.ts +180 -60
  78. package/src/api/index.ts +10 -1
  79. package/src/api/mtls-certificate.ts +148 -0
  80. package/src/api/pages/create-worker-bundle-contents.ts +80 -0
  81. package/src/api/pages/index.ts +5 -0
  82. package/src/api/pages/publish.tsx +371 -0
  83. package/src/bundle.ts +315 -148
  84. package/src/cfetch/index.ts +0 -2
  85. package/src/cfetch/internal.ts +33 -33
  86. package/src/cli.ts +4 -4
  87. package/src/config/config.ts +14 -7
  88. package/src/config/environment.ts +120 -24
  89. package/src/config/index.ts +117 -35
  90. package/src/config/validation-helpers.ts +1 -1
  91. package/src/config/validation.ts +430 -19
  92. package/src/constellation/createProject.tsx +51 -0
  93. package/src/constellation/deleteProject.ts +51 -0
  94. package/src/constellation/deleteProjectModel.ts +76 -0
  95. package/src/constellation/index.ts +75 -0
  96. package/src/constellation/listCatalog.tsx +35 -0
  97. package/src/constellation/listModel.tsx +49 -0
  98. package/src/constellation/listProject.tsx +28 -0
  99. package/src/constellation/listRuntime.tsx +28 -0
  100. package/src/constellation/options.ts +17 -0
  101. package/src/constellation/types.ts +17 -0
  102. package/src/constellation/uploadModel.tsx +84 -0
  103. package/src/constellation/utils.ts +90 -0
  104. package/src/create-worker-preview.ts +19 -8
  105. package/src/create-worker-upload-form.ts +81 -18
  106. package/src/d1/backups.tsx +47 -46
  107. package/src/d1/constants.ts +5 -0
  108. package/src/d1/create.tsx +85 -37
  109. package/src/d1/{delete.tsx → delete.ts} +12 -15
  110. package/src/d1/execute.tsx +228 -156
  111. package/src/d1/index.ts +31 -7
  112. package/src/d1/list.tsx +27 -13
  113. package/src/d1/migrations/apply.tsx +235 -0
  114. package/src/d1/migrations/create.tsx +79 -0
  115. package/src/d1/migrations/helpers.ts +171 -0
  116. package/src/d1/migrations/index.ts +3 -0
  117. package/src/d1/migrations/list.tsx +95 -0
  118. package/src/d1/migrations/options.ts +23 -0
  119. package/src/d1/options.ts +12 -2
  120. package/src/d1/splitter.ts +161 -0
  121. package/src/d1/types.ts +32 -0
  122. package/src/d1/utils.ts +12 -2
  123. package/src/delete.ts +8 -16
  124. package/src/deployments.ts +340 -46
  125. package/src/deprecated/index.ts +8 -302
  126. package/src/dev/dev.tsx +66 -46
  127. package/src/dev/local.tsx +339 -104
  128. package/src/dev/remote.tsx +36 -3
  129. package/src/dev/start-server.ts +146 -101
  130. package/src/dev/use-esbuild.ts +82 -56
  131. package/src/dev/validate-dev-props.ts +9 -0
  132. package/src/{dev-registry.tsx → dev-registry.ts} +13 -1
  133. package/src/dev.tsx +202 -125
  134. package/src/dialogs.ts +136 -0
  135. package/src/dispatch-namespace.ts +21 -17
  136. package/src/docs/helpers.ts +50 -0
  137. package/src/docs/index.ts +54 -0
  138. package/src/entry.ts +26 -11
  139. package/src/environment-variables/factory.ts +89 -0
  140. package/src/environment-variables/misc-variables.ts +30 -0
  141. package/src/generate/index.ts +303 -0
  142. package/src/git-client.ts +15 -4
  143. package/src/{index.tsx → index.ts} +148 -63
  144. package/src/init.ts +301 -197
  145. package/src/inspect.ts +122 -6
  146. package/src/jest.d.ts +4 -0
  147. package/src/kv/helpers.ts +7 -4
  148. package/src/kv/index.ts +15 -17
  149. package/src/logger.ts +36 -5
  150. package/src/metrics/metrics-config.ts +3 -3
  151. package/src/metrics/send-event.ts +6 -1
  152. package/src/miniflare-cli/assets.ts +64 -28
  153. package/src/miniflare-cli/index.ts +6 -9
  154. package/src/miniflare-cli/tsconfig.json +9 -0
  155. package/src/miniflare-cli/tsconfig.tsbuildinfo +1 -0
  156. package/src/miniflare-cli/types.ts +11 -0
  157. package/src/module-collection.ts +92 -26
  158. package/src/mtls-certificate/cli.ts +155 -0
  159. package/src/pages/build.ts +423 -0
  160. package/src/pages/buildFunctions.ts +140 -0
  161. package/src/pages/deployment-tails.ts +281 -0
  162. package/src/pages/deployments.tsx +11 -33
  163. package/src/pages/{dev.tsx → dev.ts} +192 -126
  164. package/src/pages/errors.ts +1 -0
  165. package/src/pages/functions/buildPlugin.ts +73 -69
  166. package/src/pages/functions/buildWorker.ts +342 -117
  167. package/src/pages/functions/tsconfig.json +8 -0
  168. package/src/pages/functions/tsconfig.tsbuildinfo +1 -0
  169. package/src/pages/{functions.tsx → functions.ts} +8 -4
  170. package/src/pages/{index.tsx → index.ts} +11 -3
  171. package/src/pages/projects.tsx +12 -22
  172. package/src/pages/prompt-select-project.tsx +31 -0
  173. package/src/pages/publish.tsx +45 -214
  174. package/src/pages/types.ts +6 -9
  175. package/src/pages/upload.tsx +58 -14
  176. package/src/pages/utils.ts +14 -3
  177. package/src/parse.ts +23 -1
  178. package/src/paths.ts +1 -1
  179. package/src/proxy.ts +5 -0
  180. package/src/publish/index.ts +20 -16
  181. package/src/publish/publish.ts +81 -48
  182. package/src/pubsub/{pubsub-commands.tsx → pubsub-commands.ts} +19 -20
  183. package/src/queues/cli/commands/consumer/add.ts +24 -24
  184. package/src/queues/cli/commands/consumer/index.ts +3 -6
  185. package/src/queues/cli/commands/consumer/remove.ts +11 -18
  186. package/src/queues/cli/commands/create.ts +8 -8
  187. package/src/queues/cli/commands/delete.ts +8 -8
  188. package/src/queues/cli/commands/index.ts +6 -4
  189. package/src/queues/cli/commands/list.ts +8 -8
  190. package/src/queues/client.ts +1 -0
  191. package/src/queues/utils.ts +18 -0
  192. package/src/r2/constants.ts +4 -0
  193. package/src/r2/helpers.ts +1 -0
  194. package/src/r2/index.ts +40 -28
  195. package/src/secret/index.ts +18 -17
  196. package/src/{sites.tsx → sites.ts} +165 -53
  197. package/src/tail/createTail.ts +103 -3
  198. package/src/tail/filters.ts +1 -1
  199. package/src/tail/index.ts +8 -11
  200. package/src/tail/printing.ts +27 -0
  201. package/src/traverse-module-graph.ts +54 -0
  202. package/src/tsconfig-sanity.ts +16 -0
  203. package/src/type-generation.ts +85 -57
  204. package/src/user/access.ts +0 -1
  205. package/src/user/auth-variables.ts +113 -0
  206. package/src/user/choose-account.tsx +1 -31
  207. package/src/user/index.ts +0 -1
  208. package/src/user/{user.tsx → user.ts} +124 -82
  209. package/src/utils/render.ts +93 -0
  210. package/src/{whoami.tsx → whoami.ts} +37 -71
  211. package/src/worker.ts +61 -3
  212. package/src/yargs-types.ts +22 -5
  213. package/templates/__tests__/tsconfig-sanity.ts +12 -0
  214. package/templates/__tests__/tsconfig.json +8 -0
  215. package/templates/__tests__/tsconfig.tsbuildinfo +1 -0
  216. package/templates/checked-fetch.js +9 -3
  217. package/templates/d1-beta-facade.js +95 -25
  218. package/templates/facade.d.ts +14 -0
  219. package/templates/first-party-worker-module-facade.ts +4 -3
  220. package/templates/format-dev-errors.ts +8 -6
  221. package/templates/gitignore +1 -0
  222. package/templates/init-tests/test-jest-new-worker.js +3 -5
  223. package/templates/init-tests/test-vitest-new-worker.js +3 -5
  224. package/templates/init-tests/test-vitest-new-worker.ts +25 -0
  225. package/templates/middleware/loader-modules.ts +2 -2
  226. package/templates/middleware/loader-sw.ts +51 -31
  227. package/templates/middleware/middleware-miniflare3-json-error.ts +32 -0
  228. package/templates/new-worker.ts +3 -0
  229. package/templates/pages-dev-pipeline.ts +4 -1
  230. package/templates/pages-dev-util.ts +4 -1
  231. package/templates/pages-shim.ts +4 -1
  232. package/templates/pages-template-plugin.ts +19 -10
  233. package/templates/serve-static-assets.ts +17 -14
  234. package/templates/service-bindings-module-facade.js +1 -0
  235. package/templates/tsconfig-sanity.ts +11 -0
  236. package/templates/tsconfig.init.json +105 -0
  237. package/templates/tsconfig.json +5 -103
  238. package/templates/tsconfig.tsbuildinfo +1 -0
  239. package/wrangler-dist/cli.d.ts +902 -77
  240. package/wrangler-dist/cli.js +131685 -140615
  241. package/wrangler-dist/wasm-sync.wasm +0 -0
  242. package/src/__tests__/api-devregistry.test.js +0 -57
  243. package/src/__tests__/d1.test.ts +0 -72
  244. package/src/__tests__/dialogs.test.tsx +0 -40
  245. package/src/__tests__/helpers/mock-cfetch.ts +0 -333
  246. package/src/__tests__/pages.test.ts +0 -2223
  247. package/src/d1/types.tsx +0 -14
  248. package/src/dialogs.tsx +0 -163
  249. package/src/environment-variables.ts +0 -50
  250. package/src/pages/build.tsx +0 -238
  251. package/src/user/env-vars.ts +0 -46
  252. package/templates/experimental-local-cache-stubs.js +0 -27
  253. /package/src/{bundle-reporter.tsx → bundle-reporter.ts} +0 -0
  254. /package/src/dev/{get-local-persistence-path.tsx → get-local-persistence-path.ts} +0 -0
  255. /package/src/pages/{hash.tsx → hash.ts} +0 -0
@@ -1,20 +1,11 @@
1
1
  import { writeFileSync } from "node:fs";
2
- import { FormData, Headers } from "undici";
2
+ import { rest } from "msw";
3
3
  import { mockAccountId, mockApiToken } from "./helpers/mock-account-id";
4
- import {
5
- setMockResponse,
6
- unsetAllMocks,
7
- unsetSpecialMockFns,
8
- setMockFetchKVGetValue,
9
- setMockRawResponse,
10
- createFetchResult,
11
- } from "./helpers/mock-cfetch";
12
4
  import { mockConsoleMethods } from "./helpers/mock-console";
13
- import { clearConfirmMocks, mockConfirm } from "./helpers/mock-dialogs";
5
+ import { mockConfirm, clearDialogs } from "./helpers/mock-dialogs";
14
6
  import { useMockIsTTY } from "./helpers/mock-istty";
15
- import { mockKeyListRequest } from "./helpers/mock-kv";
16
- import { mockGetMemberships } from "./helpers/mock-oauth-flow";
17
7
  import { mockProcess } from "./helpers/mock-process";
8
+ import { msw } from "./helpers/msw";
18
9
  import { runInTempDir } from "./helpers/run-in-tmp";
19
10
  import { runWrangler } from "./helpers/run-wrangler";
20
11
  import type {
@@ -22,31 +13,37 @@ import type {
22
13
  KVNamespaceInfo,
23
14
  NamespaceKeyInfo,
24
15
  } from "../kv/helpers";
25
-
26
16
  describe("wrangler", () => {
27
17
  mockAccountId();
28
18
  mockApiToken();
29
19
  runInTempDir();
20
+
30
21
  const std = mockConsoleMethods();
31
22
  const proc = mockProcess();
32
23
 
24
+ const { setIsTTY } = useMockIsTTY();
25
+ beforeEach(() => {
26
+ setIsTTY(true);
27
+ });
33
28
  afterEach(() => {
34
- unsetAllMocks();
35
- clearConfirmMocks();
29
+ clearDialogs();
36
30
  });
37
-
38
31
  describe("kv:namespace", () => {
39
32
  describe("create", () => {
40
33
  function mockCreateRequest(expectedTitle: string) {
41
- setMockResponse(
42
- "/accounts/:accountId/storage/kv/namespaces",
43
- "POST",
44
- ([_url, accountId], { body }) => {
45
- expect(accountId).toEqual("some-account-id");
46
- const title = JSON.parse(body as string).title;
47
- expect(title).toEqual(expectedTitle);
48
- return { id: "some-namespace-id" };
49
- }
34
+ msw.use(
35
+ rest.post(
36
+ "*/accounts/:accountId/storage/kv/namespaces",
37
+ async (req, res, ctx) => {
38
+ expect(req.params.accountId).toEqual("some-account-id");
39
+ const title = (await req.json()).title as string;
40
+ expect(title).toEqual(expectedTitle);
41
+ return res.once(
42
+ ctx.status(200),
43
+ ctx.json(createFetchResult({ id: "some-namespace-id" }))
44
+ );
45
+ }
46
+ )
50
47
  );
51
48
  }
52
49
 
@@ -66,10 +63,11 @@ describe("wrangler", () => {
66
63
  namespace The name of the new namespace [string] [required]
67
64
 
68
65
  Flags:
69
- -c, --config Path to .toml configuration file [string]
70
- -e, --env Environment to use for operations and .env files [string]
71
- -h, --help Show help [boolean]
72
- -v, --version Show version number [boolean]
66
+ -j, --experimental-json-config Experimental: Support wrangler.json [boolean]
67
+ -c, --config Path to .toml configuration file [string]
68
+ -e, --env Environment to use for operations and .env files [string]
69
+ -h, --help Show help [boolean]
70
+ -v, --version Show version number [boolean]
73
71
 
74
72
  Options:
75
73
  --preview Interact with a preview namespace [boolean]"
@@ -97,10 +95,11 @@ describe("wrangler", () => {
97
95
  namespace The name of the new namespace [string] [required]
98
96
 
99
97
  Flags:
100
- -c, --config Path to .toml configuration file [string]
101
- -e, --env Environment to use for operations and .env files [string]
102
- -h, --help Show help [boolean]
103
- -v, --version Show version number [boolean]
98
+ -j, --experimental-json-config Experimental: Support wrangler.json [boolean]
99
+ -c, --config Path to .toml configuration file [string]
100
+ -e, --env Environment to use for operations and .env files [string]
101
+ -h, --help Show help [boolean]
102
+ -v, --version Show version number [boolean]
104
103
 
105
104
  Options:
106
105
  --preview Interact with a preview namespace [boolean]"
@@ -129,10 +128,11 @@ describe("wrangler", () => {
129
128
  namespace The name of the new namespace [string] [required]
130
129
 
131
130
  Flags:
132
- -c, --config Path to .toml configuration file [string]
133
- -e, --env Environment to use for operations and .env files [string]
134
- -h, --help Show help [boolean]
135
- -v, --version Show version number [boolean]
131
+ -j, --experimental-json-config Experimental: Support wrangler.json [boolean]
132
+ -c, --config Path to .toml configuration file [string]
133
+ -e, --env Environment to use for operations and .env files [string]
134
+ -h, --help Show help [boolean]
135
+ -v, --version Show version number [boolean]
136
136
 
137
137
  Options:
138
138
  --preview Interact with a preview namespace [boolean]"
@@ -193,22 +193,32 @@ describe("wrangler", () => {
193
193
  });
194
194
 
195
195
  describe("list", () => {
196
- function mockListRequest(namespaces: unknown[]) {
196
+ function mockListRequest(namespaces: KVNamespaceInfo[]) {
197
197
  const requests = { count: 0 };
198
- setMockResponse(
199
- "/accounts/:accountId/storage/kv/namespaces",
200
- ([_url, accountId], init, query) => {
201
- requests.count++;
202
- expect(accountId).toEqual("some-account-id");
203
- expect(query.get("per_page")).toEqual("100");
204
- expect(query.get("order")).toEqual("title");
205
- expect(query.get("direction")).toEqual("asc");
206
- expect(query.get("page")).toEqual(`${requests.count}`);
207
- expect(init).toEqual({});
208
- const pageSize = Number(query.get("per_page"));
209
- const page = Number(query.get("page"));
210
- return namespaces.slice((page - 1) * pageSize, page * pageSize);
211
- }
198
+ msw.use(
199
+ rest.get(
200
+ "*/accounts/:accountId/storage/kv/namespaces",
201
+ async (req, res, ctx) => {
202
+ requests.count++;
203
+ expect(req.params.accountId).toEqual("some-account-id");
204
+ expect(req.url.searchParams.get("per_page")).toEqual("100");
205
+ expect(req.url.searchParams.get("order")).toEqual("title");
206
+ expect(req.url.searchParams.get("direction")).toEqual("asc");
207
+ expect(req.url.searchParams.get("page")).toEqual(
208
+ `${requests.count}`
209
+ );
210
+
211
+ const pageSize = Number(req.url.searchParams.get("per_page"));
212
+ const page = Number(req.url.searchParams.get("page"));
213
+ return res(
214
+ ctx.json(
215
+ createFetchResult(
216
+ namespaces.slice((page - 1) * pageSize, page * pageSize)
217
+ )
218
+ )
219
+ );
220
+ }
221
+ )
212
222
  );
213
223
  return requests;
214
224
  }
@@ -222,8 +232,7 @@ describe("wrangler", () => {
222
232
  await runWrangler("kv:namespace list");
223
233
 
224
234
  expect(std.err).toMatchInlineSnapshot(`""`);
225
- const namespaces = JSON.parse(std.out);
226
- expect(namespaces).toEqual(kvNamespaces);
235
+ expect(JSON.parse(std.out)).toEqual(kvNamespaces);
227
236
  });
228
237
 
229
238
  it("should make multiple requests for paginated results", async () => {
@@ -234,8 +243,8 @@ describe("wrangler", () => {
234
243
  }
235
244
  const requests = mockListRequest(kvNamespaces);
236
245
  await runWrangler("kv:namespace list");
237
- const namespaces = JSON.parse(std.out);
238
- expect(namespaces).toEqual(kvNamespaces);
246
+
247
+ expect(JSON.parse(std.out)).toEqual(kvNamespaces);
239
248
  expect(requests.count).toEqual(6);
240
249
  });
241
250
  });
@@ -243,15 +252,16 @@ describe("wrangler", () => {
243
252
  describe("delete", () => {
244
253
  function mockDeleteRequest(expectedNamespaceId: string) {
245
254
  const requests = { count: 0 };
246
- setMockResponse(
247
- "/accounts/:accountId/storage/kv/namespaces/:namespaceId",
248
- "DELETE",
249
- ([_url, accountId, namespaceId]) => {
250
- requests.count++;
251
- expect(accountId).toEqual("some-account-id");
252
- expect(namespaceId).toEqual(expectedNamespaceId);
253
- return null;
254
- }
255
+ msw.use(
256
+ rest.delete(
257
+ "*/accounts/:accountId/storage/kv/namespaces/:namespaceId",
258
+ (req, res, ctx) => {
259
+ requests.count++;
260
+ expect(req.params.accountId).toEqual("some-account-id");
261
+ expect(req.params.namespaceId).toEqual(expectedNamespaceId);
262
+ return res(ctx.status(200), ctx.json(createFetchResult(null)));
263
+ }
264
+ )
255
265
  );
256
266
  return requests;
257
267
  }
@@ -331,39 +341,43 @@ describe("wrangler", () => {
331
341
  expectedKV: KeyValue
332
342
  ) {
333
343
  const requests = { count: 0 };
334
- setMockResponse(
335
- "/accounts/:accountId/storage/kv/namespaces/:namespaceId/values/:key",
336
- "PUT",
337
- ([_url, accountId, namespaceId, key], { body }, query) => {
338
- requests.count++;
339
- expect(accountId).toEqual("some-account-id");
340
- expect(namespaceId).toEqual(expectedNamespaceId);
341
- expect(key).toEqual(expectedKV.key);
342
- if (expectedKV.metadata) {
343
- expect(body).toBeInstanceOf(FormData);
344
- expect((body as FormData).get("value")).toEqual(expectedKV.value);
345
- expect((body as FormData).get("metadata")).toEqual(
346
- JSON.stringify(expectedKV.metadata)
347
- );
348
- } else {
349
- expect(body).toEqual(expectedKV.value);
350
- }
351
- if (expectedKV.expiration !== undefined) {
352
- expect(query.get("expiration")).toEqual(
353
- `${expectedKV.expiration}`
354
- );
355
- } else {
356
- expect(query.has("expiration")).toBe(false);
344
+ msw.use(
345
+ rest.put(
346
+ "*/accounts/:accountId/storage/kv/namespaces/:namespaceId/values/:key",
347
+ (req, res, ctx) => {
348
+ requests.count++;
349
+ const { accountId, namespaceId, key } = req.params;
350
+ expect(accountId).toEqual("some-account-id");
351
+ expect(namespaceId).toEqual(expectedNamespaceId);
352
+ expect(encodeURIComponent(key as string)).toEqual(expectedKV.key);
353
+ // if (expectedKV.metadata) {
354
+ // expect(body).toBeInstanceOf(FormData);
355
+ // expect((body as FormData).get("value")).toEqual(
356
+ // expectedKV.value
357
+ // );
358
+ // expect((body as FormData).get("metadata")).toEqual(
359
+ // JSON.stringify(expectedKV.metadata)
360
+ // );
361
+ // } else {
362
+ // expect(body).toEqual(expectedKV.value);
363
+ // }
364
+ if (expectedKV.expiration !== undefined) {
365
+ expect(req.url.searchParams.get("expiration")).toEqual(
366
+ `${expectedKV.expiration}`
367
+ );
368
+ } else {
369
+ expect(req.url.searchParams.has("expiration")).toBe(false);
370
+ }
371
+ if (expectedKV.expiration_ttl) {
372
+ expect(req.url.searchParams.get("expiration_ttl")).toEqual(
373
+ `${expectedKV.expiration_ttl}`
374
+ );
375
+ } else {
376
+ expect(req.url.searchParams.has("expiration_ttl")).toBe(false);
377
+ }
378
+ return res(ctx.status(200), ctx.json(createFetchResult(null)));
357
379
  }
358
- if (expectedKV.expiration_ttl) {
359
- expect(query.get("expiration_ttl")).toEqual(
360
- `${expectedKV.expiration_ttl}`
361
- );
362
- } else {
363
- expect(query.has("expiration_ttl")).toBe(false);
364
- }
365
- return null;
366
- }
380
+ )
367
381
  );
368
382
  return requests;
369
383
  }
@@ -541,10 +555,11 @@ describe("wrangler", () => {
541
555
  value The value to write [string]
542
556
 
543
557
  Flags:
544
- -c, --config Path to .toml configuration file [string]
545
- -e, --env Environment to use for operations and .env files [string]
546
- -h, --help Show help [boolean]
547
- -v, --version Show version number [boolean]
558
+ -j, --experimental-json-config Experimental: Support wrangler.json [boolean]
559
+ -c, --config Path to .toml configuration file [string]
560
+ -e, --env Environment to use for operations and .env files [string]
561
+ -h, --help Show help [boolean]
562
+ -v, --version Show version number [boolean]
548
563
 
549
564
  Options:
550
565
  --binding The binding of the namespace to write to [string]
@@ -580,10 +595,11 @@ describe("wrangler", () => {
580
595
  value The value to write [string]
581
596
 
582
597
  Flags:
583
- -c, --config Path to .toml configuration file [string]
584
- -e, --env Environment to use for operations and .env files [string]
585
- -h, --help Show help [boolean]
586
- -v, --version Show version number [boolean]
598
+ -j, --experimental-json-config Experimental: Support wrangler.json [boolean]
599
+ -c, --config Path to .toml configuration file [string]
600
+ -e, --env Environment to use for operations and .env files [string]
601
+ -h, --help Show help [boolean]
602
+ -v, --version Show version number [boolean]
587
603
 
588
604
  Options:
589
605
  --binding The binding of the namespace to write to [string]
@@ -619,10 +635,11 @@ describe("wrangler", () => {
619
635
  value The value to write [string]
620
636
 
621
637
  Flags:
622
- -c, --config Path to .toml configuration file [string]
623
- -e, --env Environment to use for operations and .env files [string]
624
- -h, --help Show help [boolean]
625
- -v, --version Show version number [boolean]
638
+ -j, --experimental-json-config Experimental: Support wrangler.json [boolean]
639
+ -c, --config Path to .toml configuration file [string]
640
+ -e, --env Environment to use for operations and .env files [string]
641
+ -h, --help Show help [boolean]
642
+ -v, --version Show version number [boolean]
626
643
 
627
644
  Options:
628
645
  --binding The binding of the namespace to write to [string]
@@ -658,10 +675,11 @@ describe("wrangler", () => {
658
675
  value The value to write [string]
659
676
 
660
677
  Flags:
661
- -c, --config Path to .toml configuration file [string]
662
- -e, --env Environment to use for operations and .env files [string]
663
- -h, --help Show help [boolean]
664
- -v, --version Show version number [boolean]
678
+ -j, --experimental-json-config Experimental: Support wrangler.json [boolean]
679
+ -c, --config Path to .toml configuration file [string]
680
+ -e, --env Environment to use for operations and .env files [string]
681
+ -h, --help Show help [boolean]
682
+ -v, --version Show version number [boolean]
665
683
 
666
684
  Options:
667
685
  --binding The binding of the namespace to write to [string]
@@ -697,10 +715,11 @@ describe("wrangler", () => {
697
715
  value The value to write [string]
698
716
 
699
717
  Flags:
700
- -c, --config Path to .toml configuration file [string]
701
- -e, --env Environment to use for operations and .env files [string]
702
- -h, --help Show help [boolean]
703
- -v, --version Show version number [boolean]
718
+ -j, --experimental-json-config Experimental: Support wrangler.json [boolean]
719
+ -c, --config Path to .toml configuration file [string]
720
+ -e, --env Environment to use for operations and .env files [string]
721
+ -h, --help Show help [boolean]
722
+ -v, --version Show version number [boolean]
704
723
 
705
724
  Options:
706
725
  --binding The binding of the namespace to write to [string]
@@ -728,7 +747,7 @@ describe("wrangler", () => {
728
747
 
729
748
  expect(std.out).toMatchInlineSnapshot(`
730
749
  "
731
- If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new/choose"
750
+ If you think this is a bug then please create an issue at https://github.com/cloudflare/workers-sdk/issues/new/choose"
732
751
  `);
733
752
  expect(std.err).toMatchInlineSnapshot(`
734
753
  "X [ERROR] A namespace with binding name \\"otherBinding\\" was not found in the configured \\"kv_namespaces\\".
@@ -750,7 +769,7 @@ describe("wrangler", () => {
750
769
  );
751
770
  expect(std.out).toMatchInlineSnapshot(`
752
771
  "
753
- If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new/choose"
772
+ If you think this is a bug then please create an issue at https://github.com/cloudflare/workers-sdk/issues/new/choose"
754
773
  `);
755
774
  expect(std.err).toMatchInlineSnapshot(`
756
775
  "X [ERROR] someBinding has both a namespace ID and a preview ID. Specify \\"--preview\\" or \\"--preview false\\" to avoid writing data to the wrong namespace.
@@ -921,16 +940,12 @@ describe("wrangler", () => {
921
940
  `);
922
941
  expect(std.out).toMatchInlineSnapshot(`
923
942
  "
924
- If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new/choose"
943
+ If you think this is a bug then please create an issue at https://github.com/cloudflare/workers-sdk/issues/new/choose"
925
944
  `);
926
945
  });
927
946
  });
928
947
 
929
948
  describe("get", () => {
930
- afterEach(() => {
931
- unsetSpecialMockFns();
932
- });
933
-
934
949
  it("should get a key in a given namespace specified by namespace-id", async () => {
935
950
  setMockFetchKVGetValue(
936
951
  "some-account-id",
@@ -938,7 +953,9 @@ describe("wrangler", () => {
938
953
  "my-key",
939
954
  "my-value"
940
955
  );
956
+
941
957
  await runWrangler("kv:key get my-key --namespace-id some-namespace-id");
958
+
942
959
  expect(proc.write).toEqual(Buffer.from("my-value"));
943
960
  expect(std.err).toMatchInlineSnapshot(`""`);
944
961
  });
@@ -955,13 +972,14 @@ describe("wrangler", () => {
955
972
  );
956
973
  expect(proc.write).not.toEqual(Buffer.from("my-value"));
957
974
  expect(std).toMatchInlineSnapshot(`
958
- Object {
959
- "debug": "",
960
- "err": "",
961
- "out": "my-value",
962
- "warn": "",
963
- }
964
- `);
975
+ Object {
976
+ "debug": "",
977
+ "err": "",
978
+ "info": "",
979
+ "out": "my-value",
980
+ "warn": "",
981
+ }
982
+ `);
965
983
  });
966
984
 
967
985
  it("should get a binary and decode as utf8 text, resulting in improper decoding", async () => {
@@ -980,7 +998,7 @@ describe("wrangler", () => {
980
998
  );
981
999
  expect(proc.write).not.toEqual(buf);
982
1000
  expect(JSON.stringify(std)).toMatchInlineSnapshot(
983
- `"{\\"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\\":\\"\\"}"`
1001
+ `"{\\"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\`�\\",\\"info\\":\\"\\",\\"err\\":\\"\\",\\"warn\\":\\"\\"}"`
984
1002
  );
985
1003
  });
986
1004
 
@@ -1047,9 +1065,10 @@ describe("wrangler", () => {
1047
1065
  setMockFetchKVGetValue(
1048
1066
  "some-account-id",
1049
1067
  "some-namespace-id",
1050
- "%2Fmy%2Ckey",
1068
+ "%2Fmy%2Ckey", // expect the key /my,key to be encoded
1051
1069
  "my-value"
1052
1070
  );
1071
+
1053
1072
  await runWrangler(
1054
1073
  "kv:key get /my,key --namespace-id some-namespace-id"
1055
1074
  );
@@ -1073,10 +1092,11 @@ describe("wrangler", () => {
1073
1092
  key The key value to get. [string] [required]
1074
1093
 
1075
1094
  Flags:
1076
- -c, --config Path to .toml configuration file [string]
1077
- -e, --env Environment to use for operations and .env files [string]
1078
- -h, --help Show help [boolean]
1079
- -v, --version Show version number [boolean]
1095
+ -j, --experimental-json-config Experimental: Support wrangler.json [boolean]
1096
+ -c, --config Path to .toml configuration file [string]
1097
+ -e, --env Environment to use for operations and .env files [string]
1098
+ -h, --help Show help [boolean]
1099
+ -v, --version Show version number [boolean]
1080
1100
 
1081
1101
  Options:
1082
1102
  --binding The name of the namespace to get from [string]
@@ -1107,10 +1127,11 @@ describe("wrangler", () => {
1107
1127
  key The key value to get. [string] [required]
1108
1128
 
1109
1129
  Flags:
1110
- -c, --config Path to .toml configuration file [string]
1111
- -e, --env Environment to use for operations and .env files [string]
1112
- -h, --help Show help [boolean]
1113
- -v, --version Show version number [boolean]
1130
+ -j, --experimental-json-config Experimental: Support wrangler.json [boolean]
1131
+ -c, --config Path to .toml configuration file [string]
1132
+ -e, --env Environment to use for operations and .env files [string]
1133
+ -h, --help Show help [boolean]
1134
+ -v, --version Show version number [boolean]
1114
1135
 
1115
1136
  Options:
1116
1137
  --binding The name of the namespace to get from [string]
@@ -1142,10 +1163,11 @@ describe("wrangler", () => {
1142
1163
  key The key value to get. [string] [required]
1143
1164
 
1144
1165
  Flags:
1145
- -c, --config Path to .toml configuration file [string]
1146
- -e, --env Environment to use for operations and .env files [string]
1147
- -h, --help Show help [boolean]
1148
- -v, --version Show version number [boolean]
1166
+ -j, --experimental-json-config Experimental: Support wrangler.json [boolean]
1167
+ -c, --config Path to .toml configuration file [string]
1168
+ -e, --env Environment to use for operations and .env files [string]
1169
+ -h, --help Show help [boolean]
1170
+ -v, --version Show version number [boolean]
1149
1171
 
1150
1172
  Options:
1151
1173
  --binding The name of the namespace to get from [string]
@@ -1169,7 +1191,7 @@ describe("wrangler", () => {
1169
1191
  );
1170
1192
  expect(std.out).toMatchInlineSnapshot(`
1171
1193
  "
1172
- If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new/choose"
1194
+ If you think this is a bug then please create an issue at https://github.com/cloudflare/workers-sdk/issues/new/choose"
1173
1195
  `);
1174
1196
  expect(std.err).toMatchInlineSnapshot(`
1175
1197
  "X [ERROR] A namespace with binding name \\"otherBinding\\" was not found in the configured \\"kv_namespaces\\".
@@ -1179,7 +1201,6 @@ describe("wrangler", () => {
1179
1201
  });
1180
1202
 
1181
1203
  describe("non-interactive", () => {
1182
- const { setIsTTY } = useMockIsTTY();
1183
1204
  mockAccountId({ accountId: null });
1184
1205
 
1185
1206
  it("should error if there are multiple accounts available but not interactive on stdin", async () => {
@@ -1190,12 +1211,12 @@ describe("wrangler", () => {
1190
1211
  setIsTTY({ stdin: false, stdout: true });
1191
1212
  await expect(runWrangler("kv:key get key --namespace-id=xxxx"))
1192
1213
  .rejects.toThrowErrorMatchingInlineSnapshot(`
1193
- "More than one account available but unable to select one in non-interactive mode.
1194
- Please set the appropriate \`account_id\` in your \`wrangler.toml\` file.
1195
- Available accounts are (\\"<name>\\" - \\"<id>\\"):
1196
- \\"one\\" - \\"1\\")
1197
- \\"two\\" - \\"2\\")"
1198
- `);
1214
+ "More than one account available but unable to select one in non-interactive mode.
1215
+ Please set the appropriate \`account_id\` in your \`wrangler.toml\` file.
1216
+ Available accounts are (\`<name>\`: \`<account_id>\`):
1217
+ \`one\`: \`1\`
1218
+ \`two\`: \`2\`"
1219
+ `);
1199
1220
  });
1200
1221
 
1201
1222
  it("should error if there are multiple accounts available but not interactive on stdout", async () => {
@@ -1206,23 +1227,30 @@ describe("wrangler", () => {
1206
1227
  setIsTTY({ stdin: true, stdout: false });
1207
1228
  await expect(runWrangler("kv:key get key --namespace-id=xxxx"))
1208
1229
  .rejects.toThrowErrorMatchingInlineSnapshot(`
1209
- "More than one account available but unable to select one in non-interactive mode.
1210
- Please set the appropriate \`account_id\` in your \`wrangler.toml\` file.
1211
- Available accounts are (\\"<name>\\" - \\"<id>\\"):
1212
- \\"one\\" - \\"1\\")
1213
- \\"two\\" - \\"2\\")"
1214
- `);
1230
+ "More than one account available but unable to select one in non-interactive mode.
1231
+ Please set the appropriate \`account_id\` in your \`wrangler.toml\` file.
1232
+ Available accounts are (\`<name>\`: \`<account_id>\`):
1233
+ \`one\`: \`1\`
1234
+ \`two\`: \`2\`"
1235
+ `);
1215
1236
  });
1216
1237
 
1217
1238
  it("should recommend using a configuration if unable to fetch memberships", async () => {
1218
- setMockRawResponse("/memberships", () => {
1219
- return createFetchResult(undefined, false, [
1220
- {
1221
- code: 9109,
1222
- message: "Uauthorized to access requested resource",
1223
- },
1224
- ]);
1225
- });
1239
+ msw.use(
1240
+ rest.get("*/memberships", (req, res, ctx) => {
1241
+ return res.once(
1242
+ ctx.status(200),
1243
+ ctx.json(
1244
+ createFetchResult(null, false, [
1245
+ {
1246
+ code: 9109,
1247
+ message: "Uauthorized to access requested resource",
1248
+ },
1249
+ ])
1250
+ )
1251
+ );
1252
+ })
1253
+ );
1226
1254
  await expect(runWrangler("kv:key get key --namespace-id=xxxx"))
1227
1255
  .rejects.toThrowErrorMatchingInlineSnapshot(`
1228
1256
  "Failed to automatically retrieve account IDs for the logged in user.
@@ -1238,12 +1266,12 @@ describe("wrangler", () => {
1238
1266
  setIsTTY(false);
1239
1267
  await expect(runWrangler("kv:key get key --namespace-id=xxxx"))
1240
1268
  .rejects.toThrowErrorMatchingInlineSnapshot(`
1241
- "More than one account available but unable to select one in non-interactive mode.
1242
- Please set the appropriate \`account_id\` in your \`wrangler.toml\` file.
1243
- Available accounts are (\\"<name>\\" - \\"<id>\\"):
1244
- \\"one\\" - \\"1\\")
1245
- \\"two\\" - \\"2\\")"
1246
- `);
1269
+ "More than one account available but unable to select one in non-interactive mode.
1270
+ Please set the appropriate \`account_id\` in your \`wrangler.toml\` file.
1271
+ Available accounts are (\`<name>\`: \`<account_id>\`):
1272
+ \`one\`: \`1\`
1273
+ \`two\`: \`2\`"
1274
+ `);
1247
1275
  });
1248
1276
  });
1249
1277
  });
@@ -1254,16 +1282,20 @@ describe("wrangler", () => {
1254
1282
  expectedKey: string
1255
1283
  ) {
1256
1284
  const requests = { count: 0 };
1257
- setMockResponse(
1258
- "/accounts/:accountId/storage/kv/namespaces/:namespaceId/values/:key",
1259
- "DELETE",
1260
- ([_url, accountId, namespaceId, key]) => {
1261
- requests.count++;
1262
- expect(accountId).toEqual("some-account-id");
1263
- expect(namespaceId).toEqual(expectedNamespaceId);
1264
- expect(key).toEqual(expectedKey);
1265
- return null;
1266
- }
1285
+ msw.use(
1286
+ rest.delete(
1287
+ "*/accounts/:accountId/storage/kv/namespaces/:namespaceId/values/:key",
1288
+ (req, res, ctx) => {
1289
+ requests.count++;
1290
+ expect(req.params.accountId).toEqual("some-account-id");
1291
+ expect(req.params.namespaceId).toEqual(expectedNamespaceId);
1292
+ expect(req.params.key).toEqual(expectedKey);
1293
+ return res.once(
1294
+ ctx.status(200),
1295
+ ctx.json(createFetchResult(null))
1296
+ );
1297
+ }
1298
+ )
1267
1299
  );
1268
1300
  return requests;
1269
1301
  }
@@ -1277,8 +1309,9 @@ describe("wrangler", () => {
1277
1309
  });
1278
1310
 
1279
1311
  it("should encode the key in the api request to delete a value", async () => {
1280
- const requests = mockDeleteRequest("voyager", "%2FNCC-74656");
1312
+ const requests = mockDeleteRequest("voyager", "/NCC-74656");
1281
1313
  await runWrangler(`kv:key delete --namespace-id voyager /NCC-74656`);
1314
+
1282
1315
  expect(requests.count).toEqual(1);
1283
1316
  expect(std.out).toMatchInlineSnapshot(
1284
1317
  `"Deleting the key \\"/NCC-74656\\" on namespace voyager."`
@@ -1350,21 +1383,22 @@ describe("wrangler", () => {
1350
1383
  expectedKeyValues: KeyValue[]
1351
1384
  ) {
1352
1385
  const requests = { count: 0 };
1353
- setMockResponse(
1354
- "/accounts/:accountId/storage/kv/namespaces/:namespaceId/bulk",
1355
- "PUT",
1356
- ([_url, accountId, namespaceId], { body }) => {
1357
- requests.count++;
1358
- expect(accountId).toEqual("some-account-id");
1359
- expect(namespaceId).toEqual(expectedNamespaceId);
1360
- expect(JSON.parse(body as string)).toEqual(
1361
- expectedKeyValues.slice(
1362
- (requests.count - 1) * 5000,
1363
- requests.count * 5000
1364
- )
1365
- );
1366
- return null;
1367
- }
1386
+ msw.use(
1387
+ rest.put(
1388
+ "*/accounts/:accountId/storage/kv/namespaces/:namespaceId/bulk",
1389
+ async (req, res, ctx) => {
1390
+ requests.count++;
1391
+ expect(req.params.accountId).toEqual("some-account-id");
1392
+ expect(req.params.namespaceId).toEqual(expectedNamespaceId);
1393
+ expect(await req.json()).toEqual(
1394
+ expectedKeyValues.slice(
1395
+ (requests.count - 1) * 5000,
1396
+ requests.count * 5000
1397
+ )
1398
+ );
1399
+ return res(ctx.status(200), ctx.json(createFetchResult(null)));
1400
+ }
1401
+ )
1368
1402
  );
1369
1403
  return requests;
1370
1404
  }
@@ -1420,7 +1454,7 @@ describe("wrangler", () => {
1420
1454
  `);
1421
1455
  expect(std.out).toMatchInlineSnapshot(`
1422
1456
  "
1423
- If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new/choose"
1457
+ If you think this is a bug then please create an issue at https://github.com/cloudflare/workers-sdk/issues/new/choose"
1424
1458
  `);
1425
1459
  expect(std.warn).toMatchInlineSnapshot(`""`);
1426
1460
  });
@@ -1482,7 +1516,7 @@ describe("wrangler", () => {
1482
1516
 
1483
1517
  expect(std.out).toMatchInlineSnapshot(`
1484
1518
  "
1485
- If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new/choose"
1519
+ If you think this is a bug then please create an issue at https://github.com/cloudflare/workers-sdk/issues/new/choose"
1486
1520
  `);
1487
1521
  expect(std.warn).toMatchInlineSnapshot(`
1488
1522
  "▲ [WARNING] Unexpected key-value properties in \\"keys.json\\".
@@ -1500,24 +1534,25 @@ describe("wrangler", () => {
1500
1534
  expectedKeys: string[]
1501
1535
  ) {
1502
1536
  const requests = { count: 0 };
1503
- setMockResponse(
1504
- "/accounts/:accountId/storage/kv/namespaces/:namespaceId/bulk",
1505
- "DELETE",
1506
- ([_url, accountId, namespaceId], { headers, body }) => {
1507
- requests.count++;
1508
- expect(accountId).toEqual("some-account-id");
1509
- expect(namespaceId).toEqual(expectedNamespaceId);
1510
- expect(new Headers(headers ?? []).get("Content-Type")).toEqual(
1511
- "application/json"
1512
- );
1513
- expect(JSON.parse(body as string)).toEqual(
1514
- expectedKeys.slice(
1515
- (requests.count - 1) * 5000,
1516
- requests.count * 5000
1517
- )
1518
- );
1519
- return null;
1520
- }
1537
+ msw.use(
1538
+ rest.delete(
1539
+ "*/accounts/:accountId/storage/kv/namespaces/:namespaceId/bulk",
1540
+ async (req, res, ctx) => {
1541
+ requests.count++;
1542
+ expect(req.params.accountId).toEqual("some-account-id");
1543
+ expect(req.params.namespaceId).toEqual(expectedNamespaceId);
1544
+ expect(req.headers.get("Content-Type")).toEqual(
1545
+ "application/json"
1546
+ );
1547
+ expect(await req.json()).toEqual(
1548
+ expectedKeys.slice(
1549
+ (requests.count - 1) * 5000,
1550
+ requests.count * 5000
1551
+ )
1552
+ );
1553
+ return res(ctx.status(200), ctx.json(createFetchResult(null)));
1554
+ }
1555
+ )
1521
1556
  );
1522
1557
  return requests;
1523
1558
  }
@@ -1552,12 +1587,12 @@ describe("wrangler", () => {
1552
1587
  );
1553
1588
  expect(requests.count).toEqual(3);
1554
1589
  expect(std.out).toMatchInlineSnapshot(`
1555
- "Deleted 0% (0 out of 12,000)
1556
- Deleted 41% (5,000 out of 12,000)
1557
- Deleted 83% (10,000 out of 12,000)
1558
- Deleted 100% (12,000 out of 12,000)
1559
- Success!"
1560
- `);
1590
+ "Deleted 0% (0 out of 12,000)
1591
+ Deleted 41% (5,000 out of 12,000)
1592
+ Deleted 83% (10,000 out of 12,000)
1593
+ Deleted 100% (12,000 out of 12,000)
1594
+ Success!"
1595
+ `);
1561
1596
  expect(std.warn).toMatchInlineSnapshot(`""`);
1562
1597
  expect(std.err).toMatchInlineSnapshot(`""`);
1563
1598
  });
@@ -1622,9 +1657,9 @@ describe("wrangler", () => {
1622
1657
  12354"
1623
1658
  `);
1624
1659
  expect(std.out).toMatchInlineSnapshot(`
1625
- "
1626
- If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new/choose"
1627
- `);
1660
+ "
1661
+ If you think this is a bug then please create an issue at https://github.com/cloudflare/workers-sdk/issues/new/choose"
1662
+ `);
1628
1663
  expect(std.warn).toMatchInlineSnapshot(`""`);
1629
1664
  });
1630
1665
 
@@ -1647,9 +1682,9 @@ describe("wrangler", () => {
1647
1682
  The item at index 3 is type: \\"object\\" - null"
1648
1683
  `);
1649
1684
  expect(std.out).toMatchInlineSnapshot(`
1650
- "
1651
- If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new/choose"
1652
- `);
1685
+ "
1686
+ If you think this is a bug then please create an issue at https://github.com/cloudflare/workers-sdk/issues/new/choose"
1687
+ `);
1653
1688
  expect(std.warn).toMatchInlineSnapshot(`""`);
1654
1689
  });
1655
1690
  });
@@ -1673,3 +1708,92 @@ function writeWranglerConfig() {
1673
1708
  "utf-8"
1674
1709
  );
1675
1710
  }
1711
+
1712
+ function setMockFetchKVGetValue(
1713
+ accountId: string,
1714
+ namespaceId: string,
1715
+ key: string,
1716
+ value: string | Buffer
1717
+ ) {
1718
+ msw.use(
1719
+ rest.get(
1720
+ "*/accounts/:accountId/storage/kv/namespaces/:namespaceId/values/:key",
1721
+ (req, res, ctx) => {
1722
+ expect(req.params.accountId).toEqual(accountId);
1723
+ expect(req.params.namespaceId).toEqual(namespaceId);
1724
+ // Getting the key from params decodes it so we need to grab the encoded key from the URL
1725
+ expect(req.url.toString().split("/").pop()).toBe(key);
1726
+
1727
+ return res.once(ctx.status(200), ctx.body(value));
1728
+ }
1729
+ )
1730
+ );
1731
+ }
1732
+
1733
+ function createFetchResult(
1734
+ result: unknown,
1735
+ success = true,
1736
+ errors: { code: number; message: string }[] = []
1737
+ ) {
1738
+ return {
1739
+ success,
1740
+ errors,
1741
+ messages: [],
1742
+ result,
1743
+ };
1744
+ }
1745
+
1746
+ function mockGetMemberships(
1747
+ accounts: { id: string; account: { id: string; name: string } }[]
1748
+ ) {
1749
+ msw.use(
1750
+ rest.get("*/memberships", (req, res, ctx) => {
1751
+ return res.once(ctx.json(createFetchResult(accounts)));
1752
+ })
1753
+ );
1754
+ }
1755
+
1756
+ function mockKeyListRequest(
1757
+ expectedNamespaceId: string,
1758
+ expectedKeys: NamespaceKeyInfo[],
1759
+ keysPerRequest = 1000,
1760
+ blankCursorValue: "" | undefined | null = undefined
1761
+ ) {
1762
+ const requests = { count: 0 };
1763
+ // See https://api.cloudflare.com/#workers-kv-namespace-list-a-namespace-s-keys
1764
+ msw.use(
1765
+ rest.get(
1766
+ "*/accounts/:accountId/storage/kv/namespaces/:namespaceId/keys",
1767
+ (req, res, ctx) => {
1768
+ requests.count++;
1769
+ let result;
1770
+ let cursor;
1771
+
1772
+ expect(req.params.accountId).toEqual("some-account-id");
1773
+ expect(req.params.namespaceId).toEqual(expectedNamespaceId);
1774
+
1775
+ if (expectedKeys.length <= keysPerRequest) {
1776
+ result = expectedKeys;
1777
+ } else {
1778
+ const start =
1779
+ parseInt(req.url.searchParams.get("cursor") ?? "0") || 0;
1780
+ const end = start + keysPerRequest;
1781
+ cursor = end < expectedKeys.length ? end : blankCursorValue;
1782
+ result = expectedKeys.slice(start, end);
1783
+ }
1784
+ return res(
1785
+ ctx.json({
1786
+ success: true,
1787
+ errors: [],
1788
+ messages: [],
1789
+ result,
1790
+ result_info: {
1791
+ cursor,
1792
+ },
1793
+ })
1794
+ );
1795
+ }
1796
+ )
1797
+ );
1798
+ return requests;
1799
+ }