30 lines
878 B
TypeScript
30 lines
878 B
TypeScript
import os from "node:os";
|
|
import path from "node:path";
|
|
import { z } from "zod";
|
|
|
|
export const projectNameSchema = z
|
|
.string()
|
|
.trim()
|
|
.min(1, "Enter a project name.")
|
|
.max(64, "Project names must be 64 characters or fewer.")
|
|
.regex(
|
|
/^[a-zA-Z0-9][a-zA-Z0-9 _-]*$/,
|
|
"Use letters, numbers, spaces, hyphens, or underscores.",
|
|
)
|
|
.refine((name) => !name.includes(".."), "Project names cannot contain '..'.");
|
|
|
|
export function getProjectsRoot() {
|
|
return path.resolve(process.env.PROJECTS_ROOT || path.join(os.homedir(), "projects"));
|
|
}
|
|
|
|
export function getProjectPath(name: string) {
|
|
const root = getProjectsRoot();
|
|
const projectPath = path.resolve(root, name);
|
|
|
|
if (projectPath === root || !projectPath.startsWith(`${root}${path.sep}`)) {
|
|
throw new Error("The project path must remain inside the projects directory.");
|
|
}
|
|
|
|
return projectPath;
|
|
}
|