**Motivations:** - Seed AnythingLLM workspace from cloned repo using gitignore-style filters **Root causes:** - N/A **Correctifs:** - N/A **Evolutions:** - Template 4nkaiignore.default; server copies after clone; extension uploads via POST /api/v1/document/upload - New commands /workspace-sync; settings initialSync*; dependency ignore **Pages affectées:** - extensions/anythingllm-workspaces/* - services/repos-devtools-server/* - docs/features/initial-rag-sync-4nkaiignore.md
47 lines
1.4 KiB
TypeScript
47 lines
1.4 KiB
TypeScript
import * as fs from "node:fs/promises";
|
|
import * as path from "node:path";
|
|
|
|
const SAFE_NAME = /^[a-zA-Z0-9][a-zA-Z0-9._-]{0,254}$/;
|
|
|
|
export const assertSafeRepoName = (name: string): string => {
|
|
const trimmed = name.trim();
|
|
if (!SAFE_NAME.test(trimmed)) {
|
|
throw new Error("Invalid repo name: use letters, digits, . _ - only; no path segments.");
|
|
}
|
|
if (trimmed.includes("..")) {
|
|
throw new Error("Invalid repo name: path traversal rejected.");
|
|
}
|
|
return trimmed;
|
|
};
|
|
|
|
export const getCodeRoot = (): string => {
|
|
const raw = process.env.REPOS_DEVTOOLS_ROOT ?? "/home/ncantu/code";
|
|
return path.resolve(raw);
|
|
};
|
|
|
|
export const repoDirForName = (codeRoot: string, name: string): string => {
|
|
const safe = assertSafeRepoName(name);
|
|
return path.join(codeRoot, safe);
|
|
};
|
|
|
|
export const isGitRepo = async (dir: string): Promise<boolean> => {
|
|
try {
|
|
const stat = await fs.stat(path.join(dir, ".git"));
|
|
return stat.isDirectory() || stat.isFile();
|
|
} catch {
|
|
return false;
|
|
}
|
|
};
|
|
|
|
export const repoNameFromGitUrl = (rawUrl: string): string => {
|
|
const trimmed = rawUrl.trim();
|
|
const noQuery = trimmed.split("?")[0] ?? trimmed;
|
|
const base = noQuery.replace(/[/]+$/, "");
|
|
const segment = base.split("/").filter((s) => s.length > 0).pop() ?? "";
|
|
const withoutGit = segment.replace(/\.git$/i, "");
|
|
if (withoutGit.length === 0) {
|
|
throw new Error("Could not derive repository name from URL.");
|
|
}
|
|
return assertSafeRepoName(withoutGit);
|
|
};
|