Files
blog-manager/lib/paths.ts
2026-11-01 13:23:44 -05:00

27 lines
1.1 KiB
TypeScript

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;
}