Skip to content

Commit 32b7c79

Browse files
feat: add env var helpers (#580)
Co-authored-by: WillBooster (Codex CLI) <agent@willbooster.com>
1 parent 75e1d95 commit 32b7c79

File tree

3 files changed

+30
-8
lines changed

3 files changed

+30
-8
lines changed

packages/shared-lib-node/src/env.ts

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -46,12 +46,12 @@ export type EnvReaderOptions = Partial<ArgumentsCamelCase<InferredOptionTypes<ty
4646
/**
4747
* This function reads environment variables from `.env` files.
4848
* Note it does not assign them in `process.env`.
49-
* @return [envVars, [envPaths, envVarCount][]]
49+
* @return [envVars, [envPaths, envVarNames][]]
5050
* */
5151
export function readEnvironmentVariables(
5252
argv: EnvReaderOptions,
5353
cwd: string
54-
): [Record<string, string>, [string, number][]] {
54+
): [Record<string, string>, [string, string[]][]] {
5555
let envPaths = (argv.env ?? []).map((envPath) => path.resolve(cwd, envPath.toString()));
5656
const cascade =
5757
argv.cascadeEnv ??
@@ -82,21 +82,26 @@ export function readEnvironmentVariables(
8282
console.info('Reading env files:', envPaths.join(', '));
8383
}
8484

85-
const envPathAndEnvVarCountPairs: [string, number][] = [];
85+
const envPathAndEnvVarCountPairs: [string, string[]][] = [];
8686
const envVars: Record<string, string> = {};
8787
for (const envPath of envPaths) {
88-
let count = 0;
88+
const keys: string[] = [];
8989
for (const [key, value] of Object.entries(readEnvFile(path.join(cwd, envPath)))) {
9090
if (!(key in envVars)) {
9191
envVars[key] = value;
92-
count++;
92+
keys.push(key);
9393
}
9494
}
95-
envPathAndEnvVarCountPairs.push([envPath, count]);
96-
if (argv.verbose && count > 0) {
97-
console.info(`Read ${count} environment variables from ${envPath}`);
95+
envPathAndEnvVarCountPairs.push([envPath, keys]);
96+
if (argv.verbose && keys.length > 0) {
97+
console.info(`Read ${keys.length} environment variables from ${envPath}`);
9898
}
9999
}
100+
if (!argv.verbose) {
101+
console.info(
102+
`Read: ${envPathAndEnvVarCountPairs.map(([envPath, keys]) => `${envPath} (${keys.join(', ')})`).join(', ')}`
103+
);
104+
}
100105

101106
if (argv.checkEnv) {
102107
const exampleKeys = Object.keys(readEnvFile(path.join(cwd, argv.checkEnv)));

packages/shared-lib/src/env.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
type EnvSource = Record<string, string | undefined>;
2+
3+
const metaEnv: EnvSource | undefined = 'env' in import.meta ? (import.meta as { env?: EnvSource }).env : undefined;
4+
const processEnv: EnvSource | undefined = (globalThis as { process?: { env?: EnvSource } }).process?.env;
5+
6+
export function getEnvValue(key: string): string | undefined {
7+
return metaEnv?.[key] ?? processEnv?.[key];
8+
}
9+
10+
export function getRequiredEnvValue(key: string): string {
11+
const value = getEnvValue(key);
12+
if (!value) {
13+
throw new Error(`${key} environment variable is required.`);
14+
}
15+
return value;
16+
}

packages/shared-lib/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
export { errorify, ignoreError, ignoreEnoent, ignoreErrorAsync, ignoreEnoentAsync, withRetry } from './error.js';
2+
export { getEnvValue, getRequiredEnvValue } from './env.js';
23
export { humanizeNumber } from './humanize.js';
34
export { mailTemplates } from './mail.js';
45
export { parseCommandLineArgs } from './parseCommandLineArgs.js';

0 commit comments

Comments
 (0)