feat: add workspace service and route for directory management
This commit is contained in:
@@ -4,6 +4,7 @@ import { createServer } from "http";
|
|||||||
import path from "path";
|
import path from "path";
|
||||||
import { fileURLToPath } from "url";
|
import { fileURLToPath } from "url";
|
||||||
import { initWebSocket, getClientCount } from "./services/ws.service.js";
|
import { initWebSocket, getClientCount } from "./services/ws.service.js";
|
||||||
|
import workspaceRouter from "./routes/workspace.js";
|
||||||
|
|
||||||
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||||
const app = express();
|
const app = express();
|
||||||
@@ -22,6 +23,8 @@ app.get("/api/health", (_req, res) => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
app.use("/api/workspace", workspaceRouter);
|
||||||
|
|
||||||
const frontendDist = path.resolve(__dirname, "../../frontend/dist");
|
const frontendDist = path.resolve(__dirname, "../../frontend/dist");
|
||||||
app.use(express.static(frontendDist));
|
app.use(express.static(frontendDist));
|
||||||
app.get("*path", (_req, res) => {
|
app.get("*path", (_req, res) => {
|
||||||
|
|||||||
@@ -0,0 +1,29 @@
|
|||||||
|
import { Router } from "express";
|
||||||
|
import {
|
||||||
|
ensureWorkspaceStructure,
|
||||||
|
readConfig,
|
||||||
|
writeConfig,
|
||||||
|
getWorkspacePath,
|
||||||
|
} from "../services/workspace.service.js";
|
||||||
|
|
||||||
|
const router = Router();
|
||||||
|
|
||||||
|
router.get("/config", async (_req, res) => {
|
||||||
|
const config = await readConfig();
|
||||||
|
const sanitized = { ...config, githubPat: config.githubPat ? "***" : undefined };
|
||||||
|
res.json(sanitized);
|
||||||
|
});
|
||||||
|
|
||||||
|
router.put("/config", async (req, res) => {
|
||||||
|
const current = await readConfig();
|
||||||
|
const updated = { ...current, ...req.body };
|
||||||
|
await writeConfig(updated);
|
||||||
|
res.json({ ok: true });
|
||||||
|
});
|
||||||
|
|
||||||
|
router.post("/init", async (_req, res) => {
|
||||||
|
await ensureWorkspaceStructure();
|
||||||
|
res.json({ ok: true, path: getWorkspacePath() });
|
||||||
|
});
|
||||||
|
|
||||||
|
export default router;
|
||||||
@@ -0,0 +1,67 @@
|
|||||||
|
import fs from "fs/promises";
|
||||||
|
import path from "path";
|
||||||
|
|
||||||
|
const WORKSPACE_PATH = process.env.WORKSPACE_PATH || "/workspace";
|
||||||
|
|
||||||
|
interface ForgeConfig {
|
||||||
|
githubPat?: string;
|
||||||
|
workspacePath: string;
|
||||||
|
nwnHomePath: string;
|
||||||
|
setupComplete: boolean;
|
||||||
|
editorState?: {
|
||||||
|
openTabs: string[];
|
||||||
|
activeTab?: string;
|
||||||
|
cursorPositions: Record<string, { line: number; column: number }>;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const REQUIRED_DIRS = [
|
||||||
|
"repos",
|
||||||
|
"server/modules",
|
||||||
|
"server/hak",
|
||||||
|
"server/tlk",
|
||||||
|
"server/servervault",
|
||||||
|
"server/database",
|
||||||
|
"server/development",
|
||||||
|
"server/override",
|
||||||
|
"server/portraits",
|
||||||
|
"logs",
|
||||||
|
"config",
|
||||||
|
];
|
||||||
|
|
||||||
|
export async function ensureWorkspaceStructure(): Promise<void> {
|
||||||
|
for (const dir of REQUIRED_DIRS) {
|
||||||
|
await fs.mkdir(path.join(WORKSPACE_PATH, dir), { recursive: true });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function readConfig(): Promise<ForgeConfig> {
|
||||||
|
const configPath = path.join(WORKSPACE_PATH, "config", "forge.json");
|
||||||
|
try {
|
||||||
|
const raw = await fs.readFile(configPath, "utf-8");
|
||||||
|
return JSON.parse(raw);
|
||||||
|
} catch {
|
||||||
|
return {
|
||||||
|
workspacePath: WORKSPACE_PATH,
|
||||||
|
nwnHomePath: process.env.NWN_HOME_PATH || "",
|
||||||
|
setupComplete: false,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function writeConfig(config: ForgeConfig): Promise<void> {
|
||||||
|
const configPath = path.join(WORKSPACE_PATH, "config", "forge.json");
|
||||||
|
await fs.writeFile(configPath, JSON.stringify(config, null, 2));
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getWorkspacePath(): string {
|
||||||
|
return WORKSPACE_PATH;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getServerPath(...segments: string[]): string {
|
||||||
|
return path.join(WORKSPACE_PATH, "server", ...segments);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getRepoPath(repo: string, ...segments: string[]): string {
|
||||||
|
return path.join(WORKSPACE_PATH, "repos", repo, ...segments);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user