UNPKG

aws-cdk-lib

Version:

Version 2 of the AWS Cloud Development Kit library

2 lines (1 loc) 19.6 kB
"use strict";var __decorate=exports&&exports.__decorate||function(decorators,target,key,desc){var c=arguments.length,r=c<3?target:desc===null?desc=Object.getOwnPropertyDescriptor(target,key):desc,d;if(typeof Reflect=="object"&&typeof Reflect.decorate=="function")r=Reflect.decorate(decorators,target,key,desc);else for(var i=decorators.length-1;i>=0;i--)(d=decorators[i])&&(r=(c<3?d(r):c>3?d(target,key,r):d(target,key))||r);return c>3&&r&&Object.defineProperty(target,key,r),r},_a;Object.defineProperty(exports,"__esModule",{value:!0}),exports.TableV2=void 0;var jsiiDeprecationWarnings=()=>{var tmp=require("../../.warnings.jsii.js");return jsiiDeprecationWarnings=()=>tmp,tmp};const JSII_RTTI_SYMBOL_1=Symbol.for("jsii.rtti");var dynamodb_generated_1=()=>{var tmp=require("./dynamodb.generated");return dynamodb_generated_1=()=>tmp,tmp},shared_1=()=>{var tmp=require("./shared");return shared_1=()=>tmp,tmp},table_v2_base_1=()=>{var tmp=require("./table-v2-base");return table_v2_base_1=()=>tmp,tmp},aws_kms_1=()=>{var tmp=require("../../aws-kms");return aws_kms_1=()=>tmp,tmp},core_1=()=>{var tmp=require("../../core");return core_1=()=>tmp,tmp},errors_1=()=>{var tmp=require("../../core/lib/errors");return errors_1=()=>tmp,tmp},metadata_resource_1=()=>{var tmp=require("../../core/lib/metadata-resource");return metadata_resource_1=()=>tmp,tmp},cxapi=()=>{var tmp=require("../../cx-api");return cxapi=()=>tmp,tmp};const HASH_KEY_TYPE="HASH",RANGE_KEY_TYPE="RANGE",MAX_GSI_COUNT=20,MAX_LSI_COUNT=5,MAX_NON_KEY_ATTRIBUTES=100;class TableV2 extends table_v2_base_1().TableBaseV2{static fromTableName(scope,id,tableName){return TableV2.fromTableAttributes(scope,id,{tableName})}static fromTableArn(scope,id,tableArn){return TableV2.fromTableAttributes(scope,id,{tableArn})}static fromTableAttributes(scope,id,attrs){try{jsiiDeprecationWarnings().aws_cdk_lib_aws_dynamodb_TableAttributesV2(attrs)}catch(error){throw process.env.JSII_DEBUG!=="1"&&error.name==="DeprecationError"&&Error.captureStackTrace(error,this.fromTableAttributes),error}class Import extends table_v2_base_1().TableBaseV2{constructor(tableArn2,tableName2,tableId,tableStreamArn,resourcePolicy){super(scope,id,{environmentFromArn:tableArn2}),this.hasIndex=(attrs.grantIndexPermissions??!1)||(attrs.globalIndexes??[]).length>0||(attrs.localIndexes??[]).length>0;const resourceRegion=stack.splitArn(tableArn2,core_1().ArnFormat.SLASH_RESOURCE_NAME).region;if(!resourceRegion)throw new Error("Table ARN must be of the form: arn:<partition>:dynamodb:<region>:<account>:table/<table-name>");this.region=resourceRegion,this.tableArn=tableArn2,this.tableName=tableName2,this.tableId=tableId,this.tableStreamArn=tableStreamArn,this.encryptionKey=attrs.encryptionKey,this.resourcePolicy=resourcePolicy}}let tableName,tableArn;const stack=core_1().Stack.of(scope);if(attrs.tableArn){if(attrs.tableName)throw new Error("Only one of `tableArn` or `tableName` can be provided, but not both");tableArn=attrs.tableArn;const resourceName=stack.splitArn(tableArn,core_1().ArnFormat.SLASH_RESOURCE_NAME).resourceName;if(!resourceName)throw new Error("Table ARN must be of the form: arn:<partition>:dynamodb:<region>:<account>:table/<table-name>");tableName=resourceName}else{if(!attrs.tableName)throw new Error("At least one of `tableArn` or `tableName` must be provided");tableName=attrs.tableName,tableArn=stack.formatArn({service:"dynamodb",resource:"table",resourceName:tableName})}return new Import(tableArn,tableName,attrs.tableId,attrs.tableStreamArn)}constructor(scope,id,props){super(scope,id,{physicalName:props.tableName??core_1().PhysicalName.GENERATE_IF_NEEDED}),this.keySchema=[],this.attributeDefinitions=[],this.nonKeyAttributes=new Set,this.replicaTables=new Map,this.replicaKeys={},this.replicaTableArns=[],this.replicaStreamArns=[],this.globalSecondaryIndexes=new Map,this.localSecondaryIndexes=new Map,this.globalSecondaryIndexReadCapacitys=new Map,this.globalSecondaryIndexMaxReadUnits=new Map;try{jsiiDeprecationWarnings().aws_cdk_lib_aws_dynamodb_TablePropsV2(props)}catch(error){throw process.env.JSII_DEBUG!=="1"&&error.name==="DeprecationError"&&Error.captureStackTrace(error,TableV2),error}(0,metadata_resource_1().addConstructMetadata)(this,props),this.tableOptions=props,this.partitionKey=props.partitionKey,this.hasSortKey=props.sortKey!==void 0,this.region=this.stack.region,this.tags=new(core_1()).TagManager(core_1().TagType.STANDARD,dynamodb_generated_1().CfnGlobalTable.CFN_RESOURCE_TYPE_NAME),this.encryption=props.encryption,this.encryptionKey=this.encryption?.tableKey,this.configureReplicaKeys(this.encryption?.replicaKeyArns),this.addKey(props.partitionKey,HASH_KEY_TYPE),props.sortKey&&this.addKey(props.sortKey,RANGE_KEY_TYPE),this.validatePitr(props),props.billing?.mode===shared_1().BillingMode.PAY_PER_REQUEST||props.billing?.mode===void 0?(this.maxReadRequestUnits=props.billing?._renderReadCapacity(),this.maxWriteRequestUnits=props.billing?._renderWriteCapacity(),this.billingMode=shared_1().BillingMode.PAY_PER_REQUEST):(this.readProvisioning=props.billing?._renderReadCapacity(),this.writeProvisioning=props.billing?._renderWriteCapacity(),this.billingMode=props.billing.mode),props.globalSecondaryIndexes?.forEach(gsi=>this.addGlobalSecondaryIndex(gsi)),props.localSecondaryIndexes?.forEach(lsi=>this.addLocalSecondaryIndex(lsi));const resource=new(dynamodb_generated_1()).CfnGlobalTable(this,"Resource",{tableName:this.physicalName,keySchema:this.keySchema,attributeDefinitions:core_1().Lazy.any({produce:()=>this.attributeDefinitions}),replicas:core_1().Lazy.any({produce:()=>this.renderReplicaTables()}),globalSecondaryIndexes:core_1().Lazy.any({produce:()=>this.renderGlobalIndexes()},{omitEmptyArray:!0}),localSecondaryIndexes:core_1().Lazy.any({produce:()=>this.renderLocalIndexes()},{omitEmptyArray:!0}),billingMode:this.billingMode,writeProvisionedThroughputSettings:this.writeProvisioning,writeOnDemandThroughputSettings:this.maxWriteRequestUnits?{maxWriteRequestUnits:this.maxWriteRequestUnits}:void 0,streamSpecification:core_1().Lazy.any({produce:()=>props.dynamoStream?{streamViewType:props.dynamoStream}:this.renderStreamSpecification()}),sseSpecification:this.encryption?._renderSseSpecification(),timeToLiveSpecification:props.timeToLiveAttribute?{attributeName:props.timeToLiveAttribute,enabled:!0}:void 0,warmThroughput:props.warmThroughput??void 0});resource.applyRemovalPolicy(props.removalPolicy),this.tableArn=this.getResourceArnAttribute(resource.attrArn,{service:"dynamodb",resource:"table",resourceName:this.physicalName}),this.tableName=this.getResourceNameAttribute(resource.ref),this.tableId=resource.attrTableId,this.tableStreamArn=resource.attrStreamArn,props.replicas?.forEach(replica=>this.addReplica(replica)),props.tableName&&this.node.addMetadata("aws:cdk:hasPhysicalName",this.tableName)}addReplica(props){try{jsiiDeprecationWarnings().aws_cdk_lib_aws_dynamodb_ReplicaTableProps(props)}catch(error){throw process.env.JSII_DEBUG!=="1"&&error.name==="DeprecationError"&&Error.captureStackTrace(error,this.addReplica),error}this.validateReplica(props);const replicaArn=this.stack.formatArn({region:props.region,resource:"table",service:"dynamodb",resourceName:this.tableName});this.replicaTableArns.push(replicaArn);const replicaStreamArn=`${replicaArn}/stream/*`;this.replicaStreamArns.push(replicaStreamArn),this.replicaTables.set(props.region,props)}addGlobalSecondaryIndex(props){try{jsiiDeprecationWarnings().aws_cdk_lib_aws_dynamodb_GlobalSecondaryIndexPropsV2(props)}catch(error){throw process.env.JSII_DEBUG!=="1"&&error.name==="DeprecationError"&&Error.captureStackTrace(error,this.addGlobalSecondaryIndex),error}this.validateGlobalSecondaryIndex(props);const globalSecondaryIndex=this.configureGlobalSecondaryIndex(props);this.globalSecondaryIndexes.set(props.indexName,globalSecondaryIndex)}addLocalSecondaryIndex(props){try{jsiiDeprecationWarnings().aws_cdk_lib_aws_dynamodb_LocalSecondaryIndexProps(props)}catch(error){throw process.env.JSII_DEBUG!=="1"&&error.name==="DeprecationError"&&Error.captureStackTrace(error,this.addLocalSecondaryIndex),error}this.validateLocalSecondaryIndex(props);const localSecondaryIndex=this.configureLocalSecondaryIndex(props);this.localSecondaryIndexes.set(props.indexName,localSecondaryIndex)}replica(region){if(core_1().Token.isUnresolved(this.stack.region))throw new Error("Replica tables are not supported in a region agnostic stack");if(core_1().Token.isUnresolved(region))throw new Error("Provided `region` cannot be a token");if(region===this.stack.region)return this;if(!this.replicaTables.has(region))throw new Error(`No replica table exists in region ${region}`);const replicaTableArn=this.replicaTableArns.find(arn=>arn.includes(region)),replicaStreamArn=this.replicaStreamArns.find(arn=>arn.includes(region));return TableV2.fromTableAttributes(this,`ReplicaTable${region}`,{tableArn:replicaTableArn,encryptionKey:this.replicaKeys[region],grantIndexPermissions:this.hasIndex,tableStreamArn:replicaStreamArn})}configureReplicaTable(props){const contributorInsights=props.contributorInsights??this.tableOptions.contributorInsights,pointInTimeRecovery=props.pointInTimeRecovery??this.tableOptions.pointInTimeRecovery,pointInTimeRecoverySpecification=props.pointInTimeRecoverySpecification??this.tableOptions.pointInTimeRecoverySpecification??(pointInTimeRecovery!==void 0?{pointInTimeRecoveryEnabled:pointInTimeRecovery}:void 0),resourcePolicy=core_1().FeatureFlags.of(this).isEnabled(cxapi().DYNAMODB_TABLEV2_RESOURCE_POLICY_PER_REPLICA)?(props.region===this.region?this.tableOptions.resourcePolicy:props.resourcePolicy)||void 0:props.resourcePolicy??this.tableOptions.resourcePolicy,propTags=(props.tags??[]).reduce((p,item)=>({...p,[item.key]:item.value}),{}),tags=Object.entries({...this.tags.tagValues(),...propTags}).map(([k,v])=>({key:k,value:v}));return{region:props.region,globalSecondaryIndexes:this.configureReplicaGlobalSecondaryIndexes(props.globalSecondaryIndexOptions),deletionProtectionEnabled:props.deletionProtection??this.tableOptions.deletionProtection,tableClass:props.tableClass??this.tableOptions.tableClass,sseSpecification:this.encryption?._renderReplicaSseSpecification(this,props.region),kinesisStreamSpecification:props.kinesisStream?{streamArn:props.kinesisStream.streamArn}:void 0,contributorInsightsSpecification:contributorInsights!==void 0?{enabled:contributorInsights}:void 0,pointInTimeRecoverySpecification,readProvisionedThroughputSettings:props.readCapacity?props.readCapacity._renderReadCapacity():this.readProvisioning,tags:tags.length===0?void 0:tags,readOnDemandThroughputSettings:props.maxReadRequestUnits?{maxReadRequestUnits:props.maxReadRequestUnits}:this.maxReadRequestUnits?{maxReadRequestUnits:this.maxReadRequestUnits}:void 0,resourcePolicy:resourcePolicy?{policyDocument:resourcePolicy}:void 0}}configureGlobalSecondaryIndex(props){const keySchema=this.configureIndexKeySchema(props.partitionKey,props.sortKey),projection=this.configureIndexProjection(props);props.readCapacity&&this.globalSecondaryIndexReadCapacitys.set(props.indexName,props.readCapacity);const writeProvisionedThroughputSettings=props.writeCapacity?props.writeCapacity._renderWriteCapacity():this.writeProvisioning;props.maxReadRequestUnits&&this.globalSecondaryIndexMaxReadUnits.set(props.indexName,props.maxReadRequestUnits);const warmThroughput=props.warmThroughput??void 0,writeOnDemandThroughputSettings=props.maxWriteRequestUnits?{maxWriteRequestUnits:props.maxWriteRequestUnits}:void 0;return{indexName:props.indexName,keySchema,projection,writeProvisionedThroughputSettings,writeOnDemandThroughputSettings,warmThroughput}}configureLocalSecondaryIndex(props){const keySchema=this.configureIndexKeySchema(this.partitionKey,props.sortKey),projection=this.configureIndexProjection(props);return{indexName:props.indexName,keySchema,projection}}configureReplicaGlobalSecondaryIndexes(options={}){this.validateReplicaIndexOptions(options);const replicaGlobalSecondaryIndexes=[],indexNamesFromOptions=Object.keys(options);for(const gsi of this.globalSecondaryIndexes.values()){const indexName=gsi.indexName;let contributorInsights=this.tableOptions.contributorInsights,readCapacity=this.globalSecondaryIndexReadCapacitys.get(indexName),maxReadRequestUnits=this.globalSecondaryIndexMaxReadUnits.get(indexName);if(indexNamesFromOptions.includes(indexName)){const indexOptions=options[indexName];contributorInsights=indexOptions.contributorInsights,readCapacity=indexOptions.readCapacity,maxReadRequestUnits=indexOptions.maxReadRequestUnits}const readProvisionedThroughputSettings=readCapacity?._renderReadCapacity()??this.readProvisioning,readOnDemandThroughputSettings=maxReadRequestUnits?{maxReadRequestUnits}:void 0;replicaGlobalSecondaryIndexes.push({indexName,readProvisionedThroughputSettings,readOnDemandThroughputSettings,contributorInsightsSpecification:contributorInsights!==void 0?{enabled:contributorInsights}:void 0})}return replicaGlobalSecondaryIndexes.length>0?replicaGlobalSecondaryIndexes:void 0}configureIndexKeySchema(partitionKey,sortKey){this.addAttributeDefinition(partitionKey);const indexKeySchema=[{attributeName:partitionKey.name,keyType:HASH_KEY_TYPE}];return sortKey&&(this.addAttributeDefinition(sortKey),indexKeySchema.push({attributeName:sortKey.name,keyType:RANGE_KEY_TYPE})),indexKeySchema}configureIndexProjection(props){if(this.validateIndexProjection(props),props.nonKeyAttributes?.forEach(attr=>this.nonKeyAttributes.add(attr)),this.nonKeyAttributes.size>MAX_NON_KEY_ATTRIBUTES)throw new Error(`The maximum number of 'nonKeyAttributes' across all secondary indexes is ${MAX_NON_KEY_ATTRIBUTES}`);return{projectionType:props.projectionType??shared_1().ProjectionType.ALL,nonKeyAttributes:props.nonKeyAttributes??void 0}}configureReplicaKeys(replicaKeyArns={}){for(const[region,keyArn]of Object.entries(replicaKeyArns))this.replicaKeys[region]=aws_kms_1().Key.fromKeyArn(this,`ReplicaKey${region}`,keyArn)}renderReplicaTables(){const replicaTables=[];for(const replicaTable of this.replicaTables.values())replicaTables.push(this.configureReplicaTable(replicaTable));return replicaTables.push(this.configureReplicaTable({region:this.stack.region,kinesisStream:this.tableOptions.kinesisStream,tags:this.tableOptions.tags})),replicaTables}renderGlobalIndexes(){const globalSecondaryIndexes=[];for(const globalSecondaryIndex of this.globalSecondaryIndexes.values())globalSecondaryIndexes.push(globalSecondaryIndex);return globalSecondaryIndexes}renderLocalIndexes(){const localSecondaryIndexes=[];for(const localSecondaryIndex of this.localSecondaryIndexes.values())localSecondaryIndexes.push(localSecondaryIndex);return localSecondaryIndexes}renderStreamSpecification(){return this.replicaTables.size>0?{streamViewType:shared_1().StreamViewType.NEW_AND_OLD_IMAGES}:void 0}addKey(key,keyType){this.addAttributeDefinition(key),this.keySchema.push({attributeName:key.name,keyType})}addAttributeDefinition(attribute){const{name,type}=attribute,existingAttributeDef=this.attributeDefinitions.find(def=>def.attributeName===name);if(existingAttributeDef&&existingAttributeDef.attributeType!==type)throw new Error(`Unable to specify ${name} as ${type} because it was already defined as ${existingAttributeDef.attributeType}`);existingAttributeDef||this.attributeDefinitions.push({attributeName:name,attributeType:type})}get hasIndex(){return this.globalSecondaryIndexes.size+this.localSecondaryIndexes.size>0}validateIndexName(indexName){if(this.globalSecondaryIndexes.has(indexName)||this.localSecondaryIndexes.has(indexName))throw new Error(`Duplicate secondary index name, ${indexName}, is not allowed`)}validateIndexProjection(props){if(props.projectionType===shared_1().ProjectionType.INCLUDE&&!props.nonKeyAttributes)throw new Error(`Non-key attributes should be specified when using ${shared_1().ProjectionType.INCLUDE} projection type`);if(props.projectionType!==shared_1().ProjectionType.INCLUDE&&props.nonKeyAttributes)throw new Error(`Non-key attributes should not be specified when not using ${shared_1().ProjectionType.INCLUDE} projection type`)}validateReplicaIndexOptions(options){for(const indexName of Object.keys(options)){if(!this.globalSecondaryIndexes.has(indexName))throw new Error(`Cannot configure replica global secondary index, ${indexName}, because it is not defined on the primary table`);const replicaGsiOptions=options[indexName];if(this.billingMode===shared_1().BillingMode.PAY_PER_REQUEST&&replicaGsiOptions.readCapacity)throw new Error(`Cannot configure 'readCapacity' for replica global secondary index, ${indexName}, because billing mode is ${shared_1().BillingMode.PAY_PER_REQUEST}`)}}validateReplica(props){const stackRegion=this.stack.region;if(core_1().Token.isUnresolved(stackRegion))throw new Error("Replica tables are not supported in a region agnostic stack");if(core_1().Token.isUnresolved(props.region))throw new Error("Replica table region must not be a token");if(props.region===this.stack.region)throw new Error(`You cannot add a replica table in the same region as the primary table - the primary table region is ${this.region}`);if(this.replicaTables.has(props.region))throw new Error(`Duplicate replica table region, ${props.region}, is not allowed`);if(this.billingMode===shared_1().BillingMode.PAY_PER_REQUEST&&props.readCapacity)throw new Error(`You cannot provide 'readCapacity' on a replica table when the billing mode is ${shared_1().BillingMode.PAY_PER_REQUEST}`)}validateGlobalSecondaryIndex(props){if(this.validateIndexName(props.indexName),this.globalSecondaryIndexes.size===MAX_GSI_COUNT)throw new Error(`You may not provide more than ${MAX_GSI_COUNT} global secondary indexes`);if(this.billingMode===shared_1().BillingMode.PAY_PER_REQUEST&&(props.readCapacity||props.writeCapacity))throw new Error(`You cannot configure 'readCapacity' or 'writeCapacity' on a global secondary index when the billing mode is ${shared_1().BillingMode.PAY_PER_REQUEST}`)}validateLocalSecondaryIndex(props){if(this.validateIndexName(props.indexName),!this.hasSortKey)throw new Error("The table must have a sort key in order to add a local secondary index");if(this.localSecondaryIndexes.size===MAX_LSI_COUNT)throw new Error(`You may not provide more than ${MAX_LSI_COUNT} local secondary indexes`)}validatePitr(props){const recoveryPeriodInDays=props.pointInTimeRecoverySpecification?.recoveryPeriodInDays;if(props.pointInTimeRecovery!==void 0&&props.pointInTimeRecoverySpecification!==void 0)throw new(errors_1()).ValidationError("`pointInTimeRecoverySpecification` and `pointInTimeRecovery` are set. Use `pointInTimeRecoverySpecification` only.",this);if(!props.pointInTimeRecoverySpecification?.pointInTimeRecoveryEnabled&&recoveryPeriodInDays)throw new(errors_1()).ValidationError("Cannot set `recoveryPeriodInDays` while `pointInTimeRecoveryEnabled` is set to false.",this);if(recoveryPeriodInDays!==void 0&&(recoveryPeriodInDays<1||recoveryPeriodInDays>35))throw new(errors_1()).ValidationError("`recoveryPeriodInDays` must be a value between `1` and `35`.",this)}}exports.TableV2=TableV2,_a=JSII_RTTI_SYMBOL_1,TableV2[_a]={fqn:"aws-cdk-lib.aws_dynamodb.TableV2",version:"2.185.0"},__decorate([(0,metadata_resource_1().MethodMetadata)()],TableV2.prototype,"addReplica",null),__decorate([(0,metadata_resource_1().MethodMetadata)()],TableV2.prototype,"addGlobalSecondaryIndex",null),__decorate([(0,metadata_resource_1().MethodMetadata)()],TableV2.prototype,"addLocalSecondaryIndex",null),__decorate([(0,metadata_resource_1().MethodMetadata)()],TableV2.prototype,"replica",null);