Files
ermnvldmr.com/packages/cli/src/lib/env.ts
T

85 lines
2.2 KiB
TypeScript

import { existsSync } from 'node:fs';
import { dirname, join } from 'node:path';
import { config } from '@dotenvx/dotenvx';
let loaded = false;
/**
* Walks up the directory tree from `start` until it finds a directory
* containing `pnpm-workspace.yaml` (the monorepo root), or reaches the
* filesystem root.
*
* @param start - Directory to begin the search from.
* @returns The path of the monorepo root directory, or `start` as a fallback.
*
* @example
* ```typescript
* const root = findRoot(process.cwd());
* ```
*
* @internal
*/
function findRoot(start: string): string {
let dir = start;
for (;;) {
if (existsSync(join(dir, 'pnpm-workspace.yaml'))) {
return dir;
}
const parent = dirname(dir);
if (parent === dir) {
// Reached the filesystem root without finding the marker.
return start;
}
dir = parent;
}
}
/**
* Ensures dotenvx has loaded `.env.dev` from the monorepo root into `process.env`.
* Walks up from the current working directory to find the root, then loads the
* `.env.dev` file located there. Safe to call multiple times — runs only once per
* process.
*
* @example
* ```typescript
* ensureLoaded();
* ```
*
* @internal
*/
function ensureLoaded(): void {
if (!loaded) {
config({ path: join(findRoot(process.cwd()), '.env.dev') });
loaded = true;
}
}
/**
* Reads an environment variable by key, loading `.env.dev` files via dotenvx on
* the first call. Optionally returns a fallback value when the variable is
* not set.
*
* Designed for use inside `cli.ts` config files so that env values are
* resolved **at command execution time** (after dotenvx has populated
* `process.env`), not at config-parse time.
*
* @param key - The name of the environment variable to read.
* @param fallback - Optional fallback value returned when the variable is absent.
* @returns The environment variable value, the fallback, or `undefined`.
*
* @example
* ```typescript
* import { env } from '@ermnvldmr/cli';
*
* s3SyncCommand({
* bucket: env('MY_BUCKET'),
* region: env('AWS_REGION', 'us-east-1'),
* });
* ```
*/
export function env(key: string, fallback?: string): string | undefined {
ensureLoaded();
return process.env[key] ?? fallback;
}