Skip to content

Commit eeab93f

Browse files
committed
fix: parsing tree extensions with composeExtensions
1 parent 185aee7 commit eeab93f

File tree

2 files changed

+45
-2
lines changed

2 files changed

+45
-2
lines changed

app-config-extension-utils/src/index.ts

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,22 @@ import { parseValue, Root, AppConfigError } from '@app-config/core';
77
import { SchemaBuilder } from '@serafin/schema-builder';
88

99
export function composeExtensions(extensions: ParsingExtension[]): ParsingExtension {
10-
return (value, [k]) => {
10+
const composed: ParsingExtension = (value, [k]) => {
11+
// only applies to the root - override the parsing extensions
1112
if (k !== Root) return false;
1213

13-
return (_, __, source) => parseValue(value, source, extensions, { shouldFlatten: true });
14+
return (_, __, source, baseExtensions) =>
15+
// restart the parse tree, but with additional extensions included
16+
parseValue(
17+
value,
18+
source,
19+
// ensures that a recursion doesn't happen
20+
baseExtensions.concat(extensions).filter((v) => v !== composed),
21+
{ shouldFlatten: true },
22+
);
1423
};
24+
25+
return composed;
1526
}
1627

1728
export function named(name: string, parsingExtension: ParsingExtension): ParsingExtension {

app-config-extensions/src/index.test.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ import {
77
envDirective,
88
extendsDirective,
99
substituteDirective,
10+
envVarDirective,
11+
parseDirective,
1012
} from './index';
1113

1214
/* eslint-disable no-template-curly-in-string */
@@ -121,4 +123,34 @@ describe('extension combinations', () => {
121123

122124
await expect(source.readToJSON([ifDirective(), eqDirective()])).resolves.toEqual('foo');
123125
});
126+
127+
it('combines $envVar and $parseBool directives', async () => {
128+
process.env.FOO = '1';
129+
130+
const source = new LiteralSource({
131+
featureEnabled: {
132+
$parseBool: {
133+
$envVar: 'FOO',
134+
},
135+
},
136+
});
137+
138+
const parsed = await source.read([envVarDirective(), parseDirective()]);
139+
140+
expect(parsed.toJSON()).toEqual({ featureEnabled: true });
141+
});
142+
143+
it('combines $envVar and $parseBool directives 2', async () => {
144+
const source = new LiteralSource({
145+
featureEnabled: {
146+
$parseBool: {
147+
$envVar: { name: 'FOO', allowNull: true, fallback: null },
148+
},
149+
},
150+
});
151+
152+
const parsed = await source.read([parseDirective(), envVarDirective()]);
153+
154+
expect(parsed.toJSON()).toEqual({ featureEnabled: false });
155+
});
124156
});

0 commit comments

Comments
 (0)