diff --git a/example/env.yml b/example/env.yml index 9b387b8..f6e45f2 100644 --- a/example/env.yml +++ b/example/env.yml @@ -1,16 +1,14 @@ default_env: &default_env IA_ENV: ${env:IA_ENV} - FOO: ${cft:forms-api-fargate-stack.ServiceURL} BAZ: BAR - CRED: ${cred:IA_VPC_PRIVATE_SUBNET1_ID} - CRED_OPTIONAL: - value: ${cred:IDSFJKLJ} - optional: true TEST: ${poop:hello} INTEGER_VALUE: 3000 BOOLEAN_TRUE_VALUE: true BOOLEAN_FALSE_VALUE: false - VALUE_WITH_SURROUNDING_STRINGS: test-${IA_ENV}-test + VALUE_WITH_SURROUNDING_STRINGS: test-${env:IA_ENV}-test + OPTIONAL_VALUE: + value: ${env:IA_OPTIONAL} + optional: true sandbox: <<: *default_env diff --git a/package.json b/package.json index 6ba8b8b..7440d54 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,8 @@ "build": "yarn tsc", "test": "yarn jest", "precommit": "lint-staged", - "release": "semantic-release" + "release": "semantic-release", + "example": "pushd example && IA_ENV=test node ../dist/index.js -f env.yml -s development && popd" }, "bin": { "dotenvi": "dist/index.js" diff --git a/src/rewriter.test.js b/src/rewriter.test.js index 60c1d98..63d9ee9 100644 --- a/src/rewriter.test.js +++ b/src/rewriter.test.js @@ -76,4 +76,18 @@ describe('Rewriter', () => { expect(output['test']).toBe('footestbartest-test'); }); }); + + it('Supports optionals', () => { + const document = { + test: { + value: '${env:OPTIONAL}', + optional: true + } + }; + + const rewriter = new Rewriter({ resolvers: resolvers }); + return rewriter.rewrite(document).then(output => { + expect(output['test']).toBe(''); + }); + }); }); diff --git a/src/rewriter.ts b/src/rewriter.ts index 8064e92..be43849 100644 --- a/src/rewriter.ts +++ b/src/rewriter.ts @@ -1,4 +1,5 @@ import { Document, InputDocument, Config, Primitive } from './types'; +import { isNullOrUndefined } from 'util'; export class Rewriter { constructor(private config: Config) {} @@ -31,12 +32,12 @@ export class Rewriter { if (!resolver) { throw new Error(`Could not locate resolver for value ${value}`); } - const innerValue = matchResults ? matchResults[2] : value; - let innerResult = await resolver(innerValue, this.config); - if (!innerResult) { - throw new Error(`Resolver ${resolverName} didn't return any value`); + const argument = matchResults ? matchResults[2] : value; + let resolved = await resolver(argument, this.config); + const rewrittenValue = await this.rewriteValue(resolved); + if (!isNullOrUndefined(rewrittenValue)) { + result += rewrittenValue; } - result += await this.rewriteValue(innerResult); capture = ''; } else if (capture) { capture += c; diff --git a/src/utils.ts b/src/utils.ts index 27a2eeb..c11321c 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -25,7 +25,7 @@ export function validateOutput(input: InputDocument, output: Document): string[] const keys = Object.keys(input); for (const key of keys) { if (!input[key].optional) { - if (!(key in output) || output[key] === undefined) { + if (!(key in output) || output[key] === undefined || output[key] === '') { errors.push(`${key} is a required variable but is not specified in result`); } }