aws-cdk-lib
Version:
Version 2 of the AWS Cloud Development Kit library
2 lines (1 loc) • 16.4 kB
JavaScript
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.CfnParser=exports.CfnParsingContext=exports.FromCloudFormation=exports.FromCloudFormationPropertyObject=exports.FromCloudFormationResult=void 0;var cfn_fn_1=()=>{var tmp=require("../cfn-fn");return cfn_fn_1=()=>tmp,tmp},cfn_pseudo_1=()=>{var tmp=require("../cfn-pseudo");return cfn_pseudo_1=()=>tmp,tmp},cfn_resource_policy_1=()=>{var tmp=require("../cfn-resource-policy");return cfn_resource_policy_1=()=>tmp,tmp},lazy_1=()=>{var tmp=require("../lazy");return lazy_1=()=>tmp,tmp},cfn_reference_1=()=>{var tmp=require("../private/cfn-reference");return cfn_reference_1=()=>tmp,tmp},token_1=()=>{var tmp=require("../token");return token_1=()=>tmp,tmp},util_1=()=>{var tmp=require("../util");return util_1=()=>tmp,tmp};class FromCloudFormationResult{constructor(value){this.value=value,this.extraProperties={}}appendExtraProperties(prefix,properties){for(const[key,val]of Object.entries(properties??{}))this.extraProperties[`${prefix}.${key}`]=val}}exports.FromCloudFormationResult=FromCloudFormationResult;class FromCloudFormationPropertyObject extends FromCloudFormationResult{constructor(){super({}),this.recognizedProperties=new Set}addPropertyResult(cdkPropName,cfnPropName,result){this.recognizedProperties.add(cfnPropName),result&&(this.value[cdkPropName]=result.value,this.appendExtraProperties(cfnPropName,result.extraProperties))}addUnrecognizedPropertiesAsExtra(properties){for(const[key,val]of Object.entries(properties))this.recognizedProperties.has(key)||(this.extraProperties[key]=val)}}exports.FromCloudFormationPropertyObject=FromCloudFormationPropertyObject;class FromCloudFormation{static getAny(value){return new FromCloudFormationResult(value)}static getBoolean(value){if(typeof value=="string")switch(value){case"true":return new FromCloudFormationResult(!0);case"false":return new FromCloudFormationResult(!1);default:throw new Error(`Expected 'true' or 'false' for boolean value, got: '${value}'`)}return new FromCloudFormationResult(value)}static getDate(value){return(0,token_1().isResolvableObject)(value)?new FromCloudFormationResult(value):typeof value=="string"?new FromCloudFormationResult(new Date(value)):new FromCloudFormationResult(value)}static getString(value){return(0,token_1().isResolvableObject)(value)?new FromCloudFormationResult(value.toString()):typeof value=="number"?new FromCloudFormationResult(value.toString()):typeof value=="boolean"?new FromCloudFormationResult(value.toString()):new FromCloudFormationResult(value)}static getNumber(value){if((0,token_1().isResolvableObject)(value))return new FromCloudFormationResult(token_1().Token.asNumber(value));if(typeof value=="string"){const parsedValue=parseFloat(value);if(!isNaN(parsedValue))return new FromCloudFormationResult(parsedValue)}return new FromCloudFormationResult(value)}static getStringArray(value){return(0,token_1().isResolvableObject)(value)?new FromCloudFormationResult(token_1().Token.asList(value)):this.getArray(this.getString)(value)}static getArray(mapper){return value=>{if(!Array.isArray(value))return new FromCloudFormationResult(value);const values=new Array,ret=new FromCloudFormationResult(values);for(let i=0;i<value.length;i++){const result=mapper(value[i]);values.push(result.value),ret.appendExtraProperties(`${i}`,result.extraProperties)}return ret}}static getMap(mapper){return value=>{if(typeof value!="object")return new FromCloudFormationResult(value);const values={},ret=new FromCloudFormationResult(values);for(const[key,val]of Object.entries(value)){const result=mapper(val);values[key]=result.value,ret.appendExtraProperties(key,result.extraProperties)}return ret}}static getCfnTag(tag){return tag==null?new FromCloudFormationResult({}):new FromCloudFormationResult({key:tag.Key,value:tag.Value})}static getTypeUnion(validators,mappers){return value=>{for(let i=0;i<validators.length;i++){const candidate=mappers[i](value);if(validators[i](candidate.value).isSuccess)return candidate}return new FromCloudFormationResult(value)}}}exports.FromCloudFormation=FromCloudFormation;var CfnParsingContext;(function(CfnParsingContext2){CfnParsingContext2[CfnParsingContext2.CONDITIONS=0]="CONDITIONS",CfnParsingContext2[CfnParsingContext2.RULES=1]="RULES"})(CfnParsingContext||(exports.CfnParsingContext=CfnParsingContext={}));class CfnParser{constructor(options){this.options=options}handleAttributes(resource,resourceAttributes,logicalId){const cfnOptions=resource.cfnOptions;if(cfnOptions.creationPolicy=this.parseCreationPolicy(resourceAttributes.CreationPolicy),cfnOptions.updatePolicy=this.parseUpdatePolicy(resourceAttributes.UpdatePolicy),cfnOptions.deletionPolicy=this.parseDeletionPolicy(resourceAttributes.DeletionPolicy),cfnOptions.updateReplacePolicy=this.parseDeletionPolicy(resourceAttributes.UpdateReplacePolicy),cfnOptions.version=this.parseValue(resourceAttributes.Version),cfnOptions.description=this.parseValue(resourceAttributes.Description),cfnOptions.metadata=this.parseValue(resourceAttributes.Metadata),resourceAttributes.Condition){const condition=this.finder.findCondition(resourceAttributes.Condition);if(!condition)throw new Error(`Resource '${logicalId}' uses Condition '${resourceAttributes.Condition}' that doesn't exist`);cfnOptions.condition=condition}resourceAttributes.DependsOn=resourceAttributes.DependsOn??[];const dependencies=Array.isArray(resourceAttributes.DependsOn)?resourceAttributes.DependsOn:[resourceAttributes.DependsOn];for(const dep of dependencies){const depResource=this.finder.findResource(dep);if(!depResource)throw new Error(`Resource '${logicalId}' depends on '${dep}' that doesn't exist`);resource.node.addDependency(depResource)}}parseCreationPolicy(policy){if(typeof policy!="object")return;return policy=this.parseValue(policy),(0,util_1().undefinedIfAllValuesAreEmpty)({autoScalingCreationPolicy:parseAutoScalingCreationPolicy(policy.AutoScalingCreationPolicy),resourceSignal:parseResourceSignal(policy.ResourceSignal)});function parseAutoScalingCreationPolicy(p){if(typeof p=="object")return(0,util_1().undefinedIfAllValuesAreEmpty)({minSuccessfulInstancesPercent:FromCloudFormation.getNumber(p.MinSuccessfulInstancesPercent).value})}function parseResourceSignal(p){if(typeof p=="object")return(0,util_1().undefinedIfAllValuesAreEmpty)({count:FromCloudFormation.getNumber(p.Count).value,timeout:FromCloudFormation.getString(p.Timeout).value})}}parseUpdatePolicy(policy){if(typeof policy!="object")return;return policy=this.parseValue(policy),(0,util_1().undefinedIfAllValuesAreEmpty)({autoScalingReplacingUpdate:parseAutoScalingReplacingUpdate(policy.AutoScalingReplacingUpdate),autoScalingRollingUpdate:parseAutoScalingRollingUpdate(policy.AutoScalingRollingUpdate),autoScalingScheduledAction:parseAutoScalingScheduledAction(policy.AutoScalingScheduledAction),codeDeployLambdaAliasUpdate:parseCodeDeployLambdaAliasUpdate(policy.CodeDeployLambdaAliasUpdate),enableVersionUpgrade:FromCloudFormation.getBoolean(policy.EnableVersionUpgrade).value,useOnlineResharding:FromCloudFormation.getBoolean(policy.UseOnlineResharding).value});function parseAutoScalingReplacingUpdate(p){if(typeof p=="object")return(0,util_1().undefinedIfAllValuesAreEmpty)({willReplace:p.WillReplace})}function parseAutoScalingRollingUpdate(p){if(typeof p=="object")return(0,util_1().undefinedIfAllValuesAreEmpty)({maxBatchSize:FromCloudFormation.getNumber(p.MaxBatchSize).value,minInstancesInService:FromCloudFormation.getNumber(p.MinInstancesInService).value,minSuccessfulInstancesPercent:FromCloudFormation.getNumber(p.MinSuccessfulInstancesPercent).value,pauseTime:FromCloudFormation.getString(p.PauseTime).value,suspendProcesses:FromCloudFormation.getStringArray(p.SuspendProcesses).value,waitOnResourceSignals:FromCloudFormation.getBoolean(p.WaitOnResourceSignals).value})}function parseCodeDeployLambdaAliasUpdate(p){if(typeof p=="object")return{beforeAllowTrafficHook:FromCloudFormation.getString(p.BeforeAllowTrafficHook).value,afterAllowTrafficHook:FromCloudFormation.getString(p.AfterAllowTrafficHook).value,applicationName:FromCloudFormation.getString(p.ApplicationName).value,deploymentGroupName:FromCloudFormation.getString(p.DeploymentGroupName).value}}function parseAutoScalingScheduledAction(p){if(typeof p=="object")return(0,util_1().undefinedIfAllValuesAreEmpty)({ignoreUnmodifiedGroupSizeProperties:FromCloudFormation.getBoolean(p.IgnoreUnmodifiedGroupSizeProperties).value})}}parseDeletionPolicy(policy){if(policy==null)return;const isIntrinsic=this.looksLikeCfnIntrinsic(policy);switch(policy){case"Delete":return cfn_resource_policy_1().CfnDeletionPolicy.DELETE;case"Retain":return cfn_resource_policy_1().CfnDeletionPolicy.RETAIN;case"Snapshot":return cfn_resource_policy_1().CfnDeletionPolicy.SNAPSHOT;case"RetainExceptOnCreate":return cfn_resource_policy_1().CfnDeletionPolicy.RETAIN_EXCEPT_ON_CREATE;default:if(isIntrinsic)return policy=this.parseValue(policy),policy;throw new Error(`Unrecognized DeletionPolicy '${policy}'`)}}parseValue(cfnValue){if(cfnValue!=null){if((0,token_1().isResolvableObject)(cfnValue))return cfnValue;if(Array.isArray(cfnValue))return cfnValue.map(el=>this.parseValue(el));if(typeof cfnValue=="object"){const cfnIntrinsic=this.parseIfCfnIntrinsic(cfnValue);if(cfnIntrinsic!==void 0)return cfnIntrinsic;const ret={};for(const[key,val]of Object.entries(cfnValue))ret[key]=this.parseValue(val);return ret}return cfnValue}}get finder(){return this.options.finder}parseIfCfnIntrinsic(object){const key=this.looksLikeCfnIntrinsic(object);switch(key){case void 0:return;case"Ref":{const refTarget=object[key],specialRef=this.specialCaseRefs(refTarget);if(specialRef!==void 0)return specialRef;{const refElement=this.finder.findRefTarget(refTarget);if(!refElement)throw new Error(`Element used in Ref expression with logical ID: '${refTarget}' not found`);return cfn_reference_1().CfnReference.for(refElement,"Ref")}}case"Fn::GetAtt":{const value=object[key];let logicalId,attributeName,stringForm;if(typeof value=="string"){const dotIndex=value.indexOf(".");if(dotIndex===-1)throw new Error(`Short-form Fn::GetAtt must contain a '.' in its string argument, got: '${value}'`);logicalId=value.slice(0,dotIndex),attributeName=value.slice(dotIndex+1),stringForm=!0}else logicalId=value[0],attributeName=value[1],stringForm=!1;const target=this.finder.findResource(logicalId);if(!target)throw new Error(`Resource used in GetAtt expression with logical ID: '${logicalId}' not found`);return cfn_reference_1().CfnReference.for(target,attributeName,stringForm?cfn_reference_1().ReferenceRendering.GET_ATT_STRING:void 0)}case"Fn::Join":{const value=this.parseValue(object[key]);return cfn_fn_1().Fn.join(value[0],lazy_1().Lazy.list({produce:()=>value[1]}))}case"Fn::Cidr":{const value=this.parseValue(object[key]);return cfn_fn_1().Fn.cidr(value[0],value[1],value[2])}case"Fn::FindInMap":{const value=this.parseValue(object[key]);let mappingName;if(token_1().Token.isUnresolved(value[0]))mappingName=value[0];else{const mapping=this.finder.findMapping(value[0]);if(!mapping)throw new Error(`Mapping used in FindInMap expression with name '${value[0]}' was not found in the template`);mappingName=mapping.logicalId}return cfn_fn_1().Fn._findInMap(mappingName,value[1],value[2])}case"Fn::Select":{const value=this.parseValue(object[key]);return cfn_fn_1().Fn.select(value[0],value[1])}case"Fn::GetAZs":{const value=this.parseValue(object[key]);return cfn_fn_1().Fn.getAzs(value)}case"Fn::ImportValue":{const value=this.parseValue(object[key]);return cfn_fn_1().Fn.importValue(value)}case"Fn::Split":{const value=this.parseValue(object[key]);return cfn_fn_1().Fn.split(value[0],value[1])}case"Fn::Transform":{const value=this.parseValue(object[key]);return cfn_fn_1().Fn.transform(value.Name,value.Parameters)}case"Fn::Base64":{const value=this.parseValue(object[key]);return cfn_fn_1().Fn.base64(value)}case"Fn::If":{const value=this.parseValue(object[key]),condition=this.finder.findCondition(value[0]);if(!condition)throw new Error(`Condition '${value[0]}' used in an Fn::If expression does not exist in the template`);return cfn_fn_1().Fn.conditionIf(condition.logicalId,value[1],value[2])}case"Fn::Equals":{const value=this.parseValue(object[key]);return cfn_fn_1().Fn.conditionEquals(value[0],value[1])}case"Fn::And":{const value=this.parseValue(object[key]);return cfn_fn_1().Fn.conditionAnd(...value)}case"Fn::Not":{const value=this.parseValue(object[key]);return cfn_fn_1().Fn.conditionNot(value[0])}case"Fn::Or":{const value=this.parseValue(object[key]);return cfn_fn_1().Fn.conditionOr(...value)}case"Fn::Sub":{const value=this.parseValue(object[key]);let fnSubString,map;return typeof value=="string"?(fnSubString=value,map=void 0):(fnSubString=value[0],map=value[1]),this.parseFnSubString(fnSubString,map)}case"Condition":{const condition=this.finder.findCondition(object[key]);if(!condition)throw new Error(`Referenced Condition with name '${object[key]}' was not found in the template`);return{Condition:condition.logicalId}}default:if(this.options.context===CfnParsingContext.RULES)return this.handleRulesIntrinsic(key,object);throw new Error(`Unsupported CloudFormation function '${key}'`)}}looksLikeCfnIntrinsic(object){const objectKeys=Object.keys(object);if(objectKeys.length!==1)return;const key=objectKeys[0];return key==="Ref"||key.startsWith("Fn::")||this.options.context===CfnParsingContext.CONDITIONS&&key==="Condition"?key:void 0}parseFnSubString(templateString,expressionMap){const map=expressionMap??{},self=this;return cfn_fn_1().Fn.sub(go(templateString),Object.keys(map).length===0?expressionMap:map);function go(value){const leftBrace=value.indexOf("${");if(leftBrace===-1)return value;const rightBrace=value.indexOf("}",leftBrace);if(rightBrace===-1)return value;const leftHalf=value.substring(0,leftBrace),rightHalf=value.substring(rightBrace+1),refTarget=value.substring(leftBrace+2,rightBrace).trim();if(refTarget[0]==="!")return value.substring(0,rightBrace+1)+go(rightHalf);if(refTarget in map)return leftHalf+"${"+refTarget+"}"+go(rightHalf);const specialRef=self.specialCaseSubRefs(refTarget);if(specialRef!==void 0)return token_1().Token.isUnresolved(specialRef)?(map[refTarget]=specialRef,leftHalf+"${"+refTarget+"}"+go(rightHalf)):leftHalf+specialRef+go(rightHalf);const dotIndex=refTarget.indexOf(".");if(dotIndex===-1){const refElement=self.finder.findRefTarget(refTarget);if(!refElement)throw new Error(`Element referenced in Fn::Sub expression with logical ID: '${refTarget}' was not found in the template`);return leftHalf+cfn_reference_1().CfnReference.for(refElement,"Ref",cfn_reference_1().ReferenceRendering.FN_SUB).toString()+go(rightHalf)}else{const targetId=refTarget.substring(0,dotIndex),refResource=self.finder.findResource(targetId);if(!refResource)throw new Error(`Resource referenced in Fn::Sub expression with logical ID: '${targetId}' was not found in the template`);const attribute=refTarget.substring(dotIndex+1);return leftHalf+cfn_reference_1().CfnReference.for(refResource,attribute,cfn_reference_1().ReferenceRendering.FN_SUB).toString()+go(rightHalf)}}}handleRulesIntrinsic(key,object){switch(key){case"Fn::ValueOf":{const value=this.parseValue(object[key]),parameterName=value[0];if(parameterName in this.parameters)throw new Error(`Cannot substitute parameter '${parameterName}' used in Fn::ValueOf expression with attribute '${value[1]}'`);const param=this.finder.findRefTarget(parameterName);if(!param)throw new Error(`Rule references parameter '${parameterName}' which was not found in the template`);return lazy_1().Lazy.any({produce:()=>({"Fn::ValueOf":[param.logicalId,value[1]]})})}default:return}}specialCaseRefs(value){if(value in this.parameters)return this.parameters[value];switch(value){case"AWS::AccountId":return cfn_pseudo_1().Aws.ACCOUNT_ID;case"AWS::Region":return cfn_pseudo_1().Aws.REGION;case"AWS::Partition":return cfn_pseudo_1().Aws.PARTITION;case"AWS::URLSuffix":return cfn_pseudo_1().Aws.URL_SUFFIX;case"AWS::NotificationARNs":return cfn_pseudo_1().Aws.NOTIFICATION_ARNS;case"AWS::StackId":return cfn_pseudo_1().Aws.STACK_ID;case"AWS::StackName":return cfn_pseudo_1().Aws.STACK_NAME;case"AWS::NoValue":return cfn_pseudo_1().Aws.NO_VALUE;default:return}}specialCaseSubRefs(value){return value in this.parameters?this.parameters[value]:value.indexOf("::")===-1?void 0:"${"+value+"}"}get parameters(){return this.options.parameters||{}}}exports.CfnParser=CfnParser;