wrangler 2.0.8 → 2.0.12
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/kv-asset-handler.js +1 -0
- package/package.json +3 -1
- package/src/__tests__/configuration.test.ts +255 -142
- package/src/__tests__/dev.test.tsx +88 -58
- package/src/__tests__/index.test.ts +2 -1
- package/src/__tests__/init.test.ts +3 -0
- package/src/__tests__/kv.test.ts +23 -2
- package/src/__tests__/pages.test.ts +98 -1
- package/src/__tests__/publish.test.ts +514 -162
- package/src/__tests__/whoami.test.tsx +34 -0
- package/src/bundle.ts +9 -5
- package/src/cfetch/internal.ts +6 -9
- package/src/config/config.ts +1 -1
- package/src/config/environment.ts +1 -1
- package/src/config/validation-helpers.ts +10 -1
- package/src/config/validation.ts +22 -13
- package/src/create-worker-preview.ts +15 -15
- package/src/dev/dev.tsx +32 -56
- package/src/dev/local.tsx +10 -7
- package/src/dev/remote.tsx +30 -17
- package/src/dev/use-esbuild.ts +1 -4
- package/src/index.tsx +239 -244
- package/src/kv.ts +1 -1
- package/src/pages.tsx +295 -229
- package/src/parse.ts +21 -1
- package/src/proxy.ts +19 -6
- package/src/publish.ts +154 -16
- package/src/sites.tsx +49 -18
- package/src/user.tsx +12 -1
- package/src/whoami.tsx +3 -2
- package/src/worker.ts +2 -1
- package/src/zones.ts +73 -0
- package/templates/static-asset-facade.js +1 -5
- package/wrangler-dist/cli.js +73693 -73458
- package/vendor/@cloudflare/kv-asset-handler/CHANGELOG.md +0 -332
- package/vendor/@cloudflare/kv-asset-handler/LICENSE_APACHE +0 -176
- package/vendor/@cloudflare/kv-asset-handler/LICENSE_MIT +0 -25
- package/vendor/@cloudflare/kv-asset-handler/README.md +0 -245
- package/vendor/@cloudflare/kv-asset-handler/dist/index.d.ts +0 -32
- package/vendor/@cloudflare/kv-asset-handler/dist/index.js +0 -354
- package/vendor/@cloudflare/kv-asset-handler/dist/mocks.d.ts +0 -13
- package/vendor/@cloudflare/kv-asset-handler/dist/mocks.js +0 -148
- package/vendor/@cloudflare/kv-asset-handler/dist/test/getAssetFromKV.d.ts +0 -1
- package/vendor/@cloudflare/kv-asset-handler/dist/test/getAssetFromKV.js +0 -436
- package/vendor/@cloudflare/kv-asset-handler/dist/test/mapRequestToAsset.d.ts +0 -1
- package/vendor/@cloudflare/kv-asset-handler/dist/test/mapRequestToAsset.js +0 -40
- package/vendor/@cloudflare/kv-asset-handler/dist/test/serveSinglePageApp.d.ts +0 -1
- package/vendor/@cloudflare/kv-asset-handler/dist/test/serveSinglePageApp.js +0 -42
- package/vendor/@cloudflare/kv-asset-handler/dist/types.d.ts +0 -26
- package/vendor/@cloudflare/kv-asset-handler/dist/types.js +0 -31
- package/vendor/@cloudflare/kv-asset-handler/package.json +0 -52
- package/vendor/@cloudflare/kv-asset-handler/src/index.ts +0 -296
- package/vendor/@cloudflare/kv-asset-handler/src/mocks.ts +0 -136
- package/vendor/@cloudflare/kv-asset-handler/src/test/getAssetFromKV.ts +0 -464
- package/vendor/@cloudflare/kv-asset-handler/src/test/mapRequestToAsset.ts +0 -33
- package/vendor/@cloudflare/kv-asset-handler/src/test/serveSinglePageApp.ts +0 -42
- package/vendor/@cloudflare/kv-asset-handler/src/types.ts +0 -39
- package/vendor/wrangler-mime/CHANGELOG.md +0 -289
- package/vendor/wrangler-mime/LICENSE +0 -21
- package/vendor/wrangler-mime/Mime.js +0 -97
- package/vendor/wrangler-mime/README.md +0 -187
- package/vendor/wrangler-mime/cli.js +0 -46
- package/vendor/wrangler-mime/index.js +0 -4
- package/vendor/wrangler-mime/lite.js +0 -4
- package/vendor/wrangler-mime/package.json +0 -52
- package/vendor/wrangler-mime/types/other.js +0 -1
- package/vendor/wrangler-mime/types/standard.js +0 -1
|
@@ -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
|
+
"[33m▲ [43;33m[[43;30mWARNING[43;33m][0m [1mThe current authentication token does not have 'All Zones' permissions.[0m
|
|
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
|
+
[33m▲ [43;33m[[43;30mWARNING[43;33m][0m [1mPreviously deployed routes:[0m
|
|
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
|
|
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
|
});
|
|
@@ -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: "
|
|
1150
|
-
{ filePath: "
|
|
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
|
|
1177
|
-
Uploading as
|
|
1178
|
-
Reading
|
|
1179
|
-
Uploading as
|
|
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: "
|
|
1201
|
-
{ filePath: "
|
|
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
|
|
1228
|
-
Uploading as
|
|
1229
|
-
Reading
|
|
1230
|
-
Uploading as
|
|
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)
|
|
@@ -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: "
|
|
1296
|
-
{ filePath: "
|
|
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,46 @@ addEventListener('fetch', event => {});`
|
|
|
1315
1392
|
await runWrangler("publish");
|
|
1316
1393
|
|
|
1317
1394
|
expect(std.out).toMatchInlineSnapshot(`
|
|
1318
|
-
"Reading
|
|
1319
|
-
Uploading as
|
|
1320
|
-
Reading
|
|
1321
|
-
Uploading as
|
|
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 upload all the files in the directory specified by `--experimental-public`", async () => {
|
|
1408
|
+
const assets = [
|
|
1409
|
+
{ filePath: "file-1.txt", content: "Content of file-1" },
|
|
1410
|
+
{ filePath: "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
|
+
});
|
|
1419
|
+
writeWorkerSource();
|
|
1420
|
+
writeAssets(assets);
|
|
1421
|
+
mockUploadWorkerRequest({
|
|
1422
|
+
expectedMainModule: "stdin.js",
|
|
1423
|
+
});
|
|
1424
|
+
mockSubDomainRequest();
|
|
1425
|
+
mockListKVNamespacesRequest(kvNamespace);
|
|
1426
|
+
mockKeyListRequest(kvNamespace.id, []);
|
|
1427
|
+
mockUploadAssetsToKVRequest(kvNamespace.id, assets);
|
|
1428
|
+
await runWrangler("publish --experimental-public assets");
|
|
1429
|
+
|
|
1430
|
+
expect(std.out).toMatchInlineSnapshot(`
|
|
1431
|
+
"Reading file-1.txt...
|
|
1432
|
+
Uploading as file-1.2ca234f380.txt...
|
|
1433
|
+
Reading file-2.txt...
|
|
1434
|
+
Uploading as file-2.5938485188.txt...
|
|
1322
1435
|
↗️ Done syncing assets
|
|
1323
1436
|
Uploaded test-name (TIMINGS)
|
|
1324
1437
|
Published test-name (TIMINGS)
|
|
@@ -1327,10 +1440,37 @@ addEventListener('fetch', event => {});`
|
|
|
1327
1440
|
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
1328
1441
|
});
|
|
1329
1442
|
|
|
1443
|
+
it("should error if --experimental-public and --site are used together", async () => {
|
|
1444
|
+
writeWranglerToml({
|
|
1445
|
+
main: "./index.js",
|
|
1446
|
+
});
|
|
1447
|
+
writeWorkerSource();
|
|
1448
|
+
await expect(
|
|
1449
|
+
runWrangler("publish --experimental-public abc --site xyz")
|
|
1450
|
+
).rejects.toThrowErrorMatchingInlineSnapshot(
|
|
1451
|
+
`"Cannot use --experimental-public and a Site configuration together."`
|
|
1452
|
+
);
|
|
1453
|
+
});
|
|
1454
|
+
|
|
1455
|
+
it("should error if --experimental-public and config.site are used together", async () => {
|
|
1456
|
+
writeWranglerToml({
|
|
1457
|
+
main: "./index.js",
|
|
1458
|
+
site: {
|
|
1459
|
+
bucket: "xyz",
|
|
1460
|
+
},
|
|
1461
|
+
});
|
|
1462
|
+
writeWorkerSource();
|
|
1463
|
+
await expect(
|
|
1464
|
+
runWrangler("publish --experimental-public abc")
|
|
1465
|
+
).rejects.toThrowErrorMatchingInlineSnapshot(
|
|
1466
|
+
`"Cannot use --experimental-public and a Site configuration together."`
|
|
1467
|
+
);
|
|
1468
|
+
});
|
|
1469
|
+
|
|
1330
1470
|
it("should not contain backslash for assets with nested directories", async () => {
|
|
1331
1471
|
const assets = [
|
|
1332
|
-
{ filePath: "
|
|
1333
|
-
{ filePath: "
|
|
1472
|
+
{ filePath: "subdir/file-1.txt", content: "Content of file-1" },
|
|
1473
|
+
{ filePath: "subdir/file-2.txt", content: "Content of file-2" },
|
|
1334
1474
|
];
|
|
1335
1475
|
const kvNamespace = {
|
|
1336
1476
|
title: "__test-name-workers_sites_assets",
|
|
@@ -1354,7 +1494,7 @@ addEventListener('fetch', event => {});`
|
|
|
1354
1494
|
],
|
|
1355
1495
|
expectedModules: {
|
|
1356
1496
|
__STATIC_CONTENT_MANIFEST:
|
|
1357
|
-
'{"subdir/file-1.txt":"
|
|
1497
|
+
'{"subdir/file-1.txt":"subdir/file-1.2ca234f380.txt","subdir/file-2.txt":"subdir/file-2.5938485188.txt"}',
|
|
1358
1498
|
},
|
|
1359
1499
|
});
|
|
1360
1500
|
mockSubDomainRequest();
|
|
@@ -1365,10 +1505,10 @@ addEventListener('fetch', event => {});`
|
|
|
1365
1505
|
await runWrangler("publish");
|
|
1366
1506
|
|
|
1367
1507
|
expect(std.out).toMatchInlineSnapshot(`
|
|
1368
|
-
"Reading
|
|
1369
|
-
Uploading as
|
|
1370
|
-
Reading
|
|
1371
|
-
Uploading as
|
|
1508
|
+
"Reading subdir/file-1.txt...
|
|
1509
|
+
Uploading as subdir/file-1.2ca234f380.txt...
|
|
1510
|
+
Reading subdir/file-2.txt...
|
|
1511
|
+
Uploading as subdir/file-2.5938485188.txt...
|
|
1372
1512
|
↗️ Done syncing assets
|
|
1373
1513
|
Uploaded test-name (TIMINGS)
|
|
1374
1514
|
Published test-name (TIMINGS)
|
|
@@ -1379,8 +1519,8 @@ addEventListener('fetch', event => {});`
|
|
|
1379
1519
|
|
|
1380
1520
|
it("when using a service-worker type, it should add an asset manifest as a text_blob, and bind to a namespace", async () => {
|
|
1381
1521
|
const assets = [
|
|
1382
|
-
{ filePath: "
|
|
1383
|
-
{ filePath: "
|
|
1522
|
+
{ filePath: "file-1.txt", content: "Content of file-1" },
|
|
1523
|
+
{ filePath: "file-2.txt", content: "Content of file-2" },
|
|
1384
1524
|
];
|
|
1385
1525
|
const kvNamespace = {
|
|
1386
1526
|
title: "__test-name-workers_sites_assets",
|
|
@@ -1398,7 +1538,7 @@ addEventListener('fetch', event => {});`
|
|
|
1398
1538
|
expectedType: "sw",
|
|
1399
1539
|
expectedModules: {
|
|
1400
1540
|
__STATIC_CONTENT_MANIFEST:
|
|
1401
|
-
'{"file-1.txt":"
|
|
1541
|
+
'{"file-1.txt":"file-1.2ca234f380.txt","file-2.txt":"file-2.5938485188.txt"}',
|
|
1402
1542
|
},
|
|
1403
1543
|
expectedBindings: [
|
|
1404
1544
|
{
|
|
@@ -1421,10 +1561,10 @@ addEventListener('fetch', event => {});`
|
|
|
1421
1561
|
await runWrangler("publish");
|
|
1422
1562
|
|
|
1423
1563
|
expect(std.out).toMatchInlineSnapshot(`
|
|
1424
|
-
"Reading
|
|
1425
|
-
Uploading as
|
|
1426
|
-
Reading
|
|
1427
|
-
Uploading as
|
|
1564
|
+
"Reading file-1.txt...
|
|
1565
|
+
Uploading as file-1.2ca234f380.txt...
|
|
1566
|
+
Reading file-2.txt...
|
|
1567
|
+
Uploading as file-2.5938485188.txt...
|
|
1428
1568
|
↗️ Done syncing assets
|
|
1429
1569
|
Uploaded test-name (TIMINGS)
|
|
1430
1570
|
Published test-name (TIMINGS)
|
|
@@ -1435,8 +1575,8 @@ addEventListener('fetch', event => {});`
|
|
|
1435
1575
|
|
|
1436
1576
|
it("when using a module worker type, it should add an asset manifest module, and bind to a namespace", async () => {
|
|
1437
1577
|
const assets = [
|
|
1438
|
-
{ filePath: "
|
|
1439
|
-
{ filePath: "
|
|
1578
|
+
{ filePath: "file-1.txt", content: "Content of file-1" },
|
|
1579
|
+
{ filePath: "file-2.txt", content: "Content of file-2" },
|
|
1440
1580
|
];
|
|
1441
1581
|
const kvNamespace = {
|
|
1442
1582
|
title: "__test-name-workers_sites_assets",
|
|
@@ -1460,7 +1600,7 @@ addEventListener('fetch', event => {});`
|
|
|
1460
1600
|
],
|
|
1461
1601
|
expectedModules: {
|
|
1462
1602
|
__STATIC_CONTENT_MANIFEST:
|
|
1463
|
-
'{"file-1.txt":"
|
|
1603
|
+
'{"file-1.txt":"file-1.2ca234f380.txt","file-2.txt":"file-2.5938485188.txt"}',
|
|
1464
1604
|
},
|
|
1465
1605
|
});
|
|
1466
1606
|
mockSubDomainRequest();
|
|
@@ -1471,10 +1611,10 @@ addEventListener('fetch', event => {});`
|
|
|
1471
1611
|
await runWrangler("publish");
|
|
1472
1612
|
|
|
1473
1613
|
expect(std.out).toMatchInlineSnapshot(`
|
|
1474
|
-
"Reading
|
|
1475
|
-
Uploading as
|
|
1476
|
-
Reading
|
|
1477
|
-
Uploading as
|
|
1614
|
+
"Reading file-1.txt...
|
|
1615
|
+
Uploading as file-1.2ca234f380.txt...
|
|
1616
|
+
Reading file-2.txt...
|
|
1617
|
+
Uploading as file-2.5938485188.txt...
|
|
1478
1618
|
↗️ Done syncing assets
|
|
1479
1619
|
Uploaded test-name (TIMINGS)
|
|
1480
1620
|
Published test-name (TIMINGS)
|
|
@@ -1486,8 +1626,8 @@ addEventListener('fetch', event => {});`
|
|
|
1486
1626
|
it("should make environment specific kv namespace for assets, even for service envs", async () => {
|
|
1487
1627
|
// This is the same test as the one before this, but with an env arg
|
|
1488
1628
|
const assets = [
|
|
1489
|
-
{ filePath: "
|
|
1490
|
-
{ filePath: "
|
|
1629
|
+
{ filePath: "file-1.txt", content: "Content of file-1" },
|
|
1630
|
+
{ filePath: "file-2.txt", content: "Content of file-2" },
|
|
1491
1631
|
];
|
|
1492
1632
|
const kvNamespace = {
|
|
1493
1633
|
title: "__test-name-some-env-workers_sites_assets",
|
|
@@ -1519,10 +1659,10 @@ addEventListener('fetch', event => {});`
|
|
|
1519
1659
|
await runWrangler("publish --env some-env --legacy-env false");
|
|
1520
1660
|
|
|
1521
1661
|
expect(std.out).toMatchInlineSnapshot(`
|
|
1522
|
-
"Reading
|
|
1523
|
-
Uploading as
|
|
1524
|
-
Reading
|
|
1525
|
-
Uploading as
|
|
1662
|
+
"Reading file-1.txt...
|
|
1663
|
+
Uploading as file-1.2ca234f380.txt...
|
|
1664
|
+
Reading file-2.txt...
|
|
1665
|
+
Uploading as file-2.5938485188.txt...
|
|
1526
1666
|
↗️ Done syncing assets
|
|
1527
1667
|
Uploaded test-name (some-env) (TIMINGS)
|
|
1528
1668
|
Published test-name (some-env) (TIMINGS)
|
|
@@ -1534,8 +1674,8 @@ addEventListener('fetch', event => {});`
|
|
|
1534
1674
|
it("should make environment specific kv namespace for assets, even for legacy envs", async () => {
|
|
1535
1675
|
// And this is the same test as the one before this, but with legacyEnv:true
|
|
1536
1676
|
const assets = [
|
|
1537
|
-
{ filePath: "
|
|
1538
|
-
{ filePath: "
|
|
1677
|
+
{ filePath: "file-1.txt", content: "Content of file-1" },
|
|
1678
|
+
{ filePath: "file-2.txt", content: "Content of file-2" },
|
|
1539
1679
|
];
|
|
1540
1680
|
const kvNamespace = {
|
|
1541
1681
|
title: "__test-name-some-env-workers_sites_assets",
|
|
@@ -1568,10 +1708,10 @@ addEventListener('fetch', event => {});`
|
|
|
1568
1708
|
await runWrangler("publish --env some-env --legacy-env true");
|
|
1569
1709
|
|
|
1570
1710
|
expect(std.out).toMatchInlineSnapshot(`
|
|
1571
|
-
"Reading
|
|
1572
|
-
Uploading as
|
|
1573
|
-
Reading
|
|
1574
|
-
Uploading as
|
|
1711
|
+
"Reading file-1.txt...
|
|
1712
|
+
Uploading as file-1.2ca234f380.txt...
|
|
1713
|
+
Reading file-2.txt...
|
|
1714
|
+
Uploading as file-2.5938485188.txt...
|
|
1575
1715
|
↗️ Done syncing assets
|
|
1576
1716
|
Uploaded test-name-some-env (TIMINGS)
|
|
1577
1717
|
Published test-name-some-env (TIMINGS)
|
|
@@ -1582,8 +1722,8 @@ addEventListener('fetch', event => {});`
|
|
|
1582
1722
|
|
|
1583
1723
|
it("should only upload files that are not already in the KV namespace", async () => {
|
|
1584
1724
|
const assets = [
|
|
1585
|
-
{ filePath: "
|
|
1586
|
-
{ filePath: "
|
|
1725
|
+
{ filePath: "file-1.txt", content: "Content of file-1" },
|
|
1726
|
+
{ filePath: "file-2.txt", content: "Content of file-2" },
|
|
1587
1727
|
];
|
|
1588
1728
|
const kvNamespace = {
|
|
1589
1729
|
title: "__test-name-workers_sites_assets",
|
|
@@ -1601,21 +1741,19 @@ addEventListener('fetch', event => {});`
|
|
|
1601
1741
|
mockSubDomainRequest();
|
|
1602
1742
|
mockListKVNamespacesRequest(kvNamespace);
|
|
1603
1743
|
// Put file-1 in the KV namespace
|
|
1604
|
-
mockKeyListRequest(kvNamespace.id, [
|
|
1605
|
-
{ name: "assets/file-1.2ca234f380.txt" },
|
|
1606
|
-
]);
|
|
1744
|
+
mockKeyListRequest(kvNamespace.id, [{ name: "file-1.2ca234f380.txt" }]);
|
|
1607
1745
|
// Check we do not upload file-1
|
|
1608
1746
|
mockUploadAssetsToKVRequest(
|
|
1609
1747
|
kvNamespace.id,
|
|
1610
|
-
assets.filter((a) => a.filePath !== "
|
|
1748
|
+
assets.filter((a) => a.filePath !== "file-1.txt")
|
|
1611
1749
|
);
|
|
1612
1750
|
await runWrangler("publish");
|
|
1613
1751
|
|
|
1614
1752
|
expect(std.out).toMatchInlineSnapshot(`
|
|
1615
|
-
"Reading
|
|
1753
|
+
"Reading file-1.txt...
|
|
1616
1754
|
Skipping - already uploaded.
|
|
1617
|
-
Reading
|
|
1618
|
-
Uploading as
|
|
1755
|
+
Reading file-2.txt...
|
|
1756
|
+
Uploading as file-2.5938485188.txt...
|
|
1619
1757
|
↗️ Done syncing assets
|
|
1620
1758
|
Uploaded test-name (TIMINGS)
|
|
1621
1759
|
Published test-name (TIMINGS)
|
|
@@ -1626,8 +1764,8 @@ addEventListener('fetch', event => {});`
|
|
|
1626
1764
|
|
|
1627
1765
|
it("should only upload files that match the `site-include` arg", async () => {
|
|
1628
1766
|
const assets = [
|
|
1629
|
-
{ filePath: "
|
|
1630
|
-
{ filePath: "
|
|
1767
|
+
{ filePath: "file-1.txt", content: "Content of file-1" },
|
|
1768
|
+
{ filePath: "file-2.txt", content: "Content of file-2" },
|
|
1631
1769
|
];
|
|
1632
1770
|
const kvNamespace = {
|
|
1633
1771
|
title: "__test-name-workers_sites_assets",
|
|
@@ -1648,13 +1786,13 @@ addEventListener('fetch', event => {});`
|
|
|
1648
1786
|
// Check we only upload file-1
|
|
1649
1787
|
mockUploadAssetsToKVRequest(
|
|
1650
1788
|
kvNamespace.id,
|
|
1651
|
-
assets.filter((a) => a.filePath === "
|
|
1789
|
+
assets.filter((a) => a.filePath === "file-1.txt")
|
|
1652
1790
|
);
|
|
1653
1791
|
await runWrangler("publish --site-include file-1.txt");
|
|
1654
1792
|
|
|
1655
1793
|
expect(std.out).toMatchInlineSnapshot(`
|
|
1656
|
-
"Reading
|
|
1657
|
-
Uploading as
|
|
1794
|
+
"Reading file-1.txt...
|
|
1795
|
+
Uploading as file-1.2ca234f380.txt...
|
|
1658
1796
|
↗️ Done syncing assets
|
|
1659
1797
|
Uploaded test-name (TIMINGS)
|
|
1660
1798
|
Published test-name (TIMINGS)
|
|
@@ -1665,8 +1803,8 @@ addEventListener('fetch', event => {});`
|
|
|
1665
1803
|
|
|
1666
1804
|
it("should not upload files that match the `site-exclude` arg", async () => {
|
|
1667
1805
|
const assets = [
|
|
1668
|
-
{ filePath: "
|
|
1669
|
-
{ filePath: "
|
|
1806
|
+
{ filePath: "file-1.txt", content: "Content of file-1" },
|
|
1807
|
+
{ filePath: "file-2.txt", content: "Content of file-2" },
|
|
1670
1808
|
];
|
|
1671
1809
|
const kvNamespace = {
|
|
1672
1810
|
title: "__test-name-workers_sites_assets",
|
|
@@ -1687,13 +1825,13 @@ addEventListener('fetch', event => {});`
|
|
|
1687
1825
|
// Check we only upload file-1
|
|
1688
1826
|
mockUploadAssetsToKVRequest(
|
|
1689
1827
|
kvNamespace.id,
|
|
1690
|
-
assets.filter((a) => a.filePath === "
|
|
1828
|
+
assets.filter((a) => a.filePath === "file-1.txt")
|
|
1691
1829
|
);
|
|
1692
1830
|
await runWrangler("publish --site-exclude file-2.txt");
|
|
1693
1831
|
|
|
1694
1832
|
expect(std.out).toMatchInlineSnapshot(`
|
|
1695
|
-
"Reading
|
|
1696
|
-
Uploading as
|
|
1833
|
+
"Reading file-1.txt...
|
|
1834
|
+
Uploading as file-1.2ca234f380.txt...
|
|
1697
1835
|
↗️ Done syncing assets
|
|
1698
1836
|
Uploaded test-name (TIMINGS)
|
|
1699
1837
|
Published test-name (TIMINGS)
|
|
@@ -1704,8 +1842,8 @@ addEventListener('fetch', event => {});`
|
|
|
1704
1842
|
|
|
1705
1843
|
it("should only upload files that match the `site.include` config", async () => {
|
|
1706
1844
|
const assets = [
|
|
1707
|
-
{ filePath: "
|
|
1708
|
-
{ filePath: "
|
|
1845
|
+
{ filePath: "file-1.txt", content: "Content of file-1" },
|
|
1846
|
+
{ filePath: "file-2.txt", content: "Content of file-2" },
|
|
1709
1847
|
];
|
|
1710
1848
|
const kvNamespace = {
|
|
1711
1849
|
title: "__test-name-workers_sites_assets",
|
|
@@ -1727,13 +1865,13 @@ addEventListener('fetch', event => {});`
|
|
|
1727
1865
|
// Check we only upload file-1
|
|
1728
1866
|
mockUploadAssetsToKVRequest(
|
|
1729
1867
|
kvNamespace.id,
|
|
1730
|
-
assets.filter((a) => a.filePath === "
|
|
1868
|
+
assets.filter((a) => a.filePath === "file-1.txt")
|
|
1731
1869
|
);
|
|
1732
1870
|
await runWrangler("publish");
|
|
1733
1871
|
|
|
1734
1872
|
expect(std.out).toMatchInlineSnapshot(`
|
|
1735
|
-
"Reading
|
|
1736
|
-
Uploading as
|
|
1873
|
+
"Reading file-1.txt...
|
|
1874
|
+
Uploading as file-1.2ca234f380.txt...
|
|
1737
1875
|
↗️ Done syncing assets
|
|
1738
1876
|
Uploaded test-name (TIMINGS)
|
|
1739
1877
|
Published test-name (TIMINGS)
|
|
@@ -1744,8 +1882,8 @@ addEventListener('fetch', event => {});`
|
|
|
1744
1882
|
|
|
1745
1883
|
it("should not upload files that match the `site.exclude` config", async () => {
|
|
1746
1884
|
const assets = [
|
|
1747
|
-
{ filePath: "
|
|
1748
|
-
{ filePath: "
|
|
1885
|
+
{ filePath: "file-1.txt", content: "Content of file-1" },
|
|
1886
|
+
{ filePath: "file-2.txt", content: "Content of file-2" },
|
|
1749
1887
|
];
|
|
1750
1888
|
const kvNamespace = {
|
|
1751
1889
|
title: "__test-name-workers_sites_assets",
|
|
@@ -1767,13 +1905,13 @@ addEventListener('fetch', event => {});`
|
|
|
1767
1905
|
// Check we only upload file-1
|
|
1768
1906
|
mockUploadAssetsToKVRequest(
|
|
1769
1907
|
kvNamespace.id,
|
|
1770
|
-
assets.filter((a) => a.filePath === "
|
|
1908
|
+
assets.filter((a) => a.filePath === "file-1.txt")
|
|
1771
1909
|
);
|
|
1772
1910
|
await runWrangler("publish");
|
|
1773
1911
|
|
|
1774
1912
|
expect(std.out).toMatchInlineSnapshot(`
|
|
1775
|
-
"Reading
|
|
1776
|
-
Uploading as
|
|
1913
|
+
"Reading file-1.txt...
|
|
1914
|
+
Uploading as file-1.2ca234f380.txt...
|
|
1777
1915
|
↗️ Done syncing assets
|
|
1778
1916
|
Uploaded test-name (TIMINGS)
|
|
1779
1917
|
Published test-name (TIMINGS)
|
|
@@ -1784,8 +1922,8 @@ addEventListener('fetch', event => {});`
|
|
|
1784
1922
|
|
|
1785
1923
|
it("should use `site-include` arg over `site.include` config", async () => {
|
|
1786
1924
|
const assets = [
|
|
1787
|
-
{ filePath: "
|
|
1788
|
-
{ filePath: "
|
|
1925
|
+
{ filePath: "file-1.txt", content: "Content of file-1" },
|
|
1926
|
+
{ filePath: "file-2.txt", content: "Content of file-2" },
|
|
1789
1927
|
];
|
|
1790
1928
|
const kvNamespace = {
|
|
1791
1929
|
title: "__test-name-workers_sites_assets",
|
|
@@ -1807,13 +1945,13 @@ addEventListener('fetch', event => {});`
|
|
|
1807
1945
|
// Check we only upload file-1
|
|
1808
1946
|
mockUploadAssetsToKVRequest(
|
|
1809
1947
|
kvNamespace.id,
|
|
1810
|
-
assets.filter((a) => a.filePath === "
|
|
1948
|
+
assets.filter((a) => a.filePath === "file-1.txt")
|
|
1811
1949
|
);
|
|
1812
1950
|
await runWrangler("publish --site-include file-1.txt");
|
|
1813
1951
|
|
|
1814
1952
|
expect(std.out).toMatchInlineSnapshot(`
|
|
1815
|
-
"Reading
|
|
1816
|
-
Uploading as
|
|
1953
|
+
"Reading file-1.txt...
|
|
1954
|
+
Uploading as file-1.2ca234f380.txt...
|
|
1817
1955
|
↗️ Done syncing assets
|
|
1818
1956
|
Uploaded test-name (TIMINGS)
|
|
1819
1957
|
Published test-name (TIMINGS)
|
|
@@ -1824,8 +1962,8 @@ addEventListener('fetch', event => {});`
|
|
|
1824
1962
|
|
|
1825
1963
|
it("should use `site-exclude` arg over `site.exclude` config", async () => {
|
|
1826
1964
|
const assets = [
|
|
1827
|
-
{ filePath: "
|
|
1828
|
-
{ filePath: "
|
|
1965
|
+
{ filePath: "file-1.txt", content: "Content of file-1" },
|
|
1966
|
+
{ filePath: "file-2.txt", content: "Content of file-2" },
|
|
1829
1967
|
];
|
|
1830
1968
|
const kvNamespace = {
|
|
1831
1969
|
title: "__test-name-workers_sites_assets",
|
|
@@ -1835,7 +1973,7 @@ addEventListener('fetch', event => {});`
|
|
|
1835
1973
|
main: "./index.js",
|
|
1836
1974
|
site: {
|
|
1837
1975
|
bucket: "assets",
|
|
1838
|
-
exclude: ["
|
|
1976
|
+
exclude: ["file-1.txt"],
|
|
1839
1977
|
},
|
|
1840
1978
|
});
|
|
1841
1979
|
writeWorkerSource();
|
|
@@ -1847,13 +1985,13 @@ addEventListener('fetch', event => {});`
|
|
|
1847
1985
|
// Check we only upload file-1
|
|
1848
1986
|
mockUploadAssetsToKVRequest(
|
|
1849
1987
|
kvNamespace.id,
|
|
1850
|
-
assets.filter((a) => a.filePath.endsWith("
|
|
1988
|
+
assets.filter((a) => a.filePath.endsWith("file-1.txt"))
|
|
1851
1989
|
);
|
|
1852
1990
|
await runWrangler("publish --site-exclude file-2.txt");
|
|
1853
1991
|
|
|
1854
1992
|
expect(std.out).toMatchInlineSnapshot(`
|
|
1855
|
-
"Reading
|
|
1856
|
-
Uploading as
|
|
1993
|
+
"Reading file-1.txt...
|
|
1994
|
+
Uploading as file-1.2ca234f380.txt...
|
|
1857
1995
|
↗️ Done syncing assets
|
|
1858
1996
|
Uploaded test-name (TIMINGS)
|
|
1859
1997
|
Published test-name (TIMINGS)
|
|
@@ -1865,11 +2003,11 @@ addEventListener('fetch', event => {});`
|
|
|
1865
2003
|
it("should walk directories except node_modules", async () => {
|
|
1866
2004
|
const assets = [
|
|
1867
2005
|
{
|
|
1868
|
-
filePath: "
|
|
2006
|
+
filePath: "directory-1/file-1.txt",
|
|
1869
2007
|
content: "Content of file-1",
|
|
1870
2008
|
},
|
|
1871
2009
|
{
|
|
1872
|
-
filePath: "
|
|
2010
|
+
filePath: "node_modules/file-2.txt",
|
|
1873
2011
|
content: "Content of file-2",
|
|
1874
2012
|
},
|
|
1875
2013
|
];
|
|
@@ -1894,8 +2032,8 @@ addEventListener('fetch', event => {});`
|
|
|
1894
2032
|
await runWrangler("publish");
|
|
1895
2033
|
|
|
1896
2034
|
expect(std.out).toMatchInlineSnapshot(`
|
|
1897
|
-
"Reading
|
|
1898
|
-
Uploading as
|
|
2035
|
+
"Reading directory-1/file-1.txt...
|
|
2036
|
+
Uploading as directory-1/file-1.2ca234f380.txt...
|
|
1899
2037
|
↗️ Done syncing assets
|
|
1900
2038
|
Uploaded test-name (TIMINGS)
|
|
1901
2039
|
Published test-name (TIMINGS)
|
|
@@ -1907,15 +2045,15 @@ addEventListener('fetch', event => {});`
|
|
|
1907
2045
|
it("should skip hidden files and directories except `.well-known`", async () => {
|
|
1908
2046
|
const assets = [
|
|
1909
2047
|
{
|
|
1910
|
-
filePath: "
|
|
2048
|
+
filePath: ".hidden-file.txt",
|
|
1911
2049
|
content: "Content of hidden-file",
|
|
1912
2050
|
},
|
|
1913
2051
|
{
|
|
1914
|
-
filePath: "
|
|
2052
|
+
filePath: ".hidden/file-1.txt",
|
|
1915
2053
|
content: "Content of file-1",
|
|
1916
2054
|
},
|
|
1917
2055
|
{
|
|
1918
|
-
filePath: "
|
|
2056
|
+
filePath: ".well-known/file-2.txt",
|
|
1919
2057
|
content: "Content of file-2",
|
|
1920
2058
|
},
|
|
1921
2059
|
];
|
|
@@ -1940,8 +2078,8 @@ addEventListener('fetch', event => {});`
|
|
|
1940
2078
|
await runWrangler("publish");
|
|
1941
2079
|
|
|
1942
2080
|
expect(std.out).toMatchInlineSnapshot(`
|
|
1943
|
-
"Reading
|
|
1944
|
-
Uploading as
|
|
2081
|
+
"Reading .well-known/file-2.txt...
|
|
2082
|
+
Uploading as .well-known/file-2.5938485188.txt...
|
|
1945
2083
|
↗️ Done syncing assets
|
|
1946
2084
|
Uploaded test-name (TIMINGS)
|
|
1947
2085
|
Published test-name (TIMINGS)
|
|
@@ -1953,12 +2091,12 @@ addEventListener('fetch', event => {});`
|
|
|
1953
2091
|
it("should error if the asset is over 25Mb", async () => {
|
|
1954
2092
|
const assets = [
|
|
1955
2093
|
{
|
|
1956
|
-
filePath: "
|
|
2094
|
+
filePath: "large-file.txt",
|
|
1957
2095
|
// This file is greater than 25MiB when base64 encoded but small enough to be uploaded.
|
|
1958
2096
|
content: "X".repeat(25 * 1024 * 1024 * 0.8 + 1),
|
|
1959
2097
|
},
|
|
1960
2098
|
{
|
|
1961
|
-
filePath: "
|
|
2099
|
+
filePath: "too-large-file.txt",
|
|
1962
2100
|
content: "X".repeat(25 * 1024 * 1024 + 1),
|
|
1963
2101
|
},
|
|
1964
2102
|
];
|
|
@@ -1970,7 +2108,7 @@ addEventListener('fetch', event => {});`
|
|
|
1970
2108
|
main: "./index.js",
|
|
1971
2109
|
site: {
|
|
1972
2110
|
bucket: "assets",
|
|
1973
|
-
exclude: ["
|
|
2111
|
+
exclude: ["file-1.txt"],
|
|
1974
2112
|
},
|
|
1975
2113
|
});
|
|
1976
2114
|
writeWorkerSource();
|
|
@@ -1983,25 +2121,122 @@ addEventListener('fetch', event => {});`
|
|
|
1983
2121
|
await expect(
|
|
1984
2122
|
runWrangler("publish")
|
|
1985
2123
|
).rejects.toThrowErrorMatchingInlineSnapshot(
|
|
1986
|
-
`"File
|
|
2124
|
+
`"File too-large-file.txt is too big, it should be under 25 MiB. See https://developers.cloudflare.com/workers/platform/limits#kv-limits"`
|
|
1987
2125
|
);
|
|
1988
2126
|
|
|
1989
2127
|
expect(std.out).toMatchInlineSnapshot(`
|
|
1990
|
-
"Reading
|
|
1991
|
-
Uploading as
|
|
2128
|
+
"Reading large-file.txt...
|
|
2129
|
+
Uploading as large-file.0ea0637a45.txt...
|
|
2130
|
+
Reading too-large-file.txt...
|
|
1992
2131
|
|
|
1993
2132
|
[32mIf you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new/choose[0m"
|
|
1994
2133
|
`);
|
|
1995
2134
|
expect(std.err).toMatchInlineSnapshot(`
|
|
1996
|
-
"[31mX [41;31m[[41;97mERROR[41;31m][0m [1mFile
|
|
2135
|
+
"[31mX [41;31m[[41;97mERROR[41;31m][0m [1mFile too-large-file.txt is too big, it should be under 25 MiB. See https://developers.cloudflare.com/workers/platform/limits#kv-limits[0m
|
|
1997
2136
|
|
|
1998
2137
|
"
|
|
1999
2138
|
`);
|
|
2000
2139
|
});
|
|
2001
2140
|
|
|
2141
|
+
it("should batch assets in groups <100 mb", async () => {
|
|
2142
|
+
// Let's have 20 files, from size 1 - 20 mb
|
|
2143
|
+
const assets = Array.from({ length: 20 }, (_, index) => ({
|
|
2144
|
+
filePath: `file-${`${index}`.padStart(2, "0")}.txt`,
|
|
2145
|
+
content: "X".repeat(1024 * 1024 * (index + 1)),
|
|
2146
|
+
}));
|
|
2147
|
+
|
|
2148
|
+
const kvNamespace = {
|
|
2149
|
+
title: "__test-name-workers_sites_assets",
|
|
2150
|
+
id: "__test-name-workers_sites_assets-id",
|
|
2151
|
+
};
|
|
2152
|
+
writeWranglerToml({
|
|
2153
|
+
main: "./index.js",
|
|
2154
|
+
site: {
|
|
2155
|
+
bucket: "assets",
|
|
2156
|
+
},
|
|
2157
|
+
});
|
|
2158
|
+
writeWorkerSource();
|
|
2159
|
+
writeAssets(assets);
|
|
2160
|
+
mockUploadWorkerRequest();
|
|
2161
|
+
mockSubDomainRequest();
|
|
2162
|
+
mockListKVNamespacesRequest(kvNamespace);
|
|
2163
|
+
mockKeyListRequest(kvNamespace.id, []);
|
|
2164
|
+
const requests = mockUploadAssetsToKVRequest(kvNamespace.id);
|
|
2165
|
+
|
|
2166
|
+
await runWrangler("publish");
|
|
2167
|
+
|
|
2168
|
+
// We expect this to be uploaded in 3 batches
|
|
2169
|
+
// The first batch has 11 files (88mb)
|
|
2170
|
+
expect(requests[0].uploads.length).toEqual(11);
|
|
2171
|
+
// The next batch has 5 files (93mb)
|
|
2172
|
+
expect(requests[1].uploads.length).toEqual(5);
|
|
2173
|
+
// And the last one has 4 files (98mb)
|
|
2174
|
+
expect(requests[2].uploads.length).toEqual(4);
|
|
2175
|
+
|
|
2176
|
+
let assetIndex = 0;
|
|
2177
|
+
for (const request of requests) {
|
|
2178
|
+
for (const upload of request.uploads) {
|
|
2179
|
+
checkAssetUpload(assets[assetIndex], upload);
|
|
2180
|
+
assetIndex++;
|
|
2181
|
+
}
|
|
2182
|
+
}
|
|
2183
|
+
|
|
2184
|
+
expect(std).toMatchInlineSnapshot(`
|
|
2185
|
+
Object {
|
|
2186
|
+
"debug": "",
|
|
2187
|
+
"err": "",
|
|
2188
|
+
"out": "Reading file-00.txt...
|
|
2189
|
+
Uploading as file-00.be5be5dd26.txt...
|
|
2190
|
+
Reading file-01.txt...
|
|
2191
|
+
Uploading as file-01.4842d35994.txt...
|
|
2192
|
+
Reading file-02.txt...
|
|
2193
|
+
Uploading as file-02.990572ec63.txt...
|
|
2194
|
+
Reading file-03.txt...
|
|
2195
|
+
Uploading as file-03.9d7dda9045.txt...
|
|
2196
|
+
Reading file-04.txt...
|
|
2197
|
+
Uploading as file-04.2b6fac6382.txt...
|
|
2198
|
+
Reading file-05.txt...
|
|
2199
|
+
Uploading as file-05.55762dc758.txt...
|
|
2200
|
+
Reading file-06.txt...
|
|
2201
|
+
Uploading as file-06.f408a6b020.txt...
|
|
2202
|
+
Reading file-07.txt...
|
|
2203
|
+
Uploading as file-07.64c051715b.txt...
|
|
2204
|
+
Reading file-08.txt...
|
|
2205
|
+
Uploading as file-08.d286789adb.txt...
|
|
2206
|
+
Reading file-09.txt...
|
|
2207
|
+
Uploading as file-09.6838c183a8.txt...
|
|
2208
|
+
Reading file-10.txt...
|
|
2209
|
+
Uploading as file-10.6e03221d2a.txt...
|
|
2210
|
+
Reading file-11.txt...
|
|
2211
|
+
Uploading as file-11.37d3fb2eff.txt...
|
|
2212
|
+
Reading file-12.txt...
|
|
2213
|
+
Uploading as file-12.b3556942f8.txt...
|
|
2214
|
+
Reading file-13.txt...
|
|
2215
|
+
Uploading as file-13.680caf51b1.txt...
|
|
2216
|
+
Reading file-14.txt...
|
|
2217
|
+
Uploading as file-14.51e88468f0.txt...
|
|
2218
|
+
Reading file-15.txt...
|
|
2219
|
+
Uploading as file-15.8e3fedb394.txt...
|
|
2220
|
+
Reading file-16.txt...
|
|
2221
|
+
Uploading as file-16.c81c5e426f.txt...
|
|
2222
|
+
Reading file-17.txt...
|
|
2223
|
+
Uploading as file-17.4b2ae3c47b.txt...
|
|
2224
|
+
Reading file-18.txt...
|
|
2225
|
+
Uploading as file-18.07f245e02b.txt...
|
|
2226
|
+
Reading file-19.txt...
|
|
2227
|
+
Uploading as file-19.f0d69f705d.txt...
|
|
2228
|
+
↗️ Done syncing assets
|
|
2229
|
+
Uploaded test-name (TIMINGS)
|
|
2230
|
+
Published test-name (TIMINGS)
|
|
2231
|
+
test-name.test-sub-domain.workers.dev",
|
|
2232
|
+
"warn": "",
|
|
2233
|
+
}
|
|
2234
|
+
`);
|
|
2235
|
+
});
|
|
2236
|
+
|
|
2002
2237
|
it("should error if the asset key is over 512 characters", async () => {
|
|
2003
2238
|
const longFilePathAsset = {
|
|
2004
|
-
filePath: "
|
|
2239
|
+
filePath: "folder/".repeat(100) + "file.txt",
|
|
2005
2240
|
content: "content of file",
|
|
2006
2241
|
};
|
|
2007
2242
|
const kvNamespace = {
|
|
@@ -2024,16 +2259,16 @@ addEventListener('fetch', event => {});`
|
|
|
2024
2259
|
await expect(
|
|
2025
2260
|
runWrangler("publish")
|
|
2026
2261
|
).rejects.toThrowErrorMatchingInlineSnapshot(
|
|
2027
|
-
`"The asset path key \\"
|
|
2262
|
+
`"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\\","`
|
|
2028
2263
|
);
|
|
2029
2264
|
|
|
2030
2265
|
expect(std.out).toMatchInlineSnapshot(`
|
|
2031
|
-
"Reading
|
|
2266
|
+
"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...
|
|
2032
2267
|
|
|
2033
2268
|
[32mIf you think this is a bug then please create an issue at https://github.com/cloudflare/wrangler2/issues/new/choose[0m"
|
|
2034
2269
|
`);
|
|
2035
2270
|
expect(std.err).toMatchInlineSnapshot(`
|
|
2036
|
-
"[31mX [41;31m[[41;97mERROR[41;31m][0m [1mThe asset path key \\"
|
|
2271
|
+
"[31mX [41;31m[[41;97mERROR[41;31m][0m [1mThe 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\\",[0m
|
|
2037
2272
|
|
|
2038
2273
|
"
|
|
2039
2274
|
`);
|
|
@@ -2041,8 +2276,8 @@ addEventListener('fetch', event => {});`
|
|
|
2041
2276
|
|
|
2042
2277
|
it("should delete uploaded assets that aren't included anymore", async () => {
|
|
2043
2278
|
const assets = [
|
|
2044
|
-
{ filePath: "
|
|
2045
|
-
{ filePath: "
|
|
2279
|
+
{ filePath: "file-1.txt", content: "Content of file-1" },
|
|
2280
|
+
{ filePath: "file-2.txt", content: "Content of file-2" },
|
|
2046
2281
|
];
|
|
2047
2282
|
const kvNamespace = {
|
|
2048
2283
|
title: "__test-name-workers_sites_assets",
|
|
@@ -2061,32 +2296,86 @@ addEventListener('fetch', event => {});`
|
|
|
2061
2296
|
mockListKVNamespacesRequest(kvNamespace);
|
|
2062
2297
|
mockKeyListRequest(kvNamespace.id, [
|
|
2063
2298
|
// Put file-1 in the KV namespace
|
|
2064
|
-
{ name: "
|
|
2299
|
+
{ name: "file-1.2ca234f380.txt" },
|
|
2065
2300
|
// As well as a couple from a previous upload
|
|
2066
|
-
{ name: "
|
|
2067
|
-
{ name: "
|
|
2301
|
+
{ name: "file-3.somehash.txt" },
|
|
2302
|
+
{ name: "file-4.anotherhash.txt" },
|
|
2068
2303
|
]);
|
|
2069
2304
|
|
|
2070
2305
|
// we upload only file-1.txt
|
|
2071
|
-
mockUploadAssetsToKVRequest(
|
|
2072
|
-
|
|
2073
|
-
|
|
2306
|
+
mockUploadAssetsToKVRequest(
|
|
2307
|
+
kvNamespace.id,
|
|
2308
|
+
assets.filter((a) => a.filePath !== "file-1.txt")
|
|
2309
|
+
);
|
|
2074
2310
|
|
|
2075
2311
|
// and mark file-3 and file-4 for deletion
|
|
2076
2312
|
mockDeleteUnusedAssetsRequest(kvNamespace.id, [
|
|
2077
|
-
"
|
|
2078
|
-
"
|
|
2313
|
+
"file-3.somehash.txt",
|
|
2314
|
+
"file-4.anotherhash.txt",
|
|
2079
2315
|
]);
|
|
2080
2316
|
|
|
2081
2317
|
await runWrangler("publish");
|
|
2082
2318
|
|
|
2083
2319
|
expect(std.out).toMatchInlineSnapshot(`
|
|
2084
|
-
"Reading
|
|
2320
|
+
"Reading file-1.txt...
|
|
2085
2321
|
Skipping - already uploaded.
|
|
2086
|
-
Reading
|
|
2087
|
-
Uploading as
|
|
2088
|
-
Deleting
|
|
2089
|
-
Deleting
|
|
2322
|
+
Reading file-2.txt...
|
|
2323
|
+
Uploading as file-2.5938485188.txt...
|
|
2324
|
+
Deleting file-3.somehash.txt from the asset store...
|
|
2325
|
+
Deleting file-4.anotherhash.txt from the asset store...
|
|
2326
|
+
↗️ Done syncing assets
|
|
2327
|
+
Uploaded test-name (TIMINGS)
|
|
2328
|
+
Published test-name (TIMINGS)
|
|
2329
|
+
test-name.test-sub-domain.workers.dev"
|
|
2330
|
+
`);
|
|
2331
|
+
expect(std.err).toMatchInlineSnapshot(`""`);
|
|
2332
|
+
});
|
|
2333
|
+
|
|
2334
|
+
it("should generate an asset manifest with keys relative to site.bucket", async () => {
|
|
2335
|
+
const assets = [
|
|
2336
|
+
{ filePath: "file-1.txt", content: "Content of file-1" },
|
|
2337
|
+
{ filePath: "file-2.txt", content: "Content of file-2" },
|
|
2338
|
+
];
|
|
2339
|
+
const kvNamespace = {
|
|
2340
|
+
title: "__test-name-workers_sites_assets",
|
|
2341
|
+
id: "__test-name-workers_sites_assets-id",
|
|
2342
|
+
};
|
|
2343
|
+
|
|
2344
|
+
writeWranglerToml({
|
|
2345
|
+
main: "./src/index.js",
|
|
2346
|
+
site: {
|
|
2347
|
+
bucket: "assets",
|
|
2348
|
+
},
|
|
2349
|
+
});
|
|
2350
|
+
writeWorkerSource({ basePath: "src", type: "esm" });
|
|
2351
|
+
writeAssets(assets);
|
|
2352
|
+
mockUploadWorkerRequest({
|
|
2353
|
+
expectedBindings: [
|
|
2354
|
+
{
|
|
2355
|
+
name: "__STATIC_CONTENT",
|
|
2356
|
+
namespace_id: "__test-name-workers_sites_assets-id",
|
|
2357
|
+
type: "kv_namespace",
|
|
2358
|
+
},
|
|
2359
|
+
],
|
|
2360
|
+
expectedModules: {
|
|
2361
|
+
__STATIC_CONTENT_MANIFEST:
|
|
2362
|
+
'{"file-1.txt":"file-1.2ca234f380.txt","file-2.txt":"file-2.5938485188.txt"}',
|
|
2363
|
+
},
|
|
2364
|
+
});
|
|
2365
|
+
mockSubDomainRequest();
|
|
2366
|
+
mockListKVNamespacesRequest(kvNamespace);
|
|
2367
|
+
mockKeyListRequest(kvNamespace.id, []);
|
|
2368
|
+
mockUploadAssetsToKVRequest(kvNamespace.id, assets);
|
|
2369
|
+
|
|
2370
|
+
process.chdir("./src");
|
|
2371
|
+
await runWrangler("publish");
|
|
2372
|
+
process.chdir("../");
|
|
2373
|
+
|
|
2374
|
+
expect(std.out).toMatchInlineSnapshot(`
|
|
2375
|
+
"Reading file-1.txt...
|
|
2376
|
+
Uploading as file-1.2ca234f380.txt...
|
|
2377
|
+
Reading file-2.txt...
|
|
2378
|
+
Uploading as file-2.5938485188.txt...
|
|
2090
2379
|
↗️ Done syncing assets
|
|
2091
2380
|
Uploaded test-name (TIMINGS)
|
|
2092
2381
|
Published test-name (TIMINGS)
|
|
@@ -5004,7 +5293,7 @@ addEventListener('fetch', event => {});`
|
|
|
5004
5293
|
"debug": "",
|
|
5005
5294
|
"err": "",
|
|
5006
5295
|
"out": "--dry-run: exiting now.",
|
|
5007
|
-
"warn": "[33m▲ [43;33m[[43;30mWARNING[43;33m][0m [1mEnabling node.js compatibility mode for
|
|
5296
|
+
"warn": "[33m▲ [43;33m[[43;30mWARNING[43;33m][0m [1mEnabling 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.[0m
|
|
5008
5297
|
|
|
5009
5298
|
",
|
|
5010
5299
|
}
|
|
@@ -5048,7 +5337,7 @@ addEventListener('fetch', event => {});`
|
|
|
5048
5337
|
"debug": "",
|
|
5049
5338
|
"err": "",
|
|
5050
5339
|
"out": "--dry-run: exiting now.",
|
|
5051
|
-
"warn": "[33m▲ [43;33m[[43;30mWARNING[43;33m][0m [1mEnabling node.js compatibility mode for
|
|
5340
|
+
"warn": "[33m▲ [43;33m[[43;30mWARNING[43;33m][0m [1mEnabling 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.[0m
|
|
5052
5341
|
|
|
5053
5342
|
",
|
|
5054
5343
|
}
|
|
@@ -5058,10 +5347,16 @@ addEventListener('fetch', event => {});`
|
|
|
5058
5347
|
});
|
|
5059
5348
|
|
|
5060
5349
|
/** Write mock assets to the file system so they can be uploaded. */
|
|
5061
|
-
function writeAssets(
|
|
5350
|
+
function writeAssets(
|
|
5351
|
+
assets: { filePath: string; content: string }[],
|
|
5352
|
+
destination = "assets"
|
|
5353
|
+
) {
|
|
5062
5354
|
for (const asset of assets) {
|
|
5063
|
-
|
|
5064
|
-
fs.
|
|
5355
|
+
const filePathDestination = path.join(destination, asset.filePath);
|
|
5356
|
+
fs.mkdirSync(path.dirname(filePathDestination), {
|
|
5357
|
+
recursive: true,
|
|
5358
|
+
});
|
|
5359
|
+
fs.writeFileSync(filePathDestination, asset.content);
|
|
5065
5360
|
}
|
|
5066
5361
|
}
|
|
5067
5362
|
|
|
@@ -5070,6 +5365,7 @@ function mockUploadWorkerRequest(
|
|
|
5070
5365
|
options: {
|
|
5071
5366
|
available_on_subdomain?: boolean;
|
|
5072
5367
|
expectedEntry?: string;
|
|
5368
|
+
expectedMainModule?: string;
|
|
5073
5369
|
expectedType?: "esm" | "sw";
|
|
5074
5370
|
expectedBindings?: unknown;
|
|
5075
5371
|
expectedModules?: Record<string, string>;
|
|
@@ -5083,6 +5379,7 @@ function mockUploadWorkerRequest(
|
|
|
5083
5379
|
const {
|
|
5084
5380
|
available_on_subdomain = true,
|
|
5085
5381
|
expectedEntry,
|
|
5382
|
+
expectedMainModule = "index.js",
|
|
5086
5383
|
expectedType = "esm",
|
|
5087
5384
|
expectedBindings,
|
|
5088
5385
|
expectedModules = {},
|
|
@@ -5106,6 +5403,7 @@ function mockUploadWorkerRequest(
|
|
|
5106
5403
|
expect(envName).toEqual(env);
|
|
5107
5404
|
}
|
|
5108
5405
|
expect(queryParams.get("include_subdomain_availability")).toEqual("true");
|
|
5406
|
+
expect(queryParams.get("excludeScript")).toEqual("true");
|
|
5109
5407
|
const formBody = body as FormData;
|
|
5110
5408
|
if (expectedEntry !== undefined) {
|
|
5111
5409
|
expect(await (formBody.get("index.js") as File).text()).toMatch(
|
|
@@ -5116,7 +5414,7 @@ function mockUploadWorkerRequest(
|
|
|
5116
5414
|
formBody.get("metadata") as string
|
|
5117
5415
|
) as WorkerMetadata;
|
|
5118
5416
|
if (expectedType === "esm") {
|
|
5119
|
-
expect(metadata.main_module).toEqual(
|
|
5417
|
+
expect(metadata.main_module).toEqual(expectedMainModule);
|
|
5120
5418
|
} else {
|
|
5121
5419
|
expect(metadata.body_part).toEqual("index.js");
|
|
5122
5420
|
}
|
|
@@ -5226,6 +5524,49 @@ function mockPublishRoutesRequest({
|
|
|
5226
5524
|
);
|
|
5227
5525
|
}
|
|
5228
5526
|
|
|
5527
|
+
function mockUnauthorizedPublishRoutesRequest({
|
|
5528
|
+
env = undefined,
|
|
5529
|
+
legacyEnv = false,
|
|
5530
|
+
}: {
|
|
5531
|
+
env?: string | undefined;
|
|
5532
|
+
legacyEnv?: boolean | undefined;
|
|
5533
|
+
} = {}) {
|
|
5534
|
+
const servicesOrScripts = env && !legacyEnv ? "services" : "scripts";
|
|
5535
|
+
const environment = env && !legacyEnv ? "/environments/:envName" : "";
|
|
5536
|
+
|
|
5537
|
+
setMockRawResponse(
|
|
5538
|
+
`/accounts/:accountId/workers/${servicesOrScripts}/:scriptName${environment}/routes`,
|
|
5539
|
+
"PUT",
|
|
5540
|
+
() =>
|
|
5541
|
+
createFetchResult(null, false, [
|
|
5542
|
+
{ message: "Authentication error", code: 10000 },
|
|
5543
|
+
])
|
|
5544
|
+
);
|
|
5545
|
+
}
|
|
5546
|
+
|
|
5547
|
+
function mockCollectKnownRoutesRequest(
|
|
5548
|
+
routes: { pattern: string; script: string }[]
|
|
5549
|
+
) {
|
|
5550
|
+
setMockResponse(`/zones/:zoneId/workers/routes`, "GET", () => routes);
|
|
5551
|
+
}
|
|
5552
|
+
|
|
5553
|
+
function mockGetZoneFromHostRequest(host: string, zone: string) {
|
|
5554
|
+
setMockResponse("/zones", (_uri, _init, queryParams) => {
|
|
5555
|
+
expect(queryParams.get("name")).toEqual(host);
|
|
5556
|
+
return [{ id: zone }];
|
|
5557
|
+
});
|
|
5558
|
+
}
|
|
5559
|
+
|
|
5560
|
+
function mockPublishRoutesFallbackRequest(route: {
|
|
5561
|
+
pattern: string;
|
|
5562
|
+
script: string;
|
|
5563
|
+
}) {
|
|
5564
|
+
setMockResponse(`/zones/:zoneId/workers/routes`, "POST", (_url, { body }) => {
|
|
5565
|
+
expect(JSON.parse(body as string)).toEqual(route);
|
|
5566
|
+
return route.pattern;
|
|
5567
|
+
});
|
|
5568
|
+
}
|
|
5569
|
+
|
|
5229
5570
|
function mockPublishCustomDomainsRequest({
|
|
5230
5571
|
publishFlags,
|
|
5231
5572
|
domains = [],
|
|
@@ -5334,16 +5675,28 @@ function mockListKVNamespacesRequest(...namespaces: KVNamespaceInfo[]) {
|
|
|
5334
5675
|
);
|
|
5335
5676
|
}
|
|
5336
5677
|
|
|
5678
|
+
interface ExpectedAsset {
|
|
5679
|
+
filePath: string;
|
|
5680
|
+
content: string;
|
|
5681
|
+
expiration?: number;
|
|
5682
|
+
expiration_ttl?: number;
|
|
5683
|
+
}
|
|
5684
|
+
interface StaticAssetUpload {
|
|
5685
|
+
key: string;
|
|
5686
|
+
base64: boolean;
|
|
5687
|
+
value: string;
|
|
5688
|
+
expiration: number | undefined;
|
|
5689
|
+
expiration_ttl: number | undefined;
|
|
5690
|
+
}
|
|
5691
|
+
|
|
5337
5692
|
/** Create a mock handler for the request that tries to do a bulk upload of assets to a KV namespace. */
|
|
5338
5693
|
function mockUploadAssetsToKVRequest(
|
|
5339
5694
|
expectedNamespaceId: string,
|
|
5340
|
-
assets
|
|
5341
|
-
filePath: string;
|
|
5342
|
-
content: string;
|
|
5343
|
-
expiration?: number;
|
|
5344
|
-
expiration_ttl?: number;
|
|
5345
|
-
}[]
|
|
5695
|
+
assets?: ExpectedAsset[]
|
|
5346
5696
|
) {
|
|
5697
|
+
const requests: {
|
|
5698
|
+
uploads: StaticAssetUpload[];
|
|
5699
|
+
}[] = [];
|
|
5347
5700
|
setMockResponse(
|
|
5348
5701
|
"/accounts/:accountId/storage/kv/namespaces/:namespaceId/bulk",
|
|
5349
5702
|
"PUT",
|
|
@@ -5351,32 +5704,31 @@ function mockUploadAssetsToKVRequest(
|
|
|
5351
5704
|
expect(accountId).toEqual("some-account-id");
|
|
5352
5705
|
expect(namespaceId).toEqual(expectedNamespaceId);
|
|
5353
5706
|
const uploads = JSON.parse(body as string);
|
|
5354
|
-
|
|
5355
|
-
|
|
5356
|
-
|
|
5357
|
-
|
|
5358
|
-
|
|
5359
|
-
|
|
5360
|
-
|
|
5361
|
-
// - the extension
|
|
5362
|
-
const keyMatcher = new RegExp(
|
|
5363
|
-
"^" +
|
|
5364
|
-
asset.filePath
|
|
5365
|
-
.replace(/(\.[^.]+)$/, ".[a-z0-9]+$1")
|
|
5366
|
-
.replace(/\./g, "\\.")
|
|
5367
|
-
);
|
|
5368
|
-
expect(upload.key).toMatch(keyMatcher);
|
|
5369
|
-
// The asset value is base64 encoded.
|
|
5370
|
-
expect(upload.base64).toBe(true);
|
|
5371
|
-
expect(Buffer.from(upload.value, "base64").toString()).toEqual(
|
|
5372
|
-
asset.content
|
|
5373
|
-
);
|
|
5374
|
-
expect(upload.expiration).toEqual(asset.expiration);
|
|
5375
|
-
expect(upload.expiration_ttl).toEqual(asset.expiration_ttl);
|
|
5707
|
+
if (assets) {
|
|
5708
|
+
expect(assets.length).toEqual(uploads.length);
|
|
5709
|
+
for (let i = 0; i < uploads.length; i++) {
|
|
5710
|
+
checkAssetUpload(assets[i], uploads[i]);
|
|
5711
|
+
}
|
|
5712
|
+
} else {
|
|
5713
|
+
requests.push({ uploads });
|
|
5376
5714
|
}
|
|
5377
|
-
return null;
|
|
5378
5715
|
}
|
|
5379
5716
|
);
|
|
5717
|
+
return requests;
|
|
5718
|
+
}
|
|
5719
|
+
|
|
5720
|
+
function checkAssetUpload(asset: ExpectedAsset, upload: StaticAssetUpload) {
|
|
5721
|
+
// The asset key consists of: `<basename>.<hash>.<extension>`
|
|
5722
|
+
const keyMatcher = new RegExp(
|
|
5723
|
+
"^" +
|
|
5724
|
+
asset.filePath.replace(/(\.[^.]+)$/, ".[a-z0-9]+$1").replace(/\./g, "\\.")
|
|
5725
|
+
);
|
|
5726
|
+
expect(upload.key).toMatch(keyMatcher);
|
|
5727
|
+
// The asset value is base64 encoded.
|
|
5728
|
+
expect(upload.base64).toBe(true);
|
|
5729
|
+
expect(Buffer.from(upload.value, "base64").toString()).toEqual(asset.content);
|
|
5730
|
+
expect(upload.expiration).toEqual(asset.expiration);
|
|
5731
|
+
expect(upload.expiration_ttl).toEqual(asset.expiration_ttl);
|
|
5380
5732
|
}
|
|
5381
5733
|
|
|
5382
5734
|
/** Create a mock handler for thr request that does a bulk delete of unused assets */
|