-
Notifications
You must be signed in to change notification settings - Fork 4
Resolve environment variable placeholders in configuration #47
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
3a23f3a
8b2e53d
0599e0a
96f3988
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,61 @@ | ||
| import { describe, expect, it } from 'vitest'; | ||
| import { applyOverridesToRuntimeConfig } from './config.js'; | ||
|
|
||
| describe('applyOverridesToRuntimeConfig environment resolution', () => { | ||
| it('resolves {env:VAR} placeholders from process.env', () => { | ||
| process.env.TEST_VAR = 'secret-value'; | ||
| process.env.OTHER_VAR = 'other-value'; | ||
|
|
||
| const config: Record<string, unknown> = { | ||
| mcp: { | ||
| github: { | ||
| headers: { | ||
| Authorization: 'Bearer {env:TEST_VAR}', | ||
| }, | ||
| other: '{env:OTHER_VAR}', | ||
| }, | ||
| }, | ||
| unrelated: 'keep-me', | ||
| }; | ||
|
|
||
| const overrides = { | ||
| mcp: { | ||
| github: { | ||
| headers: { | ||
| Authorization: 'Bearer {env:TEST_VAR}', | ||
| }, | ||
| }, | ||
| }, | ||
| }; | ||
|
|
||
| // We apply overrides (which might already contain placeholders) | ||
| applyOverridesToRuntimeConfig(config, overrides); | ||
|
|
||
| const mcp = config.mcp as Record<string, Record<string, Record<string, string>>>; | ||
| expect(mcp.github.headers.Authorization).toBe('Bearer secret-value'); | ||
| expect(mcp.github.other).toBe('other-value'); | ||
| expect(config.unrelated).toBe('keep-me'); | ||
|
|
||
| delete process.env.TEST_VAR; | ||
| delete process.env.OTHER_VAR; | ||
| }); | ||
|
|
||
| it('handles missing environment variables by leaving placeholder intact', () => { | ||
| process.env.PRESENT_VAR = 'present'; | ||
| delete process.env.ABSENT_VAR; | ||
|
|
||
| const config: Record<string, unknown> = { | ||
| val: '{env:PRESENT_VAR}', | ||
| missing: '{env:ABSENT_VAR}', | ||
| }; | ||
|
|
||
| applyOverridesToRuntimeConfig(config, {}); | ||
|
|
||
| expect(config.val).toBe('present'); | ||
| // If it's missing, we keep it as is to avoid breaking things silently or passing empty strings | ||
| // that might be harder to debug. | ||
| expect(config.missing).toBe('{env:ABSENT_VAR}'); | ||
|
|
||
| delete process.env.PRESENT_VAR; | ||
| }); | ||
| }); | ||
|
Comment on lines
+4
to
+61
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Modifying the global Here's how you could refactor the tests: import { describe, expect, it, vi, afterEach } from 'vitest';
// ...
describe('applyOverridesToRuntimeConfig environment resolution', () => {
afterEach(() => {
vi.unstubAllEnvs();
});
it('resolves {env:VAR} placeholders from process.env', () => {
vi.stubEnv('TEST_VAR', 'secret-value');
vi.stubEnv('OTHER_VAR', 'other-value');
// ... rest of test logic, no manual cleanup needed
});
it('handles missing environment variables by leaving placeholder intact', () => {
vi.stubEnv('PRESENT_VAR', 'present');
// ABSENT_VAR is not stubbed, so it will be undefined
// ... rest of test logic, no manual cleanup needed
});
}); |
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This function has a critical bug and a potential robustness issue.
/{env:([^}]+)}/gis invalid because the{character is not escaped. This will cause aSyntaxErrorat runtime. It must be escaped as\{.I've provided a suggestion that fixes the regex and adds cycle detection using a
WeakSet.