Skip to content

Commit 783462e

Browse files
committed
Consolidated where the default .env path is referenced. Fixed up some issues with the shouldLog value being used for the hook version of the plugin, and updated the tests accordingly. Suppressed a few ts-jest warnings that are only applicable to tests and don't affect how the production-level plugin actually works, which were polluting the console on subsequent test runs
1 parent 176b026 commit 783462e

13 files changed

Lines changed: 86 additions & 60 deletions

jest.config.cts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,16 @@ const config: Config = {
66
roots: ['<rootDir>'],
77
testMatch: ['**/__tests__/**/*.ts', '**/?(*.)+(spec|test).ts'],
88
transform: {
9-
'^.+\\.ts$': ['ts-jest', { diagnostics: false, useESM: true }],
9+
'^.+\\.ts$': [
10+
'ts-jest',
11+
{
12+
diagnostics: {
13+
ignoreCodes: [151002, 1192, 1259],
14+
warnOnly: true,
15+
},
16+
useESM: true,
17+
},
18+
],
1019
},
1120
collectCoverageFrom: ['src/**/*.ts', '!src/**/*.d.ts'],
1221
coverageDirectory: 'coverage',

package-lock.json

Lines changed: 9 additions & 9 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@
4848
"@types/fs-extra": "11.0.4",
4949
"@types/jest": "30.0.0",
5050
"@types/node": "25.3.3",
51-
"eslint": "10.0.2",
51+
"eslint": "10.0.3",
5252
"globals": "15.14.0",
5353
"husky": "9.1.7",
5454
"jest": "30.2.0",

src/commands/dotenv.ts

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { SfCommand, Flags } from '@salesforce/sf-plugins-core';
2-
import { displayLoadedEnvVars, getEnv, PLUGIN_NAME } from '../shared/index.js';
2+
import { DEFAULT_ENV_PATH, displayLoadedEnvVars, getEnv, PLUGIN_NAME } from '../shared/index.js';
33

44
export default class DotEnv extends SfCommand<void> {
55
public static readonly summary =
@@ -13,8 +13,8 @@ export default class DotEnv extends SfCommand<void> {
1313
env: Flags.string({
1414
char: 'e',
1515
summary: 'Path to the .env file to load.',
16-
default: '.env',
17-
defaultHelp: '.env',
16+
default: DEFAULT_ENV_PATH,
17+
defaultHelp: DEFAULT_ENV_PATH,
1818
}),
1919
'show-values': Flags.boolean({
2020
summary: 'Print the loaded environment variable names and values.',
@@ -24,14 +24,11 @@ export default class DotEnv extends SfCommand<void> {
2424

2525
public async run(): Promise<void> {
2626
const { flags } = await this.parse(DotEnv);
27-
const envFilePath = flags.env ?? '.env';
27+
const envFilePath = flags.env ?? DEFAULT_ENV_PATH;
2828
const envConfig = await getEnv(this.argv, true, envFilePath);
2929

3030
if (!this.jsonEnabled()) {
31-
const options = flags['show-values']
32-
? { showValues: true as const }
33-
: { showValues: false as const };
34-
displayLoadedEnvVars(envConfig, options);
31+
displayLoadedEnvVars(envConfig, { showValues: flags['show-values'] });
3532
}
3633
}
3734
}

src/hooks/prerun.ts

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ function displayLoadingMessage(
4141
if (!shouldLog || argv.includes('--json')) {
4242
return;
4343
}
44-
displayLoadedEnvVars(envConfig);
44+
displayLoadedEnvVars(envConfig, { showValues: shouldLog });
4545
}
4646

4747
/**
@@ -60,10 +60,12 @@ function handleLoadError(error: unknown): void {
6060
*/
6161
const hook: Hook.Prerun = async function ({ Command, argv }) {
6262
const configAggregator = await ConfigAggregator.create({ customConfigMeta });
63-
const configValue = configAggregator.getPropertyValue(CONFIG_SHOULD_LOG_KEY);
64-
if (configValue !== undefined) {
65-
shouldLog = Boolean(configValue);
66-
}
63+
const possibleConfigLoggingValue = configAggregator.getPropertyValue(CONFIG_SHOULD_LOG_KEY) as
64+
| undefined
65+
| 'true'
66+
| 'false';
67+
68+
shouldLog = Boolean(possibleConfigLoggingValue === 'true' ? 1 : 0);
6769

6870
if (shouldSkipHook(argv, Command.pluginName) || isDotEnvDisabled()) {
6971
return;

src/shared/constants.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
1+
export const DEFAULT_ENV_PATH = '.env';
12
export const CONFIG_SHOULD_LOG_KEY = 'should-log-env';
23
export const PLUGIN_NAME = 'sf-dotenv';

src/shared/environment.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,16 @@ import dotenv from 'dotenv';
44
import fs from 'fs-extra';
55
import path from 'path';
66

7+
import { DEFAULT_ENV_PATH } from '../shared/index.js';
8+
79
function determineEnvFilePath(argv: string[], explicitPath?: string) {
810
if (explicitPath !== undefined) {
911
return { envFilePath: path.resolve(explicitPath), envFileIndex: -1 };
1012
}
1113

1214
// Check for --env or -e parameter in command arguments
1315
const envFileIndex = argv.findIndex((arg: string) => arg === '--env' || arg === '-e');
14-
let envFilePath = '.env';
16+
let envFilePath = DEFAULT_ENV_PATH;
1517

1618
if (envFileIndex !== -1 && envFileIndex + 1 < argv.length) {
1719
envFilePath = argv[envFileIndex + 1];

src/shared/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@ import configMeta from './configMeta.js';
22

33
export { configMeta };
44
export { getEnv, type EnvConfig } from './environment.js';
5-
export { displayLoadedEnvVars } from './loadingMessage.js';
5+
export { displayLoadedEnvVars, SENSITIVE_OUTPUT_WARNING } from './loadingMessage.js';
66
export * from './constants.js';

src/shared/loadingMessage.ts

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@ const DELIMITER = `\n ${CHECK}`;
99
export const SENSITIVE_OUTPUT_WARNING =
1010
'The following output contains sensitive information (environment variable values).';
1111

12-
export type DisplayLoadedEnvVarsOptions = { showValues: true } | { showValues?: false };
12+
interface DisplayLoadedEnvVarsOptions {
13+
showValues: boolean;
14+
}
1315

1416
/**
1517
* Display the "Loading Environment Variables" block.
@@ -18,7 +20,7 @@ export type DisplayLoadedEnvVarsOptions = { showValues: true } | { showValues?:
1820
*/
1921
export function displayLoadedEnvVars(
2022
envConfig: EnvConfig,
21-
options?: DisplayLoadedEnvVarsOptions
23+
options: DisplayLoadedEnvVarsOptions
2224
): void {
2325
const loadedVars = Object.keys(envConfig.env);
2426
const loadedCount = loadedVars.length;
@@ -30,12 +32,11 @@ export function displayLoadedEnvVars(
3032
const environmentVariableLabel = `environment variable${loadedCount === 1 ? '' : 's'}`;
3133
const header = `\n ────────── Loading Environment Variables ─────────\n`;
3234
const loadingLine = `Loading ${loadedCount} ${environmentVariableLabel} from file ${envConfig.envFilePath}:`;
35+
let printedMessage = sorted.join(DELIMITER);
3336

34-
if (options?.showValues === true) {
37+
if (options.showValues) {
3538
ux.warn(SENSITIVE_OUTPUT_WARNING);
36-
const keyValueLines = sorted.map((key) => `${key}=${envConfig.env[key]}`).join(DELIMITER);
37-
ux.stdout(`${header}${loadingLine}${DELIMITER}${keyValueLines}`);
38-
} else {
39-
ux.stdout(`${header}${loadingLine}${DELIMITER}${sorted.join(DELIMITER)}`);
39+
printedMessage = sorted.map((key) => `${key}=${envConfig.env[key]}`).join(DELIMITER);
4040
}
41+
ux.stdout(`${header}${loadingLine}${DELIMITER}${printedMessage}`);
4142
}

test/dotenv.test.ts

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import { jest } from '@jest/globals';
22
import { Config } from '@oclif/core';
33

4+
import { DEFAULT_ENV_PATH } from '../src/shared/index.js';
5+
46
interface GetEnvResult {
57
envFilePath: string;
68
env: Record<string, string>;
@@ -24,7 +26,7 @@ jest.mock('@salesforce/sf-plugins-core', () => ({
2426
logSensitive = jest.fn();
2527
},
2628
Flags: {
27-
string: (opts?: { default?: string }) => opts?.default ?? '.env',
29+
string: (opts?: { default?: string }) => opts?.default ?? DEFAULT_ENV_PATH,
2830
boolean: (opts?: { default?: boolean }) => opts?.default ?? false,
2931
},
3032
}));
@@ -43,7 +45,7 @@ describe('dotenv command', () => {
4345
beforeEach(() => {
4446
jest.clearAllMocks();
4547
mockGetEnv.mockResolvedValue({
46-
envFilePath: '.env',
48+
envFilePath: DEFAULT_ENV_PATH,
4749
env: { FOO: 'bar', BAZ: 'qux' },
4850
});
4951
});
@@ -54,7 +56,7 @@ describe('dotenv command', () => {
5456
): Promise<void> {
5557
const cmd = new DotEnv(argv, mockConfig);
5658
const resolvedFlags = {
57-
env: flags.env ?? '.env',
59+
env: flags.env ?? DEFAULT_ENV_PATH,
5860
'show-values': flags['show-values'] ?? false,
5961
};
6062
const mockParse = jest.fn() as jest.Mock<() => Promise<ParseResult>>;
@@ -69,7 +71,7 @@ describe('dotenv command', () => {
6971
await runCommand(['dotenv']);
7072

7173
expect(mockGetEnv).toHaveBeenCalledTimes(1);
72-
expect(mockGetEnv).toHaveBeenCalledWith(expect.any(Array), true, '.env');
74+
expect(mockGetEnv).toHaveBeenCalledWith(expect.any(Array), true, DEFAULT_ENV_PATH);
7375
});
7476

7577
it('calls getEnv with explicit path when --env is provided', async () => {
@@ -97,7 +99,7 @@ describe('dotenv command', () => {
9799

98100
expect(mockDisplayLoadedEnvVars).toHaveBeenCalledTimes(1);
99101
expect(mockDisplayLoadedEnvVars).toHaveBeenCalledWith(
100-
{ envFilePath: '.env', env: { FOO: 'bar', BAZ: 'qux' } },
102+
{ envFilePath: DEFAULT_ENV_PATH, env: { FOO: 'bar', BAZ: 'qux' } },
101103
{ showValues: false }
102104
);
103105
});
@@ -109,7 +111,7 @@ describe('dotenv command', () => {
109111

110112
expect(mockDisplayLoadedEnvVars).toHaveBeenCalledTimes(1);
111113
const call = mockDisplayLoadedEnvVars.mock.calls[0];
112-
expect(call[0]).toEqual({ envFilePath: '.env', env: { FOO: 'bar', BAZ: 'qux' } });
114+
expect(call[0]).toEqual({ envFilePath: DEFAULT_ENV_PATH, env: { FOO: 'bar', BAZ: 'qux' } });
113115
expect(call[1]).toMatchObject({ showValues: true });
114116
});
115117
});
@@ -119,7 +121,7 @@ describe('dotenv command', () => {
119121
const cmd = new DotEnv(['dotenv'], mockConfig);
120122
const mockParse = jest.fn() as jest.Mock<() => Promise<ParseResult>>;
121123
mockParse.mockResolvedValue({
122-
flags: { env: '.env', 'show-values': false },
124+
flags: { env: DEFAULT_ENV_PATH, 'show-values': false },
123125
});
124126
(cmd as unknown as { parse: typeof mockParse }).parse = mockParse;
125127
jest.spyOn(cmd, 'jsonEnabled').mockReturnValue(true);

0 commit comments

Comments
 (0)