@aws-cdk/cloudformation-diff
Version:
Utilities to diff CDK stacks against CloudFormation templates
78 lines • 9.37 kB
JavaScript
;
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==