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.
@@ -649,8 +649,85 @@ describe("publish", () => {
649
649
  await runWrangler("publish ./index --env dev --legacy-env false");
650
650
  });
651
651
 
652
+ it("should fallback to the Wrangler 1 zone-based API if the bulk-routes API fails", async () => {
653
+ writeWranglerToml({
654
+ routes: ["example.com/some-route/*"],
655
+ });
656
+ writeWorkerSource();
657
+ mockUpdateWorkerRequest({ enabled: false });
658
+ mockUploadWorkerRequest({ expectedType: "esm" });
659
+ // Simulate the bulk-routes API failing with a not authorized error.
660
+ mockUnauthorizedPublishRoutesRequest();
661
+ // Simulate that the worker has already been deployed to another route in this zone.
662
+ mockCollectKnownRoutesRequest([
663
+ {
664
+ pattern: "foo.example.com/other-route",
665
+ script: "test-name",
666
+ },
667
+ ]);
668
+ mockGetZoneFromHostRequest("example.com", "some-zone-id");
669
+ mockPublishRoutesFallbackRequest({
670
+ pattern: "example.com/some-route/*",
671
+ script: "test-name",
672
+ });
673
+ await runWrangler("publish ./index");
674
+
675
+ expect(std.err).toMatchInlineSnapshot(`""`);
676
+ expect(std.warn).toMatchInlineSnapshot(`
677
+ "▲ [WARNING] The current authentication token does not have 'All Zones' permissions.
678
+
679
+ Falling back to using the zone-based API endpoint to update each route individually.
680
+ Note that there is no access to routes associated with zones that the API token does not have
681
+ permission for.
682
+ Existing routes for this Worker in such zones will not be deleted.
683
+
684
+
685
+ ▲ [WARNING] Previously deployed routes:
686
+
687
+ The following routes were already associated with this worker, and have not been deleted:
688
+ - \\"foo.example.com/other-route\\"
689
+ If these routes are not wanted then you can remove them in the dashboard.
690
+
691
+ "
692
+ `);
693
+ expect(std.out).toMatchInlineSnapshot(`
694
+ "Uploaded test-name (TIMINGS)
695
+ Published test-name (TIMINGS)
696
+ example.com/some-route/*"
697
+ `);
698
+ });
699
+
700
+ it("should error if the bulk-routes API fails and trying to push to a non-production environment", async () => {
701
+ writeWranglerToml({
702
+ routes: ["example.com/some-route/*"],
703
+ legacy_env: false,
704
+ });
705
+ writeWorkerSource();
706
+ mockUpdateWorkerRequest({ env: "staging", enabled: false });
707
+ mockUploadWorkerRequest({ env: "staging", expectedType: "esm" });
708
+ // Simulate the bulk-routes API failing with a not authorized error.
709
+ mockUnauthorizedPublishRoutesRequest({ env: "staging" });
710
+ // Simulate that the worker has already been deployed to another route in this zone.
711
+ mockCollectKnownRoutesRequest([
712
+ {
713
+ pattern: "foo.example.com/other-route",
714
+ script: "test-name",
715
+ },
716
+ ]);
717
+ mockGetZoneFromHostRequest("example.com", "some-zone-id");
718
+ mockPublishRoutesFallbackRequest({
719
+ pattern: "example.com/some-route/*",
720
+ script: "test-name",
721
+ });
722
+ await expect(runWrangler("publish ./index --env=staging")).rejects
723
+ .toThrowErrorMatchingInlineSnapshot(`
724
+ "Service environments combined with an API token that doesn't have 'All Zones' permissions is not supported.
725
+ Either turn off service environments by setting \`legacy_env = true\`, creating an API token with 'All Zones' permissions, or logging in via OAuth"
726
+ `);
727
+ });
728
+
652
729
  describe("custom domains", () => {
653
- it("should publish routes marked with 'custom_domain' as seperate custom domains", async () => {
730
+ it("should publish routes marked with 'custom_domain' as separate custom domains", async () => {
654
731
  writeWranglerToml({
655
732
  routes: [{ pattern: "api.example.com", custom_domain: true }],
656
733
  });
@@ -1121,7 +1198,7 @@ addEventListener('fetch', event => {});`
1121
1198
 
1122
1199
  expect(std.out).toMatchInlineSnapshot(`
1123
1200
  "
1124
- If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new."
1201
+ If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new/choose"
1125
1202
  `);
1126
1203
  expect(std.err).toMatchInlineSnapshot(`
1127
1204
  "X [ERROR] Processing wrangler.toml configuration:
@@ -1146,8 +1223,8 @@ addEventListener('fetch', event => {});`
1146
1223
 
1147
1224
  it("should warn if there is a `site.entry-point` configuration", async () => {
1148
1225
  const assets = [
1149
- { filePath: "assets/file-1.txt", content: "Content of file-1" },
1150
- { filePath: "assets/file-2.txt", content: "Content of file-2" },
1226
+ { filePath: "file-1.txt", content: "Content of file-1" },
1227
+ { filePath: "file-2.txt", content: "Content of file-2" },
1151
1228
  ];
1152
1229
  const kvNamespace = {
1153
1230
  title: "__test-name-workers_sites_assets",
@@ -1173,10 +1250,10 @@ addEventListener('fetch', event => {});`
1173
1250
  Object {
1174
1251
  "debug": "",
1175
1252
  "err": "",
1176
- "out": "Reading assets/file-1.txt...
1177
- Uploading as assets/file-1.2ca234f380.txt...
1178
- Reading assets/file-2.txt...
1179
- Uploading as assets/file-2.5938485188.txt...
1253
+ "out": "Reading file-1.txt...
1254
+ Uploading as file-1.2ca234f380.txt...
1255
+ Reading file-2.txt...
1256
+ Uploading as file-2.5938485188.txt...
1180
1257
  ↗️ Done syncing assets
1181
1258
  Uploaded test-name (TIMINGS)
1182
1259
  Published test-name (TIMINGS)
@@ -1197,8 +1274,8 @@ addEventListener('fetch', event => {});`
1197
1274
 
1198
1275
  it("should resolve site.entry-point relative to wrangler.toml", async () => {
1199
1276
  const assets = [
1200
- { filePath: "assets/file-1.txt", content: "Content of file-1" },
1201
- { filePath: "assets/file-2.txt", content: "Content of file-2" },
1277
+ { filePath: "file-1.txt", content: "Content of file-1" },
1278
+ { filePath: "file-2.txt", content: "Content of file-2" },
1202
1279
  ];
1203
1280
  const kvNamespace = {
1204
1281
  title: "__test-name-workers_sites_assets",
@@ -1224,10 +1301,10 @@ addEventListener('fetch', event => {});`
1224
1301
  await runWrangler("publish --config ./my-site/wrangler.toml");
1225
1302
 
1226
1303
  expect(std.out).toMatchInlineSnapshot(`
1227
- "Reading assets/file-1.txt...
1228
- Uploading as assets/file-1.2ca234f380.txt...
1229
- Reading assets/file-2.txt...
1230
- Uploading as assets/file-2.5938485188.txt...
1304
+ "Reading file-1.txt...
1305
+ Uploading as file-1.2ca234f380.txt...
1306
+ Reading file-2.txt...
1307
+ Uploading as file-2.5938485188.txt...
1231
1308
  ↗️ Done syncing assets
1232
1309
  Uploaded test-name (TIMINGS)
1233
1310
  Published test-name (TIMINGS)
@@ -1279,7 +1356,7 @@ addEventListener('fetch', event => {});`
1279
1356
 
1280
1357
  expect(std.out).toMatchInlineSnapshot(`
1281
1358
  "
1282
- If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new."
1359
+ If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new/choose"
1283
1360
  `);
1284
1361
  expect(std.err).toMatchInlineSnapshot(`
1285
1362
  "X [ERROR] Missing entry-point: The entry-point should be specified via the command line (e.g. \`wrangler publish path/to/script\`) or the \`main\` config field.
@@ -1292,8 +1369,8 @@ addEventListener('fetch', event => {});`
1292
1369
  describe("asset upload", () => {
1293
1370
  it("should upload all the files in the directory specified by `config.site.bucket`", async () => {
1294
1371
  const assets = [
1295
- { filePath: "assets/file-1.txt", content: "Content of file-1" },
1296
- { filePath: "assets/file-2.txt", content: "Content of file-2" },
1372
+ { filePath: "file-1.txt", content: "Content of file-1" },
1373
+ { filePath: "file-2.txt", content: "Content of file-2" },
1297
1374
  ];
1298
1375
  const kvNamespace = {
1299
1376
  title: "__test-name-workers_sites_assets",
@@ -1315,10 +1392,60 @@ addEventListener('fetch', event => {});`
1315
1392
  await runWrangler("publish");
1316
1393
 
1317
1394
  expect(std.out).toMatchInlineSnapshot(`
1318
- "Reading assets/file-1.txt...
1319
- Uploading as assets/file-1.2ca234f380.txt...
1320
- Reading assets/file-2.txt...
1321
- Uploading as assets/file-2.5938485188.txt...
1395
+ "Reading file-1.txt...
1396
+ Uploading as file-1.2ca234f380.txt...
1397
+ Reading file-2.txt...
1398
+ Uploading as file-2.5938485188.txt...
1399
+ ↗️ Done syncing assets
1400
+ Uploaded test-name (TIMINGS)
1401
+ Published test-name (TIMINGS)
1402
+ test-name.test-sub-domain.workers.dev"
1403
+ `);
1404
+ expect(std.err).toMatchInlineSnapshot(`""`);
1405
+ });
1406
+
1407
+ it("should not contain backslash for assets with nested directories", async () => {
1408
+ const assets = [
1409
+ { filePath: "subdir/file-1.txt", content: "Content of file-1" },
1410
+ { filePath: "subdir/file-2.txt", content: "Content of file-2" },
1411
+ ];
1412
+ const kvNamespace = {
1413
+ title: "__test-name-workers_sites_assets",
1414
+ id: "__test-name-workers_sites_assets-id",
1415
+ };
1416
+ writeWranglerToml({
1417
+ main: "./index.js",
1418
+ site: {
1419
+ bucket: "assets",
1420
+ },
1421
+ });
1422
+ writeWorkerSource();
1423
+ writeAssets(assets);
1424
+ mockUploadWorkerRequest({
1425
+ expectedBindings: [
1426
+ {
1427
+ name: "__STATIC_CONTENT",
1428
+ namespace_id: "__test-name-workers_sites_assets-id",
1429
+ type: "kv_namespace",
1430
+ },
1431
+ ],
1432
+ expectedModules: {
1433
+ __STATIC_CONTENT_MANIFEST:
1434
+ '{"subdir/file-1.txt":"subdir/file-1.2ca234f380.txt","subdir/file-2.txt":"subdir/file-2.5938485188.txt"}',
1435
+ },
1436
+ });
1437
+ mockSubDomainRequest();
1438
+ mockListKVNamespacesRequest(kvNamespace);
1439
+ mockKeyListRequest(kvNamespace.id, []);
1440
+ mockUploadAssetsToKVRequest(kvNamespace.id, assets);
1441
+
1442
+ await runWrangler("publish");
1443
+
1444
+ expect(std.out).toMatchInlineSnapshot(`
1445
+ "Reading subdir/file-1.txt...
1446
+ Uploading as subdir/file-1.2ca234f380.txt...
1447
+ Reading subdir/file-2.txt...
1448
+ Uploading as subdir/file-2.5938485188.txt...
1322
1449
  ↗️ Done syncing assets
1323
1450
  Uploaded test-name (TIMINGS)
1324
1451
  Published test-name (TIMINGS)
@@ -1329,8 +1456,8 @@ addEventListener('fetch', event => {});`
1329
1456
 
1330
1457
  it("when using a service-worker type, it should add an asset manifest as a text_blob, and bind to a namespace", async () => {
1331
1458
  const assets = [
1332
- { filePath: "assets/file-1.txt", content: "Content of file-1" },
1333
- { filePath: "assets/file-2.txt", content: "Content of file-2" },
1459
+ { filePath: "file-1.txt", content: "Content of file-1" },
1460
+ { filePath: "file-2.txt", content: "Content of file-2" },
1334
1461
  ];
1335
1462
  const kvNamespace = {
1336
1463
  title: "__test-name-workers_sites_assets",
@@ -1348,7 +1475,7 @@ addEventListener('fetch', event => {});`
1348
1475
  expectedType: "sw",
1349
1476
  expectedModules: {
1350
1477
  __STATIC_CONTENT_MANIFEST:
1351
- '{"file-1.txt":"assets/file-1.2ca234f380.txt","file-2.txt":"assets/file-2.5938485188.txt"}',
1478
+ '{"file-1.txt":"file-1.2ca234f380.txt","file-2.txt":"file-2.5938485188.txt"}',
1352
1479
  },
1353
1480
  expectedBindings: [
1354
1481
  {
@@ -1371,10 +1498,10 @@ addEventListener('fetch', event => {});`
1371
1498
  await runWrangler("publish");
1372
1499
 
1373
1500
  expect(std.out).toMatchInlineSnapshot(`
1374
- "Reading assets/file-1.txt...
1375
- Uploading as assets/file-1.2ca234f380.txt...
1376
- Reading assets/file-2.txt...
1377
- Uploading as assets/file-2.5938485188.txt...
1501
+ "Reading file-1.txt...
1502
+ Uploading as file-1.2ca234f380.txt...
1503
+ Reading file-2.txt...
1504
+ Uploading as file-2.5938485188.txt...
1378
1505
  ↗️ Done syncing assets
1379
1506
  Uploaded test-name (TIMINGS)
1380
1507
  Published test-name (TIMINGS)
@@ -1385,8 +1512,8 @@ addEventListener('fetch', event => {});`
1385
1512
 
1386
1513
  it("when using a module worker type, it should add an asset manifest module, and bind to a namespace", async () => {
1387
1514
  const assets = [
1388
- { filePath: "assets/file-1.txt", content: "Content of file-1" },
1389
- { filePath: "assets/file-2.txt", content: "Content of file-2" },
1515
+ { filePath: "file-1.txt", content: "Content of file-1" },
1516
+ { filePath: "file-2.txt", content: "Content of file-2" },
1390
1517
  ];
1391
1518
  const kvNamespace = {
1392
1519
  title: "__test-name-workers_sites_assets",
@@ -1410,7 +1537,7 @@ addEventListener('fetch', event => {});`
1410
1537
  ],
1411
1538
  expectedModules: {
1412
1539
  __STATIC_CONTENT_MANIFEST:
1413
- '{"file-1.txt":"assets/file-1.2ca234f380.txt","file-2.txt":"assets/file-2.5938485188.txt"}',
1540
+ '{"file-1.txt":"file-1.2ca234f380.txt","file-2.txt":"file-2.5938485188.txt"}',
1414
1541
  },
1415
1542
  });
1416
1543
  mockSubDomainRequest();
@@ -1421,10 +1548,10 @@ addEventListener('fetch', event => {});`
1421
1548
  await runWrangler("publish");
1422
1549
 
1423
1550
  expect(std.out).toMatchInlineSnapshot(`
1424
- "Reading assets/file-1.txt...
1425
- Uploading as assets/file-1.2ca234f380.txt...
1426
- Reading assets/file-2.txt...
1427
- Uploading as assets/file-2.5938485188.txt...
1551
+ "Reading file-1.txt...
1552
+ Uploading as file-1.2ca234f380.txt...
1553
+ Reading file-2.txt...
1554
+ Uploading as file-2.5938485188.txt...
1428
1555
  ↗️ Done syncing assets
1429
1556
  Uploaded test-name (TIMINGS)
1430
1557
  Published test-name (TIMINGS)
@@ -1436,8 +1563,8 @@ addEventListener('fetch', event => {});`
1436
1563
  it("should make environment specific kv namespace for assets, even for service envs", async () => {
1437
1564
  // This is the same test as the one before this, but with an env arg
1438
1565
  const assets = [
1439
- { filePath: "assets/file-1.txt", content: "Content of file-1" },
1440
- { filePath: "assets/file-2.txt", content: "Content of file-2" },
1566
+ { filePath: "file-1.txt", content: "Content of file-1" },
1567
+ { filePath: "file-2.txt", content: "Content of file-2" },
1441
1568
  ];
1442
1569
  const kvNamespace = {
1443
1570
  title: "__test-name-some-env-workers_sites_assets",
@@ -1469,10 +1596,10 @@ addEventListener('fetch', event => {});`
1469
1596
  await runWrangler("publish --env some-env --legacy-env false");
1470
1597
 
1471
1598
  expect(std.out).toMatchInlineSnapshot(`
1472
- "Reading assets/file-1.txt...
1473
- Uploading as assets/file-1.2ca234f380.txt...
1474
- Reading assets/file-2.txt...
1475
- Uploading as assets/file-2.5938485188.txt...
1599
+ "Reading file-1.txt...
1600
+ Uploading as file-1.2ca234f380.txt...
1601
+ Reading file-2.txt...
1602
+ Uploading as file-2.5938485188.txt...
1476
1603
  ↗️ Done syncing assets
1477
1604
  Uploaded test-name (some-env) (TIMINGS)
1478
1605
  Published test-name (some-env) (TIMINGS)
@@ -1484,8 +1611,8 @@ addEventListener('fetch', event => {});`
1484
1611
  it("should make environment specific kv namespace for assets, even for legacy envs", async () => {
1485
1612
  // And this is the same test as the one before this, but with legacyEnv:true
1486
1613
  const assets = [
1487
- { filePath: "assets/file-1.txt", content: "Content of file-1" },
1488
- { filePath: "assets/file-2.txt", content: "Content of file-2" },
1614
+ { filePath: "file-1.txt", content: "Content of file-1" },
1615
+ { filePath: "file-2.txt", content: "Content of file-2" },
1489
1616
  ];
1490
1617
  const kvNamespace = {
1491
1618
  title: "__test-name-some-env-workers_sites_assets",
@@ -1518,10 +1645,10 @@ addEventListener('fetch', event => {});`
1518
1645
  await runWrangler("publish --env some-env --legacy-env true");
1519
1646
 
1520
1647
  expect(std.out).toMatchInlineSnapshot(`
1521
- "Reading assets/file-1.txt...
1522
- Uploading as assets/file-1.2ca234f380.txt...
1523
- Reading assets/file-2.txt...
1524
- Uploading as assets/file-2.5938485188.txt...
1648
+ "Reading file-1.txt...
1649
+ Uploading as file-1.2ca234f380.txt...
1650
+ Reading file-2.txt...
1651
+ Uploading as file-2.5938485188.txt...
1525
1652
  ↗️ Done syncing assets
1526
1653
  Uploaded test-name-some-env (TIMINGS)
1527
1654
  Published test-name-some-env (TIMINGS)
@@ -1532,8 +1659,8 @@ addEventListener('fetch', event => {});`
1532
1659
 
1533
1660
  it("should only upload files that are not already in the KV namespace", async () => {
1534
1661
  const assets = [
1535
- { filePath: "assets/file-1.txt", content: "Content of file-1" },
1536
- { filePath: "assets/file-2.txt", content: "Content of file-2" },
1662
+ { filePath: "file-1.txt", content: "Content of file-1" },
1663
+ { filePath: "file-2.txt", content: "Content of file-2" },
1537
1664
  ];
1538
1665
  const kvNamespace = {
1539
1666
  title: "__test-name-workers_sites_assets",
@@ -1551,21 +1678,19 @@ addEventListener('fetch', event => {});`
1551
1678
  mockSubDomainRequest();
1552
1679
  mockListKVNamespacesRequest(kvNamespace);
1553
1680
  // Put file-1 in the KV namespace
1554
- mockKeyListRequest(kvNamespace.id, [
1555
- { name: "assets/file-1.2ca234f380.txt" },
1556
- ]);
1681
+ mockKeyListRequest(kvNamespace.id, [{ name: "file-1.2ca234f380.txt" }]);
1557
1682
  // Check we do not upload file-1
1558
1683
  mockUploadAssetsToKVRequest(
1559
1684
  kvNamespace.id,
1560
- assets.filter((a) => a.filePath !== "assets/file-1.txt")
1685
+ assets.filter((a) => a.filePath !== "file-1.txt")
1561
1686
  );
1562
1687
  await runWrangler("publish");
1563
1688
 
1564
1689
  expect(std.out).toMatchInlineSnapshot(`
1565
- "Reading assets/file-1.txt...
1690
+ "Reading file-1.txt...
1566
1691
  Skipping - already uploaded.
1567
- Reading assets/file-2.txt...
1568
- Uploading as assets/file-2.5938485188.txt...
1692
+ Reading file-2.txt...
1693
+ Uploading as file-2.5938485188.txt...
1569
1694
  ↗️ Done syncing assets
1570
1695
  Uploaded test-name (TIMINGS)
1571
1696
  Published test-name (TIMINGS)
@@ -1576,8 +1701,8 @@ addEventListener('fetch', event => {});`
1576
1701
 
1577
1702
  it("should only upload files that match the `site-include` arg", async () => {
1578
1703
  const assets = [
1579
- { filePath: "assets/file-1.txt", content: "Content of file-1" },
1580
- { filePath: "assets/file-2.txt", content: "Content of file-2" },
1704
+ { filePath: "file-1.txt", content: "Content of file-1" },
1705
+ { filePath: "file-2.txt", content: "Content of file-2" },
1581
1706
  ];
1582
1707
  const kvNamespace = {
1583
1708
  title: "__test-name-workers_sites_assets",
@@ -1598,13 +1723,13 @@ addEventListener('fetch', event => {});`
1598
1723
  // Check we only upload file-1
1599
1724
  mockUploadAssetsToKVRequest(
1600
1725
  kvNamespace.id,
1601
- assets.filter((a) => a.filePath === "assets/file-1.txt")
1726
+ assets.filter((a) => a.filePath === "file-1.txt")
1602
1727
  );
1603
1728
  await runWrangler("publish --site-include file-1.txt");
1604
1729
 
1605
1730
  expect(std.out).toMatchInlineSnapshot(`
1606
- "Reading assets/file-1.txt...
1607
- Uploading as assets/file-1.2ca234f380.txt...
1731
+ "Reading file-1.txt...
1732
+ Uploading as file-1.2ca234f380.txt...
1608
1733
  ↗️ Done syncing assets
1609
1734
  Uploaded test-name (TIMINGS)
1610
1735
  Published test-name (TIMINGS)
@@ -1615,8 +1740,8 @@ addEventListener('fetch', event => {});`
1615
1740
 
1616
1741
  it("should not upload files that match the `site-exclude` arg", async () => {
1617
1742
  const assets = [
1618
- { filePath: "assets/file-1.txt", content: "Content of file-1" },
1619
- { filePath: "assets/file-2.txt", content: "Content of file-2" },
1743
+ { filePath: "file-1.txt", content: "Content of file-1" },
1744
+ { filePath: "file-2.txt", content: "Content of file-2" },
1620
1745
  ];
1621
1746
  const kvNamespace = {
1622
1747
  title: "__test-name-workers_sites_assets",
@@ -1637,13 +1762,13 @@ addEventListener('fetch', event => {});`
1637
1762
  // Check we only upload file-1
1638
1763
  mockUploadAssetsToKVRequest(
1639
1764
  kvNamespace.id,
1640
- assets.filter((a) => a.filePath === "assets/file-1.txt")
1765
+ assets.filter((a) => a.filePath === "file-1.txt")
1641
1766
  );
1642
1767
  await runWrangler("publish --site-exclude file-2.txt");
1643
1768
 
1644
1769
  expect(std.out).toMatchInlineSnapshot(`
1645
- "Reading assets/file-1.txt...
1646
- Uploading as assets/file-1.2ca234f380.txt...
1770
+ "Reading file-1.txt...
1771
+ Uploading as file-1.2ca234f380.txt...
1647
1772
  ↗️ Done syncing assets
1648
1773
  Uploaded test-name (TIMINGS)
1649
1774
  Published test-name (TIMINGS)
@@ -1654,8 +1779,8 @@ addEventListener('fetch', event => {});`
1654
1779
 
1655
1780
  it("should only upload files that match the `site.include` config", async () => {
1656
1781
  const assets = [
1657
- { filePath: "assets/file-1.txt", content: "Content of file-1" },
1658
- { filePath: "assets/file-2.txt", content: "Content of file-2" },
1782
+ { filePath: "file-1.txt", content: "Content of file-1" },
1783
+ { filePath: "file-2.txt", content: "Content of file-2" },
1659
1784
  ];
1660
1785
  const kvNamespace = {
1661
1786
  title: "__test-name-workers_sites_assets",
@@ -1677,13 +1802,13 @@ addEventListener('fetch', event => {});`
1677
1802
  // Check we only upload file-1
1678
1803
  mockUploadAssetsToKVRequest(
1679
1804
  kvNamespace.id,
1680
- assets.filter((a) => a.filePath === "assets/file-1.txt")
1805
+ assets.filter((a) => a.filePath === "file-1.txt")
1681
1806
  );
1682
1807
  await runWrangler("publish");
1683
1808
 
1684
1809
  expect(std.out).toMatchInlineSnapshot(`
1685
- "Reading assets/file-1.txt...
1686
- Uploading as assets/file-1.2ca234f380.txt...
1810
+ "Reading file-1.txt...
1811
+ Uploading as file-1.2ca234f380.txt...
1687
1812
  ↗️ Done syncing assets
1688
1813
  Uploaded test-name (TIMINGS)
1689
1814
  Published test-name (TIMINGS)
@@ -1694,8 +1819,8 @@ addEventListener('fetch', event => {});`
1694
1819
 
1695
1820
  it("should not upload files that match the `site.exclude` config", async () => {
1696
1821
  const assets = [
1697
- { filePath: "assets/file-1.txt", content: "Content of file-1" },
1698
- { filePath: "assets/file-2.txt", content: "Content of file-2" },
1822
+ { filePath: "file-1.txt", content: "Content of file-1" },
1823
+ { filePath: "file-2.txt", content: "Content of file-2" },
1699
1824
  ];
1700
1825
  const kvNamespace = {
1701
1826
  title: "__test-name-workers_sites_assets",
@@ -1717,13 +1842,13 @@ addEventListener('fetch', event => {});`
1717
1842
  // Check we only upload file-1
1718
1843
  mockUploadAssetsToKVRequest(
1719
1844
  kvNamespace.id,
1720
- assets.filter((a) => a.filePath === "assets/file-1.txt")
1845
+ assets.filter((a) => a.filePath === "file-1.txt")
1721
1846
  );
1722
1847
  await runWrangler("publish");
1723
1848
 
1724
1849
  expect(std.out).toMatchInlineSnapshot(`
1725
- "Reading assets/file-1.txt...
1726
- Uploading as assets/file-1.2ca234f380.txt...
1850
+ "Reading file-1.txt...
1851
+ Uploading as file-1.2ca234f380.txt...
1727
1852
  ↗️ Done syncing assets
1728
1853
  Uploaded test-name (TIMINGS)
1729
1854
  Published test-name (TIMINGS)
@@ -1734,8 +1859,8 @@ addEventListener('fetch', event => {});`
1734
1859
 
1735
1860
  it("should use `site-include` arg over `site.include` config", async () => {
1736
1861
  const assets = [
1737
- { filePath: "assets/file-1.txt", content: "Content of file-1" },
1738
- { filePath: "assets/file-2.txt", content: "Content of file-2" },
1862
+ { filePath: "file-1.txt", content: "Content of file-1" },
1863
+ { filePath: "file-2.txt", content: "Content of file-2" },
1739
1864
  ];
1740
1865
  const kvNamespace = {
1741
1866
  title: "__test-name-workers_sites_assets",
@@ -1757,13 +1882,13 @@ addEventListener('fetch', event => {});`
1757
1882
  // Check we only upload file-1
1758
1883
  mockUploadAssetsToKVRequest(
1759
1884
  kvNamespace.id,
1760
- assets.filter((a) => a.filePath === "assets/file-1.txt")
1885
+ assets.filter((a) => a.filePath === "file-1.txt")
1761
1886
  );
1762
1887
  await runWrangler("publish --site-include file-1.txt");
1763
1888
 
1764
1889
  expect(std.out).toMatchInlineSnapshot(`
1765
- "Reading assets/file-1.txt...
1766
- Uploading as assets/file-1.2ca234f380.txt...
1890
+ "Reading file-1.txt...
1891
+ Uploading as file-1.2ca234f380.txt...
1767
1892
  ↗️ Done syncing assets
1768
1893
  Uploaded test-name (TIMINGS)
1769
1894
  Published test-name (TIMINGS)
@@ -1774,8 +1899,8 @@ addEventListener('fetch', event => {});`
1774
1899
 
1775
1900
  it("should use `site-exclude` arg over `site.exclude` config", async () => {
1776
1901
  const assets = [
1777
- { filePath: "assets/file-1.txt", content: "Content of file-1" },
1778
- { filePath: "assets/file-2.txt", content: "Content of file-2" },
1902
+ { filePath: "file-1.txt", content: "Content of file-1" },
1903
+ { filePath: "file-2.txt", content: "Content of file-2" },
1779
1904
  ];
1780
1905
  const kvNamespace = {
1781
1906
  title: "__test-name-workers_sites_assets",
@@ -1785,7 +1910,7 @@ addEventListener('fetch', event => {});`
1785
1910
  main: "./index.js",
1786
1911
  site: {
1787
1912
  bucket: "assets",
1788
- exclude: ["assets/file-1.txt"],
1913
+ exclude: ["file-1.txt"],
1789
1914
  },
1790
1915
  });
1791
1916
  writeWorkerSource();
@@ -1797,13 +1922,13 @@ addEventListener('fetch', event => {});`
1797
1922
  // Check we only upload file-1
1798
1923
  mockUploadAssetsToKVRequest(
1799
1924
  kvNamespace.id,
1800
- assets.filter((a) => a.filePath.endsWith("assets/file-1.txt"))
1925
+ assets.filter((a) => a.filePath.endsWith("file-1.txt"))
1801
1926
  );
1802
1927
  await runWrangler("publish --site-exclude file-2.txt");
1803
1928
 
1804
1929
  expect(std.out).toMatchInlineSnapshot(`
1805
- "Reading assets/file-1.txt...
1806
- Uploading as assets/file-1.2ca234f380.txt...
1930
+ "Reading file-1.txt...
1931
+ Uploading as file-1.2ca234f380.txt...
1807
1932
  ↗️ Done syncing assets
1808
1933
  Uploaded test-name (TIMINGS)
1809
1934
  Published test-name (TIMINGS)
@@ -1815,11 +1940,11 @@ addEventListener('fetch', event => {});`
1815
1940
  it("should walk directories except node_modules", async () => {
1816
1941
  const assets = [
1817
1942
  {
1818
- filePath: "assets/directory-1/file-1.txt",
1943
+ filePath: "directory-1/file-1.txt",
1819
1944
  content: "Content of file-1",
1820
1945
  },
1821
1946
  {
1822
- filePath: "assets/node_modules/file-2.txt",
1947
+ filePath: "node_modules/file-2.txt",
1823
1948
  content: "Content of file-2",
1824
1949
  },
1825
1950
  ];
@@ -1844,8 +1969,8 @@ addEventListener('fetch', event => {});`
1844
1969
  await runWrangler("publish");
1845
1970
 
1846
1971
  expect(std.out).toMatchInlineSnapshot(`
1847
- "Reading assets/directory-1/file-1.txt...
1848
- Uploading as assets/directory-1/file-1.2ca234f380.txt...
1972
+ "Reading directory-1/file-1.txt...
1973
+ Uploading as directory-1/file-1.2ca234f380.txt...
1849
1974
  ↗️ Done syncing assets
1850
1975
  Uploaded test-name (TIMINGS)
1851
1976
  Published test-name (TIMINGS)
@@ -1857,15 +1982,15 @@ addEventListener('fetch', event => {});`
1857
1982
  it("should skip hidden files and directories except `.well-known`", async () => {
1858
1983
  const assets = [
1859
1984
  {
1860
- filePath: "assets/.hidden-file.txt",
1985
+ filePath: ".hidden-file.txt",
1861
1986
  content: "Content of hidden-file",
1862
1987
  },
1863
1988
  {
1864
- filePath: "assets/.hidden/file-1.txt",
1989
+ filePath: ".hidden/file-1.txt",
1865
1990
  content: "Content of file-1",
1866
1991
  },
1867
1992
  {
1868
- filePath: "assets/.well-known/file-2.txt",
1993
+ filePath: ".well-known/file-2.txt",
1869
1994
  content: "Content of file-2",
1870
1995
  },
1871
1996
  ];
@@ -1890,8 +2015,8 @@ addEventListener('fetch', event => {});`
1890
2015
  await runWrangler("publish");
1891
2016
 
1892
2017
  expect(std.out).toMatchInlineSnapshot(`
1893
- "Reading assets/.well-known/file-2.txt...
1894
- Uploading as assets/.well-known/file-2.5938485188.txt...
2018
+ "Reading .well-known/file-2.txt...
2019
+ Uploading as .well-known/file-2.5938485188.txt...
1895
2020
  ↗️ Done syncing assets
1896
2021
  Uploaded test-name (TIMINGS)
1897
2022
  Published test-name (TIMINGS)
@@ -1903,12 +2028,12 @@ addEventListener('fetch', event => {});`
1903
2028
  it("should error if the asset is over 25Mb", async () => {
1904
2029
  const assets = [
1905
2030
  {
1906
- filePath: "assets/large-file.txt",
2031
+ filePath: "large-file.txt",
1907
2032
  // This file is greater than 25MiB when base64 encoded but small enough to be uploaded.
1908
2033
  content: "X".repeat(25 * 1024 * 1024 * 0.8 + 1),
1909
2034
  },
1910
2035
  {
1911
- filePath: "assets/too-large-file.txt",
2036
+ filePath: "too-large-file.txt",
1912
2037
  content: "X".repeat(25 * 1024 * 1024 + 1),
1913
2038
  },
1914
2039
  ];
@@ -1920,7 +2045,7 @@ addEventListener('fetch', event => {});`
1920
2045
  main: "./index.js",
1921
2046
  site: {
1922
2047
  bucket: "assets",
1923
- exclude: ["assets/file-1.txt"],
2048
+ exclude: ["file-1.txt"],
1924
2049
  },
1925
2050
  });
1926
2051
  writeWorkerSource();
@@ -1933,25 +2058,131 @@ addEventListener('fetch', event => {});`
1933
2058
  await expect(
1934
2059
  runWrangler("publish")
1935
2060
  ).rejects.toThrowErrorMatchingInlineSnapshot(
1936
- `"File assets/too-large-file.txt is too big, it should be under 25 MiB. See https://developers.cloudflare.com/workers/platform/limits#kv-limits"`
2061
+ `"File too-large-file.txt is too big, it should be under 25 MiB. See https://developers.cloudflare.com/workers/platform/limits#kv-limits"`
1937
2062
  );
1938
2063
 
1939
2064
  expect(std.out).toMatchInlineSnapshot(`
1940
- "Reading assets/large-file.txt...
1941
- Uploading as assets/large-file.0ea0637a45.txt...
2065
+ "Reading large-file.txt...
2066
+ Uploading as large-file.0ea0637a45.txt...
2067
+ Reading too-large-file.txt...
1942
2068
 
1943
- If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new."
2069
+ If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new/choose"
1944
2070
  `);
1945
2071
  expect(std.err).toMatchInlineSnapshot(`
1946
- "X [ERROR] File assets/too-large-file.txt is too big, it should be under 25 MiB. See https://developers.cloudflare.com/workers/platform/limits#kv-limits
2072
+ "X [ERROR] File too-large-file.txt is too big, it should be under 25 MiB. See https://developers.cloudflare.com/workers/platform/limits#kv-limits
1947
2073
 
1948
2074
  "
1949
2075
  `);
1950
2076
  });
1951
2077
 
2078
+ it("should batch assets in groups <100 mb", async () => {
2079
+ // Let's have 20 files, from size 1 - 20 mb
2080
+ const assets = Array.from({ length: 20 }, (_, index) => ({
2081
+ filePath: `file-${`${index}`.padStart(2, "0")}.txt`,
2082
+ content: "X".repeat(1024 * 1024 * (index + 1)),
2083
+ }));
2084
+
2085
+ const kvNamespace = {
2086
+ title: "__test-name-workers_sites_assets",
2087
+ id: "__test-name-workers_sites_assets-id",
2088
+ };
2089
+ writeWranglerToml({
2090
+ main: "./index.js",
2091
+ site: {
2092
+ bucket: "assets",
2093
+ },
2094
+ });
2095
+ writeWorkerSource();
2096
+ writeAssets(assets);
2097
+ mockUploadWorkerRequest();
2098
+ mockSubDomainRequest();
2099
+ mockListKVNamespacesRequest(kvNamespace);
2100
+ mockKeyListRequest(kvNamespace.id, []);
2101
+
2102
+ // We expect this to be uploaded in 3 batches
2103
+ // The first batch has 11 files (88mb)
2104
+ // The next batch has 5 files (93mb)
2105
+ // And the last one has 4 files (98mb)
2106
+
2107
+ // Since the bulk upload api endpoint stays the same
2108
+ // We're going to have to clear the mock as soon as it's resolved
2109
+ // And immediately add a mock for another one
2110
+ // Welcome to a callback pyramid in 2022
2111
+
2112
+ const removeFirstBulkUploadMockFn = mockUploadAssetsToKVRequest(
2113
+ kvNamespace.id,
2114
+ assets.slice(0, 11),
2115
+ () => {
2116
+ removeFirstBulkUploadMockFn();
2117
+ const removeSecondBulkUploadMockFn = mockUploadAssetsToKVRequest(
2118
+ kvNamespace.id,
2119
+ assets.slice(11, 16),
2120
+ () => {
2121
+ removeSecondBulkUploadMockFn();
2122
+ mockUploadAssetsToKVRequest(kvNamespace.id, assets.slice(16, 20));
2123
+ }
2124
+ );
2125
+ }
2126
+ );
2127
+
2128
+ await runWrangler("publish");
2129
+
2130
+ expect(std).toMatchInlineSnapshot(`
2131
+ Object {
2132
+ "debug": "",
2133
+ "err": "",
2134
+ "out": "Reading file-00.txt...
2135
+ Uploading as file-00.be5be5dd26.txt...
2136
+ Reading file-01.txt...
2137
+ Uploading as file-01.4842d35994.txt...
2138
+ Reading file-02.txt...
2139
+ Uploading as file-02.990572ec63.txt...
2140
+ Reading file-03.txt...
2141
+ Uploading as file-03.9d7dda9045.txt...
2142
+ Reading file-04.txt...
2143
+ Uploading as file-04.2b6fac6382.txt...
2144
+ Reading file-05.txt...
2145
+ Uploading as file-05.55762dc758.txt...
2146
+ Reading file-06.txt...
2147
+ Uploading as file-06.f408a6b020.txt...
2148
+ Reading file-07.txt...
2149
+ Uploading as file-07.64c051715b.txt...
2150
+ Reading file-08.txt...
2151
+ Uploading as file-08.d286789adb.txt...
2152
+ Reading file-09.txt...
2153
+ Uploading as file-09.6838c183a8.txt...
2154
+ Reading file-10.txt...
2155
+ Uploading as file-10.6e03221d2a.txt...
2156
+ Reading file-11.txt...
2157
+ Uploading as file-11.37d3fb2eff.txt...
2158
+ Reading file-12.txt...
2159
+ Uploading as file-12.b3556942f8.txt...
2160
+ Reading file-13.txt...
2161
+ Uploading as file-13.680caf51b1.txt...
2162
+ Reading file-14.txt...
2163
+ Uploading as file-14.51e88468f0.txt...
2164
+ Reading file-15.txt...
2165
+ Uploading as file-15.8e3fedb394.txt...
2166
+ Reading file-16.txt...
2167
+ Uploading as file-16.c81c5e426f.txt...
2168
+ Reading file-17.txt...
2169
+ Uploading as file-17.4b2ae3c47b.txt...
2170
+ Reading file-18.txt...
2171
+ Uploading as file-18.07f245e02b.txt...
2172
+ Reading file-19.txt...
2173
+ Uploading as file-19.f0d69f705d.txt...
2174
+ ↗️ Done syncing assets
2175
+ Uploaded test-name (TIMINGS)
2176
+ Published test-name (TIMINGS)
2177
+ test-name.test-sub-domain.workers.dev",
2178
+ "warn": "",
2179
+ }
2180
+ `);
2181
+ });
2182
+
1952
2183
  it("should error if the asset key is over 512 characters", async () => {
1953
2184
  const longFilePathAsset = {
1954
- filePath: "assets/" + "folder/".repeat(100) + "file.txt",
2185
+ filePath: "folder/".repeat(100) + "file.txt",
1955
2186
  content: "content of file",
1956
2187
  };
1957
2188
  const kvNamespace = {
@@ -1974,16 +2205,16 @@ addEventListener('fetch', event => {});`
1974
2205
  await expect(
1975
2206
  runWrangler("publish")
1976
2207
  ).rejects.toThrowErrorMatchingInlineSnapshot(
1977
- `"The asset path key \\"assets/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/file.3da0d0cd12.txt\\" exceeds the maximum key size limit of 512. See https://developers.cloudflare.com/workers/platform/limits#kv-limits\\","`
2208
+ `"The asset path key \\"folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/file.3da0d0cd12.txt\\" exceeds the maximum key size limit of 512. See https://developers.cloudflare.com/workers/platform/limits#kv-limits\\","`
1978
2209
  );
1979
2210
 
1980
2211
  expect(std.out).toMatchInlineSnapshot(`
1981
- "Reading assets/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/file.txt...
2212
+ "Reading folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/file.txt...
1982
2213
 
1983
- If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new."
2214
+ If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new/choose"
1984
2215
  `);
1985
2216
  expect(std.err).toMatchInlineSnapshot(`
1986
- "X [ERROR] The asset path key \\"assets/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/file.3da0d0cd12.txt\\" exceeds the maximum key size limit of 512. See https://developers.cloudflare.com/workers/platform/limits#kv-limits\\",
2217
+ "X [ERROR] The asset path key \\"folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/folder/file.3da0d0cd12.txt\\" exceeds the maximum key size limit of 512. See https://developers.cloudflare.com/workers/platform/limits#kv-limits\\",
1987
2218
 
1988
2219
  "
1989
2220
  `);
@@ -1991,8 +2222,8 @@ addEventListener('fetch', event => {});`
1991
2222
 
1992
2223
  it("should delete uploaded assets that aren't included anymore", async () => {
1993
2224
  const assets = [
1994
- { filePath: "assets/file-1.txt", content: "Content of file-1" },
1995
- { filePath: "assets/file-2.txt", content: "Content of file-2" },
2225
+ { filePath: "file-1.txt", content: "Content of file-1" },
2226
+ { filePath: "file-2.txt", content: "Content of file-2" },
1996
2227
  ];
1997
2228
  const kvNamespace = {
1998
2229
  title: "__test-name-workers_sites_assets",
@@ -2011,32 +2242,33 @@ addEventListener('fetch', event => {});`
2011
2242
  mockListKVNamespacesRequest(kvNamespace);
2012
2243
  mockKeyListRequest(kvNamespace.id, [
2013
2244
  // Put file-1 in the KV namespace
2014
- { name: "assets/file-1.2ca234f380.txt" },
2245
+ { name: "file-1.2ca234f380.txt" },
2015
2246
  // As well as a couple from a previous upload
2016
- { name: "assets/file-3.somehash.txt" },
2017
- { name: "assets/file-4.anotherhash.txt" },
2247
+ { name: "file-3.somehash.txt" },
2248
+ { name: "file-4.anotherhash.txt" },
2018
2249
  ]);
2019
2250
 
2020
2251
  // we upload only file-1.txt
2021
- mockUploadAssetsToKVRequest(kvNamespace.id, [
2022
- ...assets.filter((a) => a.filePath !== "assets/file-1.txt"),
2023
- ]);
2252
+ mockUploadAssetsToKVRequest(
2253
+ kvNamespace.id,
2254
+ assets.filter((a) => a.filePath !== "file-1.txt")
2255
+ );
2024
2256
 
2025
2257
  // and mark file-3 and file-4 for deletion
2026
2258
  mockDeleteUnusedAssetsRequest(kvNamespace.id, [
2027
- "assets/file-3.somehash.txt",
2028
- "assets/file-4.anotherhash.txt",
2259
+ "file-3.somehash.txt",
2260
+ "file-4.anotherhash.txt",
2029
2261
  ]);
2030
2262
 
2031
2263
  await runWrangler("publish");
2032
2264
 
2033
2265
  expect(std.out).toMatchInlineSnapshot(`
2034
- "Reading assets/file-1.txt...
2266
+ "Reading file-1.txt...
2035
2267
  Skipping - already uploaded.
2036
- Reading assets/file-2.txt...
2037
- Uploading as assets/file-2.5938485188.txt...
2038
- Deleting assets/file-3.somehash.txt from the asset store...
2039
- Deleting assets/file-4.anotherhash.txt from the asset store...
2268
+ Reading file-2.txt...
2269
+ Uploading as file-2.5938485188.txt...
2270
+ Deleting file-3.somehash.txt from the asset store...
2271
+ Deleting file-4.anotherhash.txt from the asset store...
2040
2272
  ↗️ Done syncing assets
2041
2273
  Uploaded test-name (TIMINGS)
2042
2274
  Published test-name (TIMINGS)
@@ -2691,7 +2923,7 @@ addEventListener('fetch', event => {});`
2691
2923
  expect(std.out).toMatchInlineSnapshot(`
2692
2924
  "Running custom build: node -e \\"console.log('custom build');\\"
2693
2925
 
2694
- If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new."
2926
+ If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new/choose"
2695
2927
  `);
2696
2928
  expect(std.err).toMatchInlineSnapshot(`
2697
2929
  "X [ERROR] The expected output file at \\"index.js\\" was not found after running custom build: node -e \\"console.log('custom build');\\".
@@ -2730,7 +2962,7 @@ addEventListener('fetch', event => {});`
2730
2962
  expect(std.out).toMatchInlineSnapshot(`
2731
2963
  "Running custom build: node -e \\"console.log('custom build');\\"
2732
2964
 
2733
- If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new."
2965
+ If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new/choose"
2734
2966
  `);
2735
2967
  expect(std.err).toMatchInlineSnapshot(`
2736
2968
  "X [ERROR] The expected output file at \\".\\" was not found after running custom build: node -e \\"console.log('custom build');\\".
@@ -2845,7 +3077,15 @@ addEventListener('fetch', event => {});`
2845
3077
 
2846
3078
  - In wrangler.toml, you have configured [durable_objects] exported by this Worker (SomeClass),
2847
3079
  but no [migrations] for them. This may not work as expected until you add a [migrations] section
2848
- to your wrangler.toml. Refer to
3080
+ to your wrangler.toml. Add this configuration to your wrangler.toml:
3081
+
3082
+ \`\`\`
3083
+ [[migrations]]
3084
+ tag = \\"v1\\" # Should be unique for each entry
3085
+ new_classes = [\\"SomeClass\\"]
3086
+ \`\`\`
3087
+
3088
+ Refer to
2849
3089
  https://developers.cloudflare.com/workers/learning/using-durable-objects/#durable-object-migrations-in-wranglertoml
2850
3090
  for more details.
2851
3091
 
@@ -3531,7 +3771,7 @@ addEventListener('fetch', event => {});`
3531
3771
  `);
3532
3772
  expect(std.out).toMatchInlineSnapshot(`
3533
3773
  "
3534
- If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new."
3774
+ If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new/choose"
3535
3775
  `);
3536
3776
  expect(std.err).toMatchInlineSnapshot(`
3537
3777
  "X [ERROR] Processing wrangler.toml configuration:
@@ -3630,7 +3870,7 @@ addEventListener('fetch', event => {});`
3630
3870
  `);
3631
3871
  expect(std.out).toMatchInlineSnapshot(`
3632
3872
  "
3633
- If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new."
3873
+ If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new/choose"
3634
3874
  `);
3635
3875
  expect(std.err).toMatchInlineSnapshot(`
3636
3876
  "X [ERROR] Processing wrangler.toml configuration:
@@ -3764,7 +4004,7 @@ addEventListener('fetch', event => {});`
3764
4004
  `);
3765
4005
  expect(std.out).toMatchInlineSnapshot(`
3766
4006
  "
3767
- If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new."
4007
+ If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new/choose"
3768
4008
  `);
3769
4009
  expect(std.err).toMatchInlineSnapshot(`
3770
4010
  "X [ERROR] Processing wrangler.toml configuration:
@@ -3838,7 +4078,7 @@ addEventListener('fetch', event => {});`
3838
4078
  );
3839
4079
  expect(std.out).toMatchInlineSnapshot(`
3840
4080
  "
3841
- If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new."
4081
+ If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new/choose"
3842
4082
  `);
3843
4083
  expect(std.err).toMatchInlineSnapshot(`
3844
4084
  "X [ERROR] You cannot configure [wasm_modules] with an ES module worker. Instead, import the .wasm module directly in your code
@@ -3975,7 +4215,7 @@ addEventListener('fetch', event => {});`
3975
4215
  );
3976
4216
  expect(std.out).toMatchInlineSnapshot(`
3977
4217
  "
3978
- If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new."
4218
+ If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new/choose"
3979
4219
  `);
3980
4220
  expect(std.err).toMatchInlineSnapshot(`
3981
4221
  "X [ERROR] You cannot configure [text_blobs] with an ES module worker. Instead, import the file directly in your code, and optionally configure \`[rules]\` in your wrangler.toml
@@ -4084,7 +4324,7 @@ addEventListener('fetch', event => {});`
4084
4324
  );
4085
4325
  expect(std.out).toMatchInlineSnapshot(`
4086
4326
  "
4087
- If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new."
4327
+ If you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new/choose"
4088
4328
  `);
4089
4329
  expect(std.err).toMatchInlineSnapshot(`
4090
4330
  "X [ERROR] You cannot configure [data_blobs] with an ES module worker. Instead, import the file directly in your code, and optionally configure \`[rules]\` in your wrangler.toml
@@ -4946,7 +5186,7 @@ addEventListener('fetch', event => {});`
4946
5186
  "debug": "",
4947
5187
  "err": "",
4948
5188
  "out": "--dry-run: exiting now.",
4949
- "warn": "▲ [WARNING] Enabling node.js compatibility mode for builtins and globals. This is experimental and has serious tradeoffs. Please see https://github.com/ionic-team/rollup-plugin-node-polyfills/ for more details.
5189
+ "warn": "▲ [WARNING] Enabling node.js compatibility mode for built-ins and globals. This is experimental and has serious tradeoffs. Please see https://github.com/ionic-team/rollup-plugin-node-polyfills/ for more details.
4950
5190
 
4951
5191
  ",
4952
5192
  }
@@ -4990,7 +5230,7 @@ addEventListener('fetch', event => {});`
4990
5230
  "debug": "",
4991
5231
  "err": "",
4992
5232
  "out": "--dry-run: exiting now.",
4993
- "warn": "▲ [WARNING] Enabling node.js compatibility mode for builtins and globals. This is experimental and has serious tradeoffs. Please see https://github.com/ionic-team/rollup-plugin-node-polyfills/ for more details.
5233
+ "warn": "▲ [WARNING] Enabling node.js compatibility mode for built-ins and globals. This is experimental and has serious tradeoffs. Please see https://github.com/ionic-team/rollup-plugin-node-polyfills/ for more details.
4994
5234
 
4995
5235
  ",
4996
5236
  }
@@ -5000,10 +5240,16 @@ addEventListener('fetch', event => {});`
5000
5240
  });
5001
5241
 
5002
5242
  /** Write mock assets to the file system so they can be uploaded. */
5003
- function writeAssets(assets: { filePath: string; content: string }[]) {
5243
+ function writeAssets(
5244
+ assets: { filePath: string; content: string }[],
5245
+ destination = "assets"
5246
+ ) {
5004
5247
  for (const asset of assets) {
5005
- fs.mkdirSync(path.dirname(asset.filePath), { recursive: true });
5006
- fs.writeFileSync(asset.filePath, asset.content);
5248
+ const filePathDestination = path.join(destination, asset.filePath);
5249
+ fs.mkdirSync(path.dirname(filePathDestination), {
5250
+ recursive: true,
5251
+ });
5252
+ fs.writeFileSync(filePathDestination, asset.content);
5007
5253
  }
5008
5254
  }
5009
5255
 
@@ -5168,6 +5414,49 @@ function mockPublishRoutesRequest({
5168
5414
  );
5169
5415
  }
5170
5416
 
5417
+ function mockUnauthorizedPublishRoutesRequest({
5418
+ env = undefined,
5419
+ legacyEnv = false,
5420
+ }: {
5421
+ env?: string | undefined;
5422
+ legacyEnv?: boolean | undefined;
5423
+ } = {}) {
5424
+ const servicesOrScripts = env && !legacyEnv ? "services" : "scripts";
5425
+ const environment = env && !legacyEnv ? "/environments/:envName" : "";
5426
+
5427
+ setMockRawResponse(
5428
+ `/accounts/:accountId/workers/${servicesOrScripts}/:scriptName${environment}/routes`,
5429
+ "PUT",
5430
+ () =>
5431
+ createFetchResult(null, false, [
5432
+ { message: "Authentication error", code: 10000 },
5433
+ ])
5434
+ );
5435
+ }
5436
+
5437
+ function mockCollectKnownRoutesRequest(
5438
+ routes: { pattern: string; script: string }[]
5439
+ ) {
5440
+ setMockResponse(`/zones/:zoneId/workers/routes`, "GET", () => routes);
5441
+ }
5442
+
5443
+ function mockGetZoneFromHostRequest(host: string, zone: string) {
5444
+ setMockResponse("/zones", (_uri, _init, queryParams) => {
5445
+ expect(queryParams.get("name")).toEqual(host);
5446
+ return [{ id: zone }];
5447
+ });
5448
+ }
5449
+
5450
+ function mockPublishRoutesFallbackRequest(route: {
5451
+ pattern: string;
5452
+ script: string;
5453
+ }) {
5454
+ setMockResponse(`/zones/:zoneId/workers/routes`, "POST", (_url, { body }) => {
5455
+ expect(JSON.parse(body as string)).toEqual(route);
5456
+ return route.pattern;
5457
+ });
5458
+ }
5459
+
5171
5460
  function mockPublishCustomDomainsRequest({
5172
5461
  publishFlags,
5173
5462
  domains = [],
@@ -5284,9 +5573,10 @@ function mockUploadAssetsToKVRequest(
5284
5573
  content: string;
5285
5574
  expiration?: number;
5286
5575
  expiration_ttl?: number;
5287
- }[]
5576
+ }[],
5577
+ onUpload?: () => void
5288
5578
  ) {
5289
- setMockResponse(
5579
+ return setMockResponse(
5290
5580
  "/accounts/:accountId/storage/kv/namespaces/:namespaceId/bulk",
5291
5581
  "PUT",
5292
5582
  ([_url, accountId, namespaceId], { body }) => {
@@ -5316,6 +5606,7 @@ function mockUploadAssetsToKVRequest(
5316
5606
  expect(upload.expiration).toEqual(asset.expiration);
5317
5607
  expect(upload.expiration_ttl).toEqual(asset.expiration_ttl);
5318
5608
  }
5609
+ onUpload?.();
5319
5610
  return null;
5320
5611
  }
5321
5612
  );