initial commit
This commit is contained in:
26
lib/paths.ts
Normal file
26
lib/paths.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
import path from "node:path";
|
||||
import { HttpError } from "./errors";
|
||||
|
||||
/** The portfolio checkout. In Docker it is bind-mounted at /repo; for local
|
||||
* `npm run dev` it defaults to the sibling ../portfolio folder. */
|
||||
export const REPO_DIR = path.resolve(/*turbopackIgnore: true*/
|
||||
process.env.REPO_DIR ?? path.join(/*turbopackIgnore: true*/ process.cwd(), "..", "portfolio")
|
||||
);
|
||||
|
||||
/** Repo-relative paths the manager owns. Publishing commits only these. */
|
||||
export const POSTS_REL = "data/blog-posts.json";
|
||||
export const IMG_REL = "public/img/blog";
|
||||
|
||||
export const POSTS_FILE = path.join(REPO_DIR, POSTS_REL);
|
||||
export const PUBLIC_DIR = path.join(REPO_DIR, "public");
|
||||
export const IMG_ROOT = path.join(REPO_DIR, IMG_REL);
|
||||
|
||||
/** path.resolve(root, ...segments), refusing anything that escapes root. */
|
||||
export function safeJoin(root: string, ...segments: string[]): string {
|
||||
const resolved = path.resolve(/*turbopackIgnore: true*/ root, ...segments);
|
||||
const rel = path.relative(root, resolved);
|
||||
if (rel.startsWith("..") || path.isAbsolute(rel)) {
|
||||
throw new HttpError(400, "path escapes its root");
|
||||
}
|
||||
return resolved;
|
||||
}
|
||||
Reference in New Issue
Block a user