Files
layonara-forge/packages/backend/src/services/workspace.service.ts
T
plenarius f851d8b8f2 Layonara Forge — NWN Development IDE
Electron desktop application for Neverwinter Nights module development.
Clone, edit, build, and run a complete Layonara NWNX server with only
Docker required.

- React 19 + Vite frontend with Monaco editor and NWScript LSP
- Node.js + Express backend managing Docker sibling containers
- Electron shell with Docker availability check and auto-setup
- Builder image auto-builds on first use from bundled Dockerfile
- Cross-platform: Windows (.exe), macOS (.dmg), Linux (.AppImage)
- Gitea Actions CI for automated release builds
2026-04-21 12:14:38 -04:00

70 lines
1.8 KiB
TypeScript

import fs from "fs/promises";
import path from "path";
import { homedir } from "os";
const WORKSPACE_PATH = process.env.WORKSPACE_PATH || path.join(homedir(), "Layonara Forge");
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.mkdir(path.dirname(configPath), { recursive: true });
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);
}