f851d8b8f2
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
70 lines
1.8 KiB
TypeScript
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);
|
|
}
|