Skip to content

Commit c4d13ab

Browse files
authored
Merge pull request #2 from nalch/master
Add support for arbitrary deep keys
2 parents afc0bc1 + 86f7508 commit c4d13ab

File tree

2 files changed

+136
-17
lines changed

2 files changed

+136
-17
lines changed

src/aurelia-configuration.ts

Lines changed: 40 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,29 @@ export class AureliaConfiguration {
166166
return this.environment in this.obj;
167167
}
168168

169+
/**
170+
* GetDictValue
171+
* Gets a value from a dict in an arbitrary depth or throws
172+
* an error, if the key does not exist
173+
*
174+
* @param baseObject
175+
* @param key
176+
* @returns {*}
177+
*/
178+
getDictValue(baseObject: {} | any, key: string) {
179+
let splitKey = key.split('.');
180+
let currentObject = baseObject;
181+
182+
splitKey.forEach((key) => {
183+
if (currentObject[key]) {
184+
currentObject = currentObject[key];
185+
} else {
186+
throw 'Key ' + key + ' not found';
187+
}
188+
});
189+
return currentObject;
190+
}
191+
169192
/**
170193
* Get
171194
* Gets a configuration value from the main config object
@@ -197,25 +220,25 @@ export class AureliaConfiguration {
197220

198221
return returnVal;
199222
}
200-
}
201-
202-
if (key.indexOf('.') !== -1) {
203-
let splitKey = key.split('.');
204-
let parent = splitKey[0];
205-
let child = splitKey[1];
206-
207-
if (!this.environmentEnabled()) {
208-
if (this.obj[parent]) {
209-
return this.obj[parent][child] ? this.obj[parent][child] : defaultValue;
223+
} else {
224+
// nested key and environment is enabled
225+
if (this.environmentEnabled()) {
226+
if (this.environmentExists()) {
227+
try {
228+
return this.getDictValue(this.obj[this.environment], key);
229+
} catch {
230+
// nested key, env exists, key is not in environment
231+
if (this.cascade_mode) {
232+
try {
233+
return this.getDictValue(this.obj, key);
234+
} catch {}
235+
}
236+
}
210237
}
211238
} else {
212-
if (this.environmentExists() && this.obj[this.environment][parent] && this.obj[this.environment][parent][child]) {
213-
returnVal = this.obj[this.environment][parent][child];
214-
} else if (this.cascade_mode && this.obj[parent] && this.obj[parent][child]) {
215-
returnVal = this.obj[parent][child];
216-
}
217-
218-
return returnVal;
239+
try {
240+
return this.getDictValue(this.obj, key);
241+
} catch {}
219242
}
220243
}
221244

test/unit/aurelia-configuration.spec.ts

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,4 +104,100 @@ describe('Configuration class', () => {
104104
const test = configInstance.get('test');
105105
expect(test).toEqual('dev2');
106106
});
107+
108+
it('should get nested values from dicts', () => {
109+
let nestedDict = {
110+
'level1': 'level1',
111+
'nested1': {
112+
'nested12': 'nested12',
113+
'nested2': {
114+
'nested21': 'nested21'
115+
}
116+
}
117+
};
118+
configInstance.setAll(nestedDict);
119+
120+
expect(configInstance.getDictValue(nestedDict, 'level1')).toEqual('level1');
121+
expect(configInstance.getDictValue(nestedDict, 'nested1.nested12')).toEqual('nested12');
122+
expect(configInstance.getDictValue(nestedDict, 'nested1.nested2.nested21')).toEqual('nested21');
123+
124+
expect(
125+
configInstance.getDictValue(nestedDict['nested1'], 'nested2.nested21'),
126+
).toEqual('nested21');
127+
128+
expect(
129+
configInstance.getDictValue(nestedDict['nested1']['nested2'], 'nested21'),
130+
).toEqual('nested21');
131+
132+
expect(
133+
function () { configInstance.getDictValue(nestedDict, 'nonExisting') }
134+
).toThrow();
135+
});
136+
137+
it('should get nested values from configs', () => {
138+
let nestedDict = {
139+
'level1': 'level1',
140+
'nested1': {
141+
'nested12': 'nested12',
142+
'nested2': {
143+
'nested21': 'nested21'
144+
}
145+
}
146+
};
147+
configInstance.setAll(nestedDict);
148+
149+
expect(configInstance.get('level1')).toEqual('level1');
150+
expect(configInstance.get('nested1.nested12')).toEqual('nested12');
151+
expect(configInstance.get('nested1.nested2.nested21')).toEqual('nested21');
152+
expect(
153+
configInstance.get('nested1.nested2')
154+
).toEqual({'nested21': 'nested21'});
155+
expect(
156+
configInstance.get('nested1.nested2.nested21')
157+
).toEqual('nested21');
158+
expect(
159+
function () { configInstance.getDictValue(nestedDict, 'nonExisting') }
160+
).toThrow();
161+
});
162+
163+
it('should prefer environment values from configs', () => {
164+
let nestedDict = {
165+
'level1': 'level1',
166+
'nested1': {
167+
'nested12': 'nested12',
168+
'nested2': {
169+
'nested21': 'nested21'
170+
},
171+
'nested13': 'nested13'
172+
},
173+
'dev2': {
174+
'level1': 'level1e',
175+
'nested1': {
176+
'nested12': 'nested12e',
177+
'nested2': {
178+
'nested21': 'nested21e'
179+
}
180+
}
181+
}
182+
};
183+
configInstance.setAll(nestedDict);
184+
configInstance.setEnvironment('dev2');
185+
186+
expect(configInstance.get('level1')).toEqual('level1e');
187+
expect(configInstance.get('nested1.nested12')).toEqual('nested12e');
188+
expect(configInstance.get('nested1.nested2.nested21')).toEqual('nested21e');
189+
expect(
190+
configInstance.get('nested1.nested2')
191+
).toEqual({'nested21': 'nested21e'});
192+
expect(
193+
configInstance.get('nested1.nested2.nested21')
194+
).toEqual('nested21e');
195+
expect(
196+
configInstance.get('nested1.nested13')
197+
).toEqual('nested13');
198+
expect(configInstance.get('nonExisting', 'default')).toEqual('default');
199+
expect(
200+
function () { configInstance.getDictValue(nestedDict, 'nonExisting') }
201+
).toThrow();
202+
});
107203
});

0 commit comments

Comments
 (0)