mirror of
https://github.com/Nystik-gh/ignis.git
synced 2026-06-17 04:35:53 +00:00
implement demo mode
This commit is contained in:
149
server/demo/demo-provision.js
Normal file
149
server/demo/demo-provision.js
Normal file
@@ -0,0 +1,149 @@
|
||||
// Vault provisioning for demo sessions.
|
||||
//
|
||||
// Copies the template into a session-prefixed dir, installs the bridge plugin, and registers the vault on the session.
|
||||
// Re-provisions if disk was wiped under an existing session.
|
||||
|
||||
const fs = require("fs");
|
||||
const fsp = fs.promises;
|
||||
const path = require("path");
|
||||
|
||||
const config = require("../config");
|
||||
const { installBridgePlugin } = require("../bridge-plugin");
|
||||
const bootstrapRoutes = require("../routes/bootstrap");
|
||||
|
||||
const { sessions, makeStorageName } = require("./demo-sessions");
|
||||
|
||||
const DEFAULT_VAULT_NAME = "Welcome";
|
||||
|
||||
async function dirSize(dir) {
|
||||
let total = 0;
|
||||
|
||||
async function walk(d) {
|
||||
let entries;
|
||||
|
||||
try {
|
||||
entries = await fsp.readdir(d, { withFileTypes: true });
|
||||
} catch {
|
||||
return;
|
||||
}
|
||||
|
||||
for (const e of entries) {
|
||||
const full = path.join(d, e.name);
|
||||
|
||||
if (e.isDirectory()) {
|
||||
await walk(full);
|
||||
} else {
|
||||
try {
|
||||
const st = await fsp.stat(full);
|
||||
total += st.size;
|
||||
} catch {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
await walk(dir);
|
||||
return total;
|
||||
}
|
||||
|
||||
async function recomputeBytes(sessionId) {
|
||||
const s = sessions.get(sessionId);
|
||||
|
||||
if (!s) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
let total = 0;
|
||||
|
||||
for (const userVaultName of s.vaults) {
|
||||
const storageName = makeStorageName(sessionId, userVaultName);
|
||||
const vaultPath = config.getVaultPath(storageName);
|
||||
|
||||
if (vaultPath) {
|
||||
total += await dirSize(vaultPath);
|
||||
}
|
||||
}
|
||||
|
||||
s.bytesUsed = total;
|
||||
return total;
|
||||
}
|
||||
|
||||
async function provisionVault(sessionId, userVaultName) {
|
||||
const s = sessions.get(sessionId);
|
||||
|
||||
if (!s) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (s.vaults.size >= config.demoVaultsPerSession) {
|
||||
return { error: "vaults-per-session-limit" };
|
||||
}
|
||||
|
||||
const storageName = makeStorageName(sessionId, userVaultName);
|
||||
const vaultPath = path.join(config.vaultRoot, storageName);
|
||||
|
||||
await fsp.mkdir(config.vaultRoot, { recursive: true });
|
||||
|
||||
try {
|
||||
await fsp.mkdir(vaultPath, { recursive: false });
|
||||
} catch (e) {
|
||||
if (e.code === "EEXIST") {
|
||||
return { error: "vault-exists" };
|
||||
}
|
||||
|
||||
throw e;
|
||||
}
|
||||
|
||||
// Copy template (default: Welcome.md, Getting Started.md, .obsidian/*).
|
||||
await fsp.cp(config.demoTemplateDir, vaultPath, { recursive: true });
|
||||
|
||||
// Install bridge plugin
|
||||
await installBridgePlugin(vaultPath);
|
||||
|
||||
config.refreshVaults();
|
||||
bootstrapRoutes.invalidateVault(storageName);
|
||||
|
||||
s.vaults.add(userVaultName);
|
||||
await recomputeBytes(sessionId);
|
||||
|
||||
return { storageName, userVaultName };
|
||||
}
|
||||
|
||||
async function ensureDefaultVault(sessionId) {
|
||||
const s = sessions.get(sessionId);
|
||||
|
||||
if (!s) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const storageName = makeStorageName(sessionId, DEFAULT_VAULT_NAME);
|
||||
const vaultPath = config.getVaultPath(storageName);
|
||||
const onDisk = vaultPath && fs.existsSync(vaultPath);
|
||||
|
||||
if (s.vaults.has(DEFAULT_VAULT_NAME) && onDisk) {
|
||||
return DEFAULT_VAULT_NAME;
|
||||
}
|
||||
|
||||
if (onDisk) {
|
||||
// Disk has it but session forgot (cookie outlived in-memory session).
|
||||
s.vaults.add(DEFAULT_VAULT_NAME);
|
||||
return DEFAULT_VAULT_NAME;
|
||||
}
|
||||
|
||||
// Disk wiped under us; clear stale Set entry before re-provisioning.
|
||||
s.vaults.delete(DEFAULT_VAULT_NAME);
|
||||
|
||||
const result = await provisionVault(sessionId, DEFAULT_VAULT_NAME);
|
||||
|
||||
if (result && result.userVaultName) {
|
||||
return result.userVaultName;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
DEFAULT_VAULT_NAME,
|
||||
provisionVault,
|
||||
ensureDefaultVault,
|
||||
recomputeBytes,
|
||||
};
|
||||
Reference in New Issue
Block a user