Files
2026-08-20 22:41:25 +02:00

49 lines
1.8 KiB
JavaScript

/**
* Load the workspace .env into process.env.
*
* The API gets this from node's own --env-file-if-exists, but astro is launched by its
* own binary, so the web side needs it done in-process. astro.config.mjs imports this
* first, before it reads anything off process.env, and the build-time consumers
* (web/src/lib/api.ts, web/src/lib/nostr-build.ts) run in the same process afterwards.
*
* Matching node's semantics: a variable already present in the real environment is left
* alone, so `PORT=9000 pnpm dev` and systemd Environment= still win over the file.
*/
import { readFileSync } from 'node:fs';
import path from 'node:path';
import { fileURLToPath } from 'node:url';
const webRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
/** Repo root first, then a web-local override if someone wants one. */
const files = [path.join(webRoot, '..', '.env'), path.join(webRoot, '.env')];
const LINE = /^\s*(?:export\s+)?([A-Za-z_][A-Za-z0-9_]*)\s*=\s*(.*?)\s*$/;
function unquote(value) {
const quote = value[0];
if ((quote === '"' || quote === "'") && value.at(-1) === quote && value.length > 1) {
const inner = value.slice(1, -1);
return quote === '"' ? inner.replace(/\\n/g, '\n').replace(/\\"/g, '"') : inner;
}
// Unquoted: an inline comment ends the value.
return value.split(/\s+#/)[0].trim();
}
for (const file of files) {
let text;
try {
text = readFileSync(file, 'utf8');
} catch {
continue; // No .env is a supported setup — every variable has a default.
}
for (const line of text.split('\n')) {
if (!line.trim() || line.trim().startsWith('#')) continue;
const match = LINE.exec(line);
if (!match) continue;
const [, name, raw] = match;
if (name in process.env) continue;
process.env[name] = unquote(raw);
}
}