Skip to content

Commit a8570e9

Browse files
committed
fix: load local .env before evaluating config so env refs resolve
process.env.DB_PASSWORD and similar refs in shipnode.config.ts were undefined unless the var was exported in the shell. Now loadConfig reads the local .env file first, so credentials stay out of the config file without breaking setup or deploy.
1 parent 7d2e691 commit a8570e9

1 file changed

Lines changed: 24 additions & 0 deletions

File tree

src/config/loader.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,36 @@
11
import { resolve } from 'path';
2+
import { readFile } from 'node:fs/promises';
23
import { pathExists } from 'fs-extra';
34
import { createJiti } from 'jiti';
45
import type { ShipnodeConfig } from '../shared/types.js';
56
import { assembleConfig } from './assembly.js';
67
import { ConfigError } from '../shared/errors.js';
78
import type { ShipnodeBuilder } from './builder.js';
89

10+
async function loadEnvIntoProcess(cwd: string): Promise<void> {
11+
const envFile = resolve(cwd, '.env');
12+
let raw: string;
13+
try {
14+
raw = await readFile(envFile, 'utf-8');
15+
} catch {
16+
return;
17+
}
18+
for (const line of raw.split('\n')) {
19+
const trimmed = line.trim();
20+
if (!trimmed || trimmed.startsWith('#')) continue;
21+
const eq = trimmed.indexOf('=');
22+
if (eq === -1) continue;
23+
const key = trimmed.slice(0, eq).trim();
24+
let val = trimmed.slice(eq + 1).trim();
25+
if ((val.startsWith('"') && val.endsWith('"')) || (val.startsWith("'") && val.endsWith("'"))) {
26+
val = val.slice(1, -1);
27+
}
28+
if (!(key in process.env)) process.env[key] = val;
29+
}
30+
}
31+
932
export async function loadConfig(cwd: string, configPath?: string): Promise<ShipnodeConfig> {
33+
await loadEnvIntoProcess(cwd);
1034
const file = configPath ?? resolve(cwd, 'shipnode.config.ts');
1135

1236
const exists = await pathExists(file);

0 commit comments

Comments
 (0)