wrangler 2.6.2 → 2.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/wrangler.js +9 -1
- package/miniflare-dist/index.mjs +1 -1
- package/package.json +12 -10
- package/src/__tests__/api-dev.test.ts +65 -36
- package/src/__tests__/api-devregistry.test.js +14 -6
- package/src/__tests__/configuration.test.ts +2 -31
- package/src/__tests__/{d1.test.ts → d1/d1.test.ts} +48 -5
- package/src/__tests__/d1/splitter.test.ts +255 -0
- package/src/__tests__/delete.test.ts +5 -2
- package/src/__tests__/deployments.test.ts +20 -6
- package/src/__tests__/dev.test.tsx +52 -19
- package/src/__tests__/generate.test.ts +7 -4
- package/src/__tests__/helpers/mock-auth-domain.ts +20 -0
- package/src/__tests__/helpers/mock-cfetch.ts +2 -57
- package/src/__tests__/helpers/mock-dialogs.ts +70 -86
- package/src/__tests__/helpers/mock-oauth-flow.ts +64 -49
- package/src/__tests__/helpers/mock-process.ts +8 -13
- package/src/__tests__/helpers/msw/blob-worker.cjs +19 -0
- package/src/__tests__/helpers/msw/read-file-sync.js +61 -0
- package/src/__tests__/index.test.ts +46 -44
- package/src/__tests__/init.test.ts +761 -537
- package/src/__tests__/jest.setup.ts +20 -24
- package/src/__tests__/kv.test.ts +286 -173
- package/src/__tests__/logout.test.ts +1 -1
- package/src/__tests__/metrics.test.ts +5 -7
- package/src/__tests__/middleware.scheduled.test.ts +40 -30
- package/src/__tests__/middleware.test.ts +144 -120
- package/src/__tests__/pages.test.ts +1617 -1161
- package/src/__tests__/publish.test.ts +174 -125
- package/src/__tests__/r2.test.ts +2 -2
- package/src/__tests__/secret.test.ts +183 -126
- package/src/__tests__/tail.test.ts +6 -0
- package/src/__tests__/tsconfig-sanity.ts +12 -0
- package/src/__tests__/tsconfig.json +8 -0
- package/src/__tests__/tsconfig.tsbuildinfo +1 -0
- package/src/__tests__/whoami.test.tsx +1 -96
- package/src/api/dev.ts +78 -41
- package/src/api/index.ts +1 -1
- package/src/{bundle-reporter.tsx → bundle-reporter.ts} +0 -0
- package/src/cfetch/index.ts +0 -2
- package/src/cfetch/internal.ts +6 -15
- package/src/cli.ts +2 -2
- package/src/config/validation.ts +1 -2
- package/src/create-worker-upload-form.ts +2 -2
- package/src/d1/{delete.tsx → delete.ts} +0 -0
- package/src/d1/execute.tsx +8 -37
- package/src/d1/migrations/apply.tsx +29 -19
- package/src/d1/migrations/{index.tsx → index.ts} +0 -0
- package/src/d1/splitter.ts +161 -0
- package/src/d1/{types.tsx → types.ts} +0 -0
- package/src/delete.ts +3 -8
- package/src/deployments.ts +6 -0
- package/src/deprecated/index.ts +2 -295
- package/src/dev/dev.tsx +2 -2
- package/src/dev/{get-local-persistence-path.tsx → get-local-persistence-path.ts} +0 -0
- package/src/dev/local.tsx +16 -4
- package/src/dev/remote.tsx +28 -1
- package/src/dev/start-server.ts +19 -11
- package/src/dev/use-esbuild.ts +1 -1
- package/src/{dev-registry.tsx → dev-registry.ts} +0 -0
- package/src/dev.tsx +21 -2
- package/src/dialogs.ts +136 -0
- package/src/dispatch-namespace.ts +1 -1
- package/src/docs/index.ts +3 -0
- package/src/environment-variables/factory.ts +88 -0
- package/src/environment-variables/misc-variables.ts +30 -0
- package/src/generate/index.ts +300 -0
- package/src/{index.tsx → index.ts} +10 -13
- package/src/init.ts +92 -52
- package/src/jest.d.ts +4 -0
- package/src/logger.ts +15 -3
- package/src/metrics/metrics-config.ts +1 -1
- package/src/miniflare-cli/assets.ts +4 -0
- package/src/miniflare-cli/index.ts +1 -5
- package/src/miniflare-cli/tsconfig.json +9 -0
- package/src/miniflare-cli/tsconfig.tsbuildinfo +1 -0
- package/src/miniflare-cli/types.ts +11 -0
- package/src/pages/{build.tsx → build.ts} +0 -0
- package/src/pages/{deployment-tails.tsx → deployment-tails.ts} +0 -0
- package/src/pages/{dev.tsx → dev.ts} +53 -55
- package/src/pages/functions/buildWorker.ts +1 -1
- package/src/pages/functions/tsconfig.json +8 -0
- package/src/pages/functions/tsconfig.tsbuildinfo +1 -0
- package/src/pages/{functions.tsx → functions.ts} +0 -0
- package/src/pages/{hash.tsx → hash.ts} +0 -0
- package/src/pages/{index.tsx → index.ts} +0 -0
- package/src/pages/projects.tsx +3 -5
- package/src/pages/publish.tsx +5 -4
- package/src/pages/upload.tsx +1 -1
- package/src/publish/publish.ts +9 -7
- package/src/pubsub/{pubsub-commands.tsx → pubsub-commands.ts} +1 -1
- package/src/secret/index.ts +1 -1
- package/src/{sites.tsx → sites.ts} +0 -0
- package/src/tail/index.ts +2 -3
- package/src/tsconfig-sanity.ts +16 -0
- package/src/user/access.ts +0 -1
- package/src/user/auth-variables.ts +113 -0
- package/src/user/choose-account.tsx +1 -31
- package/src/user/index.ts +0 -1
- package/src/user/{user.tsx → user.ts} +107 -73
- package/src/{whoami.tsx → whoami.ts} +37 -71
- package/templates/__tests__/tsconfig-sanity.ts +12 -0
- package/templates/__tests__/tsconfig.json +8 -0
- package/templates/__tests__/tsconfig.tsbuildinfo +1 -0
- package/templates/d1-beta-facade.js +36 -0
- package/templates/facade.d.ts +14 -0
- package/templates/first-party-worker-module-facade.ts +4 -3
- package/templates/format-dev-errors.ts +7 -6
- package/templates/init-tests/test-jest-new-worker.js +3 -5
- package/templates/init-tests/test-vitest-new-worker.js +3 -5
- package/templates/init-tests/test-vitest-new-worker.ts +25 -0
- package/templates/middleware/loader-modules.ts +0 -2
- package/templates/middleware/loader-sw.ts +6 -0
- package/templates/pages-dev-pipeline.ts +4 -1
- package/templates/pages-shim.ts +4 -1
- package/templates/pages-template-plugin.ts +12 -7
- package/templates/serve-static-assets.ts +16 -14
- package/templates/tsconfig-sanity.ts +11 -0
- package/templates/tsconfig.init.json +106 -0
- package/templates/tsconfig.json +5 -103
- package/templates/tsconfig.tsbuildinfo +1 -0
- package/wrangler-dist/cli.d.ts +58 -60
- package/wrangler-dist/cli.js +34440 -55514
- package/wrangler-dist/wasm-sync.wasm +0 -0
- package/src/__tests__/dialogs.test.tsx +0 -40
- package/src/dialogs.tsx +0 -168
- package/src/environment-variables.ts +0 -50
- package/src/user/env-vars.ts +0 -46
|
@@ -1,37 +1,34 @@
|
|
|
1
|
+
/* eslint-disable no-shadow */
|
|
2
|
+
import { Blob } from "node:buffer";
|
|
1
3
|
import { mkdirSync, writeFileSync } from "node:fs";
|
|
2
4
|
import { chdir } from "node:process";
|
|
5
|
+
import { MockedRequest, rest } from "msw";
|
|
6
|
+
import { FormData } from "undici";
|
|
3
7
|
import { ROUTES_SPEC_VERSION } from "../pages/constants";
|
|
4
8
|
import { isRoutesJSONSpec } from "../pages/functions/routes-validation";
|
|
5
9
|
import { version } from "./../../package.json";
|
|
6
10
|
import { mockAccountId, mockApiToken } from "./helpers/mock-account-id";
|
|
7
|
-
import {
|
|
8
|
-
createFetchResult,
|
|
9
|
-
setMockRawResponse,
|
|
10
|
-
setMockResponse,
|
|
11
|
-
unsetAllMocks,
|
|
12
|
-
} from "./helpers/mock-cfetch";
|
|
13
11
|
import { mockConsoleMethods } from "./helpers/mock-console";
|
|
12
|
+
import { msw } from "./helpers/msw";
|
|
13
|
+
import { FileReaderSync } from "./helpers/msw/read-file-sync";
|
|
14
14
|
import { runInTempDir } from "./helpers/run-in-tmp";
|
|
15
15
|
import { runWrangler } from "./helpers/run-wrangler";
|
|
16
16
|
import type { Deployment, Project, UploadPayloadFile } from "../pages/types";
|
|
17
|
-
import type {
|
|
18
|
-
|
|
19
|
-
// Asserting within mock responses get swallowed, so run them out-of-band
|
|
20
|
-
const outOfBandTests: (() => void)[] = [];
|
|
21
|
-
function assertLater(fn: () => void) {
|
|
22
|
-
outOfBandTests.push(fn);
|
|
23
|
-
}
|
|
17
|
+
import type { RestRequest } from "msw";
|
|
24
18
|
|
|
25
19
|
function mockGetToken(jwt: string) {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
expect(accountId).toEqual("some-account-id");
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
20
|
+
msw.use(
|
|
21
|
+
rest.get(
|
|
22
|
+
"*/accounts/:accountId/pages/projects/foo/upload-token",
|
|
23
|
+
(req, res, ctx) => {
|
|
24
|
+
expect(req.params.accountId).toEqual("some-account-id");
|
|
25
|
+
|
|
26
|
+
return res(
|
|
27
|
+
ctx.status(200),
|
|
28
|
+
ctx.json({ success: true, errors: [], messages: [], result: { jwt } })
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
)
|
|
35
32
|
);
|
|
36
33
|
}
|
|
37
34
|
|
|
@@ -41,12 +38,6 @@ describe("pages", () => {
|
|
|
41
38
|
function endEventLoop() {
|
|
42
39
|
return new Promise((resolve) => setImmediate(resolve));
|
|
43
40
|
}
|
|
44
|
-
beforeEach(() => {
|
|
45
|
-
outOfBandTests.length = 0;
|
|
46
|
-
});
|
|
47
|
-
afterEach(() => {
|
|
48
|
-
outOfBandTests.forEach((fn) => fn());
|
|
49
|
-
});
|
|
50
41
|
|
|
51
42
|
beforeEach(() => {
|
|
52
43
|
// @ts-expect-error we're using a very simple setTimeout mock here
|
|
@@ -54,6 +45,13 @@ describe("pages", () => {
|
|
|
54
45
|
setImmediate(fn);
|
|
55
46
|
});
|
|
56
47
|
});
|
|
48
|
+
afterEach(async () => {
|
|
49
|
+
// Force a tick to ensure that all promises resolve
|
|
50
|
+
await endEventLoop();
|
|
51
|
+
// Reset MSW after tick to ensure that all requests have been handled
|
|
52
|
+
msw.resetHandlers();
|
|
53
|
+
msw.restoreHandlers();
|
|
54
|
+
});
|
|
57
55
|
|
|
58
56
|
it("should should display a list of available subcommands, for pages with no subcommand", async () => {
|
|
59
57
|
await runWrangler("pages");
|
|
@@ -124,28 +122,33 @@ describe("pages", () => {
|
|
|
124
122
|
mockAccountId();
|
|
125
123
|
mockApiToken();
|
|
126
124
|
|
|
127
|
-
afterEach(() => {
|
|
128
|
-
unsetAllMocks();
|
|
129
|
-
});
|
|
130
|
-
|
|
131
125
|
function mockListRequest(projects: unknown[]) {
|
|
132
126
|
const requests = { count: 0 };
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
expect(accountId).toEqual("some-account-id");
|
|
127
|
+
msw.use(
|
|
128
|
+
rest.get(
|
|
129
|
+
"*/accounts/:accountId/pages/projects",
|
|
130
|
+
async (req, res, ctx) => {
|
|
131
|
+
requests.count++;
|
|
132
|
+
const pageSize = Number(req.url.searchParams.get("per_page"));
|
|
133
|
+
const page = Number(req.url.searchParams.get("page"));
|
|
134
|
+
const expectedPageSize = 10;
|
|
135
|
+
const expectedPage = requests.count;
|
|
136
|
+
expect(req.params.accountId).toEqual("some-account-id");
|
|
143
137
|
expect(pageSize).toEqual(expectedPageSize);
|
|
144
138
|
expect(page).toEqual(expectedPage);
|
|
145
|
-
expect(
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
139
|
+
expect(await req.text()).toEqual("");
|
|
140
|
+
|
|
141
|
+
return res(
|
|
142
|
+
ctx.status(200),
|
|
143
|
+
ctx.json({
|
|
144
|
+
success: true,
|
|
145
|
+
errors: [],
|
|
146
|
+
messages: [],
|
|
147
|
+
result: projects.slice((page - 1) * pageSize, page * pageSize),
|
|
148
|
+
})
|
|
149
|
+
);
|
|
150
|
+
}
|
|
151
|
+
)
|
|
149
152
|
);
|
|
150
153
|
return requests;
|
|
151
154
|
}
|
|
@@ -210,29 +213,34 @@ describe("pages", () => {
|
|
|
210
213
|
mockAccountId();
|
|
211
214
|
mockApiToken();
|
|
212
215
|
|
|
213
|
-
afterEach(() => {
|
|
214
|
-
unsetAllMocks();
|
|
215
|
-
});
|
|
216
|
-
|
|
217
216
|
it("should create a project with a production branch", async () => {
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
expect(
|
|
217
|
+
msw.use(
|
|
218
|
+
rest.post(
|
|
219
|
+
"*/accounts/:accountId/pages/projects",
|
|
220
|
+
async (req, res, ctx) => {
|
|
221
|
+
const body = await req.json();
|
|
222
|
+
|
|
223
|
+
expect(req.params.accountId).toEqual("some-account-id");
|
|
225
224
|
expect(body).toEqual({
|
|
226
225
|
name: "a-new-project",
|
|
227
226
|
production_branch: "main",
|
|
228
227
|
});
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
228
|
+
|
|
229
|
+
return res.once(
|
|
230
|
+
ctx.status(200),
|
|
231
|
+
ctx.json({
|
|
232
|
+
success: true,
|
|
233
|
+
errors: [],
|
|
234
|
+
messages: [],
|
|
235
|
+
result: {
|
|
236
|
+
name: "a-new-project",
|
|
237
|
+
subdomain: "a-new-project.pages.dev",
|
|
238
|
+
production_branch: "main",
|
|
239
|
+
},
|
|
240
|
+
})
|
|
241
|
+
);
|
|
242
|
+
}
|
|
243
|
+
)
|
|
236
244
|
);
|
|
237
245
|
await runWrangler(
|
|
238
246
|
"pages project create a-new-project --production-branch=main"
|
|
@@ -248,21 +256,28 @@ describe("pages", () => {
|
|
|
248
256
|
mockAccountId();
|
|
249
257
|
mockApiToken();
|
|
250
258
|
|
|
251
|
-
afterEach(() => {
|
|
252
|
-
unsetAllMocks();
|
|
253
|
-
});
|
|
254
259
|
function mockListRequest(deployments: unknown[]) {
|
|
255
260
|
const requests = { count: 0 };
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
expect(
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
261
|
+
msw.use(
|
|
262
|
+
rest.get(
|
|
263
|
+
"*/accounts/:accountId/pages/projects/:project/deployments",
|
|
264
|
+
(req, res, ctx) => {
|
|
265
|
+
requests.count++;
|
|
266
|
+
|
|
267
|
+
expect(req.params.project).toEqual("images");
|
|
268
|
+
expect(req.params.accountId).toEqual("some-account-id");
|
|
269
|
+
|
|
270
|
+
return res.once(
|
|
271
|
+
ctx.status(200),
|
|
272
|
+
ctx.json({
|
|
273
|
+
success: true,
|
|
274
|
+
errors: [],
|
|
275
|
+
messages: [],
|
|
276
|
+
result: deployments,
|
|
277
|
+
})
|
|
278
|
+
);
|
|
279
|
+
}
|
|
280
|
+
)
|
|
266
281
|
);
|
|
267
282
|
return requests;
|
|
268
283
|
}
|
|
@@ -302,13 +317,13 @@ describe("pages", () => {
|
|
|
302
317
|
mockApiToken();
|
|
303
318
|
runInTempDir();
|
|
304
319
|
|
|
320
|
+
//TODO Abstract MSW handlers that repeat to this level - JACOB
|
|
305
321
|
beforeEach(() => {
|
|
306
322
|
actualProcessEnvCI = process.env.CI;
|
|
307
323
|
process.env.CI = "true";
|
|
308
324
|
});
|
|
309
325
|
|
|
310
326
|
afterEach(() => {
|
|
311
|
-
unsetAllMocks();
|
|
312
327
|
process.env.CI = actualProcessEnvCI;
|
|
313
328
|
});
|
|
314
329
|
|
|
@@ -343,33 +358,34 @@ describe("pages", () => {
|
|
|
343
358
|
|
|
344
359
|
it("should upload a directory of files", async () => {
|
|
345
360
|
writeFileSync("logo.png", "foobar");
|
|
346
|
-
|
|
347
361
|
mockGetToken("<<funfetti-auth-jwt>>");
|
|
348
362
|
|
|
349
|
-
|
|
350
|
-
"
|
|
351
|
-
|
|
352
|
-
async (_, init) => {
|
|
353
|
-
const body = JSON.parse(init.body as string) as { hashes: string[] };
|
|
354
|
-
assertLater(() => {
|
|
355
|
-
expect(init.headers).toMatchObject({
|
|
356
|
-
Authorization: "Bearer <<funfetti-auth-jwt>>",
|
|
357
|
-
});
|
|
358
|
-
expect(body).toMatchObject({
|
|
359
|
-
hashes: ["2082190357cfd3617ccfe04f340c6247"],
|
|
360
|
-
});
|
|
361
|
-
});
|
|
362
|
-
return body.hashes;
|
|
363
|
-
}
|
|
364
|
-
);
|
|
363
|
+
msw.use(
|
|
364
|
+
rest.post("*/pages/assets/check-missing", async (req, res, ctx) => {
|
|
365
|
+
const body = await req.json();
|
|
365
366
|
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
367
|
+
expect(req.headers.get("Authorization")).toBe(
|
|
368
|
+
"Bearer <<funfetti-auth-jwt>>"
|
|
369
|
+
);
|
|
370
|
+
expect(body).toMatchObject({
|
|
371
|
+
hashes: ["2082190357cfd3617ccfe04f340c6247"],
|
|
370
372
|
});
|
|
371
|
-
|
|
372
|
-
|
|
373
|
+
|
|
374
|
+
return res.once(
|
|
375
|
+
ctx.status(200),
|
|
376
|
+
ctx.json({
|
|
377
|
+
success: true,
|
|
378
|
+
errors: [],
|
|
379
|
+
messages: [],
|
|
380
|
+
result: body.hashes,
|
|
381
|
+
})
|
|
382
|
+
);
|
|
383
|
+
}),
|
|
384
|
+
rest.post("*/pages/assets/upload", async (req, res, ctx) => {
|
|
385
|
+
expect(req.headers.get("Authorization")).toMatchInlineSnapshot(
|
|
386
|
+
`"Bearer <<funfetti-auth-jwt>>"`
|
|
387
|
+
);
|
|
388
|
+
expect(await req.json()).toMatchObject([
|
|
373
389
|
{
|
|
374
390
|
key: "2082190357cfd3617ccfe04f340c6247",
|
|
375
391
|
value: Buffer.from("foobar").toString("base64"),
|
|
@@ -379,39 +395,55 @@ describe("pages", () => {
|
|
|
379
395
|
base64: true,
|
|
380
396
|
},
|
|
381
397
|
]);
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
expect(
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
return {
|
|
401
|
-
url: "https://abcxyz.foo.pages.dev/",
|
|
402
|
-
};
|
|
403
|
-
}
|
|
404
|
-
);
|
|
405
|
-
|
|
406
|
-
setMockResponse(
|
|
407
|
-
"/accounts/:accountId/pages/projects/foo",
|
|
408
|
-
"GET",
|
|
409
|
-
async ([_url, accountId]) => {
|
|
410
|
-
assertLater(() => {
|
|
411
|
-
expect(accountId).toEqual("some-account-id");
|
|
412
|
-
});
|
|
413
|
-
return { deployment_configs: { production: {}, preview: {} } };
|
|
398
|
+
return res.once(
|
|
399
|
+
ctx.status(200),
|
|
400
|
+
ctx.json({ success: true, errors: [], messages: [], result: null })
|
|
401
|
+
);
|
|
402
|
+
}),
|
|
403
|
+
rest.post(
|
|
404
|
+
"*/accounts/:accountId/pages/projects/foo/deployments",
|
|
405
|
+
async (req, res, ctx) => {
|
|
406
|
+
expect(req.params.accountId).toEqual("some-account-id");
|
|
407
|
+
expect(await (req as RestRequestWithFormData).formData())
|
|
408
|
+
.toMatchInlineSnapshot(`
|
|
409
|
+
FormData {
|
|
410
|
+
Symbol(state): Array [
|
|
411
|
+
Object {
|
|
412
|
+
"name": "manifest",
|
|
413
|
+
"value": "{\\"/logo.png\\":\\"2082190357cfd3617ccfe04f340c6247\\"}",
|
|
414
|
+
},
|
|
415
|
+
],
|
|
414
416
|
}
|
|
417
|
+
`);
|
|
418
|
+
return res.once(
|
|
419
|
+
ctx.status(200),
|
|
420
|
+
ctx.json({
|
|
421
|
+
success: true,
|
|
422
|
+
errors: [],
|
|
423
|
+
messages: [],
|
|
424
|
+
result: {
|
|
425
|
+
url: "https://abcxyz.foo.pages.dev/",
|
|
426
|
+
},
|
|
427
|
+
})
|
|
428
|
+
);
|
|
429
|
+
}
|
|
430
|
+
),
|
|
431
|
+
rest.get(
|
|
432
|
+
"*/accounts/:accountId/pages/projects/foo",
|
|
433
|
+
async (req, res, ctx) => {
|
|
434
|
+
expect(req.params.accountId).toEqual("some-account-id");
|
|
435
|
+
|
|
436
|
+
return res.once(
|
|
437
|
+
ctx.status(200),
|
|
438
|
+
ctx.json({
|
|
439
|
+
success: true,
|
|
440
|
+
errors: [],
|
|
441
|
+
messages: [],
|
|
442
|
+
result: { deployment_configs: { production: {}, preview: {} } },
|
|
443
|
+
})
|
|
444
|
+
);
|
|
445
|
+
}
|
|
446
|
+
)
|
|
415
447
|
);
|
|
416
448
|
|
|
417
449
|
await runWrangler("pages publish . --project-name=foo");
|
|
@@ -428,84 +460,35 @@ describe("pages", () => {
|
|
|
428
460
|
|
|
429
461
|
mockGetToken("<<funfetti-auth-jwt>>");
|
|
430
462
|
|
|
431
|
-
setMockResponse(
|
|
432
|
-
"/pages/assets/check-missing",
|
|
433
|
-
"POST",
|
|
434
|
-
async (_, init) => {
|
|
435
|
-
const body = JSON.parse(init.body as string) as { hashes: string[] };
|
|
436
|
-
assertLater(() => {
|
|
437
|
-
expect(init.headers).toMatchObject({
|
|
438
|
-
Authorization: "Bearer <<funfetti-auth-jwt>>",
|
|
439
|
-
});
|
|
440
|
-
expect(body).toMatchObject({
|
|
441
|
-
hashes: ["1a98fb08af91aca4a7df1764a2c4ddb0"],
|
|
442
|
-
});
|
|
443
|
-
});
|
|
444
|
-
return body.hashes;
|
|
445
|
-
}
|
|
446
|
-
);
|
|
447
|
-
|
|
448
463
|
// Accumulate multiple requests then assert afterwards
|
|
449
|
-
const requests:
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
if (requests.length < 2) {
|
|
454
|
-
return createFetchResult(null, false, [
|
|
455
|
-
{
|
|
456
|
-
code: 800000,
|
|
457
|
-
message: "Something exploded, please retry",
|
|
458
|
-
},
|
|
459
|
-
]);
|
|
460
|
-
} else {
|
|
461
|
-
return createFetchResult(null, true);
|
|
462
|
-
}
|
|
463
|
-
});
|
|
464
|
-
|
|
465
|
-
setMockResponse(
|
|
466
|
-
"/accounts/:accountId/pages/projects/foo/deployments",
|
|
467
|
-
async ([_url, accountId], init) => {
|
|
468
|
-
assertLater(() => {
|
|
469
|
-
expect(accountId).toEqual("some-account-id");
|
|
470
|
-
expect(init.method).toEqual("POST");
|
|
471
|
-
const body = init.body as FormData;
|
|
472
|
-
const manifest = JSON.parse(body.get("manifest") as string);
|
|
473
|
-
expect(manifest).toMatchInlineSnapshot(`
|
|
474
|
-
Object {
|
|
475
|
-
"/logo.txt": "1a98fb08af91aca4a7df1764a2c4ddb0",
|
|
476
|
-
}
|
|
477
|
-
`);
|
|
478
|
-
});
|
|
479
|
-
|
|
480
|
-
return {
|
|
481
|
-
url: "https://abcxyz.foo.pages.dev/",
|
|
482
|
-
};
|
|
483
|
-
}
|
|
484
|
-
);
|
|
485
|
-
|
|
486
|
-
setMockResponse(
|
|
487
|
-
"/accounts/:accountId/pages/projects/foo",
|
|
488
|
-
"GET",
|
|
489
|
-
async ([_url, accountId]) => {
|
|
490
|
-
assertLater(() => {
|
|
491
|
-
expect(accountId).toEqual("some-account-id");
|
|
492
|
-
});
|
|
493
|
-
return { deployment_configs: { production: {}, preview: {} } };
|
|
494
|
-
}
|
|
495
|
-
);
|
|
496
|
-
|
|
497
|
-
await runWrangler("pages publish . --project-name=foo");
|
|
464
|
+
const requests: RestRequest[] = [];
|
|
465
|
+
msw.use(
|
|
466
|
+
rest.post("*/pages/assets/check-missing", async (req, res, ctx) => {
|
|
467
|
+
const body = await req.json();
|
|
498
468
|
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
Authorization: "Bearer <<funfetti-auth-jwt>>",
|
|
469
|
+
expect(req.headers.get("Authorization")).toBe(
|
|
470
|
+
"Bearer <<funfetti-auth-jwt>>"
|
|
471
|
+
);
|
|
472
|
+
expect(body).toMatchObject({
|
|
473
|
+
hashes: ["1a98fb08af91aca4a7df1764a2c4ddb0"],
|
|
505
474
|
});
|
|
506
475
|
|
|
507
|
-
|
|
508
|
-
|
|
476
|
+
return res.once(
|
|
477
|
+
ctx.status(200),
|
|
478
|
+
ctx.json({
|
|
479
|
+
success: true,
|
|
480
|
+
errors: [],
|
|
481
|
+
messages: [],
|
|
482
|
+
result: body.hashes,
|
|
483
|
+
})
|
|
484
|
+
);
|
|
485
|
+
}),
|
|
486
|
+
rest.post("*/pages/assets/upload", async (req, res, ctx) => {
|
|
487
|
+
requests.push(req);
|
|
488
|
+
expect(req.headers.get("Authorization")).toBe(
|
|
489
|
+
"Bearer <<funfetti-auth-jwt>>"
|
|
490
|
+
);
|
|
491
|
+
expect(await req.json()).toMatchObject([
|
|
509
492
|
{
|
|
510
493
|
key: "1a98fb08af91aca4a7df1764a2c4ddb0",
|
|
511
494
|
value: Buffer.from("foobar").toString("base64"),
|
|
@@ -515,8 +498,80 @@ describe("pages", () => {
|
|
|
515
498
|
base64: true,
|
|
516
499
|
},
|
|
517
500
|
]);
|
|
518
|
-
|
|
519
|
-
|
|
501
|
+
|
|
502
|
+
if (requests.length < 2) {
|
|
503
|
+
return res(
|
|
504
|
+
ctx.status(200),
|
|
505
|
+
ctx.json({
|
|
506
|
+
success: false,
|
|
507
|
+
errors: [
|
|
508
|
+
{
|
|
509
|
+
code: 800000,
|
|
510
|
+
message: "Something exploded, please retry",
|
|
511
|
+
},
|
|
512
|
+
],
|
|
513
|
+
messages: [],
|
|
514
|
+
result: null,
|
|
515
|
+
})
|
|
516
|
+
);
|
|
517
|
+
} else {
|
|
518
|
+
return res(
|
|
519
|
+
ctx.status(200),
|
|
520
|
+
ctx.json({
|
|
521
|
+
success: true,
|
|
522
|
+
errors: [],
|
|
523
|
+
messages: [],
|
|
524
|
+
result: null,
|
|
525
|
+
})
|
|
526
|
+
);
|
|
527
|
+
}
|
|
528
|
+
}),
|
|
529
|
+
rest.post(
|
|
530
|
+
"*/accounts/:accountId/pages/projects/foo/deployments",
|
|
531
|
+
async (req, res, ctx) => {
|
|
532
|
+
expect(req.params.accountId).toEqual("some-account-id");
|
|
533
|
+
expect(await (req as RestRequestWithFormData).formData())
|
|
534
|
+
.toMatchInlineSnapshot(`
|
|
535
|
+
FormData {
|
|
536
|
+
Symbol(state): Array [
|
|
537
|
+
Object {
|
|
538
|
+
"name": "manifest",
|
|
539
|
+
"value": "{\\"/logo.txt\\":\\"1a98fb08af91aca4a7df1764a2c4ddb0\\"}",
|
|
540
|
+
},
|
|
541
|
+
],
|
|
542
|
+
}
|
|
543
|
+
`);
|
|
544
|
+
|
|
545
|
+
return res.once(
|
|
546
|
+
ctx.status(200),
|
|
547
|
+
ctx.json({
|
|
548
|
+
success: true,
|
|
549
|
+
errors: [],
|
|
550
|
+
messages: [],
|
|
551
|
+
result: { url: "https://abcxyz.foo.pages.dev/" },
|
|
552
|
+
})
|
|
553
|
+
);
|
|
554
|
+
}
|
|
555
|
+
),
|
|
556
|
+
rest.get(
|
|
557
|
+
"*/accounts/:accountId/pages/projects/foo",
|
|
558
|
+
async (req, res, ctx) => {
|
|
559
|
+
expect(req.params.accountId).toEqual("some-account-id");
|
|
560
|
+
|
|
561
|
+
return res.once(
|
|
562
|
+
ctx.status(200),
|
|
563
|
+
ctx.json({
|
|
564
|
+
success: true,
|
|
565
|
+
errors: [],
|
|
566
|
+
messages: [],
|
|
567
|
+
result: { deployment_configs: { production: {}, preview: {} } },
|
|
568
|
+
})
|
|
569
|
+
);
|
|
570
|
+
}
|
|
571
|
+
)
|
|
572
|
+
);
|
|
573
|
+
|
|
574
|
+
await runWrangler("pages publish . --project-name=foo");
|
|
520
575
|
|
|
521
576
|
expect(std.out).toMatchInlineSnapshot(`
|
|
522
577
|
"✨ Success! Uploaded 1 files (TIMINGS)
|
|
@@ -527,104 +582,125 @@ describe("pages", () => {
|
|
|
527
582
|
|
|
528
583
|
it("should refetch a JWT if it expires while uploading", async () => {
|
|
529
584
|
writeFileSync("logo.txt", "foobar");
|
|
585
|
+
mockGetToken("<<funfetti-auth-jwt>>");
|
|
530
586
|
|
|
531
|
-
const
|
|
587
|
+
const requests: RestRequest[] = [];
|
|
588
|
+
msw.use(
|
|
589
|
+
rest.post("*/pages/assets/check-missing", async (req, res, ctx) => {
|
|
590
|
+
const body = (await req.json()) as { hashes: string[] };
|
|
532
591
|
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
assertLater(() => {
|
|
539
|
-
expect(init.headers).toMatchObject({
|
|
540
|
-
Authorization: "Bearer <<funfetti-auth-jwt>>",
|
|
541
|
-
});
|
|
542
|
-
expect(body).toMatchObject({
|
|
543
|
-
hashes: ["1a98fb08af91aca4a7df1764a2c4ddb0"],
|
|
544
|
-
});
|
|
592
|
+
expect(req.headers.get("Authorization")).toBe(
|
|
593
|
+
"Bearer <<funfetti-auth-jwt>>"
|
|
594
|
+
);
|
|
595
|
+
expect(body).toMatchObject({
|
|
596
|
+
hashes: ["1a98fb08af91aca4a7df1764a2c4ddb0"],
|
|
545
597
|
});
|
|
546
|
-
return body.hashes;
|
|
547
|
-
}
|
|
548
|
-
);
|
|
549
598
|
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
599
|
+
return res.once(
|
|
600
|
+
ctx.status(200),
|
|
601
|
+
ctx.json({
|
|
602
|
+
success: true,
|
|
603
|
+
errors: [],
|
|
604
|
+
messages: [],
|
|
605
|
+
result: body.hashes,
|
|
606
|
+
})
|
|
607
|
+
);
|
|
608
|
+
}),
|
|
609
|
+
rest.post("*/pages/assets/upload", async (req, res, ctx) => {
|
|
610
|
+
requests.push(req);
|
|
611
|
+
expect(await req.json()).toMatchObject([
|
|
560
612
|
{
|
|
561
|
-
|
|
562
|
-
|
|
613
|
+
key: "1a98fb08af91aca4a7df1764a2c4ddb0",
|
|
614
|
+
value: Buffer.from("foobar").toString("base64"),
|
|
615
|
+
metadata: {
|
|
616
|
+
contentType: "text/plain",
|
|
617
|
+
},
|
|
618
|
+
base64: true,
|
|
563
619
|
},
|
|
564
620
|
]);
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
621
|
+
// Fail just the first request
|
|
622
|
+
if (requests.length < 2) {
|
|
623
|
+
mockGetToken("<<funfetti-auth-jwt2>>");
|
|
624
|
+
return res(
|
|
625
|
+
ctx.status(200),
|
|
626
|
+
ctx.json({
|
|
627
|
+
success: false,
|
|
628
|
+
errors: [
|
|
629
|
+
{
|
|
630
|
+
code: 8000013,
|
|
631
|
+
message: "Authorization failed",
|
|
632
|
+
},
|
|
633
|
+
],
|
|
634
|
+
messages: [],
|
|
635
|
+
result: null,
|
|
636
|
+
})
|
|
637
|
+
);
|
|
638
|
+
} else {
|
|
639
|
+
return res(
|
|
640
|
+
ctx.status(200),
|
|
641
|
+
ctx.json({
|
|
642
|
+
success: true,
|
|
643
|
+
errors: [],
|
|
644
|
+
messages: [],
|
|
645
|
+
result: null,
|
|
646
|
+
})
|
|
647
|
+
);
|
|
648
|
+
}
|
|
649
|
+
}),
|
|
650
|
+
rest.post(
|
|
651
|
+
"*/accounts/:accountId/pages/projects/foo/deployments",
|
|
652
|
+
async (req, res, ctx) => {
|
|
653
|
+
expect(req.params.accountId).toEqual("some-account-id");
|
|
654
|
+
expect(await (req as RestRequestWithFormData).formData())
|
|
655
|
+
.toMatchInlineSnapshot(`
|
|
656
|
+
FormData {
|
|
657
|
+
Symbol(state): Array [
|
|
658
|
+
Object {
|
|
659
|
+
"name": "manifest",
|
|
660
|
+
"value": "{\\"/logo.txt\\":\\"1a98fb08af91aca4a7df1764a2c4ddb0\\"}",
|
|
661
|
+
},
|
|
662
|
+
],
|
|
588
663
|
}
|
|
589
|
-
);
|
|
664
|
+
`);
|
|
590
665
|
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
666
|
+
return res.once(
|
|
667
|
+
ctx.status(200),
|
|
668
|
+
ctx.json({
|
|
669
|
+
success: true,
|
|
670
|
+
errors: [],
|
|
671
|
+
messages: [],
|
|
672
|
+
result: { url: "https://abcxyz.foo.pages.dev/" },
|
|
673
|
+
})
|
|
674
|
+
);
|
|
675
|
+
}
|
|
676
|
+
),
|
|
677
|
+
rest.get(
|
|
678
|
+
"*/accounts/:accountId/pages/projects/foo",
|
|
679
|
+
async (req, res, ctx) => {
|
|
680
|
+
expect(req.params.accountId).toEqual("some-account-id");
|
|
681
|
+
|
|
682
|
+
return res.once(
|
|
683
|
+
ctx.status(200),
|
|
684
|
+
ctx.json({
|
|
685
|
+
success: true,
|
|
686
|
+
errors: [],
|
|
687
|
+
messages: [],
|
|
688
|
+
result: { deployment_configs: { production: {}, preview: {} } },
|
|
689
|
+
})
|
|
690
|
+
);
|
|
691
|
+
}
|
|
692
|
+
)
|
|
600
693
|
);
|
|
601
694
|
|
|
602
695
|
await runWrangler("pages publish . --project-name=foo");
|
|
603
696
|
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
expect(requests[0].headers).toMatchObject({
|
|
608
|
-
Authorization: "Bearer <<funfetti-auth-jwt>>",
|
|
609
|
-
});
|
|
610
|
-
|
|
611
|
-
expect(requests[1].headers).toMatchObject({
|
|
612
|
-
Authorization: "Bearer <<funfetti-auth-jwt2>>",
|
|
613
|
-
});
|
|
697
|
+
expect(requests[0].headers.get("Authorization")).toBe(
|
|
698
|
+
"Bearer <<funfetti-auth-jwt>>"
|
|
699
|
+
);
|
|
614
700
|
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
{
|
|
619
|
-
key: "1a98fb08af91aca4a7df1764a2c4ddb0",
|
|
620
|
-
value: Buffer.from("foobar").toString("base64"),
|
|
621
|
-
metadata: {
|
|
622
|
-
contentType: "text/plain",
|
|
623
|
-
},
|
|
624
|
-
base64: true,
|
|
625
|
-
},
|
|
626
|
-
]);
|
|
627
|
-
}
|
|
701
|
+
expect(requests[1].headers.get("Authorization")).toBe(
|
|
702
|
+
"Bearer <<funfetti-auth-jwt2>>"
|
|
703
|
+
);
|
|
628
704
|
|
|
629
705
|
expect(std.out).toMatchInlineSnapshot(`
|
|
630
706
|
"✨ Success! Uploaded 1 files (TIMINGS)
|
|
@@ -641,80 +717,110 @@ describe("pages", () => {
|
|
|
641
717
|
|
|
642
718
|
mockGetToken("<<funfetti-auth-jwt>>");
|
|
643
719
|
|
|
644
|
-
setMockResponse(
|
|
645
|
-
"/pages/assets/check-missing",
|
|
646
|
-
"POST",
|
|
647
|
-
async (_, init) => {
|
|
648
|
-
const body = JSON.parse(init.body as string) as { hashes: string[] };
|
|
649
|
-
assertLater(() => {
|
|
650
|
-
expect(init.headers).toMatchObject({
|
|
651
|
-
Authorization: "Bearer <<funfetti-auth-jwt>>",
|
|
652
|
-
});
|
|
653
|
-
expect(body).toMatchObject({
|
|
654
|
-
hashes: expect.arrayContaining([
|
|
655
|
-
"d96fef225537c9f5e44a3cb27fd0b492",
|
|
656
|
-
"2082190357cfd3617ccfe04f340c6247",
|
|
657
|
-
"6be321bef99e758250dac034474ddbb8",
|
|
658
|
-
"1a98fb08af91aca4a7df1764a2c4ddb0",
|
|
659
|
-
]),
|
|
660
|
-
});
|
|
661
|
-
});
|
|
662
|
-
return body.hashes;
|
|
663
|
-
}
|
|
664
|
-
);
|
|
665
|
-
|
|
666
720
|
// Accumulate multiple requests then assert afterwards
|
|
667
|
-
const requests:
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
721
|
+
const requests: RestRequest[] = [];
|
|
722
|
+
const bodies: UploadPayloadFile[][] = [];
|
|
723
|
+
msw.use(
|
|
724
|
+
rest.post("*/pages/assets/check-missing", async (req, res, ctx) => {
|
|
725
|
+
const body = (await req.json()) as {
|
|
726
|
+
hashes: string[];
|
|
727
|
+
};
|
|
671
728
|
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
expect
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
"/logo.html": "d96fef225537c9f5e44a3cb27fd0b492",
|
|
683
|
-
"/logo.js": "6be321bef99e758250dac034474ddbb8",
|
|
684
|
-
"/logo.png": "2082190357cfd3617ccfe04f340c6247",
|
|
685
|
-
"/logo.txt": "1a98fb08af91aca4a7df1764a2c4ddb0",
|
|
686
|
-
}
|
|
687
|
-
`);
|
|
729
|
+
expect(req.headers.get("Authorization")).toBe(
|
|
730
|
+
"Bearer <<funfetti-auth-jwt>>"
|
|
731
|
+
);
|
|
732
|
+
expect(body).toMatchObject({
|
|
733
|
+
hashes: expect.arrayContaining([
|
|
734
|
+
"d96fef225537c9f5e44a3cb27fd0b492",
|
|
735
|
+
"2082190357cfd3617ccfe04f340c6247",
|
|
736
|
+
"6be321bef99e758250dac034474ddbb8",
|
|
737
|
+
"1a98fb08af91aca4a7df1764a2c4ddb0",
|
|
738
|
+
]),
|
|
688
739
|
});
|
|
689
740
|
|
|
690
|
-
return
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
741
|
+
return res.once(
|
|
742
|
+
ctx.status(200),
|
|
743
|
+
ctx.json({
|
|
744
|
+
success: true,
|
|
745
|
+
errors: [],
|
|
746
|
+
messages: [],
|
|
747
|
+
result: body.hashes,
|
|
748
|
+
})
|
|
749
|
+
);
|
|
750
|
+
}),
|
|
751
|
+
rest.post("*/pages/assets/upload", async (req, res, ctx) => {
|
|
752
|
+
requests.push(req);
|
|
695
753
|
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
754
|
+
expect(req.headers.get("Authorization")).toBe(
|
|
755
|
+
"Bearer <<funfetti-auth-jwt>>"
|
|
756
|
+
);
|
|
757
|
+
bodies.push((await req.json()) as UploadPayloadFile[]);
|
|
758
|
+
|
|
759
|
+
return res(
|
|
760
|
+
ctx.status(200),
|
|
761
|
+
ctx.json({
|
|
762
|
+
success: true,
|
|
763
|
+
errors: [],
|
|
764
|
+
messages: [],
|
|
765
|
+
result: null,
|
|
766
|
+
})
|
|
767
|
+
);
|
|
768
|
+
}),
|
|
769
|
+
rest.post(
|
|
770
|
+
"*/accounts/:accountId/pages/projects/foo/deployments",
|
|
771
|
+
async (req, res, ctx) => {
|
|
772
|
+
expect(req.params.accountId).toEqual("some-account-id");
|
|
773
|
+
|
|
774
|
+
const body = await (req as RestRequestWithFormData).formData();
|
|
775
|
+
const manifest = JSON.parse(body.get("manifest") as string);
|
|
776
|
+
|
|
777
|
+
expect(manifest).toMatchInlineSnapshot(`
|
|
778
|
+
Object {
|
|
779
|
+
"/logo.html": "d96fef225537c9f5e44a3cb27fd0b492",
|
|
780
|
+
"/logo.js": "6be321bef99e758250dac034474ddbb8",
|
|
781
|
+
"/logo.png": "2082190357cfd3617ccfe04f340c6247",
|
|
782
|
+
"/logo.txt": "1a98fb08af91aca4a7df1764a2c4ddb0",
|
|
783
|
+
}
|
|
784
|
+
`);
|
|
785
|
+
|
|
786
|
+
return res.once(
|
|
787
|
+
ctx.status(200),
|
|
788
|
+
ctx.json({
|
|
789
|
+
success: true,
|
|
790
|
+
errors: [],
|
|
791
|
+
messages: [],
|
|
792
|
+
result: {
|
|
793
|
+
url: "https://abcxyz.foo.pages.dev/",
|
|
794
|
+
},
|
|
795
|
+
})
|
|
796
|
+
);
|
|
797
|
+
}
|
|
798
|
+
),
|
|
799
|
+
rest.get(
|
|
800
|
+
"*/accounts/:accountId/pages/projects/foo",
|
|
801
|
+
async (req, res, ctx) => {
|
|
802
|
+
expect(req.params.accountId).toEqual("some-account-id");
|
|
803
|
+
|
|
804
|
+
return res.once(
|
|
805
|
+
ctx.status(200),
|
|
806
|
+
ctx.json({
|
|
807
|
+
success: true,
|
|
808
|
+
errors: [],
|
|
809
|
+
messages: [],
|
|
810
|
+
result: {
|
|
811
|
+
deployment_configs: { production: {}, preview: {} },
|
|
812
|
+
},
|
|
813
|
+
})
|
|
814
|
+
);
|
|
815
|
+
}
|
|
816
|
+
)
|
|
705
817
|
);
|
|
706
818
|
|
|
707
819
|
await runWrangler("pages publish . --project-name=foo");
|
|
708
820
|
|
|
709
821
|
// We have 3 buckets, so expect 3 uploads
|
|
710
822
|
expect(requests.length).toBe(3);
|
|
711
|
-
|
|
712
|
-
for (const init of requests) {
|
|
713
|
-
expect(init.headers).toMatchObject({
|
|
714
|
-
Authorization: "Bearer <<funfetti-auth-jwt>>",
|
|
715
|
-
});
|
|
716
|
-
bodies.push(JSON.parse(init.body as string) as UploadPayloadFile[]);
|
|
717
|
-
}
|
|
823
|
+
|
|
718
824
|
// One bucket should end up with 2 files
|
|
719
825
|
expect(bodies.map((b) => b.length).sort()).toEqual([1, 1, 2]);
|
|
720
826
|
// But we don't know the order, so flatten and test without ordering
|
|
@@ -764,82 +870,105 @@ describe("pages", () => {
|
|
|
764
870
|
|
|
765
871
|
mockGetToken("<<funfetti-auth-jwt>>");
|
|
766
872
|
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
873
|
+
// Accumulate multiple requests then assert afterwards
|
|
874
|
+
const requests: RestRequest[] = [];
|
|
875
|
+
const bodies: UploadPayloadFile[][] = [];
|
|
876
|
+
msw.use(
|
|
877
|
+
rest.post("*/pages/assets/check-missing", async (req, res, ctx) => {
|
|
878
|
+
const body = (await req.json()) as {
|
|
772
879
|
hashes: string[];
|
|
773
880
|
};
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
});
|
|
881
|
+
|
|
882
|
+
expect(req.headers.get("Authorization")).toBe(
|
|
883
|
+
"Bearer <<funfetti-auth-jwt>>"
|
|
884
|
+
);
|
|
885
|
+
expect(body).toMatchObject({
|
|
886
|
+
hashes: expect.arrayContaining([
|
|
887
|
+
"d96fef225537c9f5e44a3cb27fd0b492",
|
|
888
|
+
"2082190357cfd3617ccfe04f340c6247",
|
|
889
|
+
"6be321bef99e758250dac034474ddbb8",
|
|
890
|
+
"1a98fb08af91aca4a7df1764a2c4ddb0",
|
|
891
|
+
]),
|
|
786
892
|
});
|
|
787
|
-
return body.hashes;
|
|
788
|
-
}
|
|
789
|
-
);
|
|
790
893
|
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
894
|
+
return res.once(
|
|
895
|
+
ctx.status(200),
|
|
896
|
+
ctx.json({
|
|
897
|
+
success: true,
|
|
898
|
+
errors: [],
|
|
899
|
+
messages: [],
|
|
900
|
+
result: body.hashes,
|
|
901
|
+
})
|
|
902
|
+
);
|
|
903
|
+
}),
|
|
904
|
+
rest.post("*/pages/assets/upload", async (req, res, ctx) => {
|
|
905
|
+
requests.push(req);
|
|
796
906
|
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
907
|
+
expect(req.headers.get("Authorization")).toBe(
|
|
908
|
+
"Bearer <<funfetti-auth-jwt>>"
|
|
909
|
+
);
|
|
910
|
+
bodies.push((await req.json()) as UploadPayloadFile[]);
|
|
911
|
+
|
|
912
|
+
return res(
|
|
913
|
+
ctx.status(200),
|
|
914
|
+
ctx.json({
|
|
915
|
+
success: true,
|
|
916
|
+
errors: [],
|
|
917
|
+
messages: [],
|
|
918
|
+
result: null,
|
|
919
|
+
})
|
|
920
|
+
);
|
|
921
|
+
}),
|
|
922
|
+
rest.post(
|
|
923
|
+
"*/accounts/:accountId/pages/projects/foo/deployments",
|
|
924
|
+
async (req, res, ctx) => {
|
|
925
|
+
expect(req.params.accountId).toEqual("some-account-id");
|
|
926
|
+
const body = await (req as RestRequestWithFormData).formData();
|
|
804
927
|
const manifest = JSON.parse(body.get("manifest") as string);
|
|
805
928
|
expect(manifest).toMatchInlineSnapshot(`
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
929
|
+
Object {
|
|
930
|
+
"/imgs/logo.png": "2082190357cfd3617ccfe04f340c6247",
|
|
931
|
+
"/logo.html": "d96fef225537c9f5e44a3cb27fd0b492",
|
|
932
|
+
"/logo.js": "6be321bef99e758250dac034474ddbb8",
|
|
933
|
+
"/logo.txt": "1a98fb08af91aca4a7df1764a2c4ddb0",
|
|
934
|
+
}
|
|
935
|
+
`);
|
|
936
|
+
|
|
937
|
+
return res.once(
|
|
938
|
+
ctx.status(200),
|
|
939
|
+
ctx.json({
|
|
940
|
+
success: true,
|
|
941
|
+
errors: [],
|
|
942
|
+
messages: [],
|
|
943
|
+
result: { url: "https://abcxyz.foo.pages.dev/" },
|
|
944
|
+
})
|
|
945
|
+
);
|
|
946
|
+
}
|
|
947
|
+
),
|
|
948
|
+
rest.get(
|
|
949
|
+
"*/accounts/:accountId/pages/projects/foo",
|
|
950
|
+
async (req, res, ctx) => {
|
|
951
|
+
expect(req.params.accountId).toEqual("some-account-id");
|
|
952
|
+
|
|
953
|
+
return res.once(
|
|
954
|
+
ctx.status(200),
|
|
955
|
+
ctx.json({
|
|
956
|
+
success: true,
|
|
957
|
+
errors: [],
|
|
958
|
+
messages: [],
|
|
959
|
+
result: {
|
|
960
|
+
deployment_configs: { production: {}, preview: {} },
|
|
961
|
+
},
|
|
962
|
+
})
|
|
963
|
+
);
|
|
964
|
+
}
|
|
965
|
+
)
|
|
830
966
|
);
|
|
831
967
|
|
|
832
968
|
await runWrangler(`pages publish public --project-name=foo`);
|
|
833
969
|
|
|
834
970
|
// We have 3 buckets, so expect 3 uploads
|
|
835
971
|
expect(requests.length).toBe(3);
|
|
836
|
-
const bodies: UploadPayloadFile[][] = [];
|
|
837
|
-
for (const init of requests) {
|
|
838
|
-
expect(init.headers).toMatchObject({
|
|
839
|
-
Authorization: "Bearer <<funfetti-auth-jwt>>",
|
|
840
|
-
});
|
|
841
|
-
bodies.push(JSON.parse(init.body as string) as UploadPayloadFile[]);
|
|
842
|
-
}
|
|
843
972
|
// One bucket should end up with 2 files
|
|
844
973
|
expect(bodies.map((b) => b.length).sort()).toEqual([1, 1, 2]);
|
|
845
974
|
// But we don't know the order, so flatten and test without ordering
|
|
@@ -889,83 +1018,106 @@ describe("pages", () => {
|
|
|
889
1018
|
|
|
890
1019
|
mockGetToken("<<funfetti-auth-jwt>>");
|
|
891
1020
|
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
1021
|
+
// Accumulate multiple requests then assert afterwards
|
|
1022
|
+
const requests: RestRequest[] = [];
|
|
1023
|
+
const bodies: UploadPayloadFile[][] = [];
|
|
1024
|
+
msw.use(
|
|
1025
|
+
rest.post("*/pages/assets/check-missing", async (req, res, ctx) => {
|
|
1026
|
+
const body = (await req.json()) as {
|
|
897
1027
|
hashes: string[];
|
|
898
1028
|
};
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
});
|
|
1029
|
+
|
|
1030
|
+
expect(req.headers.get("Authorization")).toBe(
|
|
1031
|
+
"Bearer <<funfetti-auth-jwt>>"
|
|
1032
|
+
);
|
|
1033
|
+
expect(body).toMatchObject({
|
|
1034
|
+
hashes: expect.arrayContaining([
|
|
1035
|
+
"d96fef225537c9f5e44a3cb27fd0b492",
|
|
1036
|
+
"2082190357cfd3617ccfe04f340c6247",
|
|
1037
|
+
"6be321bef99e758250dac034474ddbb8",
|
|
1038
|
+
"1a98fb08af91aca4a7df1764a2c4ddb0",
|
|
1039
|
+
]),
|
|
911
1040
|
});
|
|
912
|
-
return body.hashes;
|
|
913
|
-
}
|
|
914
|
-
);
|
|
915
1041
|
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
1042
|
+
return res.once(
|
|
1043
|
+
ctx.status(200),
|
|
1044
|
+
ctx.json({
|
|
1045
|
+
success: true,
|
|
1046
|
+
errors: [],
|
|
1047
|
+
messages: [],
|
|
1048
|
+
result: body.hashes,
|
|
1049
|
+
})
|
|
1050
|
+
);
|
|
1051
|
+
}),
|
|
1052
|
+
rest.post("*/pages/assets/upload", async (req, res, ctx) => {
|
|
1053
|
+
requests.push(req);
|
|
1054
|
+
|
|
1055
|
+
expect(req.headers.get("Authorization")).toBe(
|
|
1056
|
+
"Bearer <<funfetti-auth-jwt>>"
|
|
1057
|
+
);
|
|
1058
|
+
bodies.push((await req.json()) as UploadPayloadFile[]);
|
|
1059
|
+
|
|
1060
|
+
return res(
|
|
1061
|
+
ctx.status(200),
|
|
1062
|
+
ctx.json({
|
|
1063
|
+
success: true,
|
|
1064
|
+
errors: [],
|
|
1065
|
+
messages: [],
|
|
1066
|
+
result: null,
|
|
1067
|
+
})
|
|
1068
|
+
);
|
|
1069
|
+
}),
|
|
1070
|
+
rest.post(
|
|
1071
|
+
"*/accounts/:accountId/pages/projects/foo/deployments",
|
|
1072
|
+
async (req, res, ctx) => {
|
|
1073
|
+
expect(req.params.accountId).toEqual("some-account-id");
|
|
921
1074
|
|
|
922
|
-
|
|
923
|
-
"/accounts/:accountId/pages/projects/foo/deployments",
|
|
924
|
-
async ([_url, accountId], init) => {
|
|
925
|
-
assertLater(() => {
|
|
926
|
-
expect(accountId).toEqual("some-account-id");
|
|
927
|
-
expect(init.method).toEqual("POST");
|
|
928
|
-
const body = init.body as FormData;
|
|
1075
|
+
const body = await (req as RestRequestWithFormData).formData();
|
|
929
1076
|
const manifest = JSON.parse(body.get("manifest") as string);
|
|
930
1077
|
expect(manifest).toMatchInlineSnapshot(`
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
1078
|
+
Object {
|
|
1079
|
+
"/imgs/logo.png": "2082190357cfd3617ccfe04f340c6247",
|
|
1080
|
+
"/logo.html": "d96fef225537c9f5e44a3cb27fd0b492",
|
|
1081
|
+
"/logo.js": "6be321bef99e758250dac034474ddbb8",
|
|
1082
|
+
"/logo.txt": "1a98fb08af91aca4a7df1764a2c4ddb0",
|
|
1083
|
+
}
|
|
1084
|
+
`);
|
|
1085
|
+
|
|
1086
|
+
return res.once(
|
|
1087
|
+
ctx.status(200),
|
|
1088
|
+
ctx.json({
|
|
1089
|
+
success: true,
|
|
1090
|
+
errors: [],
|
|
1091
|
+
messages: [],
|
|
1092
|
+
result: { url: "https://abcxyz.foo.pages.dev/" },
|
|
1093
|
+
})
|
|
1094
|
+
);
|
|
1095
|
+
}
|
|
1096
|
+
),
|
|
1097
|
+
rest.get(
|
|
1098
|
+
"*/accounts/:accountId/pages/projects/foo",
|
|
1099
|
+
async (req, res, ctx) => {
|
|
1100
|
+
expect(req.params.accountId).toEqual("some-account-id");
|
|
1101
|
+
|
|
1102
|
+
return res.once(
|
|
1103
|
+
ctx.status(200),
|
|
1104
|
+
ctx.json({
|
|
1105
|
+
success: true,
|
|
1106
|
+
errors: [],
|
|
1107
|
+
messages: [],
|
|
1108
|
+
result: {
|
|
1109
|
+
deployment_configs: { production: {}, preview: {} },
|
|
1110
|
+
},
|
|
1111
|
+
})
|
|
1112
|
+
);
|
|
1113
|
+
}
|
|
1114
|
+
)
|
|
955
1115
|
);
|
|
956
1116
|
|
|
957
1117
|
chdir("public");
|
|
958
1118
|
await runWrangler(`pages publish . --project-name=foo`);
|
|
959
|
-
|
|
960
1119
|
// We have 3 buckets, so expect 3 uploads
|
|
961
1120
|
expect(requests.length).toBe(3);
|
|
962
|
-
const bodies: UploadPayloadFile[][] = [];
|
|
963
|
-
for (const init of requests) {
|
|
964
|
-
expect(init.headers).toMatchObject({
|
|
965
|
-
Authorization: "Bearer <<funfetti-auth-jwt>>",
|
|
966
|
-
});
|
|
967
|
-
bodies.push(JSON.parse(init.body as string) as UploadPayloadFile[]);
|
|
968
|
-
}
|
|
969
1121
|
// One bucket should end up with 2 files
|
|
970
1122
|
expect(bodies.map((b) => b.length).sort()).toEqual([1, 1, 2]);
|
|
971
1123
|
// But we don't know the order, so flatten and test without ordering
|
|
@@ -1013,29 +1165,35 @@ describe("pages", () => {
|
|
|
1013
1165
|
|
|
1014
1166
|
mockGetToken("<<funfetti-auth-jwt>>");
|
|
1015
1167
|
|
|
1016
|
-
|
|
1017
|
-
"
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
assertLater(() => {
|
|
1022
|
-
expect(init.headers).toMatchObject({
|
|
1023
|
-
Authorization: "Bearer <<funfetti-auth-jwt>>",
|
|
1024
|
-
});
|
|
1025
|
-
expect(body).toMatchObject({
|
|
1026
|
-
hashes: ["7b764dacfd211bebd8077828a7ddefd7"],
|
|
1027
|
-
});
|
|
1028
|
-
});
|
|
1029
|
-
return body.hashes;
|
|
1030
|
-
}
|
|
1031
|
-
);
|
|
1168
|
+
msw.use(
|
|
1169
|
+
rest.post("*/pages/assets/check-missing", async (req, res, ctx) => {
|
|
1170
|
+
const body = (await req.json()) as {
|
|
1171
|
+
hashes: string[];
|
|
1172
|
+
};
|
|
1032
1173
|
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1174
|
+
expect(req.headers.get("Authorization")).toBe(
|
|
1175
|
+
"Bearer <<funfetti-auth-jwt>>"
|
|
1176
|
+
);
|
|
1177
|
+
expect(body).toMatchObject({
|
|
1178
|
+
hashes: ["7b764dacfd211bebd8077828a7ddefd7"],
|
|
1037
1179
|
});
|
|
1038
|
-
|
|
1180
|
+
|
|
1181
|
+
return res.once(
|
|
1182
|
+
ctx.status(200),
|
|
1183
|
+
ctx.json({
|
|
1184
|
+
success: true,
|
|
1185
|
+
errors: [],
|
|
1186
|
+
messages: [],
|
|
1187
|
+
result: body.hashes,
|
|
1188
|
+
})
|
|
1189
|
+
);
|
|
1190
|
+
}),
|
|
1191
|
+
|
|
1192
|
+
rest.post("*/pages/assets/upload", async (req, res, ctx) => {
|
|
1193
|
+
expect(req.headers.get("Authorization")).toBe(
|
|
1194
|
+
"Bearer <<funfetti-auth-jwt>>"
|
|
1195
|
+
);
|
|
1196
|
+
const body = (await req.json()) as UploadPayloadFile[];
|
|
1039
1197
|
expect(body).toMatchObject([
|
|
1040
1198
|
{
|
|
1041
1199
|
key: "7b764dacfd211bebd8077828a7ddefd7",
|
|
@@ -1046,25 +1204,50 @@ describe("pages", () => {
|
|
|
1046
1204
|
base64: true,
|
|
1047
1205
|
},
|
|
1048
1206
|
]);
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1207
|
+
return res.once(
|
|
1208
|
+
ctx.status(200),
|
|
1209
|
+
ctx.json({
|
|
1210
|
+
success: true,
|
|
1211
|
+
errors: [],
|
|
1212
|
+
messages: [],
|
|
1213
|
+
result: null,
|
|
1214
|
+
})
|
|
1215
|
+
);
|
|
1216
|
+
}),
|
|
1217
|
+
rest.post(
|
|
1218
|
+
"*/accounts/:accountId/pages/projects/foo/deployments",
|
|
1219
|
+
async (req, res, ctx) => {
|
|
1220
|
+
expect(req.params.accountId).toEqual("some-account-id");
|
|
1221
|
+
|
|
1222
|
+
return res.once(
|
|
1223
|
+
ctx.status(200),
|
|
1224
|
+
ctx.json({
|
|
1225
|
+
success: true,
|
|
1226
|
+
errors: [],
|
|
1227
|
+
messages: [],
|
|
1228
|
+
result: { url: "https://abcxyz.foo.pages.dev/" },
|
|
1229
|
+
})
|
|
1230
|
+
);
|
|
1231
|
+
}
|
|
1232
|
+
),
|
|
1233
|
+
rest.get(
|
|
1234
|
+
"*/accounts/:accountId/pages/projects/foo",
|
|
1235
|
+
async (req, res, ctx) => {
|
|
1236
|
+
expect(req.params.accountId).toEqual("some-account-id");
|
|
1237
|
+
|
|
1238
|
+
return res.once(
|
|
1239
|
+
ctx.status(200),
|
|
1240
|
+
ctx.json({
|
|
1241
|
+
success: true,
|
|
1242
|
+
errors: [],
|
|
1243
|
+
messages: [],
|
|
1244
|
+
result: {
|
|
1245
|
+
deployment_configs: { production: {}, preview: {} },
|
|
1246
|
+
},
|
|
1247
|
+
})
|
|
1248
|
+
);
|
|
1249
|
+
}
|
|
1250
|
+
)
|
|
1068
1251
|
);
|
|
1069
1252
|
|
|
1070
1253
|
await runWrangler("pages publish . --project-name=foo");
|
|
@@ -1103,30 +1286,35 @@ describe("pages", () => {
|
|
|
1103
1286
|
|
|
1104
1287
|
mockGetToken("<<funfetti-auth-jwt>>");
|
|
1105
1288
|
|
|
1106
|
-
|
|
1107
|
-
"
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
assertLater(() => {
|
|
1112
|
-
expect(init.headers).toMatchObject({
|
|
1113
|
-
Authorization: "Bearer <<funfetti-auth-jwt>>",
|
|
1114
|
-
});
|
|
1115
|
-
expect(body).toMatchObject({
|
|
1116
|
-
hashes: ["13a03eaf24ae98378acd36ea00f77f2f"],
|
|
1117
|
-
});
|
|
1118
|
-
});
|
|
1119
|
-
return body.hashes;
|
|
1120
|
-
}
|
|
1121
|
-
);
|
|
1289
|
+
msw.use(
|
|
1290
|
+
rest.post("*/pages/assets/check-missing", async (req, res, ctx) => {
|
|
1291
|
+
const body = (await req.json()) as {
|
|
1292
|
+
hashes: string[];
|
|
1293
|
+
};
|
|
1122
1294
|
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1295
|
+
expect(req.headers.get("Authorization")).toBe(
|
|
1296
|
+
"Bearer <<funfetti-auth-jwt>>"
|
|
1297
|
+
);
|
|
1298
|
+
expect(body).toMatchObject({
|
|
1299
|
+
hashes: ["13a03eaf24ae98378acd36ea00f77f2f"],
|
|
1127
1300
|
});
|
|
1128
|
-
|
|
1129
|
-
|
|
1301
|
+
|
|
1302
|
+
return res.once(
|
|
1303
|
+
ctx.status(200),
|
|
1304
|
+
ctx.json({
|
|
1305
|
+
success: true,
|
|
1306
|
+
errors: [],
|
|
1307
|
+
messages: [],
|
|
1308
|
+
result: body.hashes,
|
|
1309
|
+
})
|
|
1310
|
+
);
|
|
1311
|
+
}),
|
|
1312
|
+
rest.post("*/pages/assets/upload", async (req, res, ctx) => {
|
|
1313
|
+
expect(req.headers.get("Authorization")).toBe(
|
|
1314
|
+
"Bearer <<funfetti-auth-jwt>>"
|
|
1315
|
+
);
|
|
1316
|
+
|
|
1317
|
+
expect(await req.json()).toMatchObject([
|
|
1130
1318
|
{
|
|
1131
1319
|
key: "13a03eaf24ae98378acd36ea00f77f2f",
|
|
1132
1320
|
value: Buffer.from("This is a readme").toString("base64"),
|
|
@@ -1136,46 +1324,51 @@ describe("pages", () => {
|
|
|
1136
1324
|
base64: true,
|
|
1137
1325
|
},
|
|
1138
1326
|
]);
|
|
1139
|
-
|
|
1140
|
-
|
|
1327
|
+
return res.once(
|
|
1328
|
+
ctx.status(200),
|
|
1329
|
+
ctx.json({
|
|
1330
|
+
success: true,
|
|
1331
|
+
errors: [],
|
|
1332
|
+
messages: [],
|
|
1333
|
+
result: true,
|
|
1334
|
+
})
|
|
1335
|
+
);
|
|
1336
|
+
}),
|
|
1337
|
+
rest.post(`*/pages/assets/upsert-hashes`, async (req, res, ctx) => {
|
|
1338
|
+
expect(req.headers.get("Authorization")).toBe(
|
|
1339
|
+
"Bearer <<funfetti-auth-jwt>>"
|
|
1340
|
+
);
|
|
1141
1341
|
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
"POST",
|
|
1145
|
-
async (_, init) => {
|
|
1146
|
-
assertLater(() => {
|
|
1147
|
-
expect(init.headers).toMatchObject({
|
|
1148
|
-
Authorization: "Bearer <<funfetti-auth-jwt>>",
|
|
1149
|
-
});
|
|
1150
|
-
const body = JSON.parse(init.body as string) as UploadPayloadFile[];
|
|
1151
|
-
expect(body).toMatchObject({
|
|
1152
|
-
hashes: ["13a03eaf24ae98378acd36ea00f77f2f"],
|
|
1153
|
-
});
|
|
1342
|
+
expect(await req.json()).toMatchObject({
|
|
1343
|
+
hashes: ["13a03eaf24ae98378acd36ea00f77f2f"],
|
|
1154
1344
|
});
|
|
1155
1345
|
|
|
1156
|
-
return
|
|
1157
|
-
|
|
1158
|
-
|
|
1346
|
+
return res.once(
|
|
1347
|
+
ctx.status(200),
|
|
1348
|
+
ctx.json({
|
|
1349
|
+
success: true,
|
|
1350
|
+
errors: [],
|
|
1351
|
+
messages: [],
|
|
1352
|
+
result: true,
|
|
1353
|
+
})
|
|
1354
|
+
);
|
|
1355
|
+
}),
|
|
1159
1356
|
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
expect(init.method).toEqual("POST");
|
|
1166
|
-
const body = init.body as FormData;
|
|
1357
|
+
rest.post(
|
|
1358
|
+
"*/accounts/:accountId/pages/projects/foo/deployments",
|
|
1359
|
+
async (req, res, ctx) => {
|
|
1360
|
+
expect(req.params.accountId).toEqual("some-account-id");
|
|
1361
|
+
const body = await (req as RestRequestWithFormData).formData();
|
|
1167
1362
|
const manifest = JSON.parse(body.get("manifest") as string);
|
|
1168
1363
|
|
|
1169
1364
|
// for Functions projects, we auto-generate a `_worker.js`,
|
|
1170
1365
|
// `functions-filepath-routing-config.json`, and `_routes.json`
|
|
1171
1366
|
// file, based on the contents of `/functions`
|
|
1172
|
-
const generatedWorkerJS = body.get("_worker.js") as
|
|
1173
|
-
const generatedRoutesJSON =
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
body.get("functions-filepath-routing-config.json") as Blob
|
|
1178
|
-
).text();
|
|
1367
|
+
const generatedWorkerJS = body.get("_worker.js") as string;
|
|
1368
|
+
const generatedRoutesJSON = body.get("_routes.json") as string;
|
|
1369
|
+
const generatedFilepathRoutingConfig = body.get(
|
|
1370
|
+
"functions-filepath-routing-config.json"
|
|
1371
|
+
) as string;
|
|
1179
1372
|
|
|
1180
1373
|
// make sure this is all we uploaded
|
|
1181
1374
|
expect([...body.keys()]).toEqual([
|
|
@@ -1186,10 +1379,10 @@ describe("pages", () => {
|
|
|
1186
1379
|
]);
|
|
1187
1380
|
|
|
1188
1381
|
expect(manifest).toMatchInlineSnapshot(`
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1382
|
+
Object {
|
|
1383
|
+
"/README.md": "13a03eaf24ae98378acd36ea00f77f2f",
|
|
1384
|
+
}
|
|
1385
|
+
`);
|
|
1193
1386
|
|
|
1194
1387
|
// the contents of the generated `_worker.js` file is pretty massive, so I don't
|
|
1195
1388
|
// think snapshot testing makes much sense here. Plus, calling
|
|
@@ -1198,7 +1391,7 @@ describe("pages", () => {
|
|
|
1198
1391
|
// file contents is too big). So for now, let's test that _worker.js was indeed
|
|
1199
1392
|
// generated and that the file size is greater than zero
|
|
1200
1393
|
expect(generatedWorkerJS).not.toBeNull();
|
|
1201
|
-
expect(generatedWorkerJS.
|
|
1394
|
+
expect(generatedWorkerJS.length).toBeGreaterThan(0);
|
|
1202
1395
|
|
|
1203
1396
|
const maybeRoutesJSONSpec = JSON.parse(generatedRoutesJSON);
|
|
1204
1397
|
expect(isRoutesJSONSpec(maybeRoutesJSONSpec)).toBe(true);
|
|
@@ -1227,23 +1420,38 @@ describe("pages", () => {
|
|
|
1227
1420
|
],
|
|
1228
1421
|
baseURL: "/",
|
|
1229
1422
|
});
|
|
1230
|
-
});
|
|
1231
|
-
|
|
1232
|
-
return {
|
|
1233
|
-
url: "https://abcxyz.foo.pages.dev/",
|
|
1234
|
-
};
|
|
1235
|
-
}
|
|
1236
|
-
);
|
|
1237
1423
|
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1424
|
+
return res.once(
|
|
1425
|
+
ctx.status(200),
|
|
1426
|
+
ctx.json({
|
|
1427
|
+
success: true,
|
|
1428
|
+
errors: [],
|
|
1429
|
+
messages: [],
|
|
1430
|
+
result: {
|
|
1431
|
+
url: "https://abcxyz.foo.pages.dev/",
|
|
1432
|
+
},
|
|
1433
|
+
})
|
|
1434
|
+
);
|
|
1435
|
+
}
|
|
1436
|
+
),
|
|
1437
|
+
rest.get(
|
|
1438
|
+
"*/accounts/:accountId/pages/projects/foo",
|
|
1439
|
+
async (req, res, ctx) => {
|
|
1440
|
+
expect(req.params.accountId).toEqual("some-account-id");
|
|
1441
|
+
|
|
1442
|
+
return res.once(
|
|
1443
|
+
ctx.status(200),
|
|
1444
|
+
ctx.json({
|
|
1445
|
+
success: true,
|
|
1446
|
+
errors: [],
|
|
1447
|
+
messages: [],
|
|
1448
|
+
result: {
|
|
1449
|
+
deployment_configs: { production: {}, preview: {} },
|
|
1450
|
+
},
|
|
1451
|
+
})
|
|
1452
|
+
);
|
|
1453
|
+
}
|
|
1454
|
+
)
|
|
1247
1455
|
);
|
|
1248
1456
|
|
|
1249
1457
|
await runWrangler("pages publish public --project-name=foo");
|
|
@@ -1278,30 +1486,35 @@ describe("pages", () => {
|
|
|
1278
1486
|
|
|
1279
1487
|
mockGetToken("<<funfetti-auth-jwt>>");
|
|
1280
1488
|
|
|
1281
|
-
|
|
1282
|
-
"
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
assertLater(() => {
|
|
1287
|
-
expect(init.headers).toMatchObject({
|
|
1288
|
-
Authorization: "Bearer <<funfetti-auth-jwt>>",
|
|
1289
|
-
});
|
|
1290
|
-
expect(body).toMatchObject({
|
|
1291
|
-
hashes: ["13a03eaf24ae98378acd36ea00f77f2f"],
|
|
1292
|
-
});
|
|
1293
|
-
});
|
|
1294
|
-
return body.hashes;
|
|
1295
|
-
}
|
|
1296
|
-
);
|
|
1489
|
+
msw.use(
|
|
1490
|
+
rest.post("*/pages/assets/check-missing", async (req, res, ctx) => {
|
|
1491
|
+
const body = (await req.json()) as {
|
|
1492
|
+
hashes: string[];
|
|
1493
|
+
};
|
|
1297
1494
|
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1495
|
+
expect(req.headers.get("Authorization")).toBe(
|
|
1496
|
+
"Bearer <<funfetti-auth-jwt>>"
|
|
1497
|
+
);
|
|
1498
|
+
expect(body).toMatchObject({
|
|
1499
|
+
hashes: ["13a03eaf24ae98378acd36ea00f77f2f"],
|
|
1302
1500
|
});
|
|
1303
|
-
|
|
1304
|
-
|
|
1501
|
+
|
|
1502
|
+
return res.once(
|
|
1503
|
+
ctx.status(200),
|
|
1504
|
+
ctx.json({
|
|
1505
|
+
success: true,
|
|
1506
|
+
errors: [],
|
|
1507
|
+
messages: [],
|
|
1508
|
+
result: body.hashes,
|
|
1509
|
+
})
|
|
1510
|
+
);
|
|
1511
|
+
}),
|
|
1512
|
+
rest.post("*/pages/assets/upload", async (req, res, ctx) => {
|
|
1513
|
+
expect(req.headers.get("Authorization")).toBe(
|
|
1514
|
+
"Bearer <<funfetti-auth-jwt>>"
|
|
1515
|
+
);
|
|
1516
|
+
|
|
1517
|
+
expect(await req.json()).toMatchObject([
|
|
1305
1518
|
{
|
|
1306
1519
|
key: "13a03eaf24ae98378acd36ea00f77f2f",
|
|
1307
1520
|
value: Buffer.from("This is a readme").toString("base64"),
|
|
@@ -1311,56 +1524,75 @@ describe("pages", () => {
|
|
|
1311
1524
|
base64: true,
|
|
1312
1525
|
},
|
|
1313
1526
|
]);
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1527
|
+
return res.once(
|
|
1528
|
+
ctx.status(200),
|
|
1529
|
+
ctx.json({
|
|
1530
|
+
success: true,
|
|
1531
|
+
errors: [],
|
|
1532
|
+
messages: [],
|
|
1533
|
+
result: true,
|
|
1534
|
+
})
|
|
1535
|
+
);
|
|
1536
|
+
}),
|
|
1537
|
+
rest.post(
|
|
1538
|
+
"*/accounts/:accountId/pages/projects/foo/deployments",
|
|
1539
|
+
async (req, res, ctx) => {
|
|
1540
|
+
expect(req.params.accountId).toEqual("some-account-id");
|
|
1541
|
+
const body = await (req as RestRequestWithFormData).formData();
|
|
1324
1542
|
const manifest = JSON.parse(body.get("manifest") as string);
|
|
1325
|
-
const customWorkerJS =
|
|
1326
|
-
body.get("_worker.js") as Blob
|
|
1327
|
-
).text();
|
|
1543
|
+
const customWorkerJS = body.get("_worker.js");
|
|
1328
1544
|
|
|
1329
1545
|
// make sure this is all we uploaded
|
|
1330
|
-
expect([...body.keys()]).toEqual(
|
|
1546
|
+
expect([...body.keys()].sort()).toEqual(
|
|
1547
|
+
["manifest", "_worker.js"].sort()
|
|
1548
|
+
);
|
|
1331
1549
|
|
|
1332
1550
|
expect(manifest).toMatchInlineSnapshot(`
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1551
|
+
Object {
|
|
1552
|
+
"/README.md": "13a03eaf24ae98378acd36ea00f77f2f",
|
|
1553
|
+
}
|
|
1554
|
+
`);
|
|
1337
1555
|
|
|
1338
1556
|
expect(customWorkerJS).toMatchInlineSnapshot(`
|
|
1339
|
-
"
|
|
1340
|
-
export default {
|
|
1341
|
-
async fetch(request, env) {
|
|
1342
|
-
const url = new URL(request.url);
|
|
1343
|
-
return url.pathname.startsWith('/api/') ? new Response('Ok') : env.ASSETS.fetch(request);
|
|
1344
|
-
};
|
|
1345
1557
|
"
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1558
|
+
export default {
|
|
1559
|
+
async fetch(request, env) {
|
|
1560
|
+
const url = new URL(request.url);
|
|
1561
|
+
return url.pathname.startsWith('/api/') ? new Response('Ok') : env.ASSETS.fetch(request);
|
|
1562
|
+
};
|
|
1563
|
+
"
|
|
1564
|
+
`);
|
|
1565
|
+
return res.once(
|
|
1566
|
+
ctx.status(200),
|
|
1567
|
+
ctx.json({
|
|
1568
|
+
success: true,
|
|
1569
|
+
errors: [],
|
|
1570
|
+
messages: [],
|
|
1571
|
+
result: {
|
|
1572
|
+
url: "https://abcxyz.foo.pages.dev/",
|
|
1573
|
+
},
|
|
1574
|
+
})
|
|
1575
|
+
);
|
|
1576
|
+
}
|
|
1577
|
+
),
|
|
1578
|
+
rest.get(
|
|
1579
|
+
"*/accounts/:accountId/pages/projects/foo",
|
|
1580
|
+
async (req, res, ctx) => {
|
|
1581
|
+
expect(req.params.accountId).toEqual("some-account-id");
|
|
1582
|
+
|
|
1583
|
+
return res.once(
|
|
1584
|
+
ctx.status(200),
|
|
1585
|
+
ctx.json({
|
|
1586
|
+
success: true,
|
|
1587
|
+
errors: [],
|
|
1588
|
+
messages: [],
|
|
1589
|
+
result: {
|
|
1590
|
+
deployment_configs: { production: {}, preview: {} },
|
|
1591
|
+
},
|
|
1592
|
+
})
|
|
1593
|
+
);
|
|
1594
|
+
}
|
|
1595
|
+
)
|
|
1364
1596
|
);
|
|
1365
1597
|
|
|
1366
1598
|
await runWrangler("pages publish public --project-name=foo");
|
|
@@ -1414,31 +1646,35 @@ describe("pages", () => {
|
|
|
1414
1646
|
);
|
|
1415
1647
|
|
|
1416
1648
|
mockGetToken("<<funfetti-auth-jwt>>");
|
|
1649
|
+
msw.use(
|
|
1650
|
+
rest.post("*/pages/assets/check-missing", async (req, res, ctx) => {
|
|
1651
|
+
const body = (await req.json()) as {
|
|
1652
|
+
hashes: string[];
|
|
1653
|
+
};
|
|
1417
1654
|
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
assertLater(() => {
|
|
1424
|
-
expect(init.headers).toMatchObject({
|
|
1425
|
-
Authorization: "Bearer <<funfetti-auth-jwt>>",
|
|
1426
|
-
});
|
|
1427
|
-
expect(body).toMatchObject({
|
|
1428
|
-
hashes: ["13a03eaf24ae98378acd36ea00f77f2f"],
|
|
1429
|
-
});
|
|
1655
|
+
expect(req.headers.get("Authorization")).toBe(
|
|
1656
|
+
"Bearer <<funfetti-auth-jwt>>"
|
|
1657
|
+
);
|
|
1658
|
+
expect(body).toMatchObject({
|
|
1659
|
+
hashes: ["13a03eaf24ae98378acd36ea00f77f2f"],
|
|
1430
1660
|
});
|
|
1431
|
-
return body.hashes;
|
|
1432
|
-
}
|
|
1433
|
-
);
|
|
1434
1661
|
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1662
|
+
return res.once(
|
|
1663
|
+
ctx.status(200),
|
|
1664
|
+
ctx.json({
|
|
1665
|
+
success: true,
|
|
1666
|
+
errors: [],
|
|
1667
|
+
messages: [],
|
|
1668
|
+
result: body.hashes,
|
|
1669
|
+
})
|
|
1670
|
+
);
|
|
1671
|
+
}),
|
|
1672
|
+
rest.post("*/pages/assets/upload", async (req, res, ctx) => {
|
|
1673
|
+
expect(req.headers.get("Authorization")).toBe(
|
|
1674
|
+
"Bearer <<funfetti-auth-jwt>>"
|
|
1675
|
+
);
|
|
1676
|
+
|
|
1677
|
+
expect(await req.json()).toMatchObject([
|
|
1442
1678
|
{
|
|
1443
1679
|
key: "13a03eaf24ae98378acd36ea00f77f2f",
|
|
1444
1680
|
value: Buffer.from("This is a readme").toString("base64"),
|
|
@@ -1448,60 +1684,67 @@ describe("pages", () => {
|
|
|
1448
1684
|
base64: true,
|
|
1449
1685
|
},
|
|
1450
1686
|
]);
|
|
1451
|
-
});
|
|
1452
|
-
});
|
|
1453
1687
|
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
})
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1688
|
+
return res.once(
|
|
1689
|
+
ctx.status(200),
|
|
1690
|
+
ctx.json({
|
|
1691
|
+
success: true,
|
|
1692
|
+
errors: [],
|
|
1693
|
+
messages: [],
|
|
1694
|
+
result: null,
|
|
1695
|
+
})
|
|
1696
|
+
);
|
|
1697
|
+
}),
|
|
1698
|
+
rest.post(`*/pages/assets/upsert-hashes`, async (req, res, ctx) => {
|
|
1699
|
+
expect(req.headers.get("Authorization")).toBe(
|
|
1700
|
+
"Bearer <<funfetti-auth-jwt>>"
|
|
1701
|
+
);
|
|
1467
1702
|
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1703
|
+
expect(await req.json()).toMatchObject({
|
|
1704
|
+
hashes: ["13a03eaf24ae98378acd36ea00f77f2f"],
|
|
1705
|
+
});
|
|
1471
1706
|
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1707
|
+
return res.once(
|
|
1708
|
+
ctx.status(200),
|
|
1709
|
+
ctx.json({
|
|
1710
|
+
success: true,
|
|
1711
|
+
errors: [],
|
|
1712
|
+
messages: [],
|
|
1713
|
+
result: true,
|
|
1714
|
+
})
|
|
1715
|
+
);
|
|
1716
|
+
}),
|
|
1717
|
+
rest.post(
|
|
1718
|
+
"*/accounts/:accountId/pages/projects/foo/deployments",
|
|
1719
|
+
async (req, res, ctx) => {
|
|
1720
|
+
expect(req.params.accountId).toEqual("some-account-id");
|
|
1721
|
+
const body = await (req as RestRequestWithFormData).formData();
|
|
1479
1722
|
const manifest = JSON.parse(body.get("manifest") as string);
|
|
1480
|
-
const generatedWorkerJS = body.get("_worker.js") as
|
|
1481
|
-
const customRoutesJSON =
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
body.get("functions-filepath-routing-config.json") as Blob
|
|
1486
|
-
).text();
|
|
1723
|
+
const generatedWorkerJS = body.get("_worker.js") as string;
|
|
1724
|
+
const customRoutesJSON = body.get("_routes.json") as string;
|
|
1725
|
+
const generatedFilepathRoutingConfig = body.get(
|
|
1726
|
+
"functions-filepath-routing-config.json"
|
|
1727
|
+
) as string;
|
|
1487
1728
|
|
|
1488
1729
|
// make sure this is all we uploaded
|
|
1489
|
-
expect([...body.keys()]).toEqual(
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1730
|
+
expect([...body.keys()].sort()).toEqual(
|
|
1731
|
+
[
|
|
1732
|
+
"manifest",
|
|
1733
|
+
"functions-filepath-routing-config.json",
|
|
1734
|
+
"_worker.js",
|
|
1735
|
+
"_routes.json",
|
|
1736
|
+
].sort()
|
|
1737
|
+
);
|
|
1495
1738
|
|
|
1496
1739
|
expect(manifest).toMatchInlineSnapshot(`
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1740
|
+
Object {
|
|
1741
|
+
"/README.md": "13a03eaf24ae98378acd36ea00f77f2f",
|
|
1742
|
+
}
|
|
1743
|
+
`);
|
|
1501
1744
|
|
|
1502
1745
|
// file content of generated `_worker.js` is too massive to snapshot test
|
|
1503
1746
|
expect(generatedWorkerJS).not.toBeNull();
|
|
1504
|
-
expect(generatedWorkerJS.
|
|
1747
|
+
expect(generatedWorkerJS.length).toBeGreaterThan(0);
|
|
1505
1748
|
|
|
1506
1749
|
const customRoutes = JSON.parse(customRoutesJSON);
|
|
1507
1750
|
expect(customRoutes).toMatchObject({
|
|
@@ -1518,7 +1761,6 @@ describe("pages", () => {
|
|
|
1518
1761
|
// The actual shape doesn't matter that much since this
|
|
1519
1762
|
// is only used for display in Dash, but it's still useful for
|
|
1520
1763
|
// tracking unexpected changes to this config.
|
|
1521
|
-
console.log(generatedFilepathRoutingConfig);
|
|
1522
1764
|
expect(parsedFilepathRoutingConfig).toStrictEqual({
|
|
1523
1765
|
routes: [
|
|
1524
1766
|
{
|
|
@@ -1536,23 +1778,38 @@ describe("pages", () => {
|
|
|
1536
1778
|
],
|
|
1537
1779
|
baseURL: "/",
|
|
1538
1780
|
});
|
|
1539
|
-
});
|
|
1540
|
-
|
|
1541
|
-
return {
|
|
1542
|
-
url: "https://abcxyz.foo.pages.dev/",
|
|
1543
|
-
};
|
|
1544
|
-
}
|
|
1545
|
-
);
|
|
1546
1781
|
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1782
|
+
return res.once(
|
|
1783
|
+
ctx.status(200),
|
|
1784
|
+
ctx.json({
|
|
1785
|
+
success: true,
|
|
1786
|
+
errors: [],
|
|
1787
|
+
messages: [],
|
|
1788
|
+
result: {
|
|
1789
|
+
url: "https://abcxyz.foo.pages.dev/",
|
|
1790
|
+
},
|
|
1791
|
+
})
|
|
1792
|
+
);
|
|
1793
|
+
}
|
|
1794
|
+
),
|
|
1795
|
+
rest.get(
|
|
1796
|
+
"*/accounts/:accountId/pages/projects/foo",
|
|
1797
|
+
async (req, res, ctx) => {
|
|
1798
|
+
expect(req.params.accountId).toEqual("some-account-id");
|
|
1799
|
+
|
|
1800
|
+
return res.once(
|
|
1801
|
+
ctx.status(200),
|
|
1802
|
+
ctx.json({
|
|
1803
|
+
success: true,
|
|
1804
|
+
errors: [],
|
|
1805
|
+
messages: [],
|
|
1806
|
+
result: {
|
|
1807
|
+
deployment_configs: { production: {}, preview: {} },
|
|
1808
|
+
},
|
|
1809
|
+
})
|
|
1810
|
+
);
|
|
1811
|
+
}
|
|
1812
|
+
)
|
|
1556
1813
|
);
|
|
1557
1814
|
|
|
1558
1815
|
await runWrangler("pages publish public --project-name=foo");
|
|
@@ -1604,31 +1861,35 @@ describe("pages", () => {
|
|
|
1604
1861
|
);
|
|
1605
1862
|
|
|
1606
1863
|
mockGetToken("<<funfetti-auth-jwt>>");
|
|
1864
|
+
msw.use(
|
|
1865
|
+
rest.post("*/pages/assets/check-missing", async (req, res, ctx) => {
|
|
1866
|
+
const body = (await req.json()) as {
|
|
1867
|
+
hashes: string[];
|
|
1868
|
+
};
|
|
1607
1869
|
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
assertLater(() => {
|
|
1614
|
-
expect(init.headers).toMatchObject({
|
|
1615
|
-
Authorization: "Bearer <<funfetti-auth-jwt>>",
|
|
1616
|
-
});
|
|
1617
|
-
expect(body).toMatchObject({
|
|
1618
|
-
hashes: ["13a03eaf24ae98378acd36ea00f77f2f"],
|
|
1619
|
-
});
|
|
1870
|
+
expect(req.headers.get("Authorization")).toBe(
|
|
1871
|
+
"Bearer <<funfetti-auth-jwt>>"
|
|
1872
|
+
);
|
|
1873
|
+
expect(body).toMatchObject({
|
|
1874
|
+
hashes: ["13a03eaf24ae98378acd36ea00f77f2f"],
|
|
1620
1875
|
});
|
|
1621
|
-
return body.hashes;
|
|
1622
|
-
}
|
|
1623
|
-
);
|
|
1624
1876
|
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
1877
|
+
return res.once(
|
|
1878
|
+
ctx.status(200),
|
|
1879
|
+
ctx.json({
|
|
1880
|
+
success: true,
|
|
1881
|
+
errors: [],
|
|
1882
|
+
messages: [],
|
|
1883
|
+
result: body.hashes,
|
|
1884
|
+
})
|
|
1885
|
+
);
|
|
1886
|
+
}),
|
|
1887
|
+
rest.post("*/pages/assets/upload", async (req, res, ctx) => {
|
|
1888
|
+
expect(req.headers.get("Authorization")).toBe(
|
|
1889
|
+
"Bearer <<funfetti-auth-jwt>>"
|
|
1890
|
+
);
|
|
1891
|
+
|
|
1892
|
+
expect(await req.json()).toMatchObject([
|
|
1632
1893
|
{
|
|
1633
1894
|
key: "13a03eaf24ae98378acd36ea00f77f2f",
|
|
1634
1895
|
value: Buffer.from("This is a readme").toString("base64"),
|
|
@@ -1638,18 +1899,35 @@ describe("pages", () => {
|
|
|
1638
1899
|
base64: true,
|
|
1639
1900
|
},
|
|
1640
1901
|
]);
|
|
1641
|
-
});
|
|
1642
|
-
});
|
|
1643
1902
|
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1903
|
+
return res.once(
|
|
1904
|
+
ctx.status(200),
|
|
1905
|
+
ctx.json({
|
|
1906
|
+
success: true,
|
|
1907
|
+
errors: [],
|
|
1908
|
+
messages: [],
|
|
1909
|
+
result: null,
|
|
1910
|
+
})
|
|
1911
|
+
);
|
|
1912
|
+
}),
|
|
1913
|
+
rest.get(
|
|
1914
|
+
"*/accounts/:accountId/pages/projects/foo",
|
|
1915
|
+
async (req, res, ctx) => {
|
|
1916
|
+
expect(req.params.accountId).toEqual("some-account-id");
|
|
1917
|
+
|
|
1918
|
+
return res.once(
|
|
1919
|
+
ctx.status(200),
|
|
1920
|
+
ctx.json({
|
|
1921
|
+
success: true,
|
|
1922
|
+
errors: [],
|
|
1923
|
+
messages: [],
|
|
1924
|
+
result: {
|
|
1925
|
+
deployment_configs: { production: {}, preview: {} },
|
|
1926
|
+
},
|
|
1927
|
+
})
|
|
1928
|
+
);
|
|
1929
|
+
}
|
|
1930
|
+
)
|
|
1653
1931
|
);
|
|
1654
1932
|
|
|
1655
1933
|
await expect(runWrangler("pages publish public --project-name=foo"))
|
|
@@ -1697,30 +1975,35 @@ and that at least one include rule is provided.
|
|
|
1697
1975
|
|
|
1698
1976
|
mockGetToken("<<funfetti-auth-jwt>>");
|
|
1699
1977
|
|
|
1700
|
-
|
|
1701
|
-
"
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
assertLater(() => {
|
|
1706
|
-
expect(init.headers).toMatchObject({
|
|
1707
|
-
Authorization: "Bearer <<funfetti-auth-jwt>>",
|
|
1708
|
-
});
|
|
1709
|
-
expect(body).toMatchObject({
|
|
1710
|
-
hashes: ["13a03eaf24ae98378acd36ea00f77f2f"],
|
|
1711
|
-
});
|
|
1712
|
-
});
|
|
1713
|
-
return body.hashes;
|
|
1714
|
-
}
|
|
1715
|
-
);
|
|
1978
|
+
msw.use(
|
|
1979
|
+
rest.post("*/pages/assets/check-missing", async (req, res, ctx) => {
|
|
1980
|
+
const body = (await req.json()) as {
|
|
1981
|
+
hashes: string[];
|
|
1982
|
+
};
|
|
1716
1983
|
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1984
|
+
expect(req.headers.get("Authorization")).toBe(
|
|
1985
|
+
"Bearer <<funfetti-auth-jwt>>"
|
|
1986
|
+
);
|
|
1987
|
+
expect(body).toMatchObject({
|
|
1988
|
+
hashes: ["13a03eaf24ae98378acd36ea00f77f2f"],
|
|
1721
1989
|
});
|
|
1722
|
-
|
|
1723
|
-
|
|
1990
|
+
|
|
1991
|
+
return res.once(
|
|
1992
|
+
ctx.status(200),
|
|
1993
|
+
ctx.json({
|
|
1994
|
+
success: true,
|
|
1995
|
+
errors: [],
|
|
1996
|
+
messages: [],
|
|
1997
|
+
result: body.hashes,
|
|
1998
|
+
})
|
|
1999
|
+
);
|
|
2000
|
+
}),
|
|
2001
|
+
rest.post("*/pages/assets/upload", async (req, res, ctx) => {
|
|
2002
|
+
expect(req.headers.get("Authorization")).toBe(
|
|
2003
|
+
"Bearer <<funfetti-auth-jwt>>"
|
|
2004
|
+
);
|
|
2005
|
+
|
|
2006
|
+
expect(await req.json()).toMatchObject([
|
|
1724
2007
|
{
|
|
1725
2008
|
key: "13a03eaf24ae98378acd36ea00f77f2f",
|
|
1726
2009
|
value: Buffer.from("This is a readme").toString("base64"),
|
|
@@ -1730,41 +2013,44 @@ and that at least one include rule is provided.
|
|
|
1730
2013
|
base64: true,
|
|
1731
2014
|
},
|
|
1732
2015
|
]);
|
|
1733
|
-
});
|
|
1734
|
-
});
|
|
1735
2016
|
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
})
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
2017
|
+
return res.once(
|
|
2018
|
+
ctx.status(200),
|
|
2019
|
+
ctx.json({
|
|
2020
|
+
success: true,
|
|
2021
|
+
errors: [],
|
|
2022
|
+
messages: [],
|
|
2023
|
+
result: null,
|
|
2024
|
+
})
|
|
2025
|
+
);
|
|
2026
|
+
}),
|
|
2027
|
+
rest.post(`*/pages/assets/upsert-hashes`, async (req, res, ctx) => {
|
|
2028
|
+
expect(req.headers.get("Authorization")).toBe(
|
|
2029
|
+
"Bearer <<funfetti-auth-jwt>>"
|
|
2030
|
+
);
|
|
2031
|
+
|
|
2032
|
+
expect(await req.json()).toMatchObject({
|
|
2033
|
+
hashes: ["13a03eaf24ae98378acd36ea00f77f2f"],
|
|
1748
2034
|
});
|
|
1749
2035
|
|
|
1750
|
-
return
|
|
1751
|
-
|
|
1752
|
-
|
|
2036
|
+
return res.once(
|
|
2037
|
+
ctx.status(200),
|
|
2038
|
+
ctx.json({
|
|
2039
|
+
success: true,
|
|
2040
|
+
errors: [],
|
|
2041
|
+
messages: [],
|
|
2042
|
+
result: true,
|
|
2043
|
+
})
|
|
2044
|
+
);
|
|
2045
|
+
}),
|
|
2046
|
+
rest.post(
|
|
2047
|
+
"*/accounts/:accountId/pages/projects/foo/deployments",
|
|
2048
|
+
async (req, res, ctx) => {
|
|
2049
|
+
const body = await (req as RestRequestWithFormData).formData();
|
|
1753
2050
|
|
|
1754
|
-
setMockResponse(
|
|
1755
|
-
"/accounts/:accountId/pages/projects/foo/deployments",
|
|
1756
|
-
async ([_url, accountId], init) => {
|
|
1757
|
-
assertLater(async () => {
|
|
1758
|
-
expect(accountId).toEqual("some-account-id");
|
|
1759
|
-
expect(init.method).toEqual("POST");
|
|
1760
|
-
const body = init.body as FormData;
|
|
1761
2051
|
const manifest = JSON.parse(body.get("manifest") as string);
|
|
1762
|
-
const customWorkerJS =
|
|
1763
|
-
|
|
1764
|
-
).text();
|
|
1765
|
-
const customRoutesJSON = await (
|
|
1766
|
-
body.get("_routes.json") as Blob
|
|
1767
|
-
).text();
|
|
2052
|
+
const customWorkerJS = body.get("_worker.js") as string;
|
|
2053
|
+
const customRoutesJSON = body.get("_routes.json") as string;
|
|
1768
2054
|
|
|
1769
2055
|
// make sure this is all we uploaded
|
|
1770
2056
|
expect([...body.keys()]).toEqual([
|
|
@@ -1772,47 +2058,61 @@ and that at least one include rule is provided.
|
|
|
1772
2058
|
"_worker.js",
|
|
1773
2059
|
"_routes.json",
|
|
1774
2060
|
]);
|
|
1775
|
-
|
|
2061
|
+
expect(req.params.accountId).toEqual("some-account-id");
|
|
1776
2062
|
expect(manifest).toMatchInlineSnapshot(`
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
2063
|
+
Object {
|
|
2064
|
+
"/README.md": "13a03eaf24ae98378acd36ea00f77f2f",
|
|
2065
|
+
}
|
|
2066
|
+
`);
|
|
1781
2067
|
|
|
1782
2068
|
expect(customWorkerJS).toMatchInlineSnapshot(`
|
|
1783
|
-
"
|
|
1784
|
-
export default {
|
|
1785
|
-
async fetch(request, env) {
|
|
1786
|
-
const url = new URL(request.url);
|
|
1787
|
-
return url.pathname.startsWith('/api/') ? new Response('Ok') : env.ASSETS.fetch(request);
|
|
1788
|
-
};
|
|
1789
2069
|
"
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
2070
|
+
export default {
|
|
2071
|
+
async fetch(request, env) {
|
|
2072
|
+
const url = new URL(request.url);
|
|
2073
|
+
return url.pathname.startsWith('/api/') ? new Response('Ok') : env.ASSETS.fetch(request);
|
|
2074
|
+
};
|
|
2075
|
+
"
|
|
2076
|
+
`);
|
|
2077
|
+
|
|
2078
|
+
expect(JSON.parse(customRoutesJSON)).toMatchObject({
|
|
1794
2079
|
version: ROUTES_SPEC_VERSION,
|
|
1795
2080
|
description: "Custom _routes.json file",
|
|
1796
2081
|
include: ["/api/*"],
|
|
1797
2082
|
exclude: [],
|
|
1798
2083
|
});
|
|
1799
|
-
});
|
|
1800
|
-
|
|
1801
|
-
return {
|
|
1802
|
-
url: "https://abcxyz.foo.pages.dev/",
|
|
1803
|
-
};
|
|
1804
|
-
}
|
|
1805
|
-
);
|
|
1806
2084
|
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
|
|
2085
|
+
return res.once(
|
|
2086
|
+
ctx.status(200),
|
|
2087
|
+
ctx.json({
|
|
2088
|
+
success: true,
|
|
2089
|
+
errors: [],
|
|
2090
|
+
messages: [],
|
|
2091
|
+
result: {
|
|
2092
|
+
url: "https://abcxyz.foo.pages.dev/",
|
|
2093
|
+
},
|
|
2094
|
+
})
|
|
2095
|
+
);
|
|
2096
|
+
}
|
|
2097
|
+
),
|
|
2098
|
+
rest.get(
|
|
2099
|
+
"*/accounts/:accountId/pages/projects/foo",
|
|
2100
|
+
async (req, res, ctx) => {
|
|
2101
|
+
expect(req.params.accountId).toEqual("some-account-id");
|
|
2102
|
+
|
|
2103
|
+
return res.once(
|
|
2104
|
+
ctx.status(200),
|
|
2105
|
+
ctx.json({
|
|
2106
|
+
success: true,
|
|
2107
|
+
errors: [],
|
|
2108
|
+
messages: [],
|
|
2109
|
+
result: {
|
|
2110
|
+
deployment_configs: { production: {}, preview: {} },
|
|
2111
|
+
},
|
|
2112
|
+
})
|
|
2113
|
+
);
|
|
2114
|
+
}
|
|
2115
|
+
)
|
|
1816
2116
|
);
|
|
1817
2117
|
|
|
1818
2118
|
await runWrangler("pages publish public --project-name=foo");
|
|
@@ -1864,30 +2164,35 @@ and that at least one include rule is provided.
|
|
|
1864
2164
|
|
|
1865
2165
|
mockGetToken("<<funfetti-auth-jwt>>");
|
|
1866
2166
|
|
|
1867
|
-
|
|
1868
|
-
"
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
assertLater(() => {
|
|
1873
|
-
expect(init.headers).toMatchObject({
|
|
1874
|
-
Authorization: "Bearer <<funfetti-auth-jwt>>",
|
|
1875
|
-
});
|
|
1876
|
-
expect(body).toMatchObject({
|
|
1877
|
-
hashes: ["13a03eaf24ae98378acd36ea00f77f2f"],
|
|
1878
|
-
});
|
|
1879
|
-
});
|
|
1880
|
-
return body.hashes;
|
|
1881
|
-
}
|
|
1882
|
-
);
|
|
2167
|
+
msw.use(
|
|
2168
|
+
rest.post("*/pages/assets/check-missing", async (req, res, ctx) => {
|
|
2169
|
+
const body = (await req.json()) as {
|
|
2170
|
+
hashes: string[];
|
|
2171
|
+
};
|
|
1883
2172
|
|
|
1884
|
-
|
|
1885
|
-
|
|
1886
|
-
|
|
1887
|
-
|
|
2173
|
+
expect(req.headers.get("Authorization")).toBe(
|
|
2174
|
+
"Bearer <<funfetti-auth-jwt>>"
|
|
2175
|
+
);
|
|
2176
|
+
expect(body).toMatchObject({
|
|
2177
|
+
hashes: ["13a03eaf24ae98378acd36ea00f77f2f"],
|
|
1888
2178
|
});
|
|
1889
|
-
|
|
1890
|
-
|
|
2179
|
+
|
|
2180
|
+
return res.once(
|
|
2181
|
+
ctx.status(200),
|
|
2182
|
+
ctx.json({
|
|
2183
|
+
success: true,
|
|
2184
|
+
errors: [],
|
|
2185
|
+
messages: [],
|
|
2186
|
+
result: body.hashes,
|
|
2187
|
+
})
|
|
2188
|
+
);
|
|
2189
|
+
}),
|
|
2190
|
+
rest.post("*/pages/assets/upload", async (req, res, ctx) => {
|
|
2191
|
+
expect(req.headers.get("Authorization")).toBe(
|
|
2192
|
+
"Bearer <<funfetti-auth-jwt>>"
|
|
2193
|
+
);
|
|
2194
|
+
|
|
2195
|
+
expect(await req.json()).toMatchObject([
|
|
1891
2196
|
{
|
|
1892
2197
|
key: "13a03eaf24ae98378acd36ea00f77f2f",
|
|
1893
2198
|
value: Buffer.from("This is a readme").toString("base64"),
|
|
@@ -1897,18 +2202,35 @@ and that at least one include rule is provided.
|
|
|
1897
2202
|
base64: true,
|
|
1898
2203
|
},
|
|
1899
2204
|
]);
|
|
1900
|
-
});
|
|
1901
|
-
});
|
|
1902
2205
|
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
|
|
1910
|
-
|
|
1911
|
-
|
|
2206
|
+
return res.once(
|
|
2207
|
+
ctx.status(200),
|
|
2208
|
+
ctx.json({
|
|
2209
|
+
success: true,
|
|
2210
|
+
errors: [],
|
|
2211
|
+
messages: [],
|
|
2212
|
+
result: null,
|
|
2213
|
+
})
|
|
2214
|
+
);
|
|
2215
|
+
}),
|
|
2216
|
+
|
|
2217
|
+
rest.get(
|
|
2218
|
+
"*/accounts/:accountId/pages/projects/foo",
|
|
2219
|
+
async (req, res, ctx) => {
|
|
2220
|
+
expect(req.params.accountId).toEqual("some-account-id");
|
|
2221
|
+
return res.once(
|
|
2222
|
+
ctx.status(200),
|
|
2223
|
+
ctx.json({
|
|
2224
|
+
success: true,
|
|
2225
|
+
errors: [],
|
|
2226
|
+
messages: [],
|
|
2227
|
+
result: {
|
|
2228
|
+
deployment_configs: { production: {}, preview: {} },
|
|
2229
|
+
},
|
|
2230
|
+
})
|
|
2231
|
+
);
|
|
2232
|
+
}
|
|
2233
|
+
)
|
|
1912
2234
|
);
|
|
1913
2235
|
|
|
1914
2236
|
await expect(runWrangler("pages publish public --project-name=foo"))
|
|
@@ -1954,30 +2276,35 @@ and that at least one include rule is provided.
|
|
|
1954
2276
|
|
|
1955
2277
|
mockGetToken("<<funfetti-auth-jwt>>");
|
|
1956
2278
|
|
|
1957
|
-
|
|
1958
|
-
"
|
|
1959
|
-
|
|
1960
|
-
|
|
1961
|
-
|
|
1962
|
-
assertLater(() => {
|
|
1963
|
-
expect(init.headers).toMatchObject({
|
|
1964
|
-
Authorization: "Bearer <<funfetti-auth-jwt>>",
|
|
1965
|
-
});
|
|
1966
|
-
expect(body).toMatchObject({
|
|
1967
|
-
hashes: ["13a03eaf24ae98378acd36ea00f77f2f"],
|
|
1968
|
-
});
|
|
1969
|
-
});
|
|
1970
|
-
return body.hashes;
|
|
1971
|
-
}
|
|
1972
|
-
);
|
|
2279
|
+
msw.use(
|
|
2280
|
+
rest.post("*/pages/assets/check-missing", async (req, res, ctx) => {
|
|
2281
|
+
const body = (await req.json()) as {
|
|
2282
|
+
hashes: string[];
|
|
2283
|
+
};
|
|
1973
2284
|
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
|
|
1977
|
-
|
|
2285
|
+
expect(req.headers.get("Authorization")).toBe(
|
|
2286
|
+
"Bearer <<funfetti-auth-jwt>>"
|
|
2287
|
+
);
|
|
2288
|
+
expect(body).toMatchObject({
|
|
2289
|
+
hashes: ["13a03eaf24ae98378acd36ea00f77f2f"],
|
|
1978
2290
|
});
|
|
1979
|
-
|
|
1980
|
-
|
|
2291
|
+
|
|
2292
|
+
return res.once(
|
|
2293
|
+
ctx.status(200),
|
|
2294
|
+
ctx.json({
|
|
2295
|
+
success: true,
|
|
2296
|
+
errors: [],
|
|
2297
|
+
messages: [],
|
|
2298
|
+
result: body.hashes,
|
|
2299
|
+
})
|
|
2300
|
+
);
|
|
2301
|
+
}),
|
|
2302
|
+
rest.post("*/pages/assets/upload", async (req, res, ctx) => {
|
|
2303
|
+
expect(req.headers.get("Authorization")).toBe(
|
|
2304
|
+
"Bearer <<funfetti-auth-jwt>>"
|
|
2305
|
+
);
|
|
2306
|
+
|
|
2307
|
+
expect(await req.json()).toMatchObject([
|
|
1981
2308
|
{
|
|
1982
2309
|
key: "13a03eaf24ae98378acd36ea00f77f2f",
|
|
1983
2310
|
value: Buffer.from("This is a readme").toString("base64"),
|
|
@@ -1987,56 +2314,76 @@ and that at least one include rule is provided.
|
|
|
1987
2314
|
base64: true,
|
|
1988
2315
|
},
|
|
1989
2316
|
]);
|
|
1990
|
-
});
|
|
1991
|
-
});
|
|
1992
2317
|
|
|
1993
|
-
|
|
1994
|
-
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
|
|
1999
|
-
|
|
2318
|
+
return res.once(
|
|
2319
|
+
ctx.status(200),
|
|
2320
|
+
ctx.json({
|
|
2321
|
+
success: true,
|
|
2322
|
+
errors: [],
|
|
2323
|
+
messages: [],
|
|
2324
|
+
result: null,
|
|
2325
|
+
})
|
|
2326
|
+
);
|
|
2327
|
+
}),
|
|
2328
|
+
|
|
2329
|
+
rest.post(
|
|
2330
|
+
"*/accounts/:accountId/pages/projects/foo/deployments",
|
|
2331
|
+
async (req, res, ctx) => {
|
|
2332
|
+
const body = await (req as RestRequestWithFormData).formData();
|
|
2000
2333
|
const manifest = JSON.parse(body.get("manifest") as string);
|
|
2001
|
-
const customWorkerJS =
|
|
2002
|
-
body.get("_worker.js") as Blob
|
|
2003
|
-
).text();
|
|
2334
|
+
const customWorkerJS = body.get("_worker.js");
|
|
2004
2335
|
|
|
2336
|
+
expect(req.params.accountId).toEqual("some-account-id");
|
|
2005
2337
|
// make sure this is all we uploaded
|
|
2006
|
-
expect([...body.keys()]).toEqual(
|
|
2007
|
-
|
|
2338
|
+
expect([...body.keys()].sort()).toEqual(
|
|
2339
|
+
["manifest", "_worker.js"].sort()
|
|
2340
|
+
);
|
|
2008
2341
|
expect(manifest).toMatchInlineSnapshot(`
|
|
2009
|
-
|
|
2010
|
-
|
|
2011
|
-
|
|
2012
|
-
|
|
2013
|
-
|
|
2342
|
+
Object {
|
|
2343
|
+
"/README.md": "13a03eaf24ae98378acd36ea00f77f2f",
|
|
2344
|
+
}
|
|
2345
|
+
`);
|
|
2014
2346
|
expect(customWorkerJS).toMatchInlineSnapshot(`
|
|
2015
|
-
"
|
|
2016
|
-
export default {
|
|
2017
|
-
async fetch(request, env) {
|
|
2018
|
-
const url = new URL(request.url);
|
|
2019
|
-
return url.pathname.startsWith('/api/') ? new Response('Ok') : env.ASSETS.fetch(request);
|
|
2020
|
-
};
|
|
2021
2347
|
"
|
|
2022
|
-
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
2348
|
+
export default {
|
|
2349
|
+
async fetch(request, env) {
|
|
2350
|
+
const url = new URL(request.url);
|
|
2351
|
+
return url.pathname.startsWith('/api/') ? new Response('Ok') : env.ASSETS.fetch(request);
|
|
2352
|
+
};
|
|
2353
|
+
"
|
|
2354
|
+
`);
|
|
2355
|
+
|
|
2356
|
+
return res.once(
|
|
2357
|
+
ctx.status(200),
|
|
2358
|
+
ctx.json({
|
|
2359
|
+
success: true,
|
|
2360
|
+
errors: [],
|
|
2361
|
+
messages: [],
|
|
2362
|
+
result: {
|
|
2363
|
+
url: "https://abcxyz.foo.pages.dev/",
|
|
2364
|
+
},
|
|
2365
|
+
})
|
|
2366
|
+
);
|
|
2367
|
+
}
|
|
2368
|
+
),
|
|
2369
|
+
rest.get(
|
|
2370
|
+
"*/accounts/:accountId/pages/projects/foo",
|
|
2371
|
+
async (req, res, ctx) => {
|
|
2372
|
+
expect(req.params.accountId).toEqual("some-account-id");
|
|
2373
|
+
|
|
2374
|
+
return res.once(
|
|
2375
|
+
ctx.status(200),
|
|
2376
|
+
ctx.json({
|
|
2377
|
+
success: true,
|
|
2378
|
+
errors: [],
|
|
2379
|
+
messages: [],
|
|
2380
|
+
result: {
|
|
2381
|
+
deployment_configs: { production: {}, preview: {} },
|
|
2382
|
+
},
|
|
2383
|
+
})
|
|
2384
|
+
);
|
|
2385
|
+
}
|
|
2386
|
+
)
|
|
2040
2387
|
);
|
|
2041
2388
|
|
|
2042
2389
|
await runWrangler("pages publish public --project-name=foo");
|
|
@@ -2065,48 +2412,62 @@ and that at least one include rule is provided.
|
|
|
2065
2412
|
});
|
|
2066
2413
|
|
|
2067
2414
|
afterEach(() => {
|
|
2068
|
-
unsetAllMocks();
|
|
2069
2415
|
process.env = ENV_COPY;
|
|
2070
2416
|
});
|
|
2071
2417
|
|
|
2072
2418
|
it("should upload a directory of files with a provided JWT", async () => {
|
|
2073
2419
|
writeFileSync("logo.png", "foobar");
|
|
2074
2420
|
|
|
2075
|
-
|
|
2076
|
-
"
|
|
2077
|
-
|
|
2078
|
-
|
|
2079
|
-
|
|
2080
|
-
assertLater(() => {
|
|
2081
|
-
expect(init.headers).toMatchObject({
|
|
2082
|
-
Authorization: "Bearer <<funfetti-auth-jwt>>",
|
|
2083
|
-
});
|
|
2084
|
-
expect(body).toMatchObject({
|
|
2085
|
-
hashes: ["2082190357cfd3617ccfe04f340c6247"],
|
|
2086
|
-
});
|
|
2087
|
-
});
|
|
2088
|
-
return body.hashes;
|
|
2089
|
-
}
|
|
2090
|
-
);
|
|
2421
|
+
msw.use(
|
|
2422
|
+
rest.post("*/pages/assets/check-missing", async (req, res, ctx) => {
|
|
2423
|
+
const body = (await req.json()) as {
|
|
2424
|
+
hashes: string[];
|
|
2425
|
+
};
|
|
2091
2426
|
|
|
2092
|
-
|
|
2093
|
-
|
|
2094
|
-
|
|
2095
|
-
|
|
2427
|
+
expect(req.headers.get("Authorization")).toBe(
|
|
2428
|
+
"Bearer <<funfetti-auth-jwt>>"
|
|
2429
|
+
);
|
|
2430
|
+
expect(body).toMatchObject({
|
|
2431
|
+
hashes: ["2082190357cfd3617ccfe04f340c6247"],
|
|
2096
2432
|
});
|
|
2097
|
-
|
|
2098
|
-
|
|
2433
|
+
|
|
2434
|
+
return res.once(
|
|
2435
|
+
ctx.status(200),
|
|
2436
|
+
ctx.json({
|
|
2437
|
+
success: true,
|
|
2438
|
+
errors: [],
|
|
2439
|
+
messages: [],
|
|
2440
|
+
result: body.hashes,
|
|
2441
|
+
})
|
|
2442
|
+
);
|
|
2443
|
+
}),
|
|
2444
|
+
rest.post("*/pages/assets/upload", async (req, res, ctx) => {
|
|
2445
|
+
expect(req.headers.get("Authorization")).toBe(
|
|
2446
|
+
"Bearer <<funfetti-auth-jwt>>"
|
|
2447
|
+
);
|
|
2448
|
+
|
|
2449
|
+
expect(await req.json()).toMatchObject([
|
|
2099
2450
|
{
|
|
2451
|
+
base64: true,
|
|
2100
2452
|
key: "2082190357cfd3617ccfe04f340c6247",
|
|
2101
|
-
value: Buffer.from("foobar").toString("base64"),
|
|
2102
2453
|
metadata: {
|
|
2103
2454
|
contentType: "image/png",
|
|
2104
2455
|
},
|
|
2105
|
-
|
|
2456
|
+
value: "Zm9vYmFy",
|
|
2106
2457
|
},
|
|
2107
2458
|
]);
|
|
2108
|
-
|
|
2109
|
-
|
|
2459
|
+
|
|
2460
|
+
return res(
|
|
2461
|
+
ctx.status(200),
|
|
2462
|
+
ctx.json({
|
|
2463
|
+
success: true,
|
|
2464
|
+
errors: [],
|
|
2465
|
+
messages: [],
|
|
2466
|
+
result: null,
|
|
2467
|
+
})
|
|
2468
|
+
);
|
|
2469
|
+
})
|
|
2470
|
+
);
|
|
2110
2471
|
|
|
2111
2472
|
await runWrangler("pages project upload .");
|
|
2112
2473
|
|
|
@@ -2135,100 +2496,103 @@ and that at least one include rule is provided.
|
|
|
2135
2496
|
mkdirSync("functions");
|
|
2136
2497
|
writeFileSync("functions/foo.js", "func");
|
|
2137
2498
|
|
|
2138
|
-
|
|
2139
|
-
|
|
2140
|
-
|
|
2141
|
-
async (
|
|
2142
|
-
const body =
|
|
2143
|
-
|
|
2144
|
-
|
|
2145
|
-
|
|
2146
|
-
|
|
2147
|
-
|
|
2148
|
-
|
|
2149
|
-
|
|
2150
|
-
|
|
2151
|
-
|
|
2152
|
-
|
|
2153
|
-
|
|
2499
|
+
// Accumulate multiple requests then assert afterwards
|
|
2500
|
+
const requests: RestRequest[] = [];
|
|
2501
|
+
msw.use(
|
|
2502
|
+
rest.post("*/pages/assets/check-missing", async (req, res, ctx) => {
|
|
2503
|
+
const body = (await req.json()) as {
|
|
2504
|
+
hashes: string[];
|
|
2505
|
+
};
|
|
2506
|
+
|
|
2507
|
+
expect(req.headers.get("Authorization")).toBe(
|
|
2508
|
+
"Bearer <<funfetti-auth-jwt>>"
|
|
2509
|
+
);
|
|
2510
|
+
expect(body).toMatchObject({
|
|
2511
|
+
hashes: [
|
|
2512
|
+
"2082190357cfd3617ccfe04f340c6247",
|
|
2513
|
+
"95dedb64e6d4940fc2e0f11f711cc2f4",
|
|
2514
|
+
"09a79777abda8ccc8bdd51dd3ff8e9e9",
|
|
2515
|
+
],
|
|
2154
2516
|
});
|
|
2155
|
-
|
|
2156
|
-
|
|
2517
|
+
|
|
2518
|
+
return res.once(
|
|
2519
|
+
ctx.status(200),
|
|
2520
|
+
ctx.json({
|
|
2521
|
+
success: true,
|
|
2522
|
+
errors: [],
|
|
2523
|
+
messages: [],
|
|
2524
|
+
result: body.hashes,
|
|
2525
|
+
})
|
|
2526
|
+
);
|
|
2527
|
+
}),
|
|
2528
|
+
rest.post("*/pages/assets/upload", (req, res, ctx) => {
|
|
2529
|
+
requests.push(req);
|
|
2530
|
+
|
|
2531
|
+
return res(
|
|
2532
|
+
ctx.status(200),
|
|
2533
|
+
ctx.json({
|
|
2534
|
+
success: true,
|
|
2535
|
+
errors: [],
|
|
2536
|
+
messages: [],
|
|
2537
|
+
result: null,
|
|
2538
|
+
})
|
|
2539
|
+
);
|
|
2540
|
+
})
|
|
2157
2541
|
);
|
|
2158
2542
|
|
|
2159
|
-
|
|
2160
|
-
const requests: RequestInit[] = [];
|
|
2161
|
-
setMockRawResponse("/pages/assets/upload", "POST", async (_, init) => {
|
|
2162
|
-
requests.push(init);
|
|
2543
|
+
await runWrangler("pages project upload .");
|
|
2163
2544
|
|
|
2164
|
-
|
|
2165
|
-
});
|
|
2545
|
+
expect(requests.length).toBe(3);
|
|
2166
2546
|
|
|
2167
|
-
|
|
2168
|
-
|
|
2547
|
+
const resolvedRequests = await Promise.all(
|
|
2548
|
+
requests.map(async (req) => await req.json<UploadPayloadFile>())
|
|
2549
|
+
);
|
|
2169
2550
|
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
|
|
2173
|
-
);
|
|
2174
|
-
});
|
|
2551
|
+
const sortedRequests = resolvedRequests.sort((a, b) => {
|
|
2552
|
+
const aKey = a.key as string;
|
|
2553
|
+
const bKey = b.key as string;
|
|
2175
2554
|
|
|
2176
|
-
|
|
2177
|
-
|
|
2178
|
-
});
|
|
2179
|
-
|
|
2180
|
-
let body = JSON.parse(
|
|
2181
|
-
sortedRequests[0].body as string
|
|
2182
|
-
) as UploadPayloadFile[];
|
|
2183
|
-
expect(body).toMatchObject([
|
|
2184
|
-
{
|
|
2185
|
-
key: "09a79777abda8ccc8bdd51dd3ff8e9e9",
|
|
2186
|
-
value: Buffer.from("func").toString("base64"),
|
|
2187
|
-
metadata: {
|
|
2188
|
-
contentType: "application/javascript",
|
|
2189
|
-
},
|
|
2190
|
-
base64: true,
|
|
2191
|
-
},
|
|
2192
|
-
]);
|
|
2555
|
+
return aKey?.localeCompare(bKey);
|
|
2556
|
+
});
|
|
2193
2557
|
|
|
2194
|
-
|
|
2195
|
-
|
|
2196
|
-
|
|
2558
|
+
for (const req of requests) {
|
|
2559
|
+
expect(req.headers.get("Authorization")).toBe(
|
|
2560
|
+
"Bearer <<funfetti-auth-jwt>>"
|
|
2561
|
+
);
|
|
2562
|
+
}
|
|
2197
2563
|
|
|
2198
|
-
|
|
2199
|
-
|
|
2200
|
-
|
|
2201
|
-
|
|
2202
|
-
{
|
|
2203
|
-
|
|
2204
|
-
value: Buffer.from("foobar").toString("base64"),
|
|
2205
|
-
metadata: {
|
|
2206
|
-
contentType: "image/png",
|
|
2207
|
-
},
|
|
2208
|
-
base64: true,
|
|
2564
|
+
expect(sortedRequests[0]).toMatchObject([
|
|
2565
|
+
{
|
|
2566
|
+
base64: true,
|
|
2567
|
+
key: "95dedb64e6d4940fc2e0f11f711cc2f4",
|
|
2568
|
+
metadata: {
|
|
2569
|
+
contentType: "application/octet-stream",
|
|
2209
2570
|
},
|
|
2210
|
-
|
|
2211
|
-
|
|
2212
|
-
|
|
2213
|
-
Authorization: "Bearer <<funfetti-auth-jwt>>",
|
|
2214
|
-
});
|
|
2571
|
+
value: "aGVhZGVyc2ZpbGU=",
|
|
2572
|
+
},
|
|
2573
|
+
]);
|
|
2215
2574
|
|
|
2216
|
-
|
|
2217
|
-
|
|
2218
|
-
|
|
2219
|
-
|
|
2220
|
-
{
|
|
2221
|
-
|
|
2222
|
-
value: Buffer.from("headersfile").toString("base64"),
|
|
2223
|
-
metadata: {
|
|
2224
|
-
contentType: "application/octet-stream",
|
|
2225
|
-
},
|
|
2226
|
-
base64: true,
|
|
2575
|
+
expect(sortedRequests[1]).toMatchObject([
|
|
2576
|
+
{
|
|
2577
|
+
base64: true,
|
|
2578
|
+
key: "2082190357cfd3617ccfe04f340c6247",
|
|
2579
|
+
metadata: {
|
|
2580
|
+
contentType: "image/png",
|
|
2227
2581
|
},
|
|
2228
|
-
|
|
2229
|
-
|
|
2582
|
+
value: "Zm9vYmFy",
|
|
2583
|
+
},
|
|
2584
|
+
]);
|
|
2230
2585
|
|
|
2231
|
-
|
|
2586
|
+
expect(sortedRequests[2]).toMatchObject([
|
|
2587
|
+
{
|
|
2588
|
+
base64: true,
|
|
2589
|
+
key: "09a79777abda8ccc8bdd51dd3ff8e9e9",
|
|
2590
|
+
metadata: {
|
|
2591
|
+
contentType: "application/javascript",
|
|
2592
|
+
},
|
|
2593
|
+
value: "ZnVuYw==",
|
|
2594
|
+
},
|
|
2595
|
+
]);
|
|
2232
2596
|
|
|
2233
2597
|
expect(std.out).toMatchInlineSnapshot(`
|
|
2234
2598
|
"✨ Success! Uploaded 3 files (TIMINGS)
|
|
@@ -2240,62 +2604,81 @@ and that at least one include rule is provided.
|
|
|
2240
2604
|
it("should retry uploads", async () => {
|
|
2241
2605
|
writeFileSync("logo.txt", "foobar");
|
|
2242
2606
|
|
|
2243
|
-
setMockResponse(
|
|
2244
|
-
"/pages/assets/check-missing",
|
|
2245
|
-
"POST",
|
|
2246
|
-
async (_, init) => {
|
|
2247
|
-
const body = JSON.parse(init.body as string) as { hashes: string[] };
|
|
2248
|
-
assertLater(() => {
|
|
2249
|
-
expect(init.headers).toMatchObject({
|
|
2250
|
-
Authorization: "Bearer <<funfetti-auth-jwt>>",
|
|
2251
|
-
});
|
|
2252
|
-
expect(body).toMatchObject({
|
|
2253
|
-
hashes: ["1a98fb08af91aca4a7df1764a2c4ddb0"],
|
|
2254
|
-
});
|
|
2255
|
-
});
|
|
2256
|
-
return body.hashes;
|
|
2257
|
-
}
|
|
2258
|
-
);
|
|
2259
|
-
|
|
2260
2607
|
// Accumulate multiple requests then assert afterwards
|
|
2261
|
-
const requests:
|
|
2262
|
-
|
|
2263
|
-
|
|
2608
|
+
const requests: RestRequest[] = [];
|
|
2609
|
+
msw.use(
|
|
2610
|
+
rest.post("*/pages/assets/check-missing", async (req, res, ctx) => {
|
|
2611
|
+
const body = (await req.json()) as { hashes: string[] };
|
|
2264
2612
|
|
|
2265
|
-
|
|
2266
|
-
|
|
2267
|
-
|
|
2268
|
-
|
|
2269
|
-
|
|
2270
|
-
|
|
2271
|
-
|
|
2272
|
-
|
|
2273
|
-
|
|
2274
|
-
|
|
2275
|
-
|
|
2613
|
+
expect(req.headers.get("Authorization")).toBe(
|
|
2614
|
+
"Bearer <<funfetti-auth-jwt>>"
|
|
2615
|
+
);
|
|
2616
|
+
expect(body).toMatchObject({
|
|
2617
|
+
hashes: ["1a98fb08af91aca4a7df1764a2c4ddb0"],
|
|
2618
|
+
});
|
|
2619
|
+
|
|
2620
|
+
return res.once(
|
|
2621
|
+
ctx.status(200),
|
|
2622
|
+
ctx.json({
|
|
2623
|
+
success: true,
|
|
2624
|
+
errors: [],
|
|
2625
|
+
messages: [],
|
|
2626
|
+
result: body.hashes,
|
|
2627
|
+
})
|
|
2628
|
+
);
|
|
2629
|
+
}),
|
|
2630
|
+
rest.post("*/pages/assets/upload", async (req, res, ctx) => {
|
|
2631
|
+
requests.push(req);
|
|
2632
|
+
|
|
2633
|
+
if (requests.length < 2) {
|
|
2634
|
+
return res(
|
|
2635
|
+
ctx.status(200),
|
|
2636
|
+
ctx.json({
|
|
2637
|
+
success: false,
|
|
2638
|
+
errors: [
|
|
2639
|
+
{
|
|
2640
|
+
code: 800000,
|
|
2641
|
+
message: "Something exploded, please retry",
|
|
2642
|
+
},
|
|
2643
|
+
],
|
|
2644
|
+
messages: [],
|
|
2645
|
+
result: null,
|
|
2646
|
+
})
|
|
2647
|
+
);
|
|
2648
|
+
} else {
|
|
2649
|
+
return res(
|
|
2650
|
+
ctx.status(200),
|
|
2651
|
+
ctx.json({
|
|
2652
|
+
success: true,
|
|
2653
|
+
errors: [],
|
|
2654
|
+
messages: [],
|
|
2655
|
+
result: null,
|
|
2656
|
+
})
|
|
2657
|
+
);
|
|
2658
|
+
}
|
|
2659
|
+
})
|
|
2660
|
+
);
|
|
2276
2661
|
|
|
2277
2662
|
await runWrangler("pages project upload .");
|
|
2278
2663
|
|
|
2279
2664
|
// Assert two identical requests
|
|
2280
2665
|
expect(requests.length).toBe(2);
|
|
2281
2666
|
for (const init of requests) {
|
|
2282
|
-
|
|
2283
|
-
|
|
2284
|
-
|
|
2285
|
-
});
|
|
2667
|
+
expect(init.headers.get("Authorization")).toBe(
|
|
2668
|
+
"Bearer <<funfetti-auth-jwt>>"
|
|
2669
|
+
);
|
|
2286
2670
|
|
|
2287
|
-
|
|
2288
|
-
|
|
2289
|
-
|
|
2290
|
-
|
|
2291
|
-
|
|
2292
|
-
|
|
2293
|
-
|
|
2294
|
-
},
|
|
2295
|
-
base64: true,
|
|
2671
|
+
const body = (await init.json()) as UploadPayloadFile[];
|
|
2672
|
+
expect(body).toMatchObject([
|
|
2673
|
+
{
|
|
2674
|
+
key: "1a98fb08af91aca4a7df1764a2c4ddb0",
|
|
2675
|
+
value: Buffer.from("foobar").toString("base64"),
|
|
2676
|
+
metadata: {
|
|
2677
|
+
contentType: "text/plain",
|
|
2296
2678
|
},
|
|
2297
|
-
|
|
2298
|
-
|
|
2679
|
+
base64: true,
|
|
2680
|
+
},
|
|
2681
|
+
]);
|
|
2299
2682
|
}
|
|
2300
2683
|
|
|
2301
2684
|
expect(std.out).toMatchInlineSnapshot(`
|
|
@@ -2313,33 +2696,52 @@ and that at least one include rule is provided.
|
|
|
2313
2696
|
|
|
2314
2697
|
mockGetToken("<<funfetti-auth-jwt>>");
|
|
2315
2698
|
|
|
2316
|
-
|
|
2317
|
-
|
|
2318
|
-
|
|
2319
|
-
async (
|
|
2320
|
-
const body =
|
|
2321
|
-
|
|
2322
|
-
|
|
2323
|
-
|
|
2324
|
-
|
|
2325
|
-
|
|
2326
|
-
|
|
2327
|
-
|
|
2328
|
-
|
|
2329
|
-
|
|
2330
|
-
|
|
2331
|
-
|
|
2332
|
-
});
|
|
2699
|
+
// Accumulate multiple requests then assert afterwards
|
|
2700
|
+
const requests: RestRequest[] = [];
|
|
2701
|
+
msw.use(
|
|
2702
|
+
rest.post("*/pages/assets/check-missing", async (req, res, ctx) => {
|
|
2703
|
+
const body = (await req.json()) as { hashes: string[] };
|
|
2704
|
+
|
|
2705
|
+
expect(req.headers.get("Authorization")).toBe(
|
|
2706
|
+
"Bearer <<funfetti-auth-jwt>>"
|
|
2707
|
+
);
|
|
2708
|
+
expect(body).toMatchObject({
|
|
2709
|
+
hashes: expect.arrayContaining([
|
|
2710
|
+
"d96fef225537c9f5e44a3cb27fd0b492",
|
|
2711
|
+
"2082190357cfd3617ccfe04f340c6247",
|
|
2712
|
+
"6be321bef99e758250dac034474ddbb8",
|
|
2713
|
+
"1a98fb08af91aca4a7df1764a2c4ddb0",
|
|
2714
|
+
]),
|
|
2333
2715
|
});
|
|
2334
|
-
return body.hashes;
|
|
2335
|
-
}
|
|
2336
|
-
);
|
|
2337
2716
|
|
|
2338
|
-
|
|
2339
|
-
|
|
2340
|
-
|
|
2341
|
-
|
|
2342
|
-
|
|
2717
|
+
return res.once(
|
|
2718
|
+
ctx.status(200),
|
|
2719
|
+
ctx.json({
|
|
2720
|
+
success: true,
|
|
2721
|
+
errors: [],
|
|
2722
|
+
messages: [],
|
|
2723
|
+
result: body.hashes,
|
|
2724
|
+
})
|
|
2725
|
+
);
|
|
2726
|
+
}),
|
|
2727
|
+
rest.post("*/pages/assets/upload", async (req, res, ctx) => {
|
|
2728
|
+
requests.push(req);
|
|
2729
|
+
|
|
2730
|
+
expect(req.headers.get("Authorization")).toBe(
|
|
2731
|
+
"Bearer <<funfetti-auth-jwt>>"
|
|
2732
|
+
);
|
|
2733
|
+
|
|
2734
|
+
return res(
|
|
2735
|
+
ctx.status(200),
|
|
2736
|
+
ctx.json({
|
|
2737
|
+
success: true,
|
|
2738
|
+
errors: [],
|
|
2739
|
+
messages: [],
|
|
2740
|
+
result: null,
|
|
2741
|
+
})
|
|
2742
|
+
);
|
|
2743
|
+
})
|
|
2744
|
+
);
|
|
2343
2745
|
|
|
2344
2746
|
await runWrangler("pages project upload .");
|
|
2345
2747
|
|
|
@@ -2347,10 +2749,7 @@ and that at least one include rule is provided.
|
|
|
2347
2749
|
expect(requests.length).toBe(3);
|
|
2348
2750
|
const bodies: UploadPayloadFile[][] = [];
|
|
2349
2751
|
for (const init of requests) {
|
|
2350
|
-
|
|
2351
|
-
Authorization: "Bearer <<funfetti-auth-jwt>>",
|
|
2352
|
-
});
|
|
2353
|
-
bodies.push(JSON.parse(init.body as string) as UploadPayloadFile[]);
|
|
2752
|
+
bodies.push((await init.json()) as UploadPayloadFile[]);
|
|
2354
2753
|
}
|
|
2355
2754
|
// One bucket should end up with 2 files
|
|
2356
2755
|
expect(bodies.map((b) => b.length).sort()).toEqual([1, 1, 2]);
|
|
@@ -2399,29 +2798,36 @@ and that at least one include rule is provided.
|
|
|
2399
2798
|
|
|
2400
2799
|
mockGetToken("<<funfetti-auth-jwt>>");
|
|
2401
2800
|
|
|
2402
|
-
|
|
2403
|
-
|
|
2404
|
-
|
|
2405
|
-
|
|
2406
|
-
|
|
2407
|
-
|
|
2408
|
-
|
|
2409
|
-
|
|
2410
|
-
|
|
2801
|
+
msw.use(
|
|
2802
|
+
rest.post(
|
|
2803
|
+
"*/pages/assets/check-missing",
|
|
2804
|
+
|
|
2805
|
+
async (req, res, ctx) => {
|
|
2806
|
+
const body = (await req.json()) as { hashes: string[] };
|
|
2807
|
+
|
|
2808
|
+
expect(req.headers.get("Authorization")).toBe(
|
|
2809
|
+
"Bearer <<funfetti-auth-jwt>>"
|
|
2810
|
+
);
|
|
2411
2811
|
expect(body).toMatchObject({
|
|
2412
2812
|
hashes: ["7b764dacfd211bebd8077828a7ddefd7"],
|
|
2413
2813
|
});
|
|
2414
|
-
});
|
|
2415
|
-
return body.hashes;
|
|
2416
|
-
}
|
|
2417
|
-
);
|
|
2418
2814
|
|
|
2419
|
-
|
|
2420
|
-
|
|
2421
|
-
|
|
2422
|
-
|
|
2423
|
-
|
|
2424
|
-
|
|
2815
|
+
return res.once(
|
|
2816
|
+
ctx.status(200),
|
|
2817
|
+
ctx.json({
|
|
2818
|
+
success: true,
|
|
2819
|
+
errors: [],
|
|
2820
|
+
messages: [],
|
|
2821
|
+
result: body.hashes,
|
|
2822
|
+
})
|
|
2823
|
+
);
|
|
2824
|
+
}
|
|
2825
|
+
),
|
|
2826
|
+
rest.post("*/pages/assets/upload", async (req, res, ctx) => {
|
|
2827
|
+
expect(req.headers.get("Authorization")).toBe(
|
|
2828
|
+
"Bearer <<funfetti-auth-jwt>>"
|
|
2829
|
+
);
|
|
2830
|
+
const body = (await req.json()) as UploadPayloadFile[];
|
|
2425
2831
|
expect(body).toMatchObject([
|
|
2426
2832
|
{
|
|
2427
2833
|
key: "7b764dacfd211bebd8077828a7ddefd7",
|
|
@@ -2432,8 +2838,18 @@ and that at least one include rule is provided.
|
|
|
2432
2838
|
base64: true,
|
|
2433
2839
|
},
|
|
2434
2840
|
]);
|
|
2435
|
-
|
|
2436
|
-
|
|
2841
|
+
|
|
2842
|
+
return res.once(
|
|
2843
|
+
ctx.status(200),
|
|
2844
|
+
ctx.json({
|
|
2845
|
+
success: true,
|
|
2846
|
+
errors: [],
|
|
2847
|
+
messages: [],
|
|
2848
|
+
result: null,
|
|
2849
|
+
})
|
|
2850
|
+
);
|
|
2851
|
+
})
|
|
2852
|
+
);
|
|
2437
2853
|
|
|
2438
2854
|
await runWrangler("pages project upload .");
|
|
2439
2855
|
|
|
@@ -2441,3 +2857,43 @@ and that at least one include rule is provided.
|
|
|
2441
2857
|
});
|
|
2442
2858
|
});
|
|
2443
2859
|
});
|
|
2860
|
+
|
|
2861
|
+
function mockFormDataToString(this: FormData) {
|
|
2862
|
+
const entries = [];
|
|
2863
|
+
for (const [key, value] of this.entries()) {
|
|
2864
|
+
if (value instanceof Blob) {
|
|
2865
|
+
const reader = new FileReaderSync();
|
|
2866
|
+
reader.readAsText(value);
|
|
2867
|
+
const result = reader.result;
|
|
2868
|
+
entries.push([key, result]);
|
|
2869
|
+
} else {
|
|
2870
|
+
entries.push([key, value]);
|
|
2871
|
+
}
|
|
2872
|
+
}
|
|
2873
|
+
return JSON.stringify({
|
|
2874
|
+
__formdata: entries,
|
|
2875
|
+
});
|
|
2876
|
+
}
|
|
2877
|
+
|
|
2878
|
+
async function mockFormDataFromString(this: MockedRequest): Promise<FormData> {
|
|
2879
|
+
const { __formdata } = await this.json();
|
|
2880
|
+
expect(__formdata).toBeInstanceOf(Array);
|
|
2881
|
+
|
|
2882
|
+
const form = new FormData();
|
|
2883
|
+
for (const [key, value] of __formdata) {
|
|
2884
|
+
form.set(key, value);
|
|
2885
|
+
}
|
|
2886
|
+
return form;
|
|
2887
|
+
}
|
|
2888
|
+
|
|
2889
|
+
// The following two functions workaround the fact that MSW does not yet support FormData in requests.
|
|
2890
|
+
// We use the fact that MSW relies upon `node-fetch` internally, which will call `toString()` on the FormData object,
|
|
2891
|
+
// rather than passing it through or serializing it as a proper FormData object.
|
|
2892
|
+
// The hack is to serialize FormData to a JSON string by overriding `FormData.toString()`.
|
|
2893
|
+
// And then to deserialize back to a FormData object by monkey-patching a `formData()` helper onto `MockedRequest`.
|
|
2894
|
+
FormData.prototype.toString = mockFormDataToString;
|
|
2895
|
+
export interface RestRequestWithFormData extends MockedRequest, RestRequest {
|
|
2896
|
+
formData(): Promise<FormData>;
|
|
2897
|
+
}
|
|
2898
|
+
(MockedRequest.prototype as RestRequestWithFormData).formData =
|
|
2899
|
+
mockFormDataFromString;
|