Skip to content

Commit 2526ef4

Browse files
fix: skip unwanted files and directories when publishing site assets
In keeping with Wrangler 1, we now skip node_modules and hidden files and directories. An exception is made for `.well-known`. See https://datatracker.ietf.org/doc/html/rfc8615. The tests also prove that the asset uploader will walk directories in general.
1 parent a3101a1 commit 2526ef4

File tree

3 files changed

+116
-2
lines changed

3 files changed

+116
-2
lines changed

.changeset/violet-wasps-reply.md

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
---
2+
"wrangler": patch
3+
---
4+
5+
fix: skip unwanted files and directories when publishing site assets
6+
7+
In keeping with Wrangler 1, we now skip node_modules and hidden files and directories.
8+
9+
An exception is made for `.well-known`. See https://datatracker.ietf.org/doc/html/rfc8615.
10+
11+
The tests also prove that the asset uploader will walk directories in general.

packages/wrangler/src/__tests__/publish.test.ts

+88
Original file line numberDiff line numberDiff line change
@@ -383,6 +383,94 @@ describe("publish", () => {
383383
expect(error).toMatchInlineSnapshot(`undefined`);
384384
});
385385

386+
it("should walk directories except node_modules", async () => {
387+
const assets = [
388+
{
389+
filePath: "assets/directory-1/file-1.txt",
390+
content: "Content of file-1",
391+
},
392+
{
393+
filePath: "assets/node_modules/file-2.txt",
394+
content: "Content of file-2",
395+
},
396+
];
397+
const kvNamespace = {
398+
title: "__test-name_sites_assets",
399+
id: "__test-name_sites_assets-id",
400+
};
401+
writeWranglerToml("./index.js", "assets");
402+
writeEsmWorkerSource();
403+
writeAssets(assets);
404+
mockUploadWorkerRequest();
405+
mockSubDomainRequest();
406+
mockListKVNamespacesRequest(kvNamespace);
407+
mockKeyListRequest(kvNamespace.id, []);
408+
// Only expect file-1 to be uploaded
409+
mockUploadAssetsToKVRequest(kvNamespace.id, assets.slice(0, 1));
410+
const { stdout, stderr, error } = await runWrangler("publish");
411+
412+
expect(stripTimings(stdout)).toMatchInlineSnapshot(`
413+
"reading assets/directory-1/file-1.txt...
414+
uploading as assets/directory-1/file-1.2ca234f380.txt...
415+
Uploaded
416+
test-name
417+
(TIMINGS)
418+
Deployed
419+
test-name
420+
(TIMINGS)
421+
422+
test-name.test-sub-domain.workers.dev"
423+
`);
424+
expect(stderr).toMatchInlineSnapshot(`""`);
425+
expect(error).toMatchInlineSnapshot(`undefined`);
426+
});
427+
428+
it("should skip hidden files and directories except `.well-known`", async () => {
429+
const assets = [
430+
{
431+
filePath: "assets/.hidden-file.txt",
432+
content: "Content of hidden-file",
433+
},
434+
{
435+
filePath: "assets/.hidden/file-1.txt",
436+
content: "Content of file-1",
437+
},
438+
{
439+
filePath: "assets/.well-known/file-2.txt",
440+
content: "Content of file-2",
441+
},
442+
];
443+
const kvNamespace = {
444+
title: "__test-name_sites_assets",
445+
id: "__test-name_sites_assets-id",
446+
};
447+
writeWranglerToml("./index.js", "assets");
448+
writeEsmWorkerSource();
449+
writeAssets(assets);
450+
mockUploadWorkerRequest();
451+
mockSubDomainRequest();
452+
mockListKVNamespacesRequest(kvNamespace);
453+
mockKeyListRequest(kvNamespace.id, []);
454+
// Only expect file-2 to be uploaded
455+
mockUploadAssetsToKVRequest(kvNamespace.id, assets.slice(2));
456+
const { stdout, stderr, error } = await runWrangler("publish");
457+
458+
expect(stripTimings(stdout)).toMatchInlineSnapshot(`
459+
"reading assets/.well-known/file-2.txt...
460+
uploading as assets/.well-known/file-2.5938485188.txt...
461+
Uploaded
462+
test-name
463+
(TIMINGS)
464+
Deployed
465+
test-name
466+
(TIMINGS)
467+
468+
test-name.test-sub-domain.workers.dev"
469+
`);
470+
expect(stderr).toMatchInlineSnapshot(`""`);
471+
expect(error).toMatchInlineSnapshot(`undefined`);
472+
});
473+
386474
it("should error if the asset is over 25Mb", async () => {
387475
const assets = [
388476
{

packages/wrangler/src/sites.tsx

+17-2
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,26 @@ import { fetchResult } from "./cfetch";
66
import type { AssetPaths } from "./config";
77
import { listNamespaceKeys, listNamespaces, putBulkKeyValue } from "./kv";
88

9+
/** Paths to always ignore. */
10+
const ALWAYS_IGNORE = ["node_modules"];
11+
const HIDDEN_FILES_TO_INCLUDE = [
12+
".well-known", // See https://datatracker.ietf.org/doc/html/rfc8615
13+
];
14+
915
async function* getFilesInFolder(dirPath: string): AsyncIterable<string> {
1016
const files = await readdir(dirPath, { withFileTypes: true });
1117
for (const file of files) {
12-
// TODO: always ignore `node_modules`
13-
// TODO: ignore hidden files (starting with .) but not .well-known??
18+
// Skip files that we never want to process.
19+
if (ALWAYS_IGNORE.some((p) => file.name === p)) {
20+
continue;
21+
}
22+
// Skip hidden files (starting with .) except for some special ones
23+
if (
24+
file.name.startsWith(".") &&
25+
!HIDDEN_FILES_TO_INCLUDE.some((p) => file.name === p)
26+
) {
27+
continue;
28+
}
1429
// TODO: follow symlinks??
1530
if (file.isDirectory()) {
1631
yield* await getFilesInFolder(path.join(dirPath, file.name));

0 commit comments

Comments
 (0)