UNPKG

@aws-cdk/core

Version:

AWS Cloud Development Kit Core Library

193 lines 26.4 kB
"use strict"; const lib_1 = require("../lib"); const intrinsic_1 = require("../lib/private/intrinsic"); const evaluate_cfn_1 = require("./evaluate-cfn"); /** * Return two Tokens, one of which evaluates to a Token directly, one which evaluates to it lazily */ function tokensThatResolveTo(value) { return [ new intrinsic_1.Intrinsic(value), lib_1.Lazy.anyValue({ produce: () => value }) ]; } module.exports = { 'string tokens can be JSONified and JSONification can be reversed'(test) { const stack = new lib_1.Stack(); for (const token of tokensThatResolveTo('woof woof')) { // GIVEN const fido = { name: 'Fido', speaks: token }; // WHEN const resolved = stack.resolve(stack.toJsonString(fido)); // THEN test.deepEqual(evaluate_cfn_1.evaluateCFN(resolved), '{"name":"Fido","speaks":"woof woof"}'); } test.done(); }, 'string tokens can be embedded while being JSONified'(test) { const stack = new lib_1.Stack(); for (const token of tokensThatResolveTo('woof woof')) { // GIVEN const fido = { name: 'Fido', speaks: `deep ${token}` }; // WHEN const resolved = stack.resolve(stack.toJsonString(fido)); // THEN test.deepEqual(evaluate_cfn_1.evaluateCFN(resolved), '{"name":"Fido","speaks":"deep woof woof"}'); } test.done(); }, 'constant string has correct amount of quotes applied'(test) { const stack = new lib_1.Stack(); const inputString = 'Hello, "world"'; // WHEN const resolved = stack.resolve(stack.toJsonString(inputString)); // THEN test.deepEqual(evaluate_cfn_1.evaluateCFN(resolved), JSON.stringify(inputString)); test.done(); }, 'integer Tokens behave correctly in stringification and JSONification'(test) { // GIVEN const stack = new lib_1.Stack(); const num = new intrinsic_1.Intrinsic(1); const embedded = `the number is ${num}`; // WHEN test.equal(evaluate_cfn_1.evaluateCFN(stack.resolve(embedded)), "the number is 1"); test.equal(evaluate_cfn_1.evaluateCFN(stack.resolve(stack.toJsonString({ embedded }))), "{\"embedded\":\"the number is 1\"}"); test.equal(evaluate_cfn_1.evaluateCFN(stack.resolve(stack.toJsonString({ num }))), "{\"num\":1}"); test.done(); }, 'tokens in strings survive additional TokenJSON.stringification()'(test) { // GIVEN const stack = new lib_1.Stack(); for (const token of tokensThatResolveTo('pong!')) { // WHEN const stringified = stack.toJsonString(`ping? ${token}`); // THEN test.equal(evaluate_cfn_1.evaluateCFN(stack.resolve(stringified)), '"ping? pong!"'); } test.done(); }, 'intrinsic Tokens embed correctly in JSONification'(test) { // GIVEN const stack = new lib_1.Stack(); const bucketName = new intrinsic_1.Intrinsic({ Ref: 'MyBucket' }); // WHEN const resolved = stack.resolve(stack.toJsonString({ theBucket: bucketName })); // THEN const context = { MyBucket: 'TheName' }; test.equal(evaluate_cfn_1.evaluateCFN(resolved, context), '{"theBucket":"TheName"}'); test.done(); }, 'fake intrinsics are serialized to objects'(test) { const stack = new lib_1.Stack(); const fakeIntrinsics = new intrinsic_1.Intrinsic({ a: { 'Fn::GetArtifactAtt': { key: 'val', }, }, b: { 'Fn::GetParam': [ 'val1', 'val2', ], }, }); const stringified = stack.toJsonString(fakeIntrinsics); test.equal(evaluate_cfn_1.evaluateCFN(stack.resolve(stringified)), '{"a":{"Fn::GetArtifactAtt":{"key":"val"}},"b":{"Fn::GetParam":["val1","val2"]}}'); test.done(); }, 'embedded string literals in intrinsics are escaped when calling TokenJSON.stringify()'(test) { // GIVEN const stack = new lib_1.Stack(); const token = lib_1.Fn.join('', ['Hello', 'This\nIs', 'Very "cool"']); // WHEN const resolved = stack.resolve(stack.toJsonString({ literal: 'I can also "contain" quotes', token })); // THEN const expected = '{"literal":"I can also \\"contain\\" quotes","token":"HelloThis\\nIsVery \\"cool\\""}'; test.equal(evaluate_cfn_1.evaluateCFN(resolved), expected); test.done(); }, 'Tokens in Tokens are handled correctly'(test) { // GIVEN const stack = new lib_1.Stack(); const bucketName = new intrinsic_1.Intrinsic({ Ref: 'MyBucket' }); const combinedName = lib_1.Fn.join('', ['The bucket name is ', bucketName.toString()]); // WHEN const resolved = stack.resolve(stack.toJsonString({ theBucket: combinedName })); // THEN const context = { MyBucket: 'TheName' }; test.equal(evaluate_cfn_1.evaluateCFN(resolved, context), '{"theBucket":"The bucket name is TheName"}'); test.done(); }, 'Doubly nested strings evaluate correctly in JSON context'(test) { // WHEN const stack = new lib_1.Stack(); const fidoSays = lib_1.Lazy.stringValue({ produce: () => 'woof' }); // WHEN const resolved = stack.resolve(stack.toJsonString({ information: `Did you know that Fido says: ${fidoSays}` })); // THEN test.deepEqual(evaluate_cfn_1.evaluateCFN(resolved), '{"information":"Did you know that Fido says: woof"}'); test.done(); }, 'Doubly nested intrinsics evaluate correctly in JSON context'(test) { // GIVEN const stack = new lib_1.Stack(); const fidoSays = lib_1.Lazy.anyValue({ produce: () => ({ Ref: 'Something' }) }); // WHEN const resolved = stack.resolve(stack.toJsonString({ information: `Did you know that Fido says: ${fidoSays}` })); // THEN const context = { Something: 'woof woof' }; test.deepEqual(evaluate_cfn_1.evaluateCFN(resolved, context), '{"information":"Did you know that Fido says: woof woof"}'); test.done(); }, 'Quoted strings in embedded JSON context are escaped'(test) { // GIVEN const stack = new lib_1.Stack(); const fidoSays = lib_1.Lazy.stringValue({ produce: () => '"woof"' }); // WHEN const resolved = stack.resolve(stack.toJsonString({ information: `Did you know that Fido says: ${fidoSays}` })); // THEN test.deepEqual(evaluate_cfn_1.evaluateCFN(resolved), '{"information":"Did you know that Fido says: \\"woof\\""}'); test.done(); }, 'cross-stack references are also properly converted by toJsonString()'(test) { // GIVEN const app = new lib_1.App(); const stack1 = new lib_1.Stack(app, 'Stack1'); const stack2 = new lib_1.Stack(app, 'Stack2'); // WHEN new lib_1.CfnOutput(stack2, 'Stack1Id', { value: stack2.toJsonString({ Stack1Id: stack1.stackId, Stack2Id: stack2.stackId, }) }); // THEN const asm = app.synth(); test.deepEqual(asm.getStackByName('Stack2').template, { Outputs: { Stack1Id: { Value: { 'Fn::Join': ['', [ '{"Stack1Id":"', { 'Fn::ImportValue': 'Stack1:ExportsOutputRefAWSStackIdB2DD5BAA' }, '","Stack2Id":"', { Ref: 'AWS::StackId' }, '"}' ]] } } } }); test.done(); }, }; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGVzdC5jbG91ZGZvcm1hdGlvbi1qc29uLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsidGVzdC5jbG91ZGZvcm1hdGlvbi1qc29uLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFDQSxnQ0FBZ0U7QUFDaEUsd0RBQXFEO0FBQ3JELGlEQUE2QztBQTBPN0M7O0dBRUc7QUFDSCxTQUFTLG1CQUFtQixDQUFDLEtBQVU7SUFDckMsT0FBTztRQUNMLElBQUkscUJBQVMsQ0FBQyxLQUFLLENBQUM7UUFDcEIsVUFBSSxDQUFDLFFBQVEsQ0FBQyxFQUFFLE9BQU8sRUFBRSxHQUFHLEVBQUUsQ0FBQyxLQUFLLEVBQUUsQ0FBQztLQUN4QyxDQUFDO0FBQ0osQ0FBQztBQWhQRCxpQkFBUztJQUNQLGtFQUFrRSxDQUFDLElBQVU7UUFDM0UsTUFBTSxLQUFLLEdBQUcsSUFBSSxXQUFLLEVBQUUsQ0FBQztRQUUxQixLQUFLLE1BQU0sS0FBSyxJQUFJLG1CQUFtQixDQUFDLFdBQVcsQ0FBQyxFQUFFO1lBQ3BELFFBQVE7WUFDUixNQUFNLElBQUksR0FBRyxFQUFFLElBQUksRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRSxDQUFDO1lBRTdDLE9BQU87WUFDUCxNQUFNLFFBQVEsR0FBRyxLQUFLLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQztZQUV6RCxPQUFPO1lBQ1AsSUFBSSxDQUFDLFNBQVMsQ0FBQywwQkFBVyxDQUFDLFFBQVEsQ0FBQyxFQUFFLHNDQUFzQyxDQUFDLENBQUM7U0FDL0U7UUFFRCxJQUFJLENBQUMsSUFBSSxFQUFFLENBQUM7SUFDZCxDQUFDO0lBRUQscURBQXFELENBQUMsSUFBVTtRQUM5RCxNQUFNLEtBQUssR0FBRyxJQUFJLFdBQUssRUFBRSxDQUFDO1FBRTFCLEtBQUssTUFBTSxLQUFLLElBQUksbUJBQW1CLENBQUMsV0FBVyxDQUFDLEVBQUU7WUFDcEQsUUFBUTtZQUNS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LENBQUU7cUJBQ0o7aUJBQ0Y7YUFDRjtTQUNGLENBQUMsQ0FBQztRQUVILElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQztJQUNkLENBQUM7Q0FDRixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgVGVzdCB9IGZyb20gJ25vZGV1bml0JztcbmltcG9ydCB7IEFwcCwgQ2ZuT3V0cHV0LCBGbiwgTGF6eSwgU3RhY2ssIFRva2VuIH0gZnJvbSAnLi4vbGliJztcbmltcG9ydCB7IEludHJpbnNpYyB9IGZyb20gJy4uL2xpYi9wcml2YXRlL2ludHJpbnNpYyc7XG5pbXBvcnQgeyBldmFsdWF0ZUNGTiB9IGZyb20gJy4vZXZhbHVhdGUtY2ZuJztcblxuZXhwb3J0ID0ge1xuICAnc3RyaW5nIHRva2VucyBjYW4gYmUgSlNPTmlmaWVkIGFuZCBKU09OaWZpY2F0aW9uIGNhbiBiZSByZXZlcnNlZCcodGVzdDogVGVzdCkge1xuICAgIGNvbnN0IHN0YWNrID0gbmV3IFN0YWNrKCk7XG5cbiAgICBmb3IgKGNvbnN0IHRva2VuIG9mIHRva2Vuc1RoYXRSZXNvbHZlVG8oJ3dvb2Ygd29vZicpKSB7XG4gICAgICAvLyBHSVZFTlxuICAgICAgY29uc3QgZmlkbyA9IHsgbmFtZTogJ0ZpZG8nLCBzcGVha3M6IHRva2VuIH07XG5cbiAgICAgIC8vIFdIRU5cbiAgICAgIGNvbnN0IHJlc29sdmVkID0gc3RhY2sucmVzb2x2ZShzdGFjay50b0pzb25TdHJpbmcoZmlkbykpO1xuXG4gICAgICAvLyBUSEVOXG4gICAgICB0ZXN0LmRlZXBFcXVhbChldmFsdWF0ZUNGTihyZXNvbHZlZCksICd7XCJuYW1lXCI6XCJGaWRvXCIsXCJzcGVha3NcIjpcIndvb2Ygd29vZlwifScpO1xuICAgIH1cblxuICAgIHRlc3QuZG9uZSgpO1xuICB9LFxuXG4gICdzdHJpbmcgdG9rZW5zIGNhbiBiZSBlbWJlZGRlZCB3aGlsZSBiZWluZyBKU09OaWZpZWQnKHRlc3Q6IFRlc3QpIHtcbiAgICBjb25zdCBzdGFjayA9IG5ldyBTdGFjaygpO1xuXG4gICAgZm9yIChjb25zdCB0b2tlbiBvZiB0b2tlbnNUaGF0UmVzb2x2ZVRvKCd3b29mIHdvb2YnKSkge1xuICAgICAgLy8gR0lWRU5cbiAgICAgIGNvbnN0IGZpZG8gPSB7IG5hbWU6ICdGaWRvJywgc3BlYWtzOiBgZGVlcCAke3Rva2VufWAgfTtcblxuICAgICAgLy8gV0hFTlxuICAgICAgY29uc3QgcmVzb2x2ZWQgPSBzdGFjay5yZXNvbHZlKHN0YWNrLnRvSnNvblN0cmluZyhmaWRvKSk7XG5cbiAgICAgIC8vIFRIRU5cbiAgICAgIHRlc3QuZGVlcEVxdWFsKGV2YWx1YXRlQ0ZOKHJlc29sdmVkKSwgJ3tcIm5hbWVcIjpcIkZpZG9cIixcInNwZWFrc1wiOlwiZGVlcCB3b29mIHdvb2ZcIn0nKTtcbiAgICB9XG5cbiAgICB0ZXN0LmRvbmUoKTtcbiAgfSxcblxuICAnY29uc3RhbnQgc3RyaW5nIGhhcyBjb3JyZWN0IGFtb3VudCBvZiBxdW90ZXMgYXBwbGllZCcodGVzdDogVGVzdCkge1xuICAgIGNvbnN0IHN0YWNrID0gbmV3IFN0YWNrKCk7XG5cbiAgICBjb25zdCBpbnB1dFN0cmluZyA9ICdIZWxsbywgXCJ3b3JsZFwiJztcblxuICAgIC8vIFdIRU5cbiAgICBjb25zdCByZXNvbHZlZCA9IHN0YWNrLnJlc29sdmUoc3RhY2sudG9Kc29uU3RyaW5nKGlucHV0U3RyaW5nKSk7XG5cbiAgICAvLyBUSEVOXG4gICAgdGVzdC5kZWVwRXF1YWwoZXZhbHVhdGVDRk4ocmVzb2x2ZWQpLCBKU09OLnN0cmluZ2lmeShpbnB1dFN0cmluZykpO1xuXG4gICAgdGVzdC5kb25lKCk7XG4gIH0sXG5cbiAgJ2ludGVnZXIgVG9rZW5zIGJlaGF2ZSBjb3JyZWN0bHkgaW4gc3RyaW5naWZpY2F0aW9uIGFuZCBKU09OaWZpY2F0aW9uJyh0ZXN0OiBUZXN0KSB7XG4gICAgLy8gR0lWRU5cbiAgICBjb25zdCBzdGFjayA9IG5ldyBTdGFjaygpO1xuICAgIGNvbnN0IG51bSA9IG5ldyBJbnRyaW5zaWMoMSk7XG4gICAgY29uc3QgZW1iZWRkZWQgPSBgdGhlIG51bWJlciBpcyAke251bX1gO1xuXG4gICAgLy8gV0hFTlxuICAgIHRlc3QuZXF1YWwoZXZhbHVhdGVDRk4oc3RhY2sucmVzb2x2ZShlbWJlZGRlZCkpLCBcInRoZSBudW1iZXIgaXMgMVwiKTtcbiAgICB0ZXN0LmVxdWFsKGV2YWx1YXRlQ0ZOKHN0YWNrLnJlc29sdmUoc3RhY2sudG9Kc29uU3RyaW5nKHsgZW1iZWRkZWQgfSkpKSwgXCJ7XFxcImVtYmVkZGVkXFxcIjpcXFwidGhlIG51bWJlciBpcyAxXFxcIn1cIik7XG4gICAgdGVzdC5lcXVhbChldmFsdWF0ZUNGTihzdGFjay5yZXNvbHZlKHN0YWNrLnRvSnNvblN0cmluZyh7IG51bSB9KSkpLCBcIntcXFwibnVtXFxcIjoxfVwiKTtcblxuICAgIHRlc3QuZG9uZSgpO1xuICB9LFxuXG4gICd0b2tlbnMgaW4gc3RyaW5ncyBzdXJ2aXZlIGFkZGl0aW9uYWwgVG9rZW5KU09OLnN0cmluZ2lmaWNhdGlvbigpJyh0ZXN0OiBUZXN0KSB7XG4gICAgLy8gR0lWRU5cbiAgICBjb25zdCBzdGFjayA9IG5ldyBTdGFjaygpO1xuICAgIGZvciAoY29uc3QgdG9rZW4gb2YgdG9rZW5zVGhhdFJlc29sdmVUbygncG9uZyEnKSkge1xuICAgICAgLy8gV0hFTlxuICAgICAgY29uc3Qgc3RyaW5naWZpZWQgPSBzdGFjay50b0pzb25TdHJpbmcoYHBpbmc/ICR7dG9rZW59YCk7XG5cbiAgICAgIC8vIFRIRU5cbiAgICAgIHRlc3QuZXF1YWwoZXZhbHVhdGVDRk4oc3RhY2sucmVzb2x2ZShzdHJpbmdpZmllZCkpLCAnXCJwaW5nPyBwb25nIVwiJyk7XG4gICAgfVxuXG4gICAgdGVzdC5kb25lKCk7XG4gIH0sXG5cbiAgJ2ludHJpbnNpYyBUb2tlbnMgZW1iZWQgY29ycmVjdGx5IGluIEpTT05pZmljYXRpb24nKHRlc3Q6IFRlc3QpIHtcbiAgICAvLyBHSVZFTlxuICAgIGNvbnN0IHN0YWNrID0gbmV3IFN0YWNrKCk7XG4gICAgY29uc3QgYnVja2V0TmFtZSA9IG5ldyBJbnRyaW5zaWMoeyBSZWY6ICdNeUJ1Y2tldCcgfSk7XG5cbiAgICAvLyBXSEVOXG4gICAgY29uc3QgcmVzb2x2ZWQgPSBzdGFjay5yZXNvbHZlKHN0YWNrLnRvSnNvblN0cmluZyh7IHRoZUJ1Y2tldDogYnVja2V0TmFtZSB9KSk7XG5cbiAgICAvLyBUSEVOXG4gICAgY29uc3QgY29udGV4dCA9IHtNeUJ1Y2tldDogJ1RoZU5hbWUnfTtcbiAgICB0ZXN0LmVxdWFsKGV2YWx1YXRlQ0ZOKHJlc29sdmVkLCBjb250ZXh0KSwgJ3tcInRoZUJ1Y2tldFwiOlwiVGhlTmFtZVwifScpO1xuXG4gICAgdGVzdC5kb25lKCk7XG4gIH0sXG5cbiAgJ2Zha2UgaW50cmluc2ljcyBhcmUgc2VyaWFsaXplZCB0byBvYmplY3RzJyh0ZXN0OiBUZXN0KSB7XG4gICAgY29uc3Qgc3RhY2sgPSBuZXcgU3RhY2soKTtcbiAgICBjb25zdCBmYWtlSW50cmluc2ljcyA9IG5ldyBJbnRyaW5zaWMoe1xuICAgICAgYToge1xuICAgICAgICAnRm46OkdldEFydGlmYWN0QXR0Jzoge1xuICAgICAgICAgIGtleTogJ3ZhbCcsXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgICAgYjoge1xuICAgICAgICAnRm46OkdldFBhcmFtJzogW1xuICAgICAgICAgICd2YWwxJyxcbiAgICAgICAgICAndmFsMicsXG4gICAgICAgIF0sXG4gICAgICB9LFxuICAgIH0pO1xuXG4gICAgY29uc3Qgc3RyaW5naWZpZWQgPSBzdGFjay50b0pzb25TdHJpbmcoZmFrZUludHJpbnNpY3MpO1xuICAgIHRlc3QuZXF1YWwoZXZhbHVhdGVDRk4oc3RhY2sucmVzb2x2ZShzdHJpbmdpZmllZCkpLFxuICAgICAgICAne1wiYVwiOntcIkZuOjpHZXRBcnRpZmFjdEF0dFwiOntcImtleVwiOlwidmFsXCJ9fSxcImJcIjp7XCJGbjo6R2V0UGFyYW1cIjpbXCJ2YWwxXCIsXCJ2YWwyXCJdfX0nKTtcblxuICAgIHRlc3QuZG9uZSgpO1xuICB9LFxuXG4gICdlbWJlZGRlZCBzdHJpbmcgbGl0ZXJhbHMgaW4gaW50cmluc2ljcyBhcmUgZXNjYXBlZCB3aGVuIGNhbGxpbmcgVG9rZW5KU09OLnN0cmluZ2lmeSgpJyh0ZXN0OiBUZXN0KSB7XG4gICAgLy8gR0lWRU5cbiAgICBjb25zdCBzdGFjayA9IG5ldyBTdGFjaygpO1xuICAgIGNvbnN0IHRva2VuID0gRm4uam9pbignJywgWyAnSGVsbG8nLCAnVGhpc1xcbklzJywgJ1ZlcnkgXCJjb29sXCInIF0pO1xuXG4gICAgLy8gV0hFTlxuICAgIGNvbnN0IHJlc29sdmVkID0gc3RhY2sucmVzb2x2ZShzdGFjay50b0pzb25TdHJpbmcoe1xuICAgICAgbGl0ZXJhbDogJ0kgY2FuIGFsc28gXCJjb250YWluXCIgcXVvdGVzJyxcbiAgICAgIHRva2VuXG4gICAgfSkpO1xuXG4gICAgLy8gVEhFTlxuICAgIGNvbnN0IGV4cGVjdGVkID0gJ3tcImxpdGVyYWxcIjpcIkkgY2FuIGFsc28gXFxcXFwiY29udGFpblxcXFxcIiBxdW90ZXNcIixcInRva2VuXCI6XCJIZWxsb1RoaXNcXFxcbklzVmVyeSBcXFxcXCJjb29sXFxcXFwiXCJ9JztcbiAgICB0ZXN0LmVxdWFsKGV2YWx1YXRlQ0ZOKHJlc29sdmVkKSwgZXhwZWN0ZWQpO1xuXG4gICAgdGVzdC5kb25lKCk7XG4gIH0sXG5cbiAgJ1Rva2VucyBpbiBUb2tlbnMgYXJlIGhhbmRsZWQgY29ycmVjdGx5Jyh0ZXN0OiBUZXN0KSB7XG4gICAgLy8gR0lWRU5cbiAgICBjb25zdCBzdGFjayA9IG5ldyBTdGFjaygpO1xuICAgIGNvbnN0IGJ1Y2tldE5hbWUgPSBuZXcgSW50cmluc2ljKHsgUmVmOiAnTXlCdWNrZXQnIH0pO1xuICAgIGNvbnN0IGNvbWJpbmVkTmFtZSA9IEZuLmpvaW4oJycsIFsgJ1RoZSBidWNrZXQgbmFtZSBpcyAnLCBidWNrZXROYW1lLnRvU3RyaW5nKCkgXSk7XG5cbiAgICAvLyBXSEVOXG4gICAgY29uc3QgcmVzb2x2ZWQgPSBzdGFjay5yZXNvbHZlKHN0YWNrLnRvSnNvblN0cmluZyh7IHRoZUJ1Y2tldDogY29tYmluZWROYW1lIH0pKTtcblxuICAgIC8vIFRIRU5cbiAgICBjb25zdCBjb250ZXh0ID0ge015QnVja2V0OiAnVGhlTmFtZSd9O1xuICAgIHRlc3QuZXF1YWwoZXZhbHVhdGVDRk4ocmVzb2x2ZWQsIGNvbnRleHQpLCAne1widGhlQnVja2V0XCI6XCJUaGUgYnVja2V0IG5hbWUgaXMgVGhlTmFtZVwifScpO1xuXG4gICAgdGVzdC5kb25lKCk7XG4gIH0sXG5cbiAgJ0RvdWJseSBuZXN0ZWQgc3RyaW5ncyBldmFsdWF0ZSBjb3JyZWN0bHkgaW4gSlNPTiBjb250ZXh0Jyh0ZXN0OiBUZXN0KSB7XG4gICAgLy8gV0hFTlxuICAgIGNvbnN0IHN0YWNrID0gbmV3IFN0YWNrKCk7XG4gICAgY29uc3QgZmlkb1NheXMgPSBMYXp5LnN0cmluZ1ZhbHVlKHsgcHJvZHVjZTogKCkgPT4gJ3dvb2YnIH0pO1xuXG4gICAgLy8gV0hFTlxuICAgIGNvbnN0IHJlc29sdmVkID0gc3RhY2sucmVzb2x2ZShzdGFjay50b0pzb25TdHJpbmcoe1xuICAgICAgaW5mb3JtYXRpb246IGBEaWQgeW91IGtub3cgdGhhdCBGaWRvIHNheXM6ICR7Zmlkb1NheXN9YFxuICAgIH0pKTtcblxuICAgIC8vIFRIRU5cbiAgICB0ZXN0LmRlZXBFcXVhbChldmFsdWF0ZUNGTihyZXNvbHZlZCksICd7XCJpbmZvcm1hdGlvblwiOlwiRGlkIHlvdSBrbm93IHRoYXQgRmlkbyBzYXlzOiB3b29mXCJ9Jyk7XG5cbiAgICB0ZXN0LmRvbmUoKTtcbiAgfSxcblxuICAnRG91Ymx5IG5lc3RlZCBpbnRyaW5zaWNzIGV2YWx1YXRlIGNvcnJlY3RseSBpbiBKU09OIGNvbnRleHQnKHRlc3Q6IFRlc3QpIHtcbiAgICAvLyBHSVZFTlxuICAgIGNvbnN0IHN0YWNrID0gbmV3IFN0YWNrKCk7XG4gICAgY29uc3QgZmlkb1NheXMgPSBMYXp5LmFueVZhbHVlKHsgcHJvZHVjZTogKCkgPT4gKHsgUmVmOiAnU29tZXRoaW5nJyB9KSB9KTtcblxuICAgIC8vIFdIRU5cbiAgICBjb25zdCByZXNvbHZlZCA9IHN0YWNrLnJlc29sdmUoc3RhY2sudG9Kc29uU3RyaW5nKHtcbiAgICAgIGluZm9ybWF0aW9uOiBgRGlkIHlvdSBrbm93IHRoYXQgRmlkbyBzYXlzOiAke2ZpZG9TYXlzfWBcbiAgICB9KSk7XG5cbiAgICAvLyBUSEVOXG4gICAgY29uc3QgY29udGV4dCA9IHtTb21ldGhpbmc6ICd3b29mIHdvb2YnfTtcbiAgICB0ZXN0LmRlZXBFcXVhbChldmFsdWF0ZUNGTihyZXNvbHZlZCwgY29udGV4dCksICd7XCJpbmZvcm1hdGlvblwiOlwiRGlkIHlvdSBrbm93IHRoYXQgRmlkbyBzYXlzOiB3b29mIHdvb2ZcIn0nKTtcblxuICAgIHRlc3QuZG9uZSgpO1xuICB9LFxuXG4gICdRdW90ZWQgc3RyaW5ncyBpbiBlbWJlZGRlZCBKU09OIGNvbnRleHQgYXJlIGVzY2FwZWQnKHRlc3Q6IFRlc3QpIHtcbiAgICAvLyBHSVZFTlxuICAgIGNvbnN0IHN0YWNrID0gbmV3IFN0YWNrKCk7XG4gICAgY29uc3QgZmlkb1NheXMgPSBMYXp5LnN0cmluZ1ZhbHVlKHsgcHJvZHVjZTogKCkgPT4gJ1wid29vZlwiJyB9KTtcblxuICAgIC8vIFdIRU5cbiAgICBjb25zdCByZXNvbHZlZCA9IHN0YWNrLnJlc29sdmUoc3RhY2sudG9Kc29uU3RyaW5nKHtcbiAgICAgIGluZm9ybWF0aW9uOiBgRGlkIHlvdSBrbm93IHRoYXQgRmlkbyBzYXlzOiAke2ZpZG9TYXlzfWBcbiAgICB9KSk7XG5cbiAgICAvLyBUSEVOXG4gICAgdGVzdC5kZWVwRXF1YWwoZXZhbHVhdGVDRk4ocmVzb2x2ZWQpLCAne1wiaW5mb3JtYXRpb25cIjpcIkRpZCB5b3Uga25vdyB0aGF0IEZpZG8gc2F5czogXFxcXFwid29vZlxcXFxcIlwifScpO1xuXG4gICAgdGVzdC5kb25lKCk7XG4gIH0sXG5cbiAgJ2Nyb3NzLXN0YWNrIHJlZmVyZW5jZXMgYXJlIGFsc28gcHJvcGVybHkgY29udmVydGVkIGJ5IHRvSnNvblN0cmluZygpJyh0ZXN0OiBUZXN0KSB7XG4gICAgLy8gR0lWRU5cbiAgICBjb25zdCBhcHAgPSBuZXcgQXBwKCk7XG4gICAgY29uc3Qgc3RhY2sxID0gbmV3IFN0YWNrKGFwcCwgJ1N0YWNrMScpO1xuICAgIGNvbnN0IHN0YWNrMiA9IG5ldyBTdGFjayhhcHAsICdTdGFjazInKTtcblxuICAgIC8vIFdIRU5cbiAgICBuZXcgQ2ZuT3V0cHV0KHN0YWNrMiwgJ1N0YWNrMUlkJywgeyB2YWx1ZTogc3RhY2syLnRvSnNvblN0cmluZyh7XG4gICAgICBTdGFjazFJZDogc3RhY2sxLnN0YWNrSWQsXG4gICAgICBTdGFjazJJZDogc3RhY2syLnN0YWNrSWQsXG4gICAgfSl9KTtcblxuICAgIC8vIFRIRU5cbiAgICBjb25zdCBhc20gPSBhcHAuc3ludGgoKTtcbiAgICB0ZXN0LmRlZXBFcXVhbChhc20uZ2V0U3RhY2tCeU5hbWUoJ1N0YWNrMicpLnRlbXBsYXRlLCB7XG4gICAgICBPdXRwdXRzOiB7XG4gICAgICAgIFN0YWNrMUlkOiB7XG4gICAgICAgICAgVmFsdWU6IHtcbiAgICAgICAgICAgICdGbjo6Sm9pbic6IFsgJycsIFtcbiAgICAgICAgICAgICAgJ3tcIlN0YWNrMUlkXCI6XCInLFxuICAgICAgICAgICAgICB7ICdGbjo6SW1wb3J0VmFsdWUnOiAnU3RhY2sxOkV4cG9ydHNPdXRwdXRSZWZBV1NTdGFja0lkQjJERDVCQUEnIH0sXG4gICAgICAgICAgICAgICdcIixcIlN0YWNrMklkXCI6XCInLFxuICAgICAgICAgICAgICB7IFJlZjogJ0FXUzo6U3RhY2tJZCcgfSxcbiAgICAgICAgICAgICAgJ1wifSdcbiAgICAgICAgICAgIF0gXVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pO1xuXG4gICAgdGVzdC5kb25lKCk7XG4gIH0sXG59O1xuXG4vKipcbiAqIFJldHVybiB0d28gVG9rZW5zLCBvbmUgb2Ygd2hpY2ggZXZhbHVhdGVzIHRvIGEgVG9rZW4gZGlyZWN0bHksIG9uZSB3aGljaCBldmFsdWF0ZXMgdG8gaXQgbGF6aWx5XG4gKi9cbmZ1bmN0aW9uIHRva2Vuc1RoYXRSZXNvbHZlVG8odmFsdWU6IGFueSk6IFRva2VuW10ge1xuICByZXR1cm4gW1xuICAgIG5ldyBJbnRyaW5zaWModmFsdWUpLFxuICAgIExhenkuYW55VmFsdWUoeyBwcm9kdWNlOiAoKSA9PiB2YWx1ZSB9KVxuICBdO1xufVxuIl19