wrangler 2.6.1 → 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 -42
- package/src/__tests__/init.test.ts +782 -522
- 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 +1618 -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 +16 -18
- package/src/cli.ts +2 -2
- package/src/config/index.ts +2 -1
- 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 +32 -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 +35 -11
- package/src/dialogs.ts +136 -0
- package/src/dispatch-namespace.ts +1 -1
- package/src/docs/index.ts +97 -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} +16 -10
- package/src/init.ts +106 -60
- package/src/jest.d.ts +4 -0
- package/src/logger.ts +15 -3
- package/src/metrics/metrics-config.ts +1 -1
- package/src/metrics/send-event.ts +2 -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 +16 -5
- package/src/pages/upload.tsx +27 -6
- 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 +34498 -55459
- 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
|
|
|
@@ -335,6 +350,7 @@ describe("pages", () => {
|
|
|
335
350
|
--commit-hash The SHA to attach to this deployment [string]
|
|
336
351
|
--commit-message The commit message to attach to this deployment [string]
|
|
337
352
|
--commit-dirty Whether or not the workspace should be considered dirty for this deployment [boolean]
|
|
353
|
+
--skip-caching Skip asset caching which speeds up builds [boolean]
|
|
338
354
|
|
|
339
355
|
🚧 'wrangler pages <command>' is a beta command. Please report any issues to https://github.com/cloudflare/wrangler2/issues/new/choose"
|
|
340
356
|
`);
|
|
@@ -342,33 +358,34 @@ describe("pages", () => {
|
|
|
342
358
|
|
|
343
359
|
it("should upload a directory of files", async () => {
|
|
344
360
|
writeFileSync("logo.png", "foobar");
|
|
345
|
-
|
|
346
361
|
mockGetToken("<<funfetti-auth-jwt>>");
|
|
347
362
|
|
|
348
|
-
|
|
349
|
-
"
|
|
350
|
-
|
|
351
|
-
async (_, init) => {
|
|
352
|
-
const body = JSON.parse(init.body as string) as { hashes: string[] };
|
|
353
|
-
assertLater(() => {
|
|
354
|
-
expect(init.headers).toMatchObject({
|
|
355
|
-
Authorization: "Bearer <<funfetti-auth-jwt>>",
|
|
356
|
-
});
|
|
357
|
-
expect(body).toMatchObject({
|
|
358
|
-
hashes: ["2082190357cfd3617ccfe04f340c6247"],
|
|
359
|
-
});
|
|
360
|
-
});
|
|
361
|
-
return body.hashes;
|
|
362
|
-
}
|
|
363
|
-
);
|
|
363
|
+
msw.use(
|
|
364
|
+
rest.post("*/pages/assets/check-missing", async (req, res, ctx) => {
|
|
365
|
+
const body = await req.json();
|
|
364
366
|
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
367
|
+
expect(req.headers.get("Authorization")).toBe(
|
|
368
|
+
"Bearer <<funfetti-auth-jwt>>"
|
|
369
|
+
);
|
|
370
|
+
expect(body).toMatchObject({
|
|
371
|
+
hashes: ["2082190357cfd3617ccfe04f340c6247"],
|
|
369
372
|
});
|
|
370
|
-
|
|
371
|
-
|
|
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([
|
|
372
389
|
{
|
|
373
390
|
key: "2082190357cfd3617ccfe04f340c6247",
|
|
374
391
|
value: Buffer.from("foobar").toString("base64"),
|
|
@@ -378,39 +395,55 @@ describe("pages", () => {
|
|
|
378
395
|
base64: true,
|
|
379
396
|
},
|
|
380
397
|
]);
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
expect(
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
return {
|
|
400
|
-
url: "https://abcxyz.foo.pages.dev/",
|
|
401
|
-
};
|
|
402
|
-
}
|
|
403
|
-
);
|
|
404
|
-
|
|
405
|
-
setMockResponse(
|
|
406
|
-
"/accounts/:accountId/pages/projects/foo",
|
|
407
|
-
"GET",
|
|
408
|
-
async ([_url, accountId]) => {
|
|
409
|
-
assertLater(() => {
|
|
410
|
-
expect(accountId).toEqual("some-account-id");
|
|
411
|
-
});
|
|
412
|
-
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
|
+
],
|
|
413
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
|
+
)
|
|
414
447
|
);
|
|
415
448
|
|
|
416
449
|
await runWrangler("pages publish . --project-name=foo");
|
|
@@ -427,84 +460,35 @@ describe("pages", () => {
|
|
|
427
460
|
|
|
428
461
|
mockGetToken("<<funfetti-auth-jwt>>");
|
|
429
462
|
|
|
430
|
-
setMockResponse(
|
|
431
|
-
"/pages/assets/check-missing",
|
|
432
|
-
"POST",
|
|
433
|
-
async (_, init) => {
|
|
434
|
-
const body = JSON.parse(init.body as string) as { hashes: string[] };
|
|
435
|
-
assertLater(() => {
|
|
436
|
-
expect(init.headers).toMatchObject({
|
|
437
|
-
Authorization: "Bearer <<funfetti-auth-jwt>>",
|
|
438
|
-
});
|
|
439
|
-
expect(body).toMatchObject({
|
|
440
|
-
hashes: ["1a98fb08af91aca4a7df1764a2c4ddb0"],
|
|
441
|
-
});
|
|
442
|
-
});
|
|
443
|
-
return body.hashes;
|
|
444
|
-
}
|
|
445
|
-
);
|
|
446
|
-
|
|
447
463
|
// Accumulate multiple requests then assert afterwards
|
|
448
|
-
const requests:
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
if (requests.length < 2) {
|
|
453
|
-
return createFetchResult(null, false, [
|
|
454
|
-
{
|
|
455
|
-
code: 800000,
|
|
456
|
-
message: "Something exploded, please retry",
|
|
457
|
-
},
|
|
458
|
-
]);
|
|
459
|
-
} else {
|
|
460
|
-
return createFetchResult(null, true);
|
|
461
|
-
}
|
|
462
|
-
});
|
|
463
|
-
|
|
464
|
-
setMockResponse(
|
|
465
|
-
"/accounts/:accountId/pages/projects/foo/deployments",
|
|
466
|
-
async ([_url, accountId], init) => {
|
|
467
|
-
assertLater(() => {
|
|
468
|
-
expect(accountId).toEqual("some-account-id");
|
|
469
|
-
expect(init.method).toEqual("POST");
|
|
470
|
-
const body = init.body as FormData;
|
|
471
|
-
const manifest = JSON.parse(body.get("manifest") as string);
|
|
472
|
-
expect(manifest).toMatchInlineSnapshot(`
|
|
473
|
-
Object {
|
|
474
|
-
"/logo.txt": "1a98fb08af91aca4a7df1764a2c4ddb0",
|
|
475
|
-
}
|
|
476
|
-
`);
|
|
477
|
-
});
|
|
478
|
-
|
|
479
|
-
return {
|
|
480
|
-
url: "https://abcxyz.foo.pages.dev/",
|
|
481
|
-
};
|
|
482
|
-
}
|
|
483
|
-
);
|
|
484
|
-
|
|
485
|
-
setMockResponse(
|
|
486
|
-
"/accounts/:accountId/pages/projects/foo",
|
|
487
|
-
"GET",
|
|
488
|
-
async ([_url, accountId]) => {
|
|
489
|
-
assertLater(() => {
|
|
490
|
-
expect(accountId).toEqual("some-account-id");
|
|
491
|
-
});
|
|
492
|
-
return { deployment_configs: { production: {}, preview: {} } };
|
|
493
|
-
}
|
|
494
|
-
);
|
|
495
|
-
|
|
496
|
-
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();
|
|
497
468
|
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
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"],
|
|
504
474
|
});
|
|
505
475
|
|
|
506
|
-
|
|
507
|
-
|
|
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([
|
|
508
492
|
{
|
|
509
493
|
key: "1a98fb08af91aca4a7df1764a2c4ddb0",
|
|
510
494
|
value: Buffer.from("foobar").toString("base64"),
|
|
@@ -514,8 +498,80 @@ describe("pages", () => {
|
|
|
514
498
|
base64: true,
|
|
515
499
|
},
|
|
516
500
|
]);
|
|
517
|
-
|
|
518
|
-
|
|
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");
|
|
519
575
|
|
|
520
576
|
expect(std.out).toMatchInlineSnapshot(`
|
|
521
577
|
"✨ Success! Uploaded 1 files (TIMINGS)
|
|
@@ -526,104 +582,125 @@ describe("pages", () => {
|
|
|
526
582
|
|
|
527
583
|
it("should refetch a JWT if it expires while uploading", async () => {
|
|
528
584
|
writeFileSync("logo.txt", "foobar");
|
|
585
|
+
mockGetToken("<<funfetti-auth-jwt>>");
|
|
529
586
|
|
|
530
|
-
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[] };
|
|
531
591
|
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
assertLater(() => {
|
|
538
|
-
expect(init.headers).toMatchObject({
|
|
539
|
-
Authorization: "Bearer <<funfetti-auth-jwt>>",
|
|
540
|
-
});
|
|
541
|
-
expect(body).toMatchObject({
|
|
542
|
-
hashes: ["1a98fb08af91aca4a7df1764a2c4ddb0"],
|
|
543
|
-
});
|
|
592
|
+
expect(req.headers.get("Authorization")).toBe(
|
|
593
|
+
"Bearer <<funfetti-auth-jwt>>"
|
|
594
|
+
);
|
|
595
|
+
expect(body).toMatchObject({
|
|
596
|
+
hashes: ["1a98fb08af91aca4a7df1764a2c4ddb0"],
|
|
544
597
|
});
|
|
545
|
-
return body.hashes;
|
|
546
|
-
}
|
|
547
|
-
);
|
|
548
598
|
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
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([
|
|
559
612
|
{
|
|
560
|
-
|
|
561
|
-
|
|
613
|
+
key: "1a98fb08af91aca4a7df1764a2c4ddb0",
|
|
614
|
+
value: Buffer.from("foobar").toString("base64"),
|
|
615
|
+
metadata: {
|
|
616
|
+
contentType: "text/plain",
|
|
617
|
+
},
|
|
618
|
+
base64: true,
|
|
562
619
|
},
|
|
563
620
|
]);
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
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
|
+
],
|
|
587
663
|
}
|
|
588
|
-
);
|
|
664
|
+
`);
|
|
589
665
|
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
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
|
+
)
|
|
599
693
|
);
|
|
600
694
|
|
|
601
695
|
await runWrangler("pages publish . --project-name=foo");
|
|
602
696
|
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
expect(requests[0].headers).toMatchObject({
|
|
607
|
-
Authorization: "Bearer <<funfetti-auth-jwt>>",
|
|
608
|
-
});
|
|
609
|
-
|
|
610
|
-
expect(requests[1].headers).toMatchObject({
|
|
611
|
-
Authorization: "Bearer <<funfetti-auth-jwt2>>",
|
|
612
|
-
});
|
|
697
|
+
expect(requests[0].headers.get("Authorization")).toBe(
|
|
698
|
+
"Bearer <<funfetti-auth-jwt>>"
|
|
699
|
+
);
|
|
613
700
|
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
{
|
|
618
|
-
key: "1a98fb08af91aca4a7df1764a2c4ddb0",
|
|
619
|
-
value: Buffer.from("foobar").toString("base64"),
|
|
620
|
-
metadata: {
|
|
621
|
-
contentType: "text/plain",
|
|
622
|
-
},
|
|
623
|
-
base64: true,
|
|
624
|
-
},
|
|
625
|
-
]);
|
|
626
|
-
}
|
|
701
|
+
expect(requests[1].headers.get("Authorization")).toBe(
|
|
702
|
+
"Bearer <<funfetti-auth-jwt2>>"
|
|
703
|
+
);
|
|
627
704
|
|
|
628
705
|
expect(std.out).toMatchInlineSnapshot(`
|
|
629
706
|
"✨ Success! Uploaded 1 files (TIMINGS)
|
|
@@ -640,80 +717,110 @@ describe("pages", () => {
|
|
|
640
717
|
|
|
641
718
|
mockGetToken("<<funfetti-auth-jwt>>");
|
|
642
719
|
|
|
643
|
-
setMockResponse(
|
|
644
|
-
"/pages/assets/check-missing",
|
|
645
|
-
"POST",
|
|
646
|
-
async (_, init) => {
|
|
647
|
-
const body = JSON.parse(init.body as string) as { hashes: string[] };
|
|
648
|
-
assertLater(() => {
|
|
649
|
-
expect(init.headers).toMatchObject({
|
|
650
|
-
Authorization: "Bearer <<funfetti-auth-jwt>>",
|
|
651
|
-
});
|
|
652
|
-
expect(body).toMatchObject({
|
|
653
|
-
hashes: expect.arrayContaining([
|
|
654
|
-
"d96fef225537c9f5e44a3cb27fd0b492",
|
|
655
|
-
"2082190357cfd3617ccfe04f340c6247",
|
|
656
|
-
"6be321bef99e758250dac034474ddbb8",
|
|
657
|
-
"1a98fb08af91aca4a7df1764a2c4ddb0",
|
|
658
|
-
]),
|
|
659
|
-
});
|
|
660
|
-
});
|
|
661
|
-
return body.hashes;
|
|
662
|
-
}
|
|
663
|
-
);
|
|
664
|
-
|
|
665
720
|
// Accumulate multiple requests then assert afterwards
|
|
666
|
-
const requests:
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
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
|
+
};
|
|
670
728
|
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
expect
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
"/logo.html": "d96fef225537c9f5e44a3cb27fd0b492",
|
|
682
|
-
"/logo.js": "6be321bef99e758250dac034474ddbb8",
|
|
683
|
-
"/logo.png": "2082190357cfd3617ccfe04f340c6247",
|
|
684
|
-
"/logo.txt": "1a98fb08af91aca4a7df1764a2c4ddb0",
|
|
685
|
-
}
|
|
686
|
-
`);
|
|
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
|
+
]),
|
|
687
739
|
});
|
|
688
740
|
|
|
689
|
-
return
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
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);
|
|
694
753
|
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
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
|
+
)
|
|
704
817
|
);
|
|
705
818
|
|
|
706
819
|
await runWrangler("pages publish . --project-name=foo");
|
|
707
820
|
|
|
708
821
|
// We have 3 buckets, so expect 3 uploads
|
|
709
822
|
expect(requests.length).toBe(3);
|
|
710
|
-
|
|
711
|
-
for (const init of requests) {
|
|
712
|
-
expect(init.headers).toMatchObject({
|
|
713
|
-
Authorization: "Bearer <<funfetti-auth-jwt>>",
|
|
714
|
-
});
|
|
715
|
-
bodies.push(JSON.parse(init.body as string) as UploadPayloadFile[]);
|
|
716
|
-
}
|
|
823
|
+
|
|
717
824
|
// One bucket should end up with 2 files
|
|
718
825
|
expect(bodies.map((b) => b.length).sort()).toEqual([1, 1, 2]);
|
|
719
826
|
// But we don't know the order, so flatten and test without ordering
|
|
@@ -763,82 +870,105 @@ describe("pages", () => {
|
|
|
763
870
|
|
|
764
871
|
mockGetToken("<<funfetti-auth-jwt>>");
|
|
765
872
|
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
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 {
|
|
771
879
|
hashes: string[];
|
|
772
880
|
};
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
});
|
|
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
|
+
]),
|
|
785
892
|
});
|
|
786
|
-
return body.hashes;
|
|
787
|
-
}
|
|
788
|
-
);
|
|
789
893
|
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
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);
|
|
795
906
|
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
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();
|
|
803
927
|
const manifest = JSON.parse(body.get("manifest") as string);
|
|
804
928
|
expect(manifest).toMatchInlineSnapshot(`
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
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
|
+
)
|
|
829
966
|
);
|
|
830
967
|
|
|
831
968
|
await runWrangler(`pages publish public --project-name=foo`);
|
|
832
969
|
|
|
833
970
|
// We have 3 buckets, so expect 3 uploads
|
|
834
971
|
expect(requests.length).toBe(3);
|
|
835
|
-
const bodies: UploadPayloadFile[][] = [];
|
|
836
|
-
for (const init of requests) {
|
|
837
|
-
expect(init.headers).toMatchObject({
|
|
838
|
-
Authorization: "Bearer <<funfetti-auth-jwt>>",
|
|
839
|
-
});
|
|
840
|
-
bodies.push(JSON.parse(init.body as string) as UploadPayloadFile[]);
|
|
841
|
-
}
|
|
842
972
|
// One bucket should end up with 2 files
|
|
843
973
|
expect(bodies.map((b) => b.length).sort()).toEqual([1, 1, 2]);
|
|
844
974
|
// But we don't know the order, so flatten and test without ordering
|
|
@@ -888,83 +1018,106 @@ describe("pages", () => {
|
|
|
888
1018
|
|
|
889
1019
|
mockGetToken("<<funfetti-auth-jwt>>");
|
|
890
1020
|
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
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 {
|
|
896
1027
|
hashes: string[];
|
|
897
1028
|
};
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
});
|
|
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
|
+
]),
|
|
910
1040
|
});
|
|
911
|
-
return body.hashes;
|
|
912
|
-
}
|
|
913
|
-
);
|
|
914
1041
|
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
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");
|
|
920
1074
|
|
|
921
|
-
|
|
922
|
-
"/accounts/:accountId/pages/projects/foo/deployments",
|
|
923
|
-
async ([_url, accountId], init) => {
|
|
924
|
-
assertLater(() => {
|
|
925
|
-
expect(accountId).toEqual("some-account-id");
|
|
926
|
-
expect(init.method).toEqual("POST");
|
|
927
|
-
const body = init.body as FormData;
|
|
1075
|
+
const body = await (req as RestRequestWithFormData).formData();
|
|
928
1076
|
const manifest = JSON.parse(body.get("manifest") as string);
|
|
929
1077
|
expect(manifest).toMatchInlineSnapshot(`
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
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
|
+
)
|
|
954
1115
|
);
|
|
955
1116
|
|
|
956
1117
|
chdir("public");
|
|
957
1118
|
await runWrangler(`pages publish . --project-name=foo`);
|
|
958
|
-
|
|
959
1119
|
// We have 3 buckets, so expect 3 uploads
|
|
960
1120
|
expect(requests.length).toBe(3);
|
|
961
|
-
const bodies: UploadPayloadFile[][] = [];
|
|
962
|
-
for (const init of requests) {
|
|
963
|
-
expect(init.headers).toMatchObject({
|
|
964
|
-
Authorization: "Bearer <<funfetti-auth-jwt>>",
|
|
965
|
-
});
|
|
966
|
-
bodies.push(JSON.parse(init.body as string) as UploadPayloadFile[]);
|
|
967
|
-
}
|
|
968
1121
|
// One bucket should end up with 2 files
|
|
969
1122
|
expect(bodies.map((b) => b.length).sort()).toEqual([1, 1, 2]);
|
|
970
1123
|
// But we don't know the order, so flatten and test without ordering
|
|
@@ -1012,29 +1165,35 @@ describe("pages", () => {
|
|
|
1012
1165
|
|
|
1013
1166
|
mockGetToken("<<funfetti-auth-jwt>>");
|
|
1014
1167
|
|
|
1015
|
-
|
|
1016
|
-
"
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
assertLater(() => {
|
|
1021
|
-
expect(init.headers).toMatchObject({
|
|
1022
|
-
Authorization: "Bearer <<funfetti-auth-jwt>>",
|
|
1023
|
-
});
|
|
1024
|
-
expect(body).toMatchObject({
|
|
1025
|
-
hashes: ["7b764dacfd211bebd8077828a7ddefd7"],
|
|
1026
|
-
});
|
|
1027
|
-
});
|
|
1028
|
-
return body.hashes;
|
|
1029
|
-
}
|
|
1030
|
-
);
|
|
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
|
+
};
|
|
1031
1173
|
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1174
|
+
expect(req.headers.get("Authorization")).toBe(
|
|
1175
|
+
"Bearer <<funfetti-auth-jwt>>"
|
|
1176
|
+
);
|
|
1177
|
+
expect(body).toMatchObject({
|
|
1178
|
+
hashes: ["7b764dacfd211bebd8077828a7ddefd7"],
|
|
1036
1179
|
});
|
|
1037
|
-
|
|
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[];
|
|
1038
1197
|
expect(body).toMatchObject([
|
|
1039
1198
|
{
|
|
1040
1199
|
key: "7b764dacfd211bebd8077828a7ddefd7",
|
|
@@ -1045,25 +1204,50 @@ describe("pages", () => {
|
|
|
1045
1204
|
base64: true,
|
|
1046
1205
|
},
|
|
1047
1206
|
]);
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
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
|
+
)
|
|
1067
1251
|
);
|
|
1068
1252
|
|
|
1069
1253
|
await runWrangler("pages publish . --project-name=foo");
|
|
@@ -1102,30 +1286,35 @@ describe("pages", () => {
|
|
|
1102
1286
|
|
|
1103
1287
|
mockGetToken("<<funfetti-auth-jwt>>");
|
|
1104
1288
|
|
|
1105
|
-
|
|
1106
|
-
"
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
assertLater(() => {
|
|
1111
|
-
expect(init.headers).toMatchObject({
|
|
1112
|
-
Authorization: "Bearer <<funfetti-auth-jwt>>",
|
|
1113
|
-
});
|
|
1114
|
-
expect(body).toMatchObject({
|
|
1115
|
-
hashes: ["13a03eaf24ae98378acd36ea00f77f2f"],
|
|
1116
|
-
});
|
|
1117
|
-
});
|
|
1118
|
-
return body.hashes;
|
|
1119
|
-
}
|
|
1120
|
-
);
|
|
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
|
+
};
|
|
1121
1294
|
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1295
|
+
expect(req.headers.get("Authorization")).toBe(
|
|
1296
|
+
"Bearer <<funfetti-auth-jwt>>"
|
|
1297
|
+
);
|
|
1298
|
+
expect(body).toMatchObject({
|
|
1299
|
+
hashes: ["13a03eaf24ae98378acd36ea00f77f2f"],
|
|
1126
1300
|
});
|
|
1127
|
-
|
|
1128
|
-
|
|
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([
|
|
1129
1318
|
{
|
|
1130
1319
|
key: "13a03eaf24ae98378acd36ea00f77f2f",
|
|
1131
1320
|
value: Buffer.from("This is a readme").toString("base64"),
|
|
@@ -1135,46 +1324,51 @@ describe("pages", () => {
|
|
|
1135
1324
|
base64: true,
|
|
1136
1325
|
},
|
|
1137
1326
|
]);
|
|
1138
|
-
|
|
1139
|
-
|
|
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
|
+
);
|
|
1140
1341
|
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
"POST",
|
|
1144
|
-
async (_, init) => {
|
|
1145
|
-
assertLater(() => {
|
|
1146
|
-
expect(init.headers).toMatchObject({
|
|
1147
|
-
Authorization: "Bearer <<funfetti-auth-jwt>>",
|
|
1148
|
-
});
|
|
1149
|
-
const body = JSON.parse(init.body as string) as UploadPayloadFile[];
|
|
1150
|
-
expect(body).toMatchObject({
|
|
1151
|
-
hashes: ["13a03eaf24ae98378acd36ea00f77f2f"],
|
|
1152
|
-
});
|
|
1342
|
+
expect(await req.json()).toMatchObject({
|
|
1343
|
+
hashes: ["13a03eaf24ae98378acd36ea00f77f2f"],
|
|
1153
1344
|
});
|
|
1154
1345
|
|
|
1155
|
-
return
|
|
1156
|
-
|
|
1157
|
-
|
|
1346
|
+
return res.once(
|
|
1347
|
+
ctx.status(200),
|
|
1348
|
+
ctx.json({
|
|
1349
|
+
success: true,
|
|
1350
|
+
errors: [],
|
|
1351
|
+
messages: [],
|
|
1352
|
+
result: true,
|
|
1353
|
+
})
|
|
1354
|
+
);
|
|
1355
|
+
}),
|
|
1158
1356
|
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
expect(init.method).toEqual("POST");
|
|
1165
|
-
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();
|
|
1166
1362
|
const manifest = JSON.parse(body.get("manifest") as string);
|
|
1167
1363
|
|
|
1168
1364
|
// for Functions projects, we auto-generate a `_worker.js`,
|
|
1169
1365
|
// `functions-filepath-routing-config.json`, and `_routes.json`
|
|
1170
1366
|
// file, based on the contents of `/functions`
|
|
1171
|
-
const generatedWorkerJS = body.get("_worker.js") as
|
|
1172
|
-
const generatedRoutesJSON =
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
body.get("functions-filepath-routing-config.json") as Blob
|
|
1177
|
-
).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;
|
|
1178
1372
|
|
|
1179
1373
|
// make sure this is all we uploaded
|
|
1180
1374
|
expect([...body.keys()]).toEqual([
|
|
@@ -1185,10 +1379,10 @@ describe("pages", () => {
|
|
|
1185
1379
|
]);
|
|
1186
1380
|
|
|
1187
1381
|
expect(manifest).toMatchInlineSnapshot(`
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1382
|
+
Object {
|
|
1383
|
+
"/README.md": "13a03eaf24ae98378acd36ea00f77f2f",
|
|
1384
|
+
}
|
|
1385
|
+
`);
|
|
1192
1386
|
|
|
1193
1387
|
// the contents of the generated `_worker.js` file is pretty massive, so I don't
|
|
1194
1388
|
// think snapshot testing makes much sense here. Plus, calling
|
|
@@ -1197,7 +1391,7 @@ describe("pages", () => {
|
|
|
1197
1391
|
// file contents is too big). So for now, let's test that _worker.js was indeed
|
|
1198
1392
|
// generated and that the file size is greater than zero
|
|
1199
1393
|
expect(generatedWorkerJS).not.toBeNull();
|
|
1200
|
-
expect(generatedWorkerJS.
|
|
1394
|
+
expect(generatedWorkerJS.length).toBeGreaterThan(0);
|
|
1201
1395
|
|
|
1202
1396
|
const maybeRoutesJSONSpec = JSON.parse(generatedRoutesJSON);
|
|
1203
1397
|
expect(isRoutesJSONSpec(maybeRoutesJSONSpec)).toBe(true);
|
|
@@ -1226,23 +1420,38 @@ describe("pages", () => {
|
|
|
1226
1420
|
],
|
|
1227
1421
|
baseURL: "/",
|
|
1228
1422
|
});
|
|
1229
|
-
});
|
|
1230
|
-
|
|
1231
|
-
return {
|
|
1232
|
-
url: "https://abcxyz.foo.pages.dev/",
|
|
1233
|
-
};
|
|
1234
|
-
}
|
|
1235
|
-
);
|
|
1236
1423
|
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
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
|
+
)
|
|
1246
1455
|
);
|
|
1247
1456
|
|
|
1248
1457
|
await runWrangler("pages publish public --project-name=foo");
|
|
@@ -1277,30 +1486,35 @@ describe("pages", () => {
|
|
|
1277
1486
|
|
|
1278
1487
|
mockGetToken("<<funfetti-auth-jwt>>");
|
|
1279
1488
|
|
|
1280
|
-
|
|
1281
|
-
"
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
assertLater(() => {
|
|
1286
|
-
expect(init.headers).toMatchObject({
|
|
1287
|
-
Authorization: "Bearer <<funfetti-auth-jwt>>",
|
|
1288
|
-
});
|
|
1289
|
-
expect(body).toMatchObject({
|
|
1290
|
-
hashes: ["13a03eaf24ae98378acd36ea00f77f2f"],
|
|
1291
|
-
});
|
|
1292
|
-
});
|
|
1293
|
-
return body.hashes;
|
|
1294
|
-
}
|
|
1295
|
-
);
|
|
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
|
+
};
|
|
1296
1494
|
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1495
|
+
expect(req.headers.get("Authorization")).toBe(
|
|
1496
|
+
"Bearer <<funfetti-auth-jwt>>"
|
|
1497
|
+
);
|
|
1498
|
+
expect(body).toMatchObject({
|
|
1499
|
+
hashes: ["13a03eaf24ae98378acd36ea00f77f2f"],
|
|
1301
1500
|
});
|
|
1302
|
-
|
|
1303
|
-
|
|
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([
|
|
1304
1518
|
{
|
|
1305
1519
|
key: "13a03eaf24ae98378acd36ea00f77f2f",
|
|
1306
1520
|
value: Buffer.from("This is a readme").toString("base64"),
|
|
@@ -1310,56 +1524,75 @@ describe("pages", () => {
|
|
|
1310
1524
|
base64: true,
|
|
1311
1525
|
},
|
|
1312
1526
|
]);
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
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();
|
|
1323
1542
|
const manifest = JSON.parse(body.get("manifest") as string);
|
|
1324
|
-
const customWorkerJS =
|
|
1325
|
-
body.get("_worker.js") as Blob
|
|
1326
|
-
).text();
|
|
1543
|
+
const customWorkerJS = body.get("_worker.js");
|
|
1327
1544
|
|
|
1328
1545
|
// make sure this is all we uploaded
|
|
1329
|
-
expect([...body.keys()]).toEqual(
|
|
1546
|
+
expect([...body.keys()].sort()).toEqual(
|
|
1547
|
+
["manifest", "_worker.js"].sort()
|
|
1548
|
+
);
|
|
1330
1549
|
|
|
1331
1550
|
expect(manifest).toMatchInlineSnapshot(`
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1551
|
+
Object {
|
|
1552
|
+
"/README.md": "13a03eaf24ae98378acd36ea00f77f2f",
|
|
1553
|
+
}
|
|
1554
|
+
`);
|
|
1336
1555
|
|
|
1337
1556
|
expect(customWorkerJS).toMatchInlineSnapshot(`
|
|
1338
|
-
"
|
|
1339
|
-
export default {
|
|
1340
|
-
async fetch(request, env) {
|
|
1341
|
-
const url = new URL(request.url);
|
|
1342
|
-
return url.pathname.startsWith('/api/') ? new Response('Ok') : env.ASSETS.fetch(request);
|
|
1343
|
-
};
|
|
1344
1557
|
"
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
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
|
+
)
|
|
1363
1596
|
);
|
|
1364
1597
|
|
|
1365
1598
|
await runWrangler("pages publish public --project-name=foo");
|
|
@@ -1413,31 +1646,35 @@ describe("pages", () => {
|
|
|
1413
1646
|
);
|
|
1414
1647
|
|
|
1415
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
|
+
};
|
|
1416
1654
|
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
assertLater(() => {
|
|
1423
|
-
expect(init.headers).toMatchObject({
|
|
1424
|
-
Authorization: "Bearer <<funfetti-auth-jwt>>",
|
|
1425
|
-
});
|
|
1426
|
-
expect(body).toMatchObject({
|
|
1427
|
-
hashes: ["13a03eaf24ae98378acd36ea00f77f2f"],
|
|
1428
|
-
});
|
|
1655
|
+
expect(req.headers.get("Authorization")).toBe(
|
|
1656
|
+
"Bearer <<funfetti-auth-jwt>>"
|
|
1657
|
+
);
|
|
1658
|
+
expect(body).toMatchObject({
|
|
1659
|
+
hashes: ["13a03eaf24ae98378acd36ea00f77f2f"],
|
|
1429
1660
|
});
|
|
1430
|
-
return body.hashes;
|
|
1431
|
-
}
|
|
1432
|
-
);
|
|
1433
1661
|
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
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([
|
|
1441
1678
|
{
|
|
1442
1679
|
key: "13a03eaf24ae98378acd36ea00f77f2f",
|
|
1443
1680
|
value: Buffer.from("This is a readme").toString("base64"),
|
|
@@ -1447,60 +1684,67 @@ describe("pages", () => {
|
|
|
1447
1684
|
base64: true,
|
|
1448
1685
|
},
|
|
1449
1686
|
]);
|
|
1450
|
-
});
|
|
1451
|
-
});
|
|
1452
1687
|
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
})
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
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
|
+
);
|
|
1466
1702
|
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1703
|
+
expect(await req.json()).toMatchObject({
|
|
1704
|
+
hashes: ["13a03eaf24ae98378acd36ea00f77f2f"],
|
|
1705
|
+
});
|
|
1470
1706
|
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
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();
|
|
1478
1722
|
const manifest = JSON.parse(body.get("manifest") as string);
|
|
1479
|
-
const generatedWorkerJS = body.get("_worker.js") as
|
|
1480
|
-
const customRoutesJSON =
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
body.get("functions-filepath-routing-config.json") as Blob
|
|
1485
|
-
).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;
|
|
1486
1728
|
|
|
1487
1729
|
// make sure this is all we uploaded
|
|
1488
|
-
expect([...body.keys()]).toEqual(
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1730
|
+
expect([...body.keys()].sort()).toEqual(
|
|
1731
|
+
[
|
|
1732
|
+
"manifest",
|
|
1733
|
+
"functions-filepath-routing-config.json",
|
|
1734
|
+
"_worker.js",
|
|
1735
|
+
"_routes.json",
|
|
1736
|
+
].sort()
|
|
1737
|
+
);
|
|
1494
1738
|
|
|
1495
1739
|
expect(manifest).toMatchInlineSnapshot(`
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1740
|
+
Object {
|
|
1741
|
+
"/README.md": "13a03eaf24ae98378acd36ea00f77f2f",
|
|
1742
|
+
}
|
|
1743
|
+
`);
|
|
1500
1744
|
|
|
1501
1745
|
// file content of generated `_worker.js` is too massive to snapshot test
|
|
1502
1746
|
expect(generatedWorkerJS).not.toBeNull();
|
|
1503
|
-
expect(generatedWorkerJS.
|
|
1747
|
+
expect(generatedWorkerJS.length).toBeGreaterThan(0);
|
|
1504
1748
|
|
|
1505
1749
|
const customRoutes = JSON.parse(customRoutesJSON);
|
|
1506
1750
|
expect(customRoutes).toMatchObject({
|
|
@@ -1517,7 +1761,6 @@ describe("pages", () => {
|
|
|
1517
1761
|
// The actual shape doesn't matter that much since this
|
|
1518
1762
|
// is only used for display in Dash, but it's still useful for
|
|
1519
1763
|
// tracking unexpected changes to this config.
|
|
1520
|
-
console.log(generatedFilepathRoutingConfig);
|
|
1521
1764
|
expect(parsedFilepathRoutingConfig).toStrictEqual({
|
|
1522
1765
|
routes: [
|
|
1523
1766
|
{
|
|
@@ -1535,23 +1778,38 @@ describe("pages", () => {
|
|
|
1535
1778
|
],
|
|
1536
1779
|
baseURL: "/",
|
|
1537
1780
|
});
|
|
1538
|
-
});
|
|
1539
|
-
|
|
1540
|
-
return {
|
|
1541
|
-
url: "https://abcxyz.foo.pages.dev/",
|
|
1542
|
-
};
|
|
1543
|
-
}
|
|
1544
|
-
);
|
|
1545
1781
|
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
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
|
+
)
|
|
1555
1813
|
);
|
|
1556
1814
|
|
|
1557
1815
|
await runWrangler("pages publish public --project-name=foo");
|
|
@@ -1603,31 +1861,35 @@ describe("pages", () => {
|
|
|
1603
1861
|
);
|
|
1604
1862
|
|
|
1605
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
|
+
};
|
|
1606
1869
|
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
assertLater(() => {
|
|
1613
|
-
expect(init.headers).toMatchObject({
|
|
1614
|
-
Authorization: "Bearer <<funfetti-auth-jwt>>",
|
|
1615
|
-
});
|
|
1616
|
-
expect(body).toMatchObject({
|
|
1617
|
-
hashes: ["13a03eaf24ae98378acd36ea00f77f2f"],
|
|
1618
|
-
});
|
|
1870
|
+
expect(req.headers.get("Authorization")).toBe(
|
|
1871
|
+
"Bearer <<funfetti-auth-jwt>>"
|
|
1872
|
+
);
|
|
1873
|
+
expect(body).toMatchObject({
|
|
1874
|
+
hashes: ["13a03eaf24ae98378acd36ea00f77f2f"],
|
|
1619
1875
|
});
|
|
1620
|
-
return body.hashes;
|
|
1621
|
-
}
|
|
1622
|
-
);
|
|
1623
1876
|
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
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([
|
|
1631
1893
|
{
|
|
1632
1894
|
key: "13a03eaf24ae98378acd36ea00f77f2f",
|
|
1633
1895
|
value: Buffer.from("This is a readme").toString("base64"),
|
|
@@ -1637,18 +1899,35 @@ describe("pages", () => {
|
|
|
1637
1899
|
base64: true,
|
|
1638
1900
|
},
|
|
1639
1901
|
]);
|
|
1640
|
-
});
|
|
1641
|
-
});
|
|
1642
1902
|
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
|
|
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
|
+
)
|
|
1652
1931
|
);
|
|
1653
1932
|
|
|
1654
1933
|
await expect(runWrangler("pages publish public --project-name=foo"))
|
|
@@ -1696,30 +1975,35 @@ and that at least one include rule is provided.
|
|
|
1696
1975
|
|
|
1697
1976
|
mockGetToken("<<funfetti-auth-jwt>>");
|
|
1698
1977
|
|
|
1699
|
-
|
|
1700
|
-
"
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
assertLater(() => {
|
|
1705
|
-
expect(init.headers).toMatchObject({
|
|
1706
|
-
Authorization: "Bearer <<funfetti-auth-jwt>>",
|
|
1707
|
-
});
|
|
1708
|
-
expect(body).toMatchObject({
|
|
1709
|
-
hashes: ["13a03eaf24ae98378acd36ea00f77f2f"],
|
|
1710
|
-
});
|
|
1711
|
-
});
|
|
1712
|
-
return body.hashes;
|
|
1713
|
-
}
|
|
1714
|
-
);
|
|
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
|
+
};
|
|
1715
1983
|
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1984
|
+
expect(req.headers.get("Authorization")).toBe(
|
|
1985
|
+
"Bearer <<funfetti-auth-jwt>>"
|
|
1986
|
+
);
|
|
1987
|
+
expect(body).toMatchObject({
|
|
1988
|
+
hashes: ["13a03eaf24ae98378acd36ea00f77f2f"],
|
|
1720
1989
|
});
|
|
1721
|
-
|
|
1722
|
-
|
|
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([
|
|
1723
2007
|
{
|
|
1724
2008
|
key: "13a03eaf24ae98378acd36ea00f77f2f",
|
|
1725
2009
|
value: Buffer.from("This is a readme").toString("base64"),
|
|
@@ -1729,41 +2013,44 @@ and that at least one include rule is provided.
|
|
|
1729
2013
|
base64: true,
|
|
1730
2014
|
},
|
|
1731
2015
|
]);
|
|
1732
|
-
});
|
|
1733
|
-
});
|
|
1734
2016
|
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
})
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
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"],
|
|
1747
2034
|
});
|
|
1748
2035
|
|
|
1749
|
-
return
|
|
1750
|
-
|
|
1751
|
-
|
|
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();
|
|
1752
2050
|
|
|
1753
|
-
setMockResponse(
|
|
1754
|
-
"/accounts/:accountId/pages/projects/foo/deployments",
|
|
1755
|
-
async ([_url, accountId], init) => {
|
|
1756
|
-
assertLater(async () => {
|
|
1757
|
-
expect(accountId).toEqual("some-account-id");
|
|
1758
|
-
expect(init.method).toEqual("POST");
|
|
1759
|
-
const body = init.body as FormData;
|
|
1760
2051
|
const manifest = JSON.parse(body.get("manifest") as string);
|
|
1761
|
-
const customWorkerJS =
|
|
1762
|
-
|
|
1763
|
-
).text();
|
|
1764
|
-
const customRoutesJSON = await (
|
|
1765
|
-
body.get("_routes.json") as Blob
|
|
1766
|
-
).text();
|
|
2052
|
+
const customWorkerJS = body.get("_worker.js") as string;
|
|
2053
|
+
const customRoutesJSON = body.get("_routes.json") as string;
|
|
1767
2054
|
|
|
1768
2055
|
// make sure this is all we uploaded
|
|
1769
2056
|
expect([...body.keys()]).toEqual([
|
|
@@ -1771,47 +2058,61 @@ and that at least one include rule is provided.
|
|
|
1771
2058
|
"_worker.js",
|
|
1772
2059
|
"_routes.json",
|
|
1773
2060
|
]);
|
|
1774
|
-
|
|
2061
|
+
expect(req.params.accountId).toEqual("some-account-id");
|
|
1775
2062
|
expect(manifest).toMatchInlineSnapshot(`
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
2063
|
+
Object {
|
|
2064
|
+
"/README.md": "13a03eaf24ae98378acd36ea00f77f2f",
|
|
2065
|
+
}
|
|
2066
|
+
`);
|
|
1780
2067
|
|
|
1781
2068
|
expect(customWorkerJS).toMatchInlineSnapshot(`
|
|
1782
|
-
"
|
|
1783
|
-
export default {
|
|
1784
|
-
async fetch(request, env) {
|
|
1785
|
-
const url = new URL(request.url);
|
|
1786
|
-
return url.pathname.startsWith('/api/') ? new Response('Ok') : env.ASSETS.fetch(request);
|
|
1787
|
-
};
|
|
1788
2069
|
"
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
|
|
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({
|
|
1793
2079
|
version: ROUTES_SPEC_VERSION,
|
|
1794
2080
|
description: "Custom _routes.json file",
|
|
1795
2081
|
include: ["/api/*"],
|
|
1796
2082
|
exclude: [],
|
|
1797
2083
|
});
|
|
1798
|
-
});
|
|
1799
|
-
|
|
1800
|
-
return {
|
|
1801
|
-
url: "https://abcxyz.foo.pages.dev/",
|
|
1802
|
-
};
|
|
1803
|
-
}
|
|
1804
|
-
);
|
|
1805
2084
|
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
|
|
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
|
+
)
|
|
1815
2116
|
);
|
|
1816
2117
|
|
|
1817
2118
|
await runWrangler("pages publish public --project-name=foo");
|
|
@@ -1863,30 +2164,35 @@ and that at least one include rule is provided.
|
|
|
1863
2164
|
|
|
1864
2165
|
mockGetToken("<<funfetti-auth-jwt>>");
|
|
1865
2166
|
|
|
1866
|
-
|
|
1867
|
-
"
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
assertLater(() => {
|
|
1872
|
-
expect(init.headers).toMatchObject({
|
|
1873
|
-
Authorization: "Bearer <<funfetti-auth-jwt>>",
|
|
1874
|
-
});
|
|
1875
|
-
expect(body).toMatchObject({
|
|
1876
|
-
hashes: ["13a03eaf24ae98378acd36ea00f77f2f"],
|
|
1877
|
-
});
|
|
1878
|
-
});
|
|
1879
|
-
return body.hashes;
|
|
1880
|
-
}
|
|
1881
|
-
);
|
|
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
|
+
};
|
|
1882
2172
|
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
|
|
1886
|
-
|
|
2173
|
+
expect(req.headers.get("Authorization")).toBe(
|
|
2174
|
+
"Bearer <<funfetti-auth-jwt>>"
|
|
2175
|
+
);
|
|
2176
|
+
expect(body).toMatchObject({
|
|
2177
|
+
hashes: ["13a03eaf24ae98378acd36ea00f77f2f"],
|
|
1887
2178
|
});
|
|
1888
|
-
|
|
1889
|
-
|
|
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([
|
|
1890
2196
|
{
|
|
1891
2197
|
key: "13a03eaf24ae98378acd36ea00f77f2f",
|
|
1892
2198
|
value: Buffer.from("This is a readme").toString("base64"),
|
|
@@ -1896,18 +2202,35 @@ and that at least one include rule is provided.
|
|
|
1896
2202
|
base64: true,
|
|
1897
2203
|
},
|
|
1898
2204
|
]);
|
|
1899
|
-
});
|
|
1900
|
-
});
|
|
1901
2205
|
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
|
|
1910
|
-
|
|
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
|
+
)
|
|
1911
2234
|
);
|
|
1912
2235
|
|
|
1913
2236
|
await expect(runWrangler("pages publish public --project-name=foo"))
|
|
@@ -1953,30 +2276,35 @@ and that at least one include rule is provided.
|
|
|
1953
2276
|
|
|
1954
2277
|
mockGetToken("<<funfetti-auth-jwt>>");
|
|
1955
2278
|
|
|
1956
|
-
|
|
1957
|
-
"
|
|
1958
|
-
|
|
1959
|
-
|
|
1960
|
-
|
|
1961
|
-
assertLater(() => {
|
|
1962
|
-
expect(init.headers).toMatchObject({
|
|
1963
|
-
Authorization: "Bearer <<funfetti-auth-jwt>>",
|
|
1964
|
-
});
|
|
1965
|
-
expect(body).toMatchObject({
|
|
1966
|
-
hashes: ["13a03eaf24ae98378acd36ea00f77f2f"],
|
|
1967
|
-
});
|
|
1968
|
-
});
|
|
1969
|
-
return body.hashes;
|
|
1970
|
-
}
|
|
1971
|
-
);
|
|
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
|
+
};
|
|
1972
2284
|
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
|
|
2285
|
+
expect(req.headers.get("Authorization")).toBe(
|
|
2286
|
+
"Bearer <<funfetti-auth-jwt>>"
|
|
2287
|
+
);
|
|
2288
|
+
expect(body).toMatchObject({
|
|
2289
|
+
hashes: ["13a03eaf24ae98378acd36ea00f77f2f"],
|
|
1977
2290
|
});
|
|
1978
|
-
|
|
1979
|
-
|
|
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([
|
|
1980
2308
|
{
|
|
1981
2309
|
key: "13a03eaf24ae98378acd36ea00f77f2f",
|
|
1982
2310
|
value: Buffer.from("This is a readme").toString("base64"),
|
|
@@ -1986,56 +2314,76 @@ and that at least one include rule is provided.
|
|
|
1986
2314
|
base64: true,
|
|
1987
2315
|
},
|
|
1988
2316
|
]);
|
|
1989
|
-
});
|
|
1990
|
-
});
|
|
1991
2317
|
|
|
1992
|
-
|
|
1993
|
-
|
|
1994
|
-
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
|
|
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();
|
|
1999
2333
|
const manifest = JSON.parse(body.get("manifest") as string);
|
|
2000
|
-
const customWorkerJS =
|
|
2001
|
-
body.get("_worker.js") as Blob
|
|
2002
|
-
).text();
|
|
2334
|
+
const customWorkerJS = body.get("_worker.js");
|
|
2003
2335
|
|
|
2336
|
+
expect(req.params.accountId).toEqual("some-account-id");
|
|
2004
2337
|
// make sure this is all we uploaded
|
|
2005
|
-
expect([...body.keys()]).toEqual(
|
|
2006
|
-
|
|
2338
|
+
expect([...body.keys()].sort()).toEqual(
|
|
2339
|
+
["manifest", "_worker.js"].sort()
|
|
2340
|
+
);
|
|
2007
2341
|
expect(manifest).toMatchInlineSnapshot(`
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
|
|
2011
|
-
|
|
2012
|
-
|
|
2342
|
+
Object {
|
|
2343
|
+
"/README.md": "13a03eaf24ae98378acd36ea00f77f2f",
|
|
2344
|
+
}
|
|
2345
|
+
`);
|
|
2013
2346
|
expect(customWorkerJS).toMatchInlineSnapshot(`
|
|
2014
|
-
"
|
|
2015
|
-
export default {
|
|
2016
|
-
async fetch(request, env) {
|
|
2017
|
-
const url = new URL(request.url);
|
|
2018
|
-
return url.pathname.startsWith('/api/') ? new Response('Ok') : env.ASSETS.fetch(request);
|
|
2019
|
-
};
|
|
2020
2347
|
"
|
|
2021
|
-
|
|
2022
|
-
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
|
|
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
|
+
)
|
|
2039
2387
|
);
|
|
2040
2388
|
|
|
2041
2389
|
await runWrangler("pages publish public --project-name=foo");
|
|
@@ -2064,48 +2412,62 @@ and that at least one include rule is provided.
|
|
|
2064
2412
|
});
|
|
2065
2413
|
|
|
2066
2414
|
afterEach(() => {
|
|
2067
|
-
unsetAllMocks();
|
|
2068
2415
|
process.env = ENV_COPY;
|
|
2069
2416
|
});
|
|
2070
2417
|
|
|
2071
2418
|
it("should upload a directory of files with a provided JWT", async () => {
|
|
2072
2419
|
writeFileSync("logo.png", "foobar");
|
|
2073
2420
|
|
|
2074
|
-
|
|
2075
|
-
"
|
|
2076
|
-
|
|
2077
|
-
|
|
2078
|
-
|
|
2079
|
-
assertLater(() => {
|
|
2080
|
-
expect(init.headers).toMatchObject({
|
|
2081
|
-
Authorization: "Bearer <<funfetti-auth-jwt>>",
|
|
2082
|
-
});
|
|
2083
|
-
expect(body).toMatchObject({
|
|
2084
|
-
hashes: ["2082190357cfd3617ccfe04f340c6247"],
|
|
2085
|
-
});
|
|
2086
|
-
});
|
|
2087
|
-
return body.hashes;
|
|
2088
|
-
}
|
|
2089
|
-
);
|
|
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
|
+
};
|
|
2090
2426
|
|
|
2091
|
-
|
|
2092
|
-
|
|
2093
|
-
|
|
2094
|
-
|
|
2427
|
+
expect(req.headers.get("Authorization")).toBe(
|
|
2428
|
+
"Bearer <<funfetti-auth-jwt>>"
|
|
2429
|
+
);
|
|
2430
|
+
expect(body).toMatchObject({
|
|
2431
|
+
hashes: ["2082190357cfd3617ccfe04f340c6247"],
|
|
2095
2432
|
});
|
|
2096
|
-
|
|
2097
|
-
|
|
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([
|
|
2098
2450
|
{
|
|
2451
|
+
base64: true,
|
|
2099
2452
|
key: "2082190357cfd3617ccfe04f340c6247",
|
|
2100
|
-
value: Buffer.from("foobar").toString("base64"),
|
|
2101
2453
|
metadata: {
|
|
2102
2454
|
contentType: "image/png",
|
|
2103
2455
|
},
|
|
2104
|
-
|
|
2456
|
+
value: "Zm9vYmFy",
|
|
2105
2457
|
},
|
|
2106
2458
|
]);
|
|
2107
|
-
|
|
2108
|
-
|
|
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
|
+
);
|
|
2109
2471
|
|
|
2110
2472
|
await runWrangler("pages project upload .");
|
|
2111
2473
|
|
|
@@ -2134,100 +2496,103 @@ and that at least one include rule is provided.
|
|
|
2134
2496
|
mkdirSync("functions");
|
|
2135
2497
|
writeFileSync("functions/foo.js", "func");
|
|
2136
2498
|
|
|
2137
|
-
|
|
2138
|
-
|
|
2139
|
-
|
|
2140
|
-
async (
|
|
2141
|
-
const body =
|
|
2142
|
-
|
|
2143
|
-
|
|
2144
|
-
|
|
2145
|
-
|
|
2146
|
-
|
|
2147
|
-
|
|
2148
|
-
|
|
2149
|
-
|
|
2150
|
-
|
|
2151
|
-
|
|
2152
|
-
|
|
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
|
+
],
|
|
2153
2516
|
});
|
|
2154
|
-
|
|
2155
|
-
|
|
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
|
+
})
|
|
2156
2541
|
);
|
|
2157
2542
|
|
|
2158
|
-
|
|
2159
|
-
const requests: RequestInit[] = [];
|
|
2160
|
-
setMockRawResponse("/pages/assets/upload", "POST", async (_, init) => {
|
|
2161
|
-
requests.push(init);
|
|
2543
|
+
await runWrangler("pages project upload .");
|
|
2162
2544
|
|
|
2163
|
-
|
|
2164
|
-
});
|
|
2545
|
+
expect(requests.length).toBe(3);
|
|
2165
2546
|
|
|
2166
|
-
|
|
2167
|
-
|
|
2547
|
+
const resolvedRequests = await Promise.all(
|
|
2548
|
+
requests.map(async (req) => await req.json<UploadPayloadFile>())
|
|
2549
|
+
);
|
|
2168
2550
|
|
|
2169
|
-
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
);
|
|
2173
|
-
});
|
|
2551
|
+
const sortedRequests = resolvedRequests.sort((a, b) => {
|
|
2552
|
+
const aKey = a.key as string;
|
|
2553
|
+
const bKey = b.key as string;
|
|
2174
2554
|
|
|
2175
|
-
|
|
2176
|
-
|
|
2177
|
-
});
|
|
2178
|
-
|
|
2179
|
-
let body = JSON.parse(
|
|
2180
|
-
sortedRequests[0].body as string
|
|
2181
|
-
) as UploadPayloadFile[];
|
|
2182
|
-
expect(body).toMatchObject([
|
|
2183
|
-
{
|
|
2184
|
-
key: "09a79777abda8ccc8bdd51dd3ff8e9e9",
|
|
2185
|
-
value: Buffer.from("func").toString("base64"),
|
|
2186
|
-
metadata: {
|
|
2187
|
-
contentType: "application/javascript",
|
|
2188
|
-
},
|
|
2189
|
-
base64: true,
|
|
2190
|
-
},
|
|
2191
|
-
]);
|
|
2555
|
+
return aKey?.localeCompare(bKey);
|
|
2556
|
+
});
|
|
2192
2557
|
|
|
2193
|
-
|
|
2194
|
-
|
|
2195
|
-
|
|
2558
|
+
for (const req of requests) {
|
|
2559
|
+
expect(req.headers.get("Authorization")).toBe(
|
|
2560
|
+
"Bearer <<funfetti-auth-jwt>>"
|
|
2561
|
+
);
|
|
2562
|
+
}
|
|
2196
2563
|
|
|
2197
|
-
|
|
2198
|
-
|
|
2199
|
-
|
|
2200
|
-
|
|
2201
|
-
{
|
|
2202
|
-
|
|
2203
|
-
value: Buffer.from("foobar").toString("base64"),
|
|
2204
|
-
metadata: {
|
|
2205
|
-
contentType: "image/png",
|
|
2206
|
-
},
|
|
2207
|
-
base64: true,
|
|
2564
|
+
expect(sortedRequests[0]).toMatchObject([
|
|
2565
|
+
{
|
|
2566
|
+
base64: true,
|
|
2567
|
+
key: "95dedb64e6d4940fc2e0f11f711cc2f4",
|
|
2568
|
+
metadata: {
|
|
2569
|
+
contentType: "application/octet-stream",
|
|
2208
2570
|
},
|
|
2209
|
-
|
|
2210
|
-
|
|
2211
|
-
|
|
2212
|
-
Authorization: "Bearer <<funfetti-auth-jwt>>",
|
|
2213
|
-
});
|
|
2571
|
+
value: "aGVhZGVyc2ZpbGU=",
|
|
2572
|
+
},
|
|
2573
|
+
]);
|
|
2214
2574
|
|
|
2215
|
-
|
|
2216
|
-
|
|
2217
|
-
|
|
2218
|
-
|
|
2219
|
-
{
|
|
2220
|
-
|
|
2221
|
-
value: Buffer.from("headersfile").toString("base64"),
|
|
2222
|
-
metadata: {
|
|
2223
|
-
contentType: "application/octet-stream",
|
|
2224
|
-
},
|
|
2225
|
-
base64: true,
|
|
2575
|
+
expect(sortedRequests[1]).toMatchObject([
|
|
2576
|
+
{
|
|
2577
|
+
base64: true,
|
|
2578
|
+
key: "2082190357cfd3617ccfe04f340c6247",
|
|
2579
|
+
metadata: {
|
|
2580
|
+
contentType: "image/png",
|
|
2226
2581
|
},
|
|
2227
|
-
|
|
2228
|
-
|
|
2582
|
+
value: "Zm9vYmFy",
|
|
2583
|
+
},
|
|
2584
|
+
]);
|
|
2229
2585
|
|
|
2230
|
-
|
|
2586
|
+
expect(sortedRequests[2]).toMatchObject([
|
|
2587
|
+
{
|
|
2588
|
+
base64: true,
|
|
2589
|
+
key: "09a79777abda8ccc8bdd51dd3ff8e9e9",
|
|
2590
|
+
metadata: {
|
|
2591
|
+
contentType: "application/javascript",
|
|
2592
|
+
},
|
|
2593
|
+
value: "ZnVuYw==",
|
|
2594
|
+
},
|
|
2595
|
+
]);
|
|
2231
2596
|
|
|
2232
2597
|
expect(std.out).toMatchInlineSnapshot(`
|
|
2233
2598
|
"✨ Success! Uploaded 3 files (TIMINGS)
|
|
@@ -2239,62 +2604,81 @@ and that at least one include rule is provided.
|
|
|
2239
2604
|
it("should retry uploads", async () => {
|
|
2240
2605
|
writeFileSync("logo.txt", "foobar");
|
|
2241
2606
|
|
|
2242
|
-
setMockResponse(
|
|
2243
|
-
"/pages/assets/check-missing",
|
|
2244
|
-
"POST",
|
|
2245
|
-
async (_, init) => {
|
|
2246
|
-
const body = JSON.parse(init.body as string) as { hashes: string[] };
|
|
2247
|
-
assertLater(() => {
|
|
2248
|
-
expect(init.headers).toMatchObject({
|
|
2249
|
-
Authorization: "Bearer <<funfetti-auth-jwt>>",
|
|
2250
|
-
});
|
|
2251
|
-
expect(body).toMatchObject({
|
|
2252
|
-
hashes: ["1a98fb08af91aca4a7df1764a2c4ddb0"],
|
|
2253
|
-
});
|
|
2254
|
-
});
|
|
2255
|
-
return body.hashes;
|
|
2256
|
-
}
|
|
2257
|
-
);
|
|
2258
|
-
|
|
2259
2607
|
// Accumulate multiple requests then assert afterwards
|
|
2260
|
-
const requests:
|
|
2261
|
-
|
|
2262
|
-
|
|
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[] };
|
|
2263
2612
|
|
|
2264
|
-
|
|
2265
|
-
|
|
2266
|
-
|
|
2267
|
-
|
|
2268
|
-
|
|
2269
|
-
|
|
2270
|
-
|
|
2271
|
-
|
|
2272
|
-
|
|
2273
|
-
|
|
2274
|
-
|
|
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
|
+
);
|
|
2275
2661
|
|
|
2276
2662
|
await runWrangler("pages project upload .");
|
|
2277
2663
|
|
|
2278
2664
|
// Assert two identical requests
|
|
2279
2665
|
expect(requests.length).toBe(2);
|
|
2280
2666
|
for (const init of requests) {
|
|
2281
|
-
|
|
2282
|
-
|
|
2283
|
-
|
|
2284
|
-
});
|
|
2667
|
+
expect(init.headers.get("Authorization")).toBe(
|
|
2668
|
+
"Bearer <<funfetti-auth-jwt>>"
|
|
2669
|
+
);
|
|
2285
2670
|
|
|
2286
|
-
|
|
2287
|
-
|
|
2288
|
-
|
|
2289
|
-
|
|
2290
|
-
|
|
2291
|
-
|
|
2292
|
-
|
|
2293
|
-
},
|
|
2294
|
-
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",
|
|
2295
2678
|
},
|
|
2296
|
-
|
|
2297
|
-
|
|
2679
|
+
base64: true,
|
|
2680
|
+
},
|
|
2681
|
+
]);
|
|
2298
2682
|
}
|
|
2299
2683
|
|
|
2300
2684
|
expect(std.out).toMatchInlineSnapshot(`
|
|
@@ -2312,33 +2696,52 @@ and that at least one include rule is provided.
|
|
|
2312
2696
|
|
|
2313
2697
|
mockGetToken("<<funfetti-auth-jwt>>");
|
|
2314
2698
|
|
|
2315
|
-
|
|
2316
|
-
|
|
2317
|
-
|
|
2318
|
-
async (
|
|
2319
|
-
const body =
|
|
2320
|
-
|
|
2321
|
-
|
|
2322
|
-
|
|
2323
|
-
|
|
2324
|
-
|
|
2325
|
-
|
|
2326
|
-
|
|
2327
|
-
|
|
2328
|
-
|
|
2329
|
-
|
|
2330
|
-
|
|
2331
|
-
});
|
|
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
|
+
]),
|
|
2332
2715
|
});
|
|
2333
|
-
return body.hashes;
|
|
2334
|
-
}
|
|
2335
|
-
);
|
|
2336
2716
|
|
|
2337
|
-
|
|
2338
|
-
|
|
2339
|
-
|
|
2340
|
-
|
|
2341
|
-
|
|
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
|
+
);
|
|
2342
2745
|
|
|
2343
2746
|
await runWrangler("pages project upload .");
|
|
2344
2747
|
|
|
@@ -2346,10 +2749,7 @@ and that at least one include rule is provided.
|
|
|
2346
2749
|
expect(requests.length).toBe(3);
|
|
2347
2750
|
const bodies: UploadPayloadFile[][] = [];
|
|
2348
2751
|
for (const init of requests) {
|
|
2349
|
-
|
|
2350
|
-
Authorization: "Bearer <<funfetti-auth-jwt>>",
|
|
2351
|
-
});
|
|
2352
|
-
bodies.push(JSON.parse(init.body as string) as UploadPayloadFile[]);
|
|
2752
|
+
bodies.push((await init.json()) as UploadPayloadFile[]);
|
|
2353
2753
|
}
|
|
2354
2754
|
// One bucket should end up with 2 files
|
|
2355
2755
|
expect(bodies.map((b) => b.length).sort()).toEqual([1, 1, 2]);
|
|
@@ -2398,29 +2798,36 @@ and that at least one include rule is provided.
|
|
|
2398
2798
|
|
|
2399
2799
|
mockGetToken("<<funfetti-auth-jwt>>");
|
|
2400
2800
|
|
|
2401
|
-
|
|
2402
|
-
|
|
2403
|
-
|
|
2404
|
-
|
|
2405
|
-
|
|
2406
|
-
|
|
2407
|
-
|
|
2408
|
-
|
|
2409
|
-
|
|
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
|
+
);
|
|
2410
2811
|
expect(body).toMatchObject({
|
|
2411
2812
|
hashes: ["7b764dacfd211bebd8077828a7ddefd7"],
|
|
2412
2813
|
});
|
|
2413
|
-
});
|
|
2414
|
-
return body.hashes;
|
|
2415
|
-
}
|
|
2416
|
-
);
|
|
2417
2814
|
|
|
2418
|
-
|
|
2419
|
-
|
|
2420
|
-
|
|
2421
|
-
|
|
2422
|
-
|
|
2423
|
-
|
|
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[];
|
|
2424
2831
|
expect(body).toMatchObject([
|
|
2425
2832
|
{
|
|
2426
2833
|
key: "7b764dacfd211bebd8077828a7ddefd7",
|
|
@@ -2431,8 +2838,18 @@ and that at least one include rule is provided.
|
|
|
2431
2838
|
base64: true,
|
|
2432
2839
|
},
|
|
2433
2840
|
]);
|
|
2434
|
-
|
|
2435
|
-
|
|
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
|
+
);
|
|
2436
2853
|
|
|
2437
2854
|
await runWrangler("pages project upload .");
|
|
2438
2855
|
|
|
@@ -2440,3 +2857,43 @@ and that at least one include rule is provided.
|
|
|
2440
2857
|
});
|
|
2441
2858
|
});
|
|
2442
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;
|