Skip to content

Commit 3d80916

Browse files
fix: .well-known static folder not working (#3676)
This folder is typically used for site metadata like `security.txt` and other stuff.
1 parent 9f68496 commit 3d80916

File tree

2 files changed

+41
-4
lines changed

2 files changed

+41
-4
lines changed

packages/fresh/src/dev/builder_test.ts

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,42 @@ Deno.test({
281281
sanitizeResources: false,
282282
});
283283

284+
Deno.test({
285+
name: "Builder - .well-known static files",
286+
fn: async () => {
287+
await using _tmp = await withTmpDir();
288+
const tmp = _tmp.dir;
289+
290+
const foo = path.join(tmp, ".well-known", "foo.json");
291+
await Deno.mkdir(path.dirname(foo), { recursive: true });
292+
await Deno.writeTextFile(foo, JSON.stringify({ ok: true }));
293+
294+
const builder = new Builder({
295+
outDir: path.join(tmp, "dist"),
296+
staticDir: tmp,
297+
});
298+
const app = new App().use(staticFiles());
299+
const abort = new AbortController();
300+
const port = 8011;
301+
await builder.listen(() => Promise.resolve(app), {
302+
port,
303+
signal: abort.signal,
304+
});
305+
306+
const res = await fetch(
307+
`http://localhost:${port}/.well-known/foo.json`,
308+
);
309+
const json = await res.json();
310+
await abort.abort();
311+
312+
expect(res.ok).toBe(true);
313+
expect(res.status).toBe(200);
314+
expect(json).toEqual({ ok: true });
315+
},
316+
sanitizeOps: false,
317+
sanitizeResources: false,
318+
});
319+
284320
Deno.test({
285321
name: "Builder - write prod routePattern",
286322
fn: async () => {

packages/fresh/src/dev/dev_build_cache.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ export class MemoryBuildCache<State> implements DevBuildCache<State> {
142142
for (let i = 0; i < transformed.length; i++) {
143143
const file = transformed[i];
144144
const relative = path.relative(this.#config.staticDir, file.path);
145-
if (relative.startsWith(".")) {
145+
if (relative.startsWith("..")) {
146146
throw new Error(
147147
`Processed file resolved outside of static dir ${file.path}`,
148148
);
@@ -158,7 +158,7 @@ export class MemoryBuildCache<State> implements DevBuildCache<State> {
158158
try {
159159
const filePath = path.join(this.#config.staticDir, pathname);
160160
const relative = path.relative(this.#config.staticDir, filePath);
161-
if (!relative.startsWith(".") && (await Deno.stat(filePath)).isFile) {
161+
if (!relative.startsWith("..") && (await Deno.stat(filePath)).isFile) {
162162
const pathname = new URL(relative, "http://localhost").pathname;
163163
this.addUnprocessedFile(pathname, this.#config.staticDir);
164164
return this.readFile(pathname);
@@ -301,8 +301,9 @@ export class DiskBuildCache<State> implements DevBuildCache<State> {
301301
includeDirs: false,
302302
includeFiles: true,
303303
followSymlinks: false,
304-
// Skip any folder or file starting with a "."
305-
skip: [/\/\.[^/]+(\/|$)/],
304+
// Skip any folder or file starting with a ".", but allow
305+
// ".well-known" for things like PWA manifests
306+
skip: [/\/\.(?!well-known)[^/]+(\/|$)/],
306307
});
307308

308309
for await (const entry of entries) {

0 commit comments

Comments
 (0)