wrangler 2.0.7 → 2.0.11

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.
@@ -7,100 +7,210 @@ const { getPackageManager, getPackageManagerName } =
7
7
  jest.requireActual("../package-manager");
8
8
  interface TestCase {
9
9
  npm: boolean;
10
+ pnpm: boolean;
10
11
  yarn: boolean;
11
12
  npmLockFile: boolean;
12
13
  yarnLockFile: boolean;
14
+ pnpmLockFile: boolean;
13
15
  expectedPackageManager: string;
14
16
  }
15
17
 
16
18
  const testCases: TestCase[] = [
17
- // npm binary - no yarn binary
19
+ // npm binary only
18
20
  {
19
21
  npm: true,
20
22
  yarn: false,
23
+ pnpm: false,
21
24
  npmLockFile: false,
22
25
  yarnLockFile: false,
26
+ pnpmLockFile: false,
23
27
  expectedPackageManager: "npm",
24
28
  },
25
29
  {
26
30
  npm: true,
27
31
  yarn: false,
32
+ pnpm: false,
28
33
  npmLockFile: true,
29
34
  yarnLockFile: false,
35
+ pnpmLockFile: false,
30
36
  expectedPackageManager: "npm",
31
37
  },
32
38
  {
33
39
  npm: true,
34
40
  yarn: false,
41
+ pnpm: false,
35
42
  npmLockFile: false,
36
43
  yarnLockFile: true,
44
+ pnpmLockFile: false,
37
45
  expectedPackageManager: "npm",
38
46
  },
39
47
  {
40
48
  npm: true,
41
49
  yarn: false,
50
+ pnpm: false,
42
51
  npmLockFile: true,
43
52
  yarnLockFile: true,
53
+ pnpmLockFile: false,
44
54
  expectedPackageManager: "npm",
45
55
  },
46
56
 
47
- // yarn binary - no npm binary
57
+ // yarn binary only
48
58
  {
49
59
  npm: false,
50
60
  yarn: true,
61
+ pnpm: false,
51
62
  npmLockFile: false,
52
63
  yarnLockFile: false,
64
+ pnpmLockFile: false,
53
65
  expectedPackageManager: "yarn",
54
66
  },
55
67
  {
56
68
  npm: false,
57
69
  yarn: true,
70
+ pnpm: false,
58
71
  npmLockFile: true,
59
72
  yarnLockFile: false,
73
+ pnpmLockFile: false,
60
74
  expectedPackageManager: "yarn",
61
75
  },
62
76
  {
63
77
  npm: false,
64
78
  yarn: true,
79
+ pnpm: false,
65
80
  npmLockFile: false,
66
81
  yarnLockFile: true,
82
+ pnpmLockFile: false,
67
83
  expectedPackageManager: "yarn",
68
84
  },
69
85
  {
70
86
  npm: false,
71
87
  yarn: true,
88
+ pnpm: false,
72
89
  npmLockFile: true,
73
90
  yarnLockFile: true,
91
+ pnpmLockFile: false,
74
92
  expectedPackageManager: "yarn",
75
93
  },
76
94
 
95
+ // pnpm binary only
96
+ {
97
+ npm: false,
98
+ yarn: false,
99
+ pnpm: true,
100
+ npmLockFile: false,
101
+ yarnLockFile: false,
102
+ pnpmLockFile: true,
103
+ expectedPackageManager: "pnpm",
104
+ },
105
+ {
106
+ npm: false,
107
+ yarn: false,
108
+ pnpm: true,
109
+ npmLockFile: true,
110
+ yarnLockFile: false,
111
+ pnpmLockFile: false,
112
+ expectedPackageManager: "pnpm",
113
+ },
114
+ {
115
+ npm: false,
116
+ yarn: false,
117
+ pnpm: true,
118
+ npmLockFile: false,
119
+ yarnLockFile: true,
120
+ pnpmLockFile: false,
121
+ expectedPackageManager: "pnpm",
122
+ },
123
+ {
124
+ npm: false,
125
+ yarn: false,
126
+ pnpm: true,
127
+ npmLockFile: true,
128
+ yarnLockFile: true,
129
+ pnpmLockFile: true,
130
+ expectedPackageManager: "pnpm",
131
+ },
132
+
77
133
  // npm and yarn binaries
78
134
  {
79
135
  npm: true,
80
136
  yarn: true,
137
+ pnpm: false,
81
138
  npmLockFile: false,
82
139
  yarnLockFile: false,
140
+ pnpmLockFile: false,
83
141
  expectedPackageManager: "npm",
84
142
  },
85
143
  {
86
144
  npm: true,
87
145
  yarn: true,
146
+ pnpm: false,
88
147
  npmLockFile: true,
89
148
  yarnLockFile: false,
149
+ pnpmLockFile: false,
90
150
  expectedPackageManager: "npm",
91
151
  },
92
152
  {
93
153
  npm: true,
94
154
  yarn: true,
155
+ pnpm: false,
95
156
  npmLockFile: false,
96
157
  yarnLockFile: true,
158
+ pnpmLockFile: false,
97
159
  expectedPackageManager: "yarn",
98
160
  },
99
161
  {
100
162
  npm: true,
101
163
  yarn: true,
164
+ pnpm: false,
102
165
  npmLockFile: true,
103
166
  yarnLockFile: true,
167
+ pnpmLockFile: false,
168
+ expectedPackageManager: "npm",
169
+ },
170
+ // npm, yarn and pnpm binaries
171
+ {
172
+ npm: true,
173
+ yarn: true,
174
+ pnpm: true,
175
+ npmLockFile: false,
176
+ yarnLockFile: false,
177
+ pnpmLockFile: false,
178
+ expectedPackageManager: "npm",
179
+ },
180
+ {
181
+ npm: true,
182
+ yarn: true,
183
+ pnpm: true,
184
+ npmLockFile: true,
185
+ yarnLockFile: false,
186
+ pnpmLockFile: false,
187
+ expectedPackageManager: "npm",
188
+ },
189
+ {
190
+ npm: true,
191
+ yarn: true,
192
+ pnpm: true,
193
+ npmLockFile: false,
194
+ yarnLockFile: true,
195
+ pnpmLockFile: false,
196
+ expectedPackageManager: "yarn",
197
+ },
198
+ {
199
+ npm: true,
200
+ yarn: true,
201
+ pnpm: true,
202
+ npmLockFile: false,
203
+ yarnLockFile: false,
204
+ pnpmLockFile: true,
205
+ expectedPackageManager: "pnpm",
206
+ },
207
+ {
208
+ npm: true,
209
+ yarn: true,
210
+ pnpm: true,
211
+ npmLockFile: true,
212
+ yarnLockFile: true,
213
+ pnpmLockFile: true,
104
214
  expectedPackageManager: "npm",
105
215
  },
106
216
  ];
@@ -112,12 +222,13 @@ describe("getPackageManager()", () => {
112
222
  describe("no supported package manager", () => {
113
223
  mockYarn(false);
114
224
  mockNpm(false);
225
+ mockPnpm(false);
115
226
 
116
227
  it("should throw an error", async () => {
117
228
  await expect(() =>
118
229
  getPackageManager(process.cwd())
119
230
  ).rejects.toThrowErrorMatchingInlineSnapshot(
120
- `"Unable to find a package manager. Supported managers are: npm and yarn."`
231
+ `"Unable to find a package manager. Supported managers are: npm, yarn, and pnpm."`
121
232
  );
122
233
  });
123
234
  });
@@ -125,16 +236,26 @@ describe("getPackageManager()", () => {
125
236
  for (const {
126
237
  npm,
127
238
  yarn,
239
+ pnpm,
128
240
  npmLockFile,
129
241
  yarnLockFile,
242
+ pnpmLockFile,
130
243
  expectedPackageManager,
131
244
  } of testCases) {
132
245
  describe(
133
- getTestCaseDescription(npm, yarn, npmLockFile, yarnLockFile),
246
+ getTestCaseDescription(
247
+ npm,
248
+ yarn,
249
+ pnpm,
250
+ npmLockFile,
251
+ yarnLockFile,
252
+ pnpmLockFile
253
+ ),
134
254
  () => {
135
255
  mockYarn(yarn);
136
256
  mockNpm(npm);
137
- mockLockFiles(npmLockFile, yarnLockFile);
257
+ mockPnpm(pnpm);
258
+ mockLockFiles(npmLockFile, yarnLockFile, pnpmLockFile);
138
259
 
139
260
  it(`should return the ${expectedPackageManager} package manager`, async () => {
140
261
  const actualPackageManager = await getPackageManager(process.cwd());
@@ -169,10 +290,25 @@ function mockNpm(succeed: boolean): void {
169
290
  afterEach(() => unMock());
170
291
  }
171
292
 
293
+ /**
294
+ * Create a fake pnpm binary
295
+ */
296
+ function mockPnpm(succeed: boolean): void {
297
+ let unMock: () => void;
298
+ beforeEach(async () => {
299
+ unMock = await mockBinary("pnpm", `process.exit(${succeed ? 0 : 1})`);
300
+ });
301
+ afterEach(() => unMock());
302
+ }
303
+
172
304
  /**
173
305
  * Create a fake lock files.
174
306
  */
175
- function mockLockFiles(npmLockFile: boolean, yarnLockFile: boolean) {
307
+ function mockLockFiles(
308
+ npmLockFile: boolean,
309
+ yarnLockFile: boolean,
310
+ pnpmLockFile: boolean
311
+ ) {
176
312
  beforeEach(() => {
177
313
  if (npmLockFile) {
178
314
  writeFileSync("package-lock.json", "");
@@ -180,14 +316,19 @@ function mockLockFiles(npmLockFile: boolean, yarnLockFile: boolean) {
180
316
  if (yarnLockFile) {
181
317
  writeFileSync("yarn.lock", "");
182
318
  }
319
+ if (pnpmLockFile) {
320
+ writeFileSync("pnpm-lock.yaml", "");
321
+ }
183
322
  });
184
323
  }
185
324
 
186
325
  function getTestCaseDescription(
187
326
  npm: boolean,
188
327
  yarn: boolean,
328
+ pnpm: boolean,
189
329
  npmLockFile: boolean,
190
- yarnLockFile: boolean
330
+ yarnLockFile: boolean,
331
+ pnpmLockFile: boolean
191
332
  ): string {
192
333
  const criteria: string[] = [];
193
334
  if (npm) {
@@ -202,5 +343,11 @@ function getTestCaseDescription(
202
343
  if (yarnLockFile) {
203
344
  criteria.push("yarn.lock");
204
345
  }
346
+ if (pnpm) {
347
+ criteria.push("pnpm");
348
+ }
349
+ if (pnpmLockFile) {
350
+ criteria.push("pnpm-lock.yaml");
351
+ }
205
352
  return "using " + criteria.join("; ");
206
353
  }
@@ -19,7 +19,7 @@ function assertLater(fn: () => void) {
19
19
  }
20
20
 
21
21
  function mockGetToken(jwt: string) {
22
- setMockResponse(
22
+ return setMockResponse(
23
23
  "/accounts/:accountId/pages/projects/foo/upload-token",
24
24
  async ([_url, accountId]) => {
25
25
  assertLater(() => {
@@ -79,7 +79,7 @@ describe("pages", () => {
79
79
  expect(std.out).toMatchInlineSnapshot(`
80
80
  "🚧 'wrangler pages <command>' is a beta command. Please report any issues to https://github.com/cloudflare/wrangler2/issues/new/choose
81
81
 
82
- If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new."
82
+ If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new/choose"
83
83
  `);
84
84
  });
85
85
 
@@ -89,7 +89,7 @@ describe("pages", () => {
89
89
  expect(std.out).toMatchInlineSnapshot(`
90
90
  "🚧 'wrangler pages <command>' is a beta command. Please report any issues to https://github.com/cloudflare/wrangler2/issues/new/choose
91
91
 
92
- If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new."
92
+ If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new/choose"
93
93
  `);
94
94
  });
95
95
  });
@@ -374,10 +374,10 @@ describe("pages", () => {
374
374
  const body = init.body as FormData;
375
375
  const manifest = JSON.parse(body.get("manifest") as string);
376
376
  expect(manifest).toMatchInlineSnapshot(`
377
- Object {
378
- "/logo.png": "2082190357cfd3617ccfe04f340c6247",
379
- }
380
- `);
377
+ Object {
378
+ "/logo.png": "2082190357cfd3617ccfe04f340c6247",
379
+ }
380
+ `);
381
381
  });
382
382
 
383
383
  return {
@@ -445,10 +445,10 @@ describe("pages", () => {
445
445
  const body = init.body as FormData;
446
446
  const manifest = JSON.parse(body.get("manifest") as string);
447
447
  expect(manifest).toMatchInlineSnapshot(`
448
- Object {
449
- "/logo.txt": "1a98fb08af91aca4a7df1764a2c4ddb0",
450
- }
451
- `);
448
+ Object {
449
+ "/logo.txt": "1a98fb08af91aca4a7df1764a2c4ddb0",
450
+ }
451
+ `);
452
452
  });
453
453
 
454
454
  return {
@@ -488,6 +488,103 @@ describe("pages", () => {
488
488
  `);
489
489
  });
490
490
 
491
+ it("should refetch a JWT if it expires while uploading", async () => {
492
+ writeFileSync("logo.txt", "foobar");
493
+
494
+ const cancelMockGetToken = mockGetToken("<<funfetti-auth-jwt>>");
495
+
496
+ setMockResponse(
497
+ "/pages/assets/check-missing",
498
+ "POST",
499
+ async (_, init) => {
500
+ const body = JSON.parse(init.body as string) as { hashes: string[] };
501
+ assertLater(() => {
502
+ expect(init.headers).toMatchObject({
503
+ Authorization: "Bearer <<funfetti-auth-jwt>>",
504
+ });
505
+ expect(body).toMatchObject({
506
+ hashes: ["1a98fb08af91aca4a7df1764a2c4ddb0"],
507
+ });
508
+ });
509
+ return body.hashes;
510
+ }
511
+ );
512
+
513
+ // Accumulate multiple requests then assert afterwards
514
+ const requests: RequestInit[] = [];
515
+ setMockRawResponse("/pages/assets/upload", "POST", async (_, init) => {
516
+ requests.push(init);
517
+
518
+ // Fail just the first request
519
+ if (requests.length < 2) {
520
+ cancelMockGetToken();
521
+ mockGetToken("<<funfetti-auth-jwt2>>");
522
+ return createFetchResult(null, false, [
523
+ {
524
+ code: 8000013,
525
+ message: "Authorization failed",
526
+ },
527
+ ]);
528
+ } else {
529
+ return createFetchResult(null, true);
530
+ }
531
+ });
532
+
533
+ setMockResponse(
534
+ "/accounts/:accountId/pages/projects/foo/deployments",
535
+ async ([_url, accountId], init) => {
536
+ assertLater(() => {
537
+ expect(accountId).toEqual("some-account-id");
538
+ expect(init.method).toEqual("POST");
539
+ const body = init.body as FormData;
540
+ const manifest = JSON.parse(body.get("manifest") as string);
541
+ expect(manifest).toMatchInlineSnapshot(`
542
+ Object {
543
+ "/logo.txt": "1a98fb08af91aca4a7df1764a2c4ddb0",
544
+ }
545
+ `);
546
+ });
547
+
548
+ return {
549
+ url: "https://abcxyz.foo.pages.dev/",
550
+ };
551
+ }
552
+ );
553
+
554
+ await runWrangler("pages publish . --project-name=foo");
555
+
556
+ // Assert two requests
557
+ expect(requests.length).toBe(2);
558
+
559
+ expect(requests[0].headers).toMatchObject({
560
+ Authorization: "Bearer <<funfetti-auth-jwt>>",
561
+ });
562
+
563
+ expect(requests[1].headers).toMatchObject({
564
+ Authorization: "Bearer <<funfetti-auth-jwt2>>",
565
+ });
566
+
567
+ for (const init of requests) {
568
+ const body = JSON.parse(init.body as string) as UploadPayloadFile[];
569
+ expect(body).toMatchObject([
570
+ {
571
+ key: "1a98fb08af91aca4a7df1764a2c4ddb0",
572
+ value: Buffer.from("foobar").toString("base64"),
573
+ metadata: {
574
+ contentType: "text/plain",
575
+ },
576
+ base64: true,
577
+ },
578
+ ]);
579
+ }
580
+
581
+ expect(std.out).toMatchInlineSnapshot(`
582
+ "✨ Success! Uploaded 1 files (TIMINGS)
583
+
584
+ ✨ Deployment complete! Take a peek over at https://abcxyz.foo.pages.dev/"
585
+ `);
586
+ });
587
+
491
588
  it("should try to use multiple buckets (up to the max concurrency)", async () => {
492
589
  writeFileSync("logo.txt", "foobar");
493
590
  writeFileSync("logo.png", "foobar");
@@ -533,13 +630,13 @@ describe("pages", () => {
533
630
  const body = init.body as FormData;
534
631
  const manifest = JSON.parse(body.get("manifest") as string);
535
632
  expect(manifest).toMatchInlineSnapshot(`
536
- Object {
537
- "/logo.html": "d96fef225537c9f5e44a3cb27fd0b492",
538
- "/logo.js": "6be321bef99e758250dac034474ddbb8",
539
- "/logo.png": "2082190357cfd3617ccfe04f340c6247",
540
- "/logo.txt": "1a98fb08af91aca4a7df1764a2c4ddb0",
541
- }
542
- `);
633
+ Object {
634
+ "/logo.html": "d96fef225537c9f5e44a3cb27fd0b492",
635
+ "/logo.js": "6be321bef99e758250dac034474ddbb8",
636
+ "/logo.png": "2082190357cfd3617ccfe04f340c6247",
637
+ "/logo.txt": "1a98fb08af91aca4a7df1764a2c4ddb0",
638
+ }
639
+ `);
543
640
  });
544
641
 
545
642
  return {