bun-plugin-stx 0.2.172 → 0.2.174
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/dist/serve.d.ts +19 -0
- package/dist/serve.js +23 -2
- package/package.json +1 -1
package/dist/serve.d.ts
CHANGED
|
@@ -42,6 +42,25 @@ export declare function routeSpecificity(fileRouteBase: string): number;
|
|
|
42
42
|
* `.html`) return false; those are routable.
|
|
43
43
|
*/
|
|
44
44
|
export declare function isStaticAssetPath(requestPath: string): boolean;
|
|
45
|
+
/**
|
|
46
|
+
* Does a file actually exist under `publicDir` for this request path?
|
|
47
|
+
*
|
|
48
|
+
* The extension test above is a guess about intent, and it is the wrong
|
|
49
|
+
* question to ask before dropping a catch-all: an app whose catch-all
|
|
50
|
+
* legitimately serves paths that carry extensions - a file browser, a docs
|
|
51
|
+
* site addressing `guide.md`, anything rendering a repository - has every
|
|
52
|
+
* such page refused, because the guess says "asset" and the only route that
|
|
53
|
+
* could answer is the one being dropped.
|
|
54
|
+
*
|
|
55
|
+
* Asking the disk instead keeps what stacksjs/stx#1841 was protecting (a real
|
|
56
|
+
* `public/images/logo.jpg` still wins over `[...all].stx`) and costs one stat
|
|
57
|
+
* on a path that was going to be looked up moments later anyway.
|
|
58
|
+
*
|
|
59
|
+
* Traversal is normalized before the prefix check, the same way the publicDir
|
|
60
|
+
* handler does it, so `..` cannot walk out of the root and report on a file
|
|
61
|
+
* that is none of the caller's business.
|
|
62
|
+
*/
|
|
63
|
+
export declare function publicFileExists(requestPath: string, publicDir: string): boolean;
|
|
45
64
|
/**
|
|
46
65
|
* Are we serving in production? In production the built-in 404 must not
|
|
47
66
|
* enumerate the app's route list (information disclosure) and must not
|
package/dist/serve.js
CHANGED
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
|
|
10
10
|
// src/serve.ts
|
|
11
11
|
var {serve: bunServe, Glob } = globalThis.Bun;
|
|
12
|
-
import { watch as fsWatch } from "fs";
|
|
12
|
+
import { existsSync as existsSync2, watch as fsWatch, statSync as statSync3 } from "fs";
|
|
13
13
|
import nodeFs from "fs/promises";
|
|
14
14
|
import nodePath from "path";
|
|
15
15
|
import process19 from "process";
|
|
@@ -8813,6 +8813,26 @@ function routeSpecificity(fileRouteBase) {
|
|
|
8813
8813
|
function isStaticAssetPath(requestPath) {
|
|
8814
8814
|
return /\.[a-z0-9]+$/i.test(requestPath) && !/\.(?:stx|md|html)$/i.test(requestPath);
|
|
8815
8815
|
}
|
|
8816
|
+
function publicFileExists(requestPath, publicDir) {
|
|
8817
|
+
let decoded;
|
|
8818
|
+
try {
|
|
8819
|
+
decoded = decodeURIComponent(requestPath);
|
|
8820
|
+
} catch {
|
|
8821
|
+
decoded = requestPath;
|
|
8822
|
+
}
|
|
8823
|
+
if (decoded.includes("\x00"))
|
|
8824
|
+
return false;
|
|
8825
|
+
const publicRoot = nodePath.resolve(process19.cwd(), publicDir);
|
|
8826
|
+
const resolved = nodePath.resolve(publicRoot, `.${decoded}`);
|
|
8827
|
+
const inside = resolved === publicRoot || resolved.startsWith(`${publicRoot}${nodePath.sep}`);
|
|
8828
|
+
if (!inside)
|
|
8829
|
+
return false;
|
|
8830
|
+
try {
|
|
8831
|
+
return existsSync2(resolved) && !statSync3(resolved).isDirectory();
|
|
8832
|
+
} catch {
|
|
8833
|
+
return false;
|
|
8834
|
+
}
|
|
8835
|
+
}
|
|
8816
8836
|
function escapeHtml(input) {
|
|
8817
8837
|
return input.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
8818
8838
|
}
|
|
@@ -9864,7 +9884,7 @@ function __stxOverlay(errs){
|
|
|
9864
9884
|
}
|
|
9865
9885
|
}
|
|
9866
9886
|
}
|
|
9867
|
-
const isAssetRequest =
|
|
9887
|
+
const isAssetRequest = publicFileExists(`/${normalizedPath}`, publicDir);
|
|
9868
9888
|
const dynamicFiles = files.filter((f) => {
|
|
9869
9889
|
const nf = f.replace(/^\.\//, "").replace(/\\/g, "/");
|
|
9870
9890
|
if (!nf.includes("["))
|
|
@@ -10840,6 +10860,7 @@ export {
|
|
|
10840
10860
|
routeSpecificity,
|
|
10841
10861
|
resolveServeOpenUrl,
|
|
10842
10862
|
render404Page,
|
|
10863
|
+
publicFileExists,
|
|
10843
10864
|
isStaticAssetPath,
|
|
10844
10865
|
isRenderableCacheCandidate,
|
|
10845
10866
|
isRenderFailure,
|
package/package.json
CHANGED