wrangler 0.0.0-e64812e → 0.0.0-e6488257

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 (185) hide show
  1. package/README.md +29 -11
  2. package/bin/wrangler.js +86 -67
  3. package/config-schema.json +2947 -0
  4. package/kv-asset-handler.js +1 -0
  5. package/package.json +114 -77
  6. package/templates/__tests__/pages-dev-util.test.ts +128 -0
  7. package/templates/__tests__/tsconfig-sanity.ts +12 -0
  8. package/templates/__tests__/tsconfig.json +8 -0
  9. package/templates/checked-fetch.js +30 -0
  10. package/templates/facade.d.ts +19 -0
  11. package/templates/gitignore +0 -4
  12. package/templates/init-tests/test-jest-new-worker.js +23 -0
  13. package/templates/init-tests/test-vitest-new-worker.js +24 -0
  14. package/templates/init-tests/test-vitest-new-worker.ts +25 -0
  15. package/templates/middleware/common.ts +67 -0
  16. package/templates/middleware/loader-modules.ts +134 -0
  17. package/templates/middleware/loader-sw.ts +229 -0
  18. package/templates/middleware/middleware-ensure-req-body-drained.ts +18 -0
  19. package/templates/middleware/middleware-miniflare3-json-error.ts +32 -0
  20. package/templates/middleware/middleware-pretty-error.ts +40 -0
  21. package/templates/middleware/middleware-scheduled.ts +15 -0
  22. package/templates/middleware/middleware-serve-static-assets.d.ts +6 -0
  23. package/templates/middleware/middleware-serve-static-assets.ts +56 -0
  24. package/templates/modules-watch-stub.js +4 -0
  25. package/templates/new-worker-scheduled.js +3 -3
  26. package/templates/new-worker-scheduled.ts +16 -16
  27. package/templates/new-worker.js +3 -3
  28. package/templates/new-worker.ts +19 -16
  29. package/templates/no-op-worker.js +10 -0
  30. package/templates/pages-dev-pipeline.ts +32 -0
  31. package/templates/pages-dev-util.ts +55 -0
  32. package/templates/pages-shim.ts +9 -0
  33. package/templates/pages-template-plugin.ts +190 -0
  34. package/templates/pages-template-worker.ts +198 -0
  35. package/templates/startDevWorker/InspectorProxyWorker.ts +664 -0
  36. package/templates/startDevWorker/ProxyWorker.ts +334 -0
  37. package/templates/tsconfig-sanity.ts +11 -0
  38. package/templates/tsconfig.init.json +105 -0
  39. package/templates/tsconfig.json +6 -103
  40. package/wrangler-dist/InspectorProxyWorker.js +464 -0
  41. package/wrangler-dist/InspectorProxyWorker.js.map +6 -0
  42. package/wrangler-dist/ProxyWorker.js +240 -0
  43. package/wrangler-dist/ProxyWorker.js.map +6 -0
  44. package/wrangler-dist/cli.d.ts +24215 -0
  45. package/wrangler-dist/cli.js +188741 -107044
  46. package/wrangler-dist/wasm-sync.wasm +0 -0
  47. package/Cloudflare_CA.pem +0 -18
  48. package/import_meta_url.js +0 -3
  49. package/miniflare-config-stubs/.env.empty +0 -0
  50. package/miniflare-config-stubs/package.empty.json +0 -1
  51. package/miniflare-config-stubs/wrangler.empty.toml +0 -0
  52. package/miniflare-dist/index.mjs +0 -4886
  53. package/pages/functions/buildPlugin.ts +0 -105
  54. package/pages/functions/buildWorker.ts +0 -151
  55. package/pages/functions/filepath-routing.test.ts +0 -234
  56. package/pages/functions/filepath-routing.ts +0 -189
  57. package/pages/functions/identifiers.ts +0 -78
  58. package/pages/functions/routes.ts +0 -156
  59. package/pages/functions/template-plugin.ts +0 -147
  60. package/pages/functions/template-worker.ts +0 -143
  61. package/src/__tests__/config-cache.test.ts +0 -36
  62. package/src/__tests__/configuration.test.ts +0 -3374
  63. package/src/__tests__/dev.test.tsx +0 -980
  64. package/src/__tests__/guess-worker-format.test.ts +0 -85
  65. package/src/__tests__/helpers/clipboardy-mock.js +0 -4
  66. package/src/__tests__/helpers/cmd-shim.d.ts +0 -11
  67. package/src/__tests__/helpers/faye-websocket.d.ts +0 -6
  68. package/src/__tests__/helpers/mock-account-id.ts +0 -48
  69. package/src/__tests__/helpers/mock-bin.ts +0 -36
  70. package/src/__tests__/helpers/mock-cfetch.ts +0 -211
  71. package/src/__tests__/helpers/mock-console.ts +0 -87
  72. package/src/__tests__/helpers/mock-dialogs.ts +0 -130
  73. package/src/__tests__/helpers/mock-http-server.ts +0 -46
  74. package/src/__tests__/helpers/mock-istty.ts +0 -27
  75. package/src/__tests__/helpers/mock-kv.ts +0 -33
  76. package/src/__tests__/helpers/mock-oauth-flow.ts +0 -255
  77. package/src/__tests__/helpers/mock-stdin.ts +0 -103
  78. package/src/__tests__/helpers/mock-web-socket.ts +0 -29
  79. package/src/__tests__/helpers/run-in-tmp.ts +0 -39
  80. package/src/__tests__/helpers/run-wrangler.ts +0 -16
  81. package/src/__tests__/helpers/write-worker-source.ts +0 -31
  82. package/src/__tests__/helpers/write-wrangler-toml.ts +0 -17
  83. package/src/__tests__/https-options.test.ts +0 -130
  84. package/src/__tests__/index.test.ts +0 -256
  85. package/src/__tests__/init.test.ts +0 -1634
  86. package/src/__tests__/jest.setup.ts +0 -77
  87. package/src/__tests__/kv.test.ts +0 -1481
  88. package/src/__tests__/logger.test.ts +0 -115
  89. package/src/__tests__/package-manager.test.ts +0 -353
  90. package/src/__tests__/pages.test.ts +0 -754
  91. package/src/__tests__/parse.test.ts +0 -330
  92. package/src/__tests__/publish.test.ts +0 -5468
  93. package/src/__tests__/r2.test.ts +0 -233
  94. package/src/__tests__/route.test.ts +0 -45
  95. package/src/__tests__/secret.test.ts +0 -481
  96. package/src/__tests__/tail.test.ts +0 -690
  97. package/src/__tests__/user.test.ts +0 -131
  98. package/src/__tests__/whoami.test.tsx +0 -105
  99. package/src/abort.d.ts +0 -3
  100. package/src/bundle.ts +0 -200
  101. package/src/cfetch/index.ts +0 -121
  102. package/src/cfetch/internal.ts +0 -145
  103. package/src/cli.ts +0 -13
  104. package/src/config/README.md +0 -107
  105. package/src/config/config.ts +0 -234
  106. package/src/config/diagnostics.ts +0 -80
  107. package/src/config/environment.ts +0 -420
  108. package/src/config/index.ts +0 -225
  109. package/src/config/validation-helpers.ts +0 -575
  110. package/src/config/validation.ts +0 -1539
  111. package/src/config-cache.ts +0 -45
  112. package/src/create-worker-preview.ts +0 -185
  113. package/src/create-worker-upload-form.ts +0 -254
  114. package/src/dev/dev-vars.ts +0 -36
  115. package/src/dev/dev.tsx +0 -419
  116. package/src/dev/local.tsx +0 -318
  117. package/src/dev/remote.tsx +0 -227
  118. package/src/dev/use-esbuild.ts +0 -118
  119. package/src/dialogs.tsx +0 -135
  120. package/src/durable.ts +0 -102
  121. package/src/entry.ts +0 -322
  122. package/src/environment-variables.ts +0 -35
  123. package/src/errors.ts +0 -11
  124. package/src/https-options.ts +0 -123
  125. package/src/index.tsx +0 -2864
  126. package/src/inspect.ts +0 -662
  127. package/src/intl-polyfill.d.ts +0 -139
  128. package/src/kv.ts +0 -408
  129. package/src/logger.ts +0 -66
  130. package/src/miniflare-cli/README.md +0 -30
  131. package/src/miniflare-cli/enum-keys.ts +0 -17
  132. package/src/miniflare-cli/index.ts +0 -41
  133. package/src/miniflare-cli/request-context.ts +0 -40
  134. package/src/module-collection.ts +0 -258
  135. package/src/open-in-browser.ts +0 -19
  136. package/src/package-manager.ts +0 -174
  137. package/src/pages.tsx +0 -2038
  138. package/src/parse.ts +0 -202
  139. package/src/paths.ts +0 -26
  140. package/src/proxy.ts +0 -465
  141. package/src/publish.ts +0 -583
  142. package/src/r2.ts +0 -50
  143. package/src/selfsigned.d.ts +0 -29
  144. package/src/sites.tsx +0 -295
  145. package/src/tail/filters.ts +0 -279
  146. package/src/tail/index.ts +0 -299
  147. package/src/tail/printing.ts +0 -67
  148. package/src/update-check.ts +0 -19
  149. package/src/user.tsx +0 -1203
  150. package/src/whoami.tsx +0 -70
  151. package/src/worker.ts +0 -180
  152. package/templates/static-asset-facade.js +0 -47
  153. package/vendor/@cloudflare/kv-asset-handler/CHANGELOG.md +0 -332
  154. package/vendor/@cloudflare/kv-asset-handler/LICENSE_APACHE +0 -176
  155. package/vendor/@cloudflare/kv-asset-handler/LICENSE_MIT +0 -25
  156. package/vendor/@cloudflare/kv-asset-handler/README.md +0 -245
  157. package/vendor/@cloudflare/kv-asset-handler/dist/index.d.ts +0 -32
  158. package/vendor/@cloudflare/kv-asset-handler/dist/index.js +0 -354
  159. package/vendor/@cloudflare/kv-asset-handler/dist/mocks.d.ts +0 -13
  160. package/vendor/@cloudflare/kv-asset-handler/dist/mocks.js +0 -148
  161. package/vendor/@cloudflare/kv-asset-handler/dist/test/getAssetFromKV.d.ts +0 -1
  162. package/vendor/@cloudflare/kv-asset-handler/dist/test/getAssetFromKV.js +0 -436
  163. package/vendor/@cloudflare/kv-asset-handler/dist/test/mapRequestToAsset.d.ts +0 -1
  164. package/vendor/@cloudflare/kv-asset-handler/dist/test/mapRequestToAsset.js +0 -40
  165. package/vendor/@cloudflare/kv-asset-handler/dist/test/serveSinglePageApp.d.ts +0 -1
  166. package/vendor/@cloudflare/kv-asset-handler/dist/test/serveSinglePageApp.js +0 -42
  167. package/vendor/@cloudflare/kv-asset-handler/dist/types.d.ts +0 -26
  168. package/vendor/@cloudflare/kv-asset-handler/dist/types.js +0 -31
  169. package/vendor/@cloudflare/kv-asset-handler/package.json +0 -52
  170. package/vendor/@cloudflare/kv-asset-handler/src/index.ts +0 -296
  171. package/vendor/@cloudflare/kv-asset-handler/src/mocks.ts +0 -136
  172. package/vendor/@cloudflare/kv-asset-handler/src/test/getAssetFromKV.ts +0 -464
  173. package/vendor/@cloudflare/kv-asset-handler/src/test/mapRequestToAsset.ts +0 -33
  174. package/vendor/@cloudflare/kv-asset-handler/src/test/serveSinglePageApp.ts +0 -42
  175. package/vendor/@cloudflare/kv-asset-handler/src/types.ts +0 -39
  176. package/vendor/wrangler-mime/CHANGELOG.md +0 -289
  177. package/vendor/wrangler-mime/LICENSE +0 -21
  178. package/vendor/wrangler-mime/Mime.js +0 -97
  179. package/vendor/wrangler-mime/README.md +0 -187
  180. package/vendor/wrangler-mime/cli.js +0 -46
  181. package/vendor/wrangler-mime/index.js +0 -4
  182. package/vendor/wrangler-mime/lite.js +0 -4
  183. package/vendor/wrangler-mime/package.json +0 -52
  184. package/vendor/wrangler-mime/types/other.js +0 -1
  185. package/vendor/wrangler-mime/types/standard.js +0 -1
@@ -1,754 +0,0 @@
1
- import { mkdirSync, writeFileSync } from "node:fs";
2
- import { mockAccountId, mockApiToken } from "./helpers/mock-account-id";
3
- import {
4
- createFetchResult,
5
- setMockRawResponse,
6
- setMockResponse,
7
- unsetAllMocks,
8
- } from "./helpers/mock-cfetch";
9
- import { mockConsoleMethods } from "./helpers/mock-console";
10
- import { runInTempDir } from "./helpers/run-in-tmp";
11
- import { runWrangler } from "./helpers/run-wrangler";
12
- import type { Deployment, Project, UploadPayloadFile } from "../pages";
13
- import type { FormData, RequestInit } from "undici";
14
-
15
- // Asserting within mock responses get swallowed, so run them out-of-band
16
- const outOfBandTests: (() => void)[] = [];
17
- function assertLater(fn: () => void) {
18
- outOfBandTests.push(fn);
19
- }
20
-
21
- function mockGetToken(jwt: string) {
22
- return setMockResponse(
23
- "/accounts/:accountId/pages/projects/foo/upload-token",
24
- async ([_url, accountId]) => {
25
- assertLater(() => {
26
- expect(accountId).toEqual("some-account-id");
27
- });
28
-
29
- return { jwt };
30
- }
31
- );
32
- }
33
-
34
- describe("pages", () => {
35
- runInTempDir();
36
- const std = mockConsoleMethods();
37
- function endEventLoop() {
38
- return new Promise((resolve) => setImmediate(resolve));
39
- }
40
- beforeEach(() => {
41
- outOfBandTests.length = 0;
42
- });
43
- afterEach(() => {
44
- outOfBandTests.forEach((fn) => fn());
45
- });
46
-
47
- it("should should display a list of available subcommands, for pages with no subcommand", async () => {
48
- await runWrangler("pages");
49
- await endEventLoop();
50
-
51
- expect(std.out).toMatchInlineSnapshot(`
52
- "wrangler pages
53
-
54
- ⚡️ Configure Cloudflare Pages
55
-
56
- Commands:
57
- wrangler pages dev [directory] [-- command..] 🧑‍💻 Develop your full-stack Pages application locally
58
- wrangler pages project ⚡️ Interact with your Pages projects
59
- wrangler pages deployment 🚀 Interact with the deployments of a project
60
- wrangler pages publish [directory] 🆙 Publish a directory of static assets as a Pages deployment
61
-
62
- Flags:
63
- -c, --config Path to .toml configuration file [string]
64
- -h, --help Show help [boolean]
65
- -v, --version Show version number [boolean]
66
-
67
- 🚧 'wrangler pages <command>' is a beta command. Please report any issues to https://github.com/cloudflare/wrangler2/issues/new/choose"
68
- `);
69
- });
70
-
71
- describe("beta message for subcommands", () => {
72
- it("should display for pages:dev", async () => {
73
- await expect(
74
- runWrangler("pages dev")
75
- ).rejects.toThrowErrorMatchingInlineSnapshot(
76
- `"Must specify a directory of static assets to serve or a command to run."`
77
- );
78
-
79
- expect(std.out).toMatchInlineSnapshot(`
80
- "🚧 'wrangler pages <command>' is a beta command. Please report any issues to https://github.com/cloudflare/wrangler2/issues/new/choose
81
-
82
- If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new/choose"
83
- `);
84
- });
85
-
86
- it("should display for pages:functions:build", async () => {
87
- await expect(runWrangler("pages functions build")).rejects.toThrowError();
88
-
89
- expect(std.out).toMatchInlineSnapshot(`
90
- "🚧 'wrangler pages <command>' is a beta command. Please report any issues to https://github.com/cloudflare/wrangler2/issues/new/choose
91
-
92
- If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new/choose"
93
- `);
94
- });
95
- });
96
-
97
- describe("project list", () => {
98
- mockAccountId();
99
- mockApiToken();
100
-
101
- afterEach(() => {
102
- unsetAllMocks();
103
- });
104
-
105
- function mockListRequest(projects: unknown[]) {
106
- const requests = { count: 0 };
107
- setMockResponse(
108
- "/accounts/:accountId/pages/projects",
109
- ([_url, accountId], init, query) => {
110
- requests.count++;
111
- const pageSize = Number(query.get("per_page"));
112
- const page = Number(query.get("page"));
113
- const expectedPageSize = 10;
114
- const expectedPage = requests.count;
115
- assertLater(() => {
116
- expect(accountId).toEqual("some-account-id");
117
- expect(pageSize).toEqual(expectedPageSize);
118
- expect(page).toEqual(expectedPage);
119
- expect(init).toEqual({});
120
- });
121
- return projects.slice((page - 1) * pageSize, page * pageSize);
122
- }
123
- );
124
- return requests;
125
- }
126
-
127
- it("should make request to list projects", async () => {
128
- const projects: Project[] = [
129
- {
130
- name: "dogs",
131
- subdomain: "docs.pages.dev",
132
- domains: ["dogs.pages.dev"],
133
- source: {
134
- type: "github",
135
- },
136
- latest_deployment: {
137
- modified_on: "2021-11-17T14:52:26.133835Z",
138
- },
139
- created_on: "2021-11-17T14:52:26.133835Z",
140
- production_branch: "main",
141
- },
142
- {
143
- name: "cats",
144
- subdomain: "cats.pages.dev",
145
- domains: ["cats.pages.dev", "kitten.com"],
146
- latest_deployment: {
147
- modified_on: "2021-11-17T14:52:26.133835Z",
148
- },
149
- created_on: "2021-11-17T14:52:26.133835Z",
150
- production_branch: "main",
151
- },
152
- ];
153
-
154
- const requests = mockListRequest(projects);
155
- await runWrangler("pages project list");
156
-
157
- expect(requests.count).toBe(1);
158
- });
159
-
160
- it("should make multiple requests for paginated results", async () => {
161
- const projects: Project[] = [];
162
- for (let i = 0; i < 15; i++) {
163
- projects.push({
164
- name: "dogs" + i,
165
- subdomain: i + "dogs.pages.dev",
166
- domains: [i + "dogs.pages.dev"],
167
- source: {
168
- type: "github",
169
- },
170
- latest_deployment: {
171
- modified_on: "2021-11-17T14:52:26.133835Z",
172
- },
173
- created_on: "2021-11-17T14:52:26.133835Z",
174
- production_branch: "main",
175
- });
176
- }
177
- const requests = mockListRequest(projects);
178
- await runWrangler("pages project list");
179
- expect(requests.count).toEqual(2);
180
- });
181
- });
182
-
183
- describe("project create", () => {
184
- mockAccountId();
185
- mockApiToken();
186
-
187
- afterEach(() => {
188
- unsetAllMocks();
189
- });
190
-
191
- it("should create a project with a production branch", async () => {
192
- setMockResponse(
193
- "/accounts/:accountId/pages/projects",
194
- ([_url, accountId], init) => {
195
- const body = JSON.parse(init.body as string);
196
- assertLater(() => {
197
- expect(accountId).toEqual("some-account-id");
198
- expect(init.method).toEqual("POST");
199
- expect(body).toEqual({
200
- name: "a-new-project",
201
- production_branch: "main",
202
- });
203
- });
204
- return {
205
- name: "a-new-project",
206
- subdomain: "a-new-project.pages.dev",
207
- production_branch: "main",
208
- };
209
- }
210
- );
211
- await runWrangler(
212
- "pages project create a-new-project --production-branch=main"
213
- );
214
- expect(std.out).toMatchInlineSnapshot(`
215
- "✨ Successfully created the 'a-new-project' project. It will be available at https://a-new-project.pages.dev/ once you create your first deployment.
216
- To deploy a folder of assets, run 'wrangler pages publish [directory]'."
217
- `);
218
- });
219
- });
220
-
221
- describe("deployment list", () => {
222
- mockAccountId();
223
- mockApiToken();
224
-
225
- afterEach(() => {
226
- unsetAllMocks();
227
- });
228
- function mockListRequest(deployments: unknown[]) {
229
- const requests = { count: 0 };
230
- setMockResponse(
231
- "/accounts/:accountId/pages/projects/:project/deployments",
232
- ([_url, accountId, project]) => {
233
- requests.count++;
234
- assertLater(() => {
235
- expect(project).toEqual("images");
236
- expect(accountId).toEqual("some-account-id");
237
- });
238
- return deployments;
239
- }
240
- );
241
- return requests;
242
- }
243
-
244
- it("should make request to list deployments", async () => {
245
- const deployments: Deployment[] = [
246
- {
247
- id: "87bbc8fe-16be-45cd-81e0-63d722e82cdf",
248
- url: "https://87bbc8fe.images.pages.dev",
249
- environment: "preview",
250
- latest_stage: {
251
- ended_on: "2021-11-17T14:52:26.133835Z",
252
- status: "success",
253
- },
254
- deployment_trigger: {
255
- metadata: {
256
- branch: "main",
257
- commit_hash: "c7649364c4cb32ad4f65b530b9424e8be5bec9d6",
258
- },
259
- },
260
- project_name: "images",
261
- },
262
- ];
263
-
264
- const requests = mockListRequest(deployments);
265
- await runWrangler("pages deployment list --project-name=images");
266
-
267
- expect(requests.count).toBe(1);
268
- });
269
- });
270
-
271
- describe("deployment create", () => {
272
- let actualProcessEnvCI: string | undefined;
273
-
274
- mockAccountId();
275
- mockApiToken();
276
- runInTempDir();
277
-
278
- beforeEach(() => {
279
- actualProcessEnvCI = process.env.CI;
280
- process.env.CI = "true";
281
- });
282
-
283
- afterEach(() => {
284
- unsetAllMocks();
285
- process.env.CI = actualProcessEnvCI;
286
- });
287
-
288
- it("should be aliased with 'wrangler pages publish'", async () => {
289
- await runWrangler("pages publish --help");
290
- await endEventLoop();
291
-
292
- expect(std.out).toMatchInlineSnapshot(`
293
- "wrangler pages publish [directory]
294
-
295
- 🆙 Publish a directory of static assets as a Pages deployment
296
-
297
- Positionals:
298
- directory The directory of static files to upload [string]
299
-
300
- Flags:
301
- -c, --config Path to .toml configuration file [string]
302
- -h, --help Show help [boolean]
303
- -v, --version Show version number [boolean]
304
-
305
- Options:
306
- --project-name The name of the project you want to deploy to [string]
307
- --branch The name of the branch you want to deploy to [string]
308
- --commit-hash The SHA to attach to this deployment [string]
309
- --commit-message The commit message to attach to this deployment [string]
310
- --commit-dirty Whether or not the workspace should be considered dirty for this deployment [boolean]
311
-
312
- 🚧 'wrangler pages <command>' is a beta command. Please report any issues to https://github.com/cloudflare/wrangler2/issues/new/choose"
313
- `);
314
- });
315
-
316
- it("should upload a directory of files", async () => {
317
- writeFileSync("logo.png", "foobar");
318
-
319
- setMockResponse(
320
- "/accounts/:accountId/pages/projects/foo/upload-token",
321
- async ([_url, accountId]) => {
322
- assertLater(() => {
323
- expect(accountId).toEqual("some-account-id");
324
- });
325
-
326
- return {
327
- jwt: "<<funfetti-auth-jwt>>",
328
- };
329
- }
330
- );
331
-
332
- setMockResponse(
333
- "/pages/assets/check-missing",
334
- "POST",
335
- async (_, init) => {
336
- const body = JSON.parse(init.body as string) as { hashes: string[] };
337
- assertLater(() => {
338
- expect(init.headers).toMatchObject({
339
- Authorization: "Bearer <<funfetti-auth-jwt>>",
340
- });
341
- expect(body).toMatchObject({
342
- hashes: ["2082190357cfd3617ccfe04f340c6247"],
343
- });
344
- });
345
- return body.hashes;
346
- }
347
- );
348
-
349
- setMockResponse("/pages/assets/upload", "POST", async (_, init) => {
350
- assertLater(() => {
351
- expect(init.headers).toMatchObject({
352
- Authorization: "Bearer <<funfetti-auth-jwt>>",
353
- });
354
- const body = JSON.parse(init.body as string) as UploadPayloadFile[];
355
- expect(body).toMatchObject([
356
- {
357
- key: "2082190357cfd3617ccfe04f340c6247",
358
- value: Buffer.from("foobar").toString("base64"),
359
- metadata: {
360
- contentType: "image/png",
361
- },
362
- base64: true,
363
- },
364
- ]);
365
- });
366
- });
367
-
368
- setMockResponse(
369
- "/accounts/:accountId/pages/projects/foo/deployments",
370
- async ([_url, accountId], init) => {
371
- assertLater(() => {
372
- expect(accountId).toEqual("some-account-id");
373
- expect(init.method).toEqual("POST");
374
- const body = init.body as FormData;
375
- const manifest = JSON.parse(body.get("manifest") as string);
376
- expect(manifest).toMatchInlineSnapshot(`
377
- Object {
378
- "/logo.png": "2082190357cfd3617ccfe04f340c6247",
379
- }
380
- `);
381
- });
382
-
383
- return {
384
- url: "https://abcxyz.foo.pages.dev/",
385
- };
386
- }
387
- );
388
-
389
- await runWrangler("pages publish . --project-name=foo");
390
-
391
- // TODO: Unmounting somehow loses this output
392
-
393
- // expect(std.out).toMatchInlineSnapshot(`
394
- // "✨ Success! Uploaded 1 files (TIMINGS)
395
-
396
- // ✨ Deployment complete! Take a peek over at https://abcxyz.foo.pages.dev/"
397
- // `);
398
- });
399
-
400
- it("should retry uploads", async () => {
401
- writeFileSync("logo.txt", "foobar");
402
-
403
- mockGetToken("<<funfetti-auth-jwt>>");
404
-
405
- setMockResponse(
406
- "/pages/assets/check-missing",
407
- "POST",
408
- async (_, init) => {
409
- const body = JSON.parse(init.body as string) as { hashes: string[] };
410
- assertLater(() => {
411
- expect(init.headers).toMatchObject({
412
- Authorization: "Bearer <<funfetti-auth-jwt>>",
413
- });
414
- expect(body).toMatchObject({
415
- hashes: ["1a98fb08af91aca4a7df1764a2c4ddb0"],
416
- });
417
- });
418
- return body.hashes;
419
- }
420
- );
421
-
422
- // Accumulate multiple requests then assert afterwards
423
- const requests: RequestInit[] = [];
424
- setMockRawResponse("/pages/assets/upload", "POST", async (_, init) => {
425
- requests.push(init);
426
-
427
- if (requests.length < 2) {
428
- return createFetchResult(null, false, [
429
- {
430
- code: 800000,
431
- message: "Something exploded, please retry",
432
- },
433
- ]);
434
- } else {
435
- return createFetchResult(null, true);
436
- }
437
- });
438
-
439
- setMockResponse(
440
- "/accounts/:accountId/pages/projects/foo/deployments",
441
- async ([_url, accountId], init) => {
442
- assertLater(() => {
443
- expect(accountId).toEqual("some-account-id");
444
- expect(init.method).toEqual("POST");
445
- const body = init.body as FormData;
446
- const manifest = JSON.parse(body.get("manifest") as string);
447
- expect(manifest).toMatchInlineSnapshot(`
448
- Object {
449
- "/logo.txt": "1a98fb08af91aca4a7df1764a2c4ddb0",
450
- }
451
- `);
452
- });
453
-
454
- return {
455
- url: "https://abcxyz.foo.pages.dev/",
456
- };
457
- }
458
- );
459
-
460
- await runWrangler("pages publish . --project-name=foo");
461
-
462
- // Assert two identical requests
463
- expect(requests.length).toBe(2);
464
- for (const init of requests) {
465
- assertLater(() => {
466
- expect(init.headers).toMatchObject({
467
- Authorization: "Bearer <<funfetti-auth-jwt>>",
468
- });
469
-
470
- const body = JSON.parse(init.body as string) as UploadPayloadFile[];
471
- expect(body).toMatchObject([
472
- {
473
- key: "1a98fb08af91aca4a7df1764a2c4ddb0",
474
- value: Buffer.from("foobar").toString("base64"),
475
- metadata: {
476
- contentType: "text/plain",
477
- },
478
- base64: true,
479
- },
480
- ]);
481
- });
482
- }
483
-
484
- expect(std.out).toMatchInlineSnapshot(`
485
- "✨ Success! Uploaded 1 files (TIMINGS)
486
-
487
- ✨ Deployment complete! Take a peek over at https://abcxyz.foo.pages.dev/"
488
- `);
489
- });
490
-
491
- it("should refetch a JWT if it expires while uploading", async () => {
492
- writeFileSync("logo.txt", "foobar");
493
-
494
- const cancelMockGetToken = mockGetToken("<<funfetti-auth-jwt>>");
495
-
496
- setMockResponse(
497
- "/pages/assets/check-missing",
498
- "POST",
499
- async (_, init) => {
500
- const body = JSON.parse(init.body as string) as { hashes: string[] };
501
- assertLater(() => {
502
- expect(init.headers).toMatchObject({
503
- Authorization: "Bearer <<funfetti-auth-jwt>>",
504
- });
505
- expect(body).toMatchObject({
506
- hashes: ["1a98fb08af91aca4a7df1764a2c4ddb0"],
507
- });
508
- });
509
- return body.hashes;
510
- }
511
- );
512
-
513
- // Accumulate multiple requests then assert afterwards
514
- const requests: RequestInit[] = [];
515
- setMockRawResponse("/pages/assets/upload", "POST", async (_, init) => {
516
- requests.push(init);
517
-
518
- // Fail just the first request
519
- if (requests.length < 2) {
520
- cancelMockGetToken();
521
- mockGetToken("<<funfetti-auth-jwt2>>");
522
- return createFetchResult(null, false, [
523
- {
524
- code: 8000013,
525
- message: "Authorization failed",
526
- },
527
- ]);
528
- } else {
529
- return createFetchResult(null, true);
530
- }
531
- });
532
-
533
- setMockResponse(
534
- "/accounts/:accountId/pages/projects/foo/deployments",
535
- async ([_url, accountId], init) => {
536
- assertLater(() => {
537
- expect(accountId).toEqual("some-account-id");
538
- expect(init.method).toEqual("POST");
539
- const body = init.body as FormData;
540
- const manifest = JSON.parse(body.get("manifest") as string);
541
- expect(manifest).toMatchInlineSnapshot(`
542
- Object {
543
- "/logo.txt": "1a98fb08af91aca4a7df1764a2c4ddb0",
544
- }
545
- `);
546
- });
547
-
548
- return {
549
- url: "https://abcxyz.foo.pages.dev/",
550
- };
551
- }
552
- );
553
-
554
- await runWrangler("pages publish . --project-name=foo");
555
-
556
- // Assert two requests
557
- expect(requests.length).toBe(2);
558
-
559
- expect(requests[0].headers).toMatchObject({
560
- Authorization: "Bearer <<funfetti-auth-jwt>>",
561
- });
562
-
563
- expect(requests[1].headers).toMatchObject({
564
- Authorization: "Bearer <<funfetti-auth-jwt2>>",
565
- });
566
-
567
- for (const init of requests) {
568
- const body = JSON.parse(init.body as string) as UploadPayloadFile[];
569
- expect(body).toMatchObject([
570
- {
571
- key: "1a98fb08af91aca4a7df1764a2c4ddb0",
572
- value: Buffer.from("foobar").toString("base64"),
573
- metadata: {
574
- contentType: "text/plain",
575
- },
576
- base64: true,
577
- },
578
- ]);
579
- }
580
-
581
- expect(std.out).toMatchInlineSnapshot(`
582
- "✨ Success! Uploaded 1 files (TIMINGS)
583
-
584
- ✨ Deployment complete! Take a peek over at https://abcxyz.foo.pages.dev/"
585
- `);
586
- });
587
-
588
- it("should try to use multiple buckets (up to the max concurrency)", async () => {
589
- writeFileSync("logo.txt", "foobar");
590
- writeFileSync("logo.png", "foobar");
591
- writeFileSync("logo.html", "foobar");
592
- writeFileSync("logo.js", "foobar");
593
-
594
- mockGetToken("<<funfetti-auth-jwt>>");
595
-
596
- setMockResponse(
597
- "/pages/assets/check-missing",
598
- "POST",
599
- async (_, init) => {
600
- const body = JSON.parse(init.body as string) as { hashes: string[] };
601
- assertLater(() => {
602
- expect(init.headers).toMatchObject({
603
- Authorization: "Bearer <<funfetti-auth-jwt>>",
604
- });
605
- expect(body).toMatchObject({
606
- hashes: expect.arrayContaining([
607
- "d96fef225537c9f5e44a3cb27fd0b492",
608
- "2082190357cfd3617ccfe04f340c6247",
609
- "6be321bef99e758250dac034474ddbb8",
610
- "1a98fb08af91aca4a7df1764a2c4ddb0",
611
- ]),
612
- });
613
- });
614
- return body.hashes;
615
- }
616
- );
617
-
618
- // Accumulate multiple requests then assert afterwards
619
- const requests: RequestInit[] = [];
620
- setMockResponse("/pages/assets/upload", "POST", async (_, init) => {
621
- requests.push(init);
622
- });
623
-
624
- setMockResponse(
625
- "/accounts/:accountId/pages/projects/foo/deployments",
626
- async ([_url, accountId], init) => {
627
- assertLater(() => {
628
- expect(accountId).toEqual("some-account-id");
629
- expect(init.method).toEqual("POST");
630
- const body = init.body as FormData;
631
- const manifest = JSON.parse(body.get("manifest") as string);
632
- expect(manifest).toMatchInlineSnapshot(`
633
- Object {
634
- "/logo.html": "d96fef225537c9f5e44a3cb27fd0b492",
635
- "/logo.js": "6be321bef99e758250dac034474ddbb8",
636
- "/logo.png": "2082190357cfd3617ccfe04f340c6247",
637
- "/logo.txt": "1a98fb08af91aca4a7df1764a2c4ddb0",
638
- }
639
- `);
640
- });
641
-
642
- return {
643
- url: "https://abcxyz.foo.pages.dev/",
644
- };
645
- }
646
- );
647
-
648
- await runWrangler("pages publish . --project-name=foo");
649
-
650
- // We have 3 buckets, so expect 3 uploads
651
- expect(requests.length).toBe(3);
652
- const bodies: UploadPayloadFile[][] = [];
653
- for (const init of requests) {
654
- expect(init.headers).toMatchObject({
655
- Authorization: "Bearer <<funfetti-auth-jwt>>",
656
- });
657
- bodies.push(JSON.parse(init.body as string) as UploadPayloadFile[]);
658
- }
659
- // First bucket should end up with 2 files
660
- expect(bodies.map((b) => b.length)).toEqual([2, 1, 1]);
661
- // But we don't know the order, so flatten and test without ordering
662
- expect(bodies.flatMap((b) => b)).toEqual(
663
- expect.arrayContaining([
664
- {
665
- base64: true,
666
- key: "d96fef225537c9f5e44a3cb27fd0b492",
667
- metadata: { contentType: "text/html" },
668
- value: "Zm9vYmFy",
669
- },
670
- {
671
- base64: true,
672
- key: "1a98fb08af91aca4a7df1764a2c4ddb0",
673
- metadata: { contentType: "text/plain" },
674
- value: "Zm9vYmFy",
675
- },
676
- {
677
- base64: true,
678
- key: "6be321bef99e758250dac034474ddbb8",
679
- metadata: { contentType: "application/javascript" },
680
- value: "Zm9vYmFy",
681
- },
682
- {
683
- base64: true,
684
- key: "2082190357cfd3617ccfe04f340c6247",
685
- metadata: { contentType: "image/png" },
686
- value: "Zm9vYmFy",
687
- },
688
- ])
689
- );
690
-
691
- expect(std.out).toMatchInlineSnapshot(`
692
- "✨ Success! Uploaded 4 files (TIMINGS)
693
-
694
- ✨ Deployment complete! Take a peek over at https://abcxyz.foo.pages.dev/"
695
- `);
696
- });
697
-
698
- it("should not error when directory names contain periods and houses a extensionless file", async () => {
699
- mkdirSync(".well-known");
700
- // Note: same content as previous test, but since it's a different extension,
701
- // it hashes to a different value
702
- writeFileSync(".well-known/foobar", "foobar");
703
-
704
- mockGetToken("<<funfetti-auth-jwt>>");
705
-
706
- setMockResponse(
707
- "/pages/assets/check-missing",
708
- "POST",
709
- async (_, init) => {
710
- const body = JSON.parse(init.body as string) as { hashes: string[] };
711
- assertLater(() => {
712
- expect(init.headers).toMatchObject({
713
- Authorization: "Bearer <<funfetti-auth-jwt>>",
714
- });
715
- expect(body).toMatchObject({
716
- hashes: ["7b764dacfd211bebd8077828a7ddefd7"],
717
- });
718
- });
719
- return body.hashes;
720
- }
721
- );
722
-
723
- setMockResponse("/pages/assets/upload", "POST", async (_, init) => {
724
- assertLater(() => {
725
- expect(init.headers).toMatchObject({
726
- Authorization: "Bearer <<funfetti-auth-jwt>>",
727
- });
728
- const body = JSON.parse(init.body as string) as UploadPayloadFile[];
729
- expect(body).toMatchObject([
730
- {
731
- key: "7b764dacfd211bebd8077828a7ddefd7",
732
- value: Buffer.from("foobar").toString("base64"),
733
- metadata: {
734
- contentType: "application/octet-stream",
735
- },
736
- base64: true,
737
- },
738
- ]);
739
- });
740
- });
741
-
742
- setMockResponse(
743
- "/accounts/:accountId/pages/projects/foo/deployments",
744
- async () => ({
745
- url: "https://abcxyz.foo.pages.dev/",
746
- })
747
- );
748
-
749
- await runWrangler("pages publish . --project-name=foo");
750
-
751
- expect(std.err).toMatchInlineSnapshot(`""`);
752
- });
753
- });
754
- });