config-loader: more talking about includes instead of secrets

This commit is contained in:
Patrik Oldsberg
2021-01-25 00:27:33 +01:00
parent a6faeeab4b
commit b2e5c844f7
3 changed files with 19 additions and 18 deletions
@@ -19,8 +19,7 @@ import { TransformFunc } from './types';
import { isObject } from './utils';
/**
* Reads and parses, and validates, and transforms a single config file.
* The transformation rewrites any special values, like the $secret key.
* Applies a set of transforms to raw configuration data.
*/
export async function applyConfigTransforms(
initialDir: string,
@@ -113,7 +113,9 @@ describe('includeTransform', () => {
it('should reject invalid includes', async () => {
await expect(
includeTransform({ $include: 'no-parser.js' }, '/'),
).rejects.toThrow('no configuration parser available for extension .js');
).rejects.toThrow(
'no configuration parser available for included file no-parser.js',
);
await expect(
includeTransform({ $include: 'no-data.yml#different.key' }, '/'),
).rejects.toThrow('File not found!');
@@ -30,7 +30,7 @@ const includeFileParser: {
};
/**
* Transforms a secret description into the actual secret value.
* Transforms a include description into the actual included value.
*/
export function createIncludeTransform(
env: EnvFunc,
@@ -41,40 +41,40 @@ export function createIncludeTransform(
return { applied: false };
}
// Check if there's any key that starts with a '$', in that case we treat
// this entire object as a secret.
const [secretKey] = Object.keys(input).filter(key => key.startsWith('$'));
if (secretKey) {
// this entire object as an include description.
const [includeKey] = Object.keys(input).filter(key => key.startsWith('$'));
if (includeKey) {
if (Object.keys(input).length !== 1) {
throw new Error(
`include key ${secretKey} should not have adjacent keys`,
`include key ${includeKey} should not have adjacent keys`,
);
}
} else {
return { applied: false };
}
const secretValue = input[secretKey];
if (typeof secretValue !== 'string') {
throw new Error(`${secretKey} include value is not a string`);
const includeValue = input[includeKey];
if (typeof includeValue !== 'string') {
throw new Error(`${includeKey} include value is not a string`);
}
switch (secretKey) {
switch (includeKey) {
case '$file':
try {
const value = await readFile(resolvePath(baseDir, secretValue));
const value = await readFile(resolvePath(baseDir, includeValue));
return { applied: true, value };
} catch (error) {
throw new Error(`failed to read file ${secretValue}, ${error}`);
throw new Error(`failed to read file ${includeValue}, ${error}`);
}
case '$env':
try {
return { applied: true, value: await env(secretValue) };
return { applied: true, value: await env(includeValue) };
} catch (error) {
throw new Error(`failed to read env ${secretValue}, ${error}`);
throw new Error(`failed to read env ${includeValue}, ${error}`);
}
case '$include': {
const [filePath, dataPath] = secretValue.split(/#(.*)/);
const [filePath, dataPath] = includeValue.split(/#(.*)/);
const ext = extname(filePath);
const parser = includeFileParser[ext];
@@ -118,7 +118,7 @@ export function createIncludeTransform(
}
default:
throw new Error(`unknown secret ${secretKey}`);
throw new Error(`unknown include ${includeKey}`);
}
};
}