wrangler 0.0.0-e64812e → 0.0.0-e7a0cd5b

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 (291) hide show
  1. package/README.md +23 -3
  2. package/bin/wrangler.js +150 -62
  3. package/kv-asset-handler.js +1 -0
  4. package/miniflare-dist/index.mjs +1451 -21
  5. package/package.json +190 -152
  6. package/src/__tests__/access.test.ts +25 -0
  7. package/src/__tests__/api-dev.test.ts +209 -0
  8. package/src/__tests__/api-devregistry.test.js +57 -0
  9. package/src/__tests__/api.test.ts +80 -0
  10. package/src/__tests__/config-cache-without-cache-dir.test.ts +38 -0
  11. package/src/__tests__/config-cache.test.ts +30 -24
  12. package/src/__tests__/configuration.test.ts +4017 -3363
  13. package/src/__tests__/d1.test.ts +72 -0
  14. package/src/__tests__/delete.test.ts +230 -0
  15. package/src/__tests__/deployments.test.ts +95 -0
  16. package/src/__tests__/dev.test.tsx +1480 -951
  17. package/src/__tests__/dialogs.test.tsx +40 -0
  18. package/src/__tests__/generate.test.ts +235 -0
  19. package/src/__tests__/get-host-from-url.test.ts +16 -0
  20. package/src/__tests__/guess-worker-format.test.ts +68 -68
  21. package/src/__tests__/helpers/cmd-shim.d.ts +6 -6
  22. package/src/__tests__/helpers/mock-account-id.ts +24 -24
  23. package/src/__tests__/helpers/mock-bin.ts +20 -20
  24. package/src/__tests__/helpers/mock-cfetch.ts +216 -94
  25. package/src/__tests__/helpers/mock-console.ts +58 -39
  26. package/src/__tests__/helpers/mock-dialogs.ts +94 -71
  27. package/src/__tests__/helpers/mock-get-zone-from-host.ts +8 -0
  28. package/src/__tests__/helpers/mock-http-server.ts +30 -30
  29. package/src/__tests__/helpers/mock-istty.ts +65 -18
  30. package/src/__tests__/helpers/mock-known-routes.ts +7 -0
  31. package/src/__tests__/helpers/mock-kv.ts +27 -27
  32. package/src/__tests__/helpers/mock-oauth-flow.ts +225 -228
  33. package/src/__tests__/helpers/mock-process.ts +39 -0
  34. package/src/__tests__/helpers/mock-stdin.ts +82 -77
  35. package/src/__tests__/helpers/mock-web-socket.ts +21 -21
  36. package/src/__tests__/helpers/msw/handlers/access.ts +13 -0
  37. package/src/__tests__/helpers/msw/handlers/deployments.ts +59 -0
  38. package/src/__tests__/helpers/msw/handlers/namespaces.ts +104 -0
  39. package/src/__tests__/helpers/msw/handlers/oauth.ts +36 -0
  40. package/src/__tests__/helpers/msw/handlers/r2.ts +80 -0
  41. package/src/__tests__/helpers/msw/handlers/script.ts +75 -0
  42. package/src/__tests__/helpers/msw/handlers/user.ts +63 -0
  43. package/src/__tests__/helpers/msw/handlers/zones.ts +22 -0
  44. package/src/__tests__/helpers/msw/index.ts +21 -0
  45. package/src/__tests__/helpers/run-in-tmp.ts +27 -28
  46. package/src/__tests__/helpers/run-wrangler.ts +8 -8
  47. package/src/__tests__/helpers/worker-scripts/child-wrangler.toml +1 -0
  48. package/src/__tests__/helpers/worker-scripts/hello-world-worker.js +5 -0
  49. package/src/__tests__/helpers/worker-scripts/hello-world-wrangler.toml +1 -0
  50. package/src/__tests__/helpers/worker-scripts/parent-worker.js +8 -0
  51. package/src/__tests__/helpers/worker-scripts/parent-wrangler.toml +5 -0
  52. package/src/__tests__/helpers/write-worker-source.ts +16 -16
  53. package/src/__tests__/helpers/write-wrangler-toml.ts +9 -9
  54. package/src/__tests__/https-options.test.ts +142 -109
  55. package/src/__tests__/index.test.ts +239 -233
  56. package/src/__tests__/init.test.ts +2869 -1603
  57. package/src/__tests__/jest.setup.ts +159 -34
  58. package/src/__tests__/kv.test.ts +1660 -1466
  59. package/src/__tests__/logger.test.ts +100 -74
  60. package/src/__tests__/metrics.test.ts +450 -0
  61. package/src/__tests__/middleware.scheduled.test.ts +135 -0
  62. package/src/__tests__/middleware.test.ts +726 -0
  63. package/src/__tests__/package-manager.test.ts +303 -303
  64. package/src/__tests__/pages.test.ts +2204 -735
  65. package/src/__tests__/parse.test.ts +252 -252
  66. package/src/__tests__/paths.test.ts +39 -0
  67. package/src/__tests__/publish.test.ts +7543 -5351
  68. package/src/__tests__/pubsub.test.ts +370 -0
  69. package/src/__tests__/queues.test.ts +371 -0
  70. package/src/__tests__/r2.test.ts +371 -228
  71. package/src/__tests__/route.test.ts +18 -18
  72. package/src/__tests__/secret.test.ts +622 -459
  73. package/src/__tests__/tail.test.ts +677 -567
  74. package/src/__tests__/test-old-node-version.js +31 -0
  75. package/src/__tests__/type-generation.test.ts +217 -0
  76. package/src/__tests__/user.test.ts +140 -116
  77. package/src/__tests__/utils-collectKeyValues.test.ts +47 -0
  78. package/src/__tests__/validate-dev-props.test.ts +56 -0
  79. package/src/__tests__/version.test.ts +35 -0
  80. package/src/__tests__/whoami.test.tsx +264 -91
  81. package/src/__tests__/worker-namespace.test.ts +326 -0
  82. package/src/abort.d.ts +1 -1
  83. package/src/api/dev.ts +208 -0
  84. package/src/api/index.ts +2 -0
  85. package/src/bundle-reporter.tsx +68 -0
  86. package/src/bundle.ts +746 -161
  87. package/src/cfetch/index.ts +120 -81
  88. package/src/cfetch/internal.ts +209 -91
  89. package/src/cli.ts +23 -8
  90. package/src/config/config.ts +236 -195
  91. package/src/config/diagnostics.ts +61 -61
  92. package/src/config/environment.ts +500 -357
  93. package/src/config/index.ts +310 -193
  94. package/src/config/validation-helpers.ts +379 -357
  95. package/src/config/validation.ts +1941 -1367
  96. package/src/config-cache.ts +81 -41
  97. package/src/create-worker-preview.ts +239 -142
  98. package/src/create-worker-upload-form.ts +305 -238
  99. package/src/d1/backups.tsx +218 -0
  100. package/src/d1/create.tsx +54 -0
  101. package/src/d1/delete.tsx +56 -0
  102. package/src/d1/execute.tsx +299 -0
  103. package/src/d1/formatTimeAgo.ts +14 -0
  104. package/src/d1/index.ts +76 -0
  105. package/src/d1/list.tsx +48 -0
  106. package/src/d1/options.ts +12 -0
  107. package/src/d1/types.tsx +14 -0
  108. package/src/d1/utils.ts +39 -0
  109. package/src/delete.ts +108 -0
  110. package/src/deployments.ts +74 -0
  111. package/src/deprecated/index.ts +438 -0
  112. package/src/dev/dev-vars.ts +20 -17
  113. package/src/dev/dev.tsx +520 -352
  114. package/src/dev/get-local-persistence-path.tsx +31 -0
  115. package/src/dev/local.tsx +697 -298
  116. package/src/dev/remote.tsx +591 -215
  117. package/src/dev/start-server.ts +513 -0
  118. package/src/dev/use-esbuild.ts +183 -97
  119. package/src/dev/validate-dev-props.ts +31 -0
  120. package/src/dev-registry.tsx +201 -0
  121. package/src/dev.tsx +869 -0
  122. package/src/dialogs.tsx +126 -98
  123. package/src/dispatch-namespace.ts +207 -0
  124. package/src/durable.ts +87 -87
  125. package/src/entry.ts +235 -228
  126. package/src/environment-variables.ts +38 -23
  127. package/src/errors.ts +6 -6
  128. package/src/git-client.ts +124 -0
  129. package/src/global-wrangler-config-path.ts +26 -0
  130. package/src/https-options.ts +84 -80
  131. package/src/index.tsx +627 -2807
  132. package/src/init.ts +970 -0
  133. package/src/inspect.ts +698 -593
  134. package/src/intl-polyfill.d.ts +123 -123
  135. package/src/is-ci.ts +14 -0
  136. package/src/is-interactive.ts +16 -0
  137. package/src/kv/helpers.ts +430 -0
  138. package/src/kv/index.ts +596 -0
  139. package/src/logger.ts +67 -41
  140. package/src/metrics/index.ts +5 -0
  141. package/src/metrics/metrics-config.ts +239 -0
  142. package/src/metrics/metrics-dispatcher.ts +96 -0
  143. package/src/metrics/metrics-usage-headers.ts +24 -0
  144. package/src/metrics/send-event.ts +94 -0
  145. package/src/miniflare-cli/assets.ts +215 -0
  146. package/src/miniflare-cli/index.ts +205 -33
  147. package/src/miniflare-cli/request-context.ts +18 -18
  148. package/src/module-collection.ts +221 -212
  149. package/src/open-in-browser.ts +4 -6
  150. package/src/package-manager.ts +173 -128
  151. package/src/pages/build.tsx +238 -0
  152. package/src/pages/constants.ts +18 -0
  153. package/src/pages/deployments.tsx +106 -0
  154. package/src/pages/dev.tsx +693 -0
  155. package/src/pages/errors.ts +66 -0
  156. package/src/pages/functions/buildPlugin.ts +110 -0
  157. package/src/pages/functions/buildWorker.ts +156 -0
  158. package/{pages → src/pages}/functions/filepath-routing.test.ts +113 -113
  159. package/src/pages/functions/filepath-routing.ts +189 -0
  160. package/src/pages/functions/identifiers.ts +78 -0
  161. package/src/pages/functions/routes-consolidation.test.ts +250 -0
  162. package/src/pages/functions/routes-consolidation.ts +73 -0
  163. package/src/pages/functions/routes-transformation.test.ts +282 -0
  164. package/src/pages/functions/routes-transformation.ts +115 -0
  165. package/src/pages/functions/routes-validation.test.ts +403 -0
  166. package/src/pages/functions/routes-validation.ts +202 -0
  167. package/src/pages/functions/routes.ts +151 -0
  168. package/src/pages/functions.tsx +82 -0
  169. package/src/pages/hash.tsx +13 -0
  170. package/src/pages/index.tsx +94 -0
  171. package/src/pages/projects.tsx +169 -0
  172. package/src/pages/publish.tsx +436 -0
  173. package/src/pages/types.ts +49 -0
  174. package/src/pages/upload.tsx +425 -0
  175. package/src/pages/utils.ts +12 -0
  176. package/src/parse.ts +209 -125
  177. package/src/paths.ts +53 -8
  178. package/src/proxy.ts +618 -394
  179. package/src/publish/index.ts +270 -0
  180. package/src/publish/publish.ts +1035 -0
  181. package/src/pubsub/index.ts +286 -0
  182. package/src/pubsub/pubsub-commands.tsx +624 -0
  183. package/src/queues/cli/commands/consumer/add.ts +71 -0
  184. package/src/queues/cli/commands/consumer/index.ts +22 -0
  185. package/src/queues/cli/commands/consumer/remove.ts +38 -0
  186. package/src/queues/cli/commands/create.ts +25 -0
  187. package/src/queues/cli/commands/delete.ts +26 -0
  188. package/src/queues/cli/commands/index.ts +33 -0
  189. package/src/queues/cli/commands/list.ts +25 -0
  190. package/src/queues/client.ts +135 -0
  191. package/src/r2/helpers.ts +131 -0
  192. package/src/r2/index.ts +277 -0
  193. package/src/routes.ts +140 -0
  194. package/src/secret/index.ts +379 -0
  195. package/src/selfsigned.d.ts +23 -23
  196. package/src/sites.tsx +280 -203
  197. package/src/tail/createTail.ts +315 -0
  198. package/src/tail/filters.ts +108 -110
  199. package/src/tail/index.ts +211 -296
  200. package/src/tail/printing.ts +86 -46
  201. package/src/type-generation.ts +159 -0
  202. package/src/update-check.ts +11 -11
  203. package/src/user/access.ts +69 -0
  204. package/src/user/choose-account.tsx +69 -0
  205. package/src/user/env-vars.ts +46 -0
  206. package/src/user/generate-auth-url.ts +33 -0
  207. package/src/user/generate-random-state.ts +16 -0
  208. package/src/user/index.ts +3 -0
  209. package/src/user/user.tsx +1192 -0
  210. package/src/utils/collectKeyValues.ts +14 -0
  211. package/src/whoami.tsx +141 -42
  212. package/src/worker.ts +168 -106
  213. package/src/yargs-types.ts +20 -0
  214. package/src/zones.ts +191 -0
  215. package/templates/__tests__/pages-dev-util.test.ts +128 -0
  216. package/templates/checked-fetch.js +17 -0
  217. package/templates/d1-beta-facade.js +174 -0
  218. package/templates/experimental-local-cache-stubs.js +27 -0
  219. package/templates/first-party-worker-module-facade.ts +18 -0
  220. package/templates/format-dev-errors.ts +32 -0
  221. package/templates/init-tests/test-jest-new-worker.js +25 -0
  222. package/templates/init-tests/test-vitest-new-worker.js +26 -0
  223. package/templates/middleware/common.ts +62 -0
  224. package/templates/middleware/loader-modules.ts +84 -0
  225. package/templates/middleware/loader-sw.ts +213 -0
  226. package/templates/middleware/middleware-pretty-error.ts +40 -0
  227. package/templates/middleware/middleware-scheduled.ts +15 -0
  228. package/templates/new-worker-scheduled.js +3 -3
  229. package/templates/new-worker-scheduled.ts +15 -15
  230. package/templates/new-worker.js +3 -3
  231. package/templates/new-worker.ts +15 -15
  232. package/templates/no-op-worker.js +10 -0
  233. package/templates/pages-dev-pipeline.ts +28 -0
  234. package/templates/pages-dev-util.ts +52 -0
  235. package/templates/pages-shim.ts +9 -0
  236. package/templates/pages-template-plugin.ts +171 -0
  237. package/templates/pages-template-worker.ts +189 -0
  238. package/templates/serve-static-assets.ts +63 -0
  239. package/templates/service-bindings-module-facade.js +54 -0
  240. package/templates/service-bindings-sw-facade.js +42 -0
  241. package/templates/tsconfig.json +96 -95
  242. package/wrangler-dist/cli.d.ts +892 -0
  243. package/wrangler-dist/cli.js +145674 -108957
  244. package/pages/functions/buildPlugin.ts +0 -105
  245. package/pages/functions/buildWorker.ts +0 -151
  246. package/pages/functions/filepath-routing.ts +0 -189
  247. package/pages/functions/identifiers.ts +0 -78
  248. package/pages/functions/routes.ts +0 -156
  249. package/pages/functions/template-plugin.ts +0 -147
  250. package/pages/functions/template-worker.ts +0 -143
  251. package/src/__tests__/helpers/faye-websocket.d.ts +0 -6
  252. package/src/kv.ts +0 -408
  253. package/src/miniflare-cli/enum-keys.ts +0 -17
  254. package/src/pages.tsx +0 -2038
  255. package/src/publish.ts +0 -583
  256. package/src/r2.ts +0 -50
  257. package/src/user.tsx +0 -1203
  258. package/templates/static-asset-facade.js +0 -47
  259. package/vendor/@cloudflare/kv-asset-handler/CHANGELOG.md +0 -332
  260. package/vendor/@cloudflare/kv-asset-handler/LICENSE_APACHE +0 -176
  261. package/vendor/@cloudflare/kv-asset-handler/LICENSE_MIT +0 -25
  262. package/vendor/@cloudflare/kv-asset-handler/README.md +0 -245
  263. package/vendor/@cloudflare/kv-asset-handler/dist/index.d.ts +0 -32
  264. package/vendor/@cloudflare/kv-asset-handler/dist/index.js +0 -354
  265. package/vendor/@cloudflare/kv-asset-handler/dist/mocks.d.ts +0 -13
  266. package/vendor/@cloudflare/kv-asset-handler/dist/mocks.js +0 -148
  267. package/vendor/@cloudflare/kv-asset-handler/dist/test/getAssetFromKV.d.ts +0 -1
  268. package/vendor/@cloudflare/kv-asset-handler/dist/test/getAssetFromKV.js +0 -436
  269. package/vendor/@cloudflare/kv-asset-handler/dist/test/mapRequestToAsset.d.ts +0 -1
  270. package/vendor/@cloudflare/kv-asset-handler/dist/test/mapRequestToAsset.js +0 -40
  271. package/vendor/@cloudflare/kv-asset-handler/dist/test/serveSinglePageApp.d.ts +0 -1
  272. package/vendor/@cloudflare/kv-asset-handler/dist/test/serveSinglePageApp.js +0 -42
  273. package/vendor/@cloudflare/kv-asset-handler/dist/types.d.ts +0 -26
  274. package/vendor/@cloudflare/kv-asset-handler/dist/types.js +0 -31
  275. package/vendor/@cloudflare/kv-asset-handler/package.json +0 -52
  276. package/vendor/@cloudflare/kv-asset-handler/src/index.ts +0 -296
  277. package/vendor/@cloudflare/kv-asset-handler/src/mocks.ts +0 -136
  278. package/vendor/@cloudflare/kv-asset-handler/src/test/getAssetFromKV.ts +0 -464
  279. package/vendor/@cloudflare/kv-asset-handler/src/test/mapRequestToAsset.ts +0 -33
  280. package/vendor/@cloudflare/kv-asset-handler/src/test/serveSinglePageApp.ts +0 -42
  281. package/vendor/@cloudflare/kv-asset-handler/src/types.ts +0 -39
  282. package/vendor/wrangler-mime/CHANGELOG.md +0 -289
  283. package/vendor/wrangler-mime/LICENSE +0 -21
  284. package/vendor/wrangler-mime/Mime.js +0 -97
  285. package/vendor/wrangler-mime/README.md +0 -187
  286. package/vendor/wrangler-mime/cli.js +0 -46
  287. package/vendor/wrangler-mime/index.js +0 -4
  288. package/vendor/wrangler-mime/lite.js +0 -4
  289. package/vendor/wrangler-mime/package.json +0 -52
  290. package/vendor/wrangler-mime/types/other.js +0 -1
  291. package/vendor/wrangler-mime/types/standard.js +0 -1
@@ -1,9 +1,27 @@
1
1
  import fetchMock from "jest-fetch-mock";
2
2
  import { Request } from "undici";
3
- import { getCloudflareApiBaseUrl } from "../../cfetch";
4
3
  import openInBrowser from "../../open-in-browser";
4
+ import {
5
+ createFetchResult,
6
+ setMockRawResponse,
7
+ setMockResponse,
8
+ } from "./mock-cfetch";
5
9
  import { mockHttpServer } from "./mock-http-server";
6
10
 
11
+ export function mockGetMemberships(
12
+ accounts: { id: string; account: { id: string; name: string } }[]
13
+ ) {
14
+ setMockResponse("/memberships", "GET", () => {
15
+ return accounts;
16
+ });
17
+ }
18
+
19
+ export function mockGetMembershipsFail() {
20
+ setMockRawResponse("/memberships", () => {
21
+ return createFetchResult([], false);
22
+ });
23
+ }
24
+
7
25
  // the response to send when wrangler wants an oauth grant
8
26
  let oauthGrantResponse: GrantResponseOptions | "timeout" = {};
9
27
 
@@ -11,245 +29,224 @@ let oauthGrantResponse: GrantResponseOptions | "timeout" = {};
11
29
  * Functions to help with mocking various parts of the OAuth Flow
12
30
  */
13
31
  export const mockOAuthFlow = () => {
14
- const fetchHttp = mockHttpServer();
15
-
16
- afterEach(() => {
17
- fetchMock.resetMocks();
18
- });
19
-
20
- /**
21
- * Mock out the callback from a browser to our HttpServer.
22
- *
23
- * This function will override `openInBrowser()` so that instead of opening a browser window
24
- * at the OAuth URL, it will automatically trigger the callback URL on the mock HttpServer that
25
- * we have created as part of the call to `mockOAuthFlow()`.
26
- */
27
- const mockOAuthServerCallback = () => {
28
- (
29
- openInBrowser as jest.MockedFunction<typeof openInBrowser>
30
- ).mockImplementation(async (url: string) => {
31
- // We don't support the grant response timing out.
32
- if (oauthGrantResponse === "timeout") {
33
- throw "unimplemented";
34
- }
35
-
36
- // Create a fake callback request that would be created by the OAuth server
37
- const { searchParams } = new URL(url);
38
- const queryParams = toQueryParams(oauthGrantResponse, searchParams);
39
- const request = new Request(
40
- `${searchParams.get("redirect_uri")}?${queryParams}`
41
- );
42
-
43
- // Trigger the mock HttpServer to handle this fake request to continue the OAuth flow.
44
- fetchHttp(request).catch((e) => {
45
- throw new Error(
46
- "Failed to send OAuth Grant to wrangler, maybe the server was closed?",
47
- e as Error
48
- );
49
- });
50
- });
51
- };
52
-
53
- const mockGrantAuthorization = ({
54
- respondWith,
55
- }: {
56
- respondWith: "timeout" | "success" | "failure" | GrantResponseOptions;
57
- }) => {
58
- if (respondWith === "failure") {
59
- oauthGrantResponse = {
60
- error: "access_denied",
61
- };
62
- } else if (respondWith === "success") {
63
- oauthGrantResponse = {
64
- code: "test-oauth-code",
65
- };
66
- } else if (respondWith === "timeout") {
67
- oauthGrantResponse = "timeout";
68
- } else {
69
- oauthGrantResponse = respondWith;
70
- }
71
- };
72
-
73
- const mockRevokeAuthorization = () => {
74
- const outcome = {
75
- actual: new Request("https://example.org"),
76
- expected: new Request("https://dash.cloudflare.com/oauth2/revoke", {
77
- method: "POST",
78
- }),
79
- };
80
-
81
- fetchMock.mockIf(outcome.expected.url, async (req) => {
82
- outcome.actual = req;
83
- return "";
84
- });
85
-
86
- return outcome;
87
- };
88
-
89
- const mockGetMemberships = (args: {
90
- success: boolean;
91
- result: { id: string; account: { id: string; name: string } }[];
92
- }) => {
93
- const outcome = {
94
- actual: new Request("https://example.org"),
95
- expected: new Request(`${getCloudflareApiBaseUrl()}/memberships`, {
96
- method: "GET",
97
- }),
98
- };
99
-
100
- fetchMock.mockIf(outcome.expected.url, async (req) => {
101
- outcome.actual = req;
102
- return {
103
- status: 200,
104
- body: JSON.stringify(args),
105
- };
106
- });
107
-
108
- return outcome;
109
- };
110
-
111
- const mockGrantAccessToken = ({
112
- respondWith,
113
- }: {
114
- respondWith: MockTokenResponse;
115
- }) => {
116
- const outcome = {
117
- actual: new Request("https://example.org"),
118
- expected: new Request("https://dash.cloudflare.com/oauth2/token", {
119
- method: "POST",
120
- }),
121
- };
122
-
123
- fetchMock.mockOnceIf(outcome.expected.url, async (req) => {
124
- outcome.actual = req;
125
- return makeTokenResponse(respondWith);
126
- });
127
-
128
- return outcome;
129
- };
130
-
131
- const mockExchangeRefreshTokenForAccessToken = ({
132
- respondWith,
133
- }: {
134
- respondWith: "refreshSuccess" | "refreshError" | "badResponse";
135
- }) => {
136
- fetchMock.mockOnceIf(
137
- "https://dash.cloudflare.com/oauth2/token",
138
- async () => {
139
- switch (respondWith) {
140
- case "refreshSuccess":
141
- return {
142
- status: 200,
143
- body: JSON.stringify({
144
- access_token: "access_token_success_mock",
145
- expires_in: 1701,
146
- refresh_token: "refresh_token_sucess_mock",
147
- scope: "scope_success_mock",
148
- token_type: "bearer",
149
- }),
150
- };
151
- case "refreshError":
152
- return {
153
- status: 400,
154
- body: JSON.stringify({
155
- error: "invalid_request",
156
- error_description: "error_description_mock",
157
- error_hint: "error_hint_mock",
158
- error_verbose: "error_verbose_mock",
159
- status_code: 400,
160
- }),
161
- };
162
- case "badResponse":
163
- return {
164
- status: 400,
165
- body: `<html> <body> This shouldn't be sent, but should be handled </body> </html>`,
166
- };
167
-
168
- default:
169
- return "Not a respondWith option for `mockExchangeRefreshTokenForAccessToken`";
170
- }
171
- }
172
- );
173
- };
174
-
175
- return {
176
- mockGetMemberships,
177
- mockGrantAccessToken,
178
- mockGrantAuthorization,
179
- mockOAuthServerCallback,
180
- mockRevokeAuthorization,
181
- mockExchangeRefreshTokenForAccessToken,
182
- };
32
+ const fetchHttp = mockHttpServer();
33
+
34
+ afterEach(() => {
35
+ fetchMock.resetMocks();
36
+ });
37
+
38
+ /**
39
+ * Mock out the callback from a browser to our HttpServer.
40
+ *
41
+ * This function will override `openInBrowser()` so that instead of opening a browser window
42
+ * at the OAuth URL, it will automatically trigger the callback URL on the mock HttpServer that
43
+ * we have created as part of the call to `mockOAuthFlow()`.
44
+ */
45
+ const mockOAuthServerCallback = () => {
46
+ (
47
+ openInBrowser as jest.MockedFunction<typeof openInBrowser>
48
+ ).mockImplementation(async (url: string) => {
49
+ // We don't support the grant response timing out.
50
+ if (oauthGrantResponse === "timeout") {
51
+ throw "unimplemented";
52
+ }
53
+
54
+ // Create a fake callback request that would be created by the OAuth server
55
+ const { searchParams } = new URL(url);
56
+ const queryParams = toQueryParams(oauthGrantResponse, searchParams);
57
+ const request = new Request(
58
+ `${searchParams.get("redirect_uri")}?${queryParams}`
59
+ );
60
+
61
+ // Trigger the mock HttpServer to handle this fake request to continue the OAuth flow.
62
+ fetchHttp(request).catch((e) => {
63
+ throw new Error(
64
+ "Failed to send OAuth Grant to wrangler, maybe the server was closed?",
65
+ e as Error
66
+ );
67
+ });
68
+ });
69
+ };
70
+
71
+ const mockGrantAuthorization = ({
72
+ respondWith,
73
+ }: {
74
+ respondWith: "timeout" | "success" | "failure" | GrantResponseOptions;
75
+ }) => {
76
+ if (respondWith === "failure") {
77
+ oauthGrantResponse = {
78
+ error: "access_denied",
79
+ };
80
+ } else if (respondWith === "success") {
81
+ oauthGrantResponse = {
82
+ code: "test-oauth-code",
83
+ };
84
+ } else if (respondWith === "timeout") {
85
+ oauthGrantResponse = "timeout";
86
+ } else {
87
+ oauthGrantResponse = respondWith;
88
+ }
89
+ };
90
+
91
+ const mockRevokeAuthorization = () => {
92
+ const outcome = {
93
+ actual: new Request("https://example.org"),
94
+ expected: new Request("https://dash.cloudflare.com/oauth2/revoke", {
95
+ method: "POST",
96
+ }),
97
+ };
98
+
99
+ fetchMock.mockIf(outcome.expected.url, async (req) => {
100
+ // TODO: update Miniflare typings to match full undici Request
101
+ outcome.actual = req as unknown as Request;
102
+ return "";
103
+ });
104
+
105
+ return outcome;
106
+ };
107
+
108
+ const mockGrantAccessToken = ({
109
+ respondWith,
110
+ }: {
111
+ respondWith: MockTokenResponse;
112
+ }) => {
113
+ const outcome = {
114
+ actual: new Request("https://example.org"),
115
+ expected: new Request("https://dash.cloudflare.com/oauth2/token", {
116
+ method: "POST",
117
+ }),
118
+ };
119
+
120
+ fetchMock.mockOnceIf(outcome.expected.url, async (req) => {
121
+ // TODO: update Miniflare typings to match full undici Request
122
+ outcome.actual = req as unknown as Request;
123
+ return makeTokenResponse(respondWith);
124
+ });
125
+
126
+ return outcome;
127
+ };
128
+
129
+ const mockExchangeRefreshTokenForAccessToken = ({
130
+ respondWith,
131
+ }: {
132
+ respondWith: "refreshSuccess" | "refreshError" | "badResponse";
133
+ }) => {
134
+ fetchMock.mockOnceIf(
135
+ "https://dash.cloudflare.com/oauth2/token",
136
+ async () => {
137
+ switch (respondWith) {
138
+ case "refreshSuccess":
139
+ return {
140
+ status: 200,
141
+ body: JSON.stringify({
142
+ access_token: "access_token_success_mock",
143
+ expires_in: 1701,
144
+ refresh_token: "refresh_token_sucess_mock",
145
+ scope: "scope_success_mock",
146
+ token_type: "bearer",
147
+ }),
148
+ };
149
+ case "refreshError":
150
+ return {
151
+ status: 400,
152
+ body: JSON.stringify({
153
+ error: "invalid_request",
154
+ error_description: "error_description_mock",
155
+ error_hint: "error_hint_mock",
156
+ error_verbose: "error_verbose_mock",
157
+ status_code: 400,
158
+ }),
159
+ };
160
+ case "badResponse":
161
+ return {
162
+ status: 400,
163
+ body: `<html> <body> This shouldn't be sent, but should be handled </body> </html>`,
164
+ };
165
+
166
+ default:
167
+ return "Not a respondWith option for `mockExchangeRefreshTokenForAccessToken`";
168
+ }
169
+ }
170
+ );
171
+ };
172
+
173
+ return {
174
+ mockGrantAccessToken,
175
+ mockGrantAuthorization,
176
+ mockOAuthServerCallback,
177
+ mockRevokeAuthorization,
178
+ mockExchangeRefreshTokenForAccessToken,
179
+ };
183
180
  };
184
181
 
185
182
  type GrantResponseOptions = {
186
- code?: string;
187
- error?: ErrorType | ErrorType[];
183
+ code?: string;
184
+ error?: ErrorType | ErrorType[];
188
185
  };
189
186
 
190
187
  const toQueryParams = (
191
- { code, error }: GrantResponseOptions,
192
- wranglerRequestParams: URLSearchParams
188
+ { code, error }: GrantResponseOptions,
189
+ wranglerRequestParams: URLSearchParams
193
190
  ): string => {
194
- const queryParams = [];
195
- if (code) {
196
- queryParams.push(`code=${code}`);
197
- }
198
- if (error) {
199
- const stringifiedErr = Array.isArray(error) ? error.join(",") : error;
200
- queryParams.push(`error=${stringifiedErr}`);
201
- }
202
-
203
- queryParams.push(`state=${wranglerRequestParams.get("state")}`);
204
-
205
- return queryParams.join("&");
191
+ const queryParams = [];
192
+ if (code) {
193
+ queryParams.push(`code=${code}`);
194
+ }
195
+ if (error) {
196
+ const stringifiedErr = Array.isArray(error) ? error.join(",") : error;
197
+ queryParams.push(`error=${stringifiedErr}`);
198
+ }
199
+
200
+ queryParams.push(`state=${wranglerRequestParams.get("state")}`);
201
+
202
+ return queryParams.join("&");
206
203
  };
207
204
 
208
205
  type ErrorType =
209
- | "invalid_request"
210
- | "invalid_grant"
211
- | "unauthorized_client"
212
- | "access_denied"
213
- | "unsupported_response_type"
214
- | "invalid_scope"
215
- | "server_error"
216
- | "temporarily_unavailable"
217
- | "invalid_client"
218
- | "unsupported_grant_type"
219
- | "invalid_json"
220
- | "invalid_token"
221
- | "test-token-grant-error";
206
+ | "invalid_request"
207
+ | "invalid_grant"
208
+ | "unauthorized_client"
209
+ | "access_denied"
210
+ | "unsupported_response_type"
211
+ | "invalid_scope"
212
+ | "server_error"
213
+ | "temporarily_unavailable"
214
+ | "invalid_client"
215
+ | "unsupported_grant_type"
216
+ | "invalid_json"
217
+ | "invalid_token"
218
+ | "test-token-grant-error";
222
219
 
223
220
  type MockTokenResponse =
224
- | "ok"
225
- | "error"
226
- | {
227
- access_token: string;
228
- expires_in: number;
229
- refresh_token: string;
230
- scope: string;
231
- }
232
- | {
233
- error: ErrorType;
234
- };
221
+ | "ok"
222
+ | "error"
223
+ | {
224
+ access_token: string;
225
+ expires_in: number;
226
+ refresh_token: string;
227
+ scope: string;
228
+ }
229
+ | {
230
+ error: ErrorType;
231
+ };
235
232
 
236
233
  const makeTokenResponse = (partialResponse: MockTokenResponse): string => {
237
- let fullResponse: MockTokenResponse;
238
-
239
- if (partialResponse === "ok") {
240
- fullResponse = {
241
- access_token: "test-access-token",
242
- expires_in: 100000,
243
- refresh_token: "test-refresh-token",
244
- scope: "account:read",
245
- };
246
- } else if (partialResponse === "error") {
247
- fullResponse = {
248
- error: "test-token-grant-error",
249
- };
250
- } else {
251
- fullResponse = partialResponse;
252
- }
253
-
254
- return JSON.stringify(fullResponse);
234
+ let fullResponse: MockTokenResponse;
235
+
236
+ if (partialResponse === "ok") {
237
+ fullResponse = {
238
+ access_token: "test-access-token",
239
+ expires_in: 100000,
240
+ refresh_token: "test-refresh-token",
241
+ scope: "account:read",
242
+ };
243
+ } else if (partialResponse === "error") {
244
+ fullResponse = {
245
+ error: "test-token-grant-error",
246
+ };
247
+ } else {
248
+ fullResponse = partialResponse;
249
+ }
250
+
251
+ return JSON.stringify(fullResponse);
255
252
  };
@@ -0,0 +1,39 @@
1
+ /**
2
+ * We use this module to mock process methods (write only for now),
3
+ * and optionally assert on the values they're called with in our tests.
4
+ */
5
+
6
+ let writeSpy: jest.SpyInstance;
7
+
8
+ function captureLastWriteCall(spy: jest.SpyInstance): Buffer {
9
+ const calls = spy.mock.calls;
10
+ if (calls.length > 1) {
11
+ throw new Error(
12
+ "Unexpected calls to `stdout.write()`: " + JSON.stringify(calls)
13
+ );
14
+ }
15
+ const buffer = calls[0]?.[0] ?? Buffer.alloc(0);
16
+ if (buffer instanceof Buffer) {
17
+ return buffer;
18
+ } else {
19
+ throw new Error(
20
+ `Unexpected non-Buffer passed to \`stdout.write()\`: "${JSON.stringify(
21
+ buffer
22
+ )}"`
23
+ );
24
+ }
25
+ }
26
+
27
+ export function mockProcess() {
28
+ beforeEach(() => {
29
+ writeSpy = jest.spyOn(process.stdout, "write").mockImplementation();
30
+ });
31
+ afterEach(() => {
32
+ writeSpy.mockRestore();
33
+ });
34
+ return {
35
+ get write() {
36
+ return captureLastWriteCall(writeSpy);
37
+ },
38
+ };
39
+ }