UNPKG

@aws-cdk/cloudformation-diff

Version:

Utilities to diff CDK stacks against CloudFormation templates

78 lines 9.37 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.renderIntrinsics = renderIntrinsics; /** * Turn CloudFormation intrinsics into strings * * ------ * * This stringification is not intended to be mechanically reversible! It's intended * to be understood by humans! * * ------ * * Turns Fn::GetAtt and Fn::Ref objects into the same strings that can be * parsed by Fn::Sub, but without the surrounding intrinsics. * * Evaluates Fn::Join directly if the second argument is a literal list of strings. * * Removes list and object values evaluating to { Ref: 'AWS::NoValue' }. * * For other intrinsics we choose a string representation that CloudFormation * cannot actually parse, but is comprehensible to humans. */ function renderIntrinsics(x) { if (Array.isArray(x)) { return x.filter(el => !isNoValue(el)).map(renderIntrinsics); } if (isNoValue(x)) { return undefined; } const intrinsic = getIntrinsic(x); if (intrinsic) { if (intrinsic.fn === 'Ref') { return '${' + intrinsic.args + '}'; } if (intrinsic.fn === 'Fn::GetAtt') { return '${' + intrinsic.args[0] + '.' + intrinsic.args[1] + '}'; } if (intrinsic.fn === 'Fn::Join') { return unCloudFormationFnJoin(intrinsic.args[0], intrinsic.args[1]); } return stringifyIntrinsic(intrinsic.fn, intrinsic.args); } if (typeof x === 'object' && x !== null) { const ret = {}; for (const [key, value] of Object.entries(x)) { if (!isNoValue(value)) { ret[key] = renderIntrinsics(value); } } return ret; } return x; } function unCloudFormationFnJoin(separator, args) { if (Array.isArray(args)) { return args.filter(el => !isNoValue(el)).map(renderIntrinsics).join(separator); } return stringifyIntrinsic('Fn::Join', [separator, args]); } function stringifyIntrinsic(fn, args) { return JSON.stringify({ [fn]: renderIntrinsics(args) }); } function getIntrinsic(x) { if (x === undefined || x === null || Array.isArray(x)) { return undefined; } if (typeof x !== 'object') { return undefined; } const keys = Object.keys(x); return keys.length === 1 && (keys[0] === 'Ref' || keys[0].startsWith('Fn::')) ? { fn: keys[0], args: x[keys[0]] } : undefined; } function isNoValue(x) { const int = getIntrinsic(x); return int && int.fn === 'Ref' && int.args === 'AWS::NoValue'; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVuZGVyLWludHJpbnNpY3MuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJyZW5kZXItaW50cmluc2ljcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQW9CQSw0Q0FpQ0M7QUFyREQ7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FtQkc7QUFDSCxTQUFnQixnQkFBZ0IsQ0FBQyxDQUFNO0lBQ3JDLElBQUksS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO1FBQ3JCLE9BQU8sQ0FBQyxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsU0FBUyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLGdCQUFnQixDQUFDLENBQUM7SUFDOUQsQ0FBQztJQUVELElBQUksU0FBUyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7UUFDakIsT0FBTyxTQUFTLENBQUM7SUFDbkIsQ0FBQztJQUVELE1BQU0sU0FBUyxHQUFHLFlBQVksQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUNsQyxJQUFJLFNBQVMsRUFBRSxDQUFDO1FBQ2QsSUFBSSxTQUFTLENBQUMsRUFBRSxLQUFLLEtBQUssRUFBRSxDQUFDO1lBQzNCLE9BQU8sSUFBSSxHQUFHLFNBQVMsQ0FBQyxJQUFJLEdBQUcsR0FBRyxDQUFDO1FBQ3JDLENBQUM7UUFDRCxJQUFJLFNBQVMsQ0FBQyxFQUFFLEtBQUssWUFBWSxFQUFFLENBQUM7WUFDbEMsT0FBTyxJQUFJLEdBQUcsU0FBUyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLEdBQUcsU0FBUyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLENBQUM7UUFDbEUsQ0FBQztRQUNELElBQUksU0FBUyxDQUFDLEVBQUUsS0FBSyxVQUFVLEVBQUUsQ0FBQztZQUNoQyxPQUFPLHNCQUFzQixDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsU0FBUyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3RFLENBQUM7UUFDRCxPQUFPLGtCQUFrQixDQUFDLFNBQVMsQ0FBQyxFQUFFLEVBQUUsU0FBUyxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQzFELENBQUM7SUFFRCxJQUFJLE9BQU8sQ0FBQyxLQUFLLFFBQVEsSUFBSSxDQUFDLEtBQUssSUFBSSxFQUFFLENBQUM7UUFDeEMsTUFBTSxHQUFHLEdBQVEsRUFBRSxDQUFDO1FBQ3BCLEtBQUssTUFBTSxDQUFDLEdBQUcsRUFBRSxLQUFLLENBQUMsSUFBSSxNQUFNLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7WUFDN0MsSUFBSSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDO2dCQUN0QixHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsZ0JBQWdCLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDckMsQ0FBQztRQUNILENBQUM7UUFDRCxPQUFPLEdBQUcsQ0FBQztJQUNiLENBQUM7SUFDRCxPQUFPLENBQUMsQ0FBQztBQUNYLENBQUM7QUFFRCxTQUFTLHNCQUFzQixDQUFDLFNBQWlCLEVBQUUsSUFBUztJQUMxRCxJQUFJLEtBQUssQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQztRQUN4QixPQUFPLElBQUksQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQztJQUNqRixDQUFDO0lBQ0QsT0FBTyxrQkFBa0IsQ0FBQyxVQUFVLEVBQUUsQ0FBQyxTQUFTLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQztBQUMzRCxDQUFDO0FBRUQsU0FBUyxrQkFBa0IsQ0FBQyxFQUFVLEVBQUUsSUFBUztJQUMvQyxPQUFPLElBQUksQ0FBQyxTQUFTLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLGdCQUFnQixDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQztBQUMxRCxDQUFDO0FBRUQsU0FBUyxZQUFZLENBQUMsQ0FBTTtJQUMxQixJQUFJLENBQUMsS0FBSyxTQUFTLElBQUksQ0FBQyxLQUFLLElBQUksSUFBSSxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7UUFDdEQsT0FBTyxTQUFTLENBQUM7SUFDbkIsQ0FBQztJQUNELElBQUksT0FBTyxDQUFDLEtBQUssUUFBUSxFQUFFLENBQUM7UUFDMUIsT0FBTyxTQUFTLENBQUM7SUFDbkIsQ0FBQztJQUNELE1BQU0sSUFBSSxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDNUIsT0FBTyxJQUFJLENBQUMsTUFBTSxLQUFLLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsS0FBSyxLQUFLLElBQUksSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsRUFBRSxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUM7QUFDaEksQ0FBQztBQUVELFNBQVMsU0FBUyxDQUFDLENBQU07SUFDdkIsTUFBTSxHQUFHLEdBQUcsWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQzVCLE9BQU8sR0FBRyxJQUFJLEdBQUcsQ0FBQyxFQUFFLEtBQUssS0FBSyxJQUFJLEdBQUcsQ0FBQyxJQUFJLEtBQUssY0FBYyxDQUFDO0FBQ2hFLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIFR1cm4gQ2xvdWRGb3JtYXRpb24gaW50cmluc2ljcyBpbnRvIHN0cmluZ3NcbiAqXG4gKiAtLS0tLS1cbiAqXG4gKiBUaGlzIHN0cmluZ2lmaWNhdGlvbiBpcyBub3QgaW50ZW5kZWQgdG8gYmUgbWVjaGFuaWNhbGx5IHJldmVyc2libGUhIEl0J3MgaW50ZW5kZWRcbiAqIHRvIGJlIHVuZGVyc3Rvb2QgYnkgaHVtYW5zIVxuICpcbiAqIC0tLS0tLVxuICpcbiAqIFR1cm5zIEZuOjpHZXRBdHQgYW5kIEZuOjpSZWYgb2JqZWN0cyBpbnRvIHRoZSBzYW1lIHN0cmluZ3MgdGhhdCBjYW4gYmVcbiAqIHBhcnNlZCBieSBGbjo6U3ViLCBidXQgd2l0aG91dCB0aGUgc3Vycm91bmRpbmcgaW50cmluc2ljcy5cbiAqXG4gKiBFdmFsdWF0ZXMgRm46OkpvaW4gZGlyZWN0bHkgaWYgdGhlIHNlY29uZCBhcmd1bWVudCBpcyBhIGxpdGVyYWwgbGlzdCBvZiBzdHJpbmdzLlxuICpcbiAqIFJlbW92ZXMgbGlzdCBhbmQgb2JqZWN0IHZhbHVlcyBldmFsdWF0aW5nIHRvIHsgUmVmOiAnQVdTOjpOb1ZhbHVlJyB9LlxuICpcbiAqIEZvciBvdGhlciBpbnRyaW5zaWNzIHdlIGNob29zZSBhIHN0cmluZyByZXByZXNlbnRhdGlvbiB0aGF0IENsb3VkRm9ybWF0aW9uXG4gKiBjYW5ub3QgYWN0dWFsbHkgcGFyc2UsIGJ1dCBpcyBjb21wcmVoZW5zaWJsZSB0byBodW1hbnMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZW5kZXJJbnRyaW5zaWNzKHg6IGFueSk6IGFueSB7XG4gIGlmIChBcnJheS5pc0FycmF5KHgpKSB7XG4gICAgcmV0dXJuIHguZmlsdGVyKGVsID0+ICFpc05vVmFsdWUoZWwpKS5tYXAocmVuZGVySW50cmluc2ljcyk7XG4gIH1cblxuICBpZiAoaXNOb1ZhbHVlKHgpKSB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuXG4gIGNvbnN0IGludHJpbnNpYyA9IGdldEludHJpbnNpYyh4KTtcbiAgaWYgKGludHJpbnNpYykge1xuICAgIGlmIChpbnRyaW5zaWMuZm4gPT09ICdSZWYnKSB7XG4gICAgICByZXR1cm4gJyR7JyArIGludHJpbnNpYy5hcmdzICsgJ30nO1xuICAgIH1cbiAgICBpZiAoaW50cmluc2ljLmZuID09PSAnRm46OkdldEF0dCcpIHtcbiAgICAgIHJldHVybiAnJHsnICsgaW50cmluc2ljLmFyZ3NbMF0gKyAnLicgKyBpbnRyaW5zaWMuYXJnc1sxXSArICd9JztcbiAgICB9XG4gICAgaWYgKGludHJpbnNpYy5mbiA9PT0gJ0ZuOjpKb2luJykge1xuICAgICAgcmV0dXJuIHVuQ2xvdWRGb3JtYXRpb25GbkpvaW4oaW50cmluc2ljLmFyZ3NbMF0sIGludHJpbnNpYy5hcmdzWzFdKTtcbiAgICB9XG4gICAgcmV0dXJuIHN0cmluZ2lmeUludHJpbnNpYyhpbnRyaW5zaWMuZm4sIGludHJpbnNpYy5hcmdzKTtcbiAgfVxuXG4gIGlmICh0eXBlb2YgeCA9PT0gJ29iamVjdCcgJiYgeCAhPT0gbnVsbCkge1xuICAgIGNvbnN0IHJldDogYW55ID0ge307XG4gICAgZm9yIChjb25zdCBba2V5LCB2YWx1ZV0gb2YgT2JqZWN0LmVudHJpZXMoeCkpIHtcbiAgICAgIGlmICghaXNOb1ZhbHVlKHZhbHVlKSkge1xuICAgICAgICByZXRba2V5XSA9IHJlbmRlckludHJpbnNpY3ModmFsdWUpO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gcmV0O1xuICB9XG4gIHJldHVybiB4O1xufVxuXG5mdW5jdGlvbiB1bkNsb3VkRm9ybWF0aW9uRm5Kb2luKHNlcGFyYXRvcjogc3RyaW5nLCBhcmdzOiBhbnkpIHtcbiAgaWYgKEFycmF5LmlzQXJyYXkoYXJncykpIHtcbiAgICByZXR1cm4gYXJncy5maWx0ZXIoZWwgPT4gIWlzTm9WYWx1ZShlbCkpLm1hcChyZW5kZXJJbnRyaW5zaWNzKS5qb2luKHNlcGFyYXRvcik7XG4gIH1cbiAgcmV0dXJuIHN0cmluZ2lmeUludHJpbnNpYygnRm46OkpvaW4nLCBbc2VwYXJhdG9yLCBhcmdzXSk7XG59XG5cbmZ1bmN0aW9uIHN0cmluZ2lmeUludHJpbnNpYyhmbjogc3RyaW5nLCBhcmdzOiBhbnkpIHtcbiAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KHsgW2ZuXTogcmVuZGVySW50cmluc2ljcyhhcmdzKSB9KTtcbn1cblxuZnVuY3Rpb24gZ2V0SW50cmluc2ljKHg6IGFueSk6IEludHJpbnNpYyB8IHVuZGVmaW5lZCB7XG4gIGlmICh4ID09PSB1bmRlZmluZWQgfHwgeCA9PT0gbnVsbCB8fCBBcnJheS5pc0FycmF5KHgpKSB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuICBpZiAodHlwZW9mIHggIT09ICdvYmplY3QnKSB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuICBjb25zdCBrZXlzID0gT2JqZWN0LmtleXMoeCk7XG4gIHJldHVybiBrZXlzLmxlbmd0aCA9PT0gMSAmJiAoa2V5c1swXSA9PT0gJ1JlZicgfHwga2V5c1swXS5zdGFydHNXaXRoKCdGbjo6JykpID8geyBmbjoga2V5c1swXSwgYXJnczogeFtrZXlzWzBdXSB9IDogdW5kZWZpbmVkO1xufVxuXG5mdW5jdGlvbiBpc05vVmFsdWUoeDogYW55KSB7XG4gIGNvbnN0IGludCA9IGdldEludHJpbnNpYyh4KTtcbiAgcmV0dXJuIGludCAmJiBpbnQuZm4gPT09ICdSZWYnICYmIGludC5hcmdzID09PSAnQVdTOjpOb1ZhbHVlJztcbn1cblxuaW50ZXJmYWNlIEludHJpbnNpYyB7XG4gIGZuOiBzdHJpbmc7XG4gIGFyZ3M6IGFueTtcbn1cbiJdfQ==