120 lines
4.1 KiB
JavaScript
120 lines
4.1 KiB
JavaScript
import fs from 'node:fs';
|
|
import path from 'node:path';
|
|
|
|
export const MEMIND_RUNTIME_PROFILES = new Set(['local', 'split-service', 'production']);
|
|
|
|
/**
|
|
* Load Memind env files in standard order. Later files only fill unset keys.
|
|
*/
|
|
export function loadMemindEnvFiles(rootDir, env = process.env) {
|
|
const root = path.resolve(rootDir);
|
|
for (const relativePath of ['../../.env.local', '.env']) {
|
|
loadEnvFile(path.join(root, relativePath), env);
|
|
}
|
|
}
|
|
|
|
function loadEnvFile(filePath, env = process.env) {
|
|
if (!fs.existsSync(filePath)) return;
|
|
for (const line of fs.readFileSync(filePath, 'utf8').split('\n')) {
|
|
const trimmed = line.trim();
|
|
if (!trimmed || trimmed.startsWith('#')) continue;
|
|
const separator = trimmed.indexOf('=');
|
|
if (separator < 0) continue;
|
|
const key = trimmed.slice(0, separator).trim();
|
|
const value = trimmed.slice(separator + 1).trim();
|
|
if (!env[key]) env[key] = value;
|
|
}
|
|
}
|
|
|
|
function expandEnvReference(value, env = process.env) {
|
|
const raw = String(value ?? '').trim();
|
|
const match = raw.match(/^\$\{([A-Z0-9_]+)\}$/);
|
|
if (!match) return raw;
|
|
return String(env[match[1]] ?? '').trim() || raw;
|
|
}
|
|
|
|
export function resolveMemindRuntimeProfile(env = process.env) {
|
|
const explicit = String(env.MEMIND_RUNTIME_PROFILE ?? '').trim().toLowerCase();
|
|
if (explicit) {
|
|
if (!MEMIND_RUNTIME_PROFILES.has(explicit)) {
|
|
throw new Error(
|
|
`Unsupported MEMIND_RUNTIME_PROFILE "${explicit}". Expected: ${[...MEMIND_RUNTIME_PROFILES].join(', ')}`,
|
|
);
|
|
}
|
|
return explicit;
|
|
}
|
|
if (String(env.NODE_ENV ?? '').trim().toLowerCase() === 'production') {
|
|
return 'production';
|
|
}
|
|
return 'local';
|
|
}
|
|
|
|
/**
|
|
* Apply environment-specific defaults after .env files are loaded.
|
|
*
|
|
* - local: monolith MindSpace adapter, repo-local storage (pnpm dev default)
|
|
* - split-service: remote adapter against standalone MindSpace on 8082
|
|
* - production: no overrides; 103 .env is source of truth
|
|
*/
|
|
export function applyMemindRuntimeProfile({
|
|
rootDir = process.cwd(),
|
|
env = process.env,
|
|
profile,
|
|
} = {}) {
|
|
const resolvedProfile = profile ?? resolveMemindRuntimeProfile(env);
|
|
env.MEMIND_RUNTIME_PROFILE = resolvedProfile;
|
|
|
|
if (resolvedProfile === 'local') {
|
|
env.MINDSPACE_SERVER_ADAPTER = 'local';
|
|
if (!env.MINDSPACE_STORAGE_ROOT) {
|
|
env.MINDSPACE_STORAGE_ROOT = path.join(path.resolve(rootDir), 'data', 'mindspace');
|
|
}
|
|
return {
|
|
profile: resolvedProfile,
|
|
mindspaceAdapter: 'local',
|
|
storageRoot: env.MINDSPACE_STORAGE_ROOT,
|
|
};
|
|
}
|
|
|
|
if (resolvedProfile === 'split-service') {
|
|
env.MINDSPACE_SERVER_ADAPTER = 'remote';
|
|
env.MINDSPACE_REMOTE_BASE_URL = String(
|
|
env.MINDSPACE_REMOTE_BASE_URL ?? 'http://127.0.0.1:8082',
|
|
).trim();
|
|
const expandedToken = expandEnvReference(env.MINDSPACE_REMOTE_AUTH_TOKEN, env);
|
|
if (expandedToken) {
|
|
env.MINDSPACE_REMOTE_AUTH_TOKEN = expandedToken;
|
|
} else if (env.TKMIND_SERVER__SECRET_KEY) {
|
|
env.MINDSPACE_REMOTE_AUTH_TOKEN = String(env.TKMIND_SERVER__SECRET_KEY).trim();
|
|
}
|
|
if (!env.MINDSPACE_STORAGE_ROOT) {
|
|
env.MINDSPACE_STORAGE_ROOT = '/Users/john/MindSpace/data/mindspace';
|
|
}
|
|
return {
|
|
profile: resolvedProfile,
|
|
mindspaceAdapter: 'remote',
|
|
remoteBaseUrl: env.MINDSPACE_REMOTE_BASE_URL,
|
|
storageRoot: env.MINDSPACE_STORAGE_ROOT,
|
|
};
|
|
}
|
|
|
|
return {
|
|
profile: resolvedProfile,
|
|
mindspaceAdapter: String(env.MINDSPACE_SERVER_ADAPTER ?? 'local').trim().toLowerCase() || 'local',
|
|
storageRoot: env.MINDSPACE_STORAGE_ROOT ?? null,
|
|
};
|
|
}
|
|
|
|
export function describeMemindRuntimeProfile(env = process.env) {
|
|
const profile = resolveMemindRuntimeProfile(env);
|
|
const adapter = String(env.MINDSPACE_SERVER_ADAPTER ?? 'local').trim().toLowerCase() || 'local';
|
|
const parts = [`MEMIND_RUNTIME_PROFILE=${profile}`, `MINDSPACE_SERVER_ADAPTER=${adapter}`];
|
|
if (adapter === 'remote') {
|
|
parts.push(`MINDSPACE_REMOTE_BASE_URL=${env.MINDSPACE_REMOTE_BASE_URL ?? '(unset)'}`);
|
|
}
|
|
if (env.MINDSPACE_STORAGE_ROOT) {
|
|
parts.push(`MINDSPACE_STORAGE_ROOT=${env.MINDSPACE_STORAGE_ROOT}`);
|
|
}
|
|
return parts.join(', ');
|
|
}
|