UNPKG

@aws-cdk/core

Version:

AWS Cloud Development Kit Core Library

121 lines 15.5 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const reference_1 = require("../reference"); const CFN_REFERENCE_SYMBOL = Symbol.for('@aws-cdk/core.CfnReference'); /** * A Token that represents a CloudFormation reference to another resource * * If these references are used in a different stack from where they are * defined, appropriate CloudFormation `Export`s and `Fn::ImportValue`s will be * synthesized automatically instead of the regular CloudFormation references. * * Additionally, the dependency between the stacks will be recorded, and the toolkit * will make sure to deploy producing stack before the consuming stack. * * This magic happens in the prepare() phase, where consuming stacks will call * `consumeFromStack` on these Tokens and if they happen to be exported by a different * Stack, we'll register the dependency. */ class CfnReference extends reference_1.Reference { constructor(value, displayName, target) { // prepend scope path to display name super(value, target, displayName); this.replacementTokens = new Map(); this.targetStack = stack_1.Stack.of(target); Object.defineProperty(this, CFN_REFERENCE_SYMBOL, { value: true }); } /** * Check whether this is actually a Reference */ static isCfnReference(x) { return CFN_REFERENCE_SYMBOL in x; } /** * Return the CfnReference for the indicated target * * Will make sure that multiple invocations for the same target and intrinsic * return the same CfnReference. Because CfnReferences accumulate state in * the prepare() phase (for the purpose of cross-stack references), it's * important that the state isn't lost if it's lazily created, like so: * * Lazy.stringValue({ produce: () => new CfnReference(...) }) */ static for(target, attribute) { return CfnReference.singletonReference(target, attribute, () => { const cfnIntrinsic = attribute === 'Ref' ? { Ref: target.logicalId } : { 'Fn::GetAtt': [target.logicalId, attribute] }; return new CfnReference(cfnIntrinsic, attribute, target); }); } /** * Return a CfnReference that references a pseudo referencd */ static forPseudo(pseudoName, scope) { return CfnReference.singletonReference(scope, `Pseudo:${pseudoName}`, () => { const cfnIntrinsic = { Ref: pseudoName }; return new CfnReference(cfnIntrinsic, pseudoName, scope); }); } /** * Get or create the table */ static singletonReference(target, attribKey, fresh) { let attribs = CfnReference.referenceTable.get(target); if (!attribs) { attribs = new Map(); CfnReference.referenceTable.set(target, attribs); } let ref = attribs.get(attribKey); if (!ref) { ref = fresh(); attribs.set(attribKey, ref); } return ref; } resolve(context) { // If we have a special token for this consuming stack, resolve that. Otherwise resolve as if // we are in the same stack. const consumingStack = stack_1.Stack.of(context.scope); const token = this.replacementTokens.get(consumingStack); // if (!token && this.isCrossStackReference(consumingStack) && !context.preparing) { // tslint:disable-next-line:max-line-length // throw new Error(`Cross-stack reference (${context.scope.node.path} -> ${this.target.node.path}) has not been assigned a value--call prepare() first`); // } if (token) { return token.resolve(context); } else { return super.resolve(context); } } hasValueForStack(stack) { if (stack === this.targetStack) { return true; } return this.replacementTokens.has(stack); } assignValueForStack(stack, value) { if (stack === this.targetStack) { throw new Error('cannot assign a value for the same stack'); } if (this.hasValueForStack(stack)) { throw new Error('Cannot assign a reference value twice to the same stack. Use hasValueForStack to check first'); } this.replacementTokens.set(stack, value); } /** * Implementation of toString() that will use the display name */ toString() { return token_1.Token.asString(this, { displayHint: `${this.target.node.id}.${this.displayName}`, }); } } exports.CfnReference = CfnReference; /** * Static table where we keep singleton CfnReference instances */ CfnReference.referenceTable = new Map(); const stack_1 = require("../stack"); const token_1 = require("../token"); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2ZuLXJlZmVyZW5jZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbImNmbi1yZWZlcmVuY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSw0Q0FBeUM7QUFFekMsTUFBTSxvQkFBb0IsR0FBRyxNQUFNLENBQUMsR0FBRyxDQUFDLDRCQUE0QixDQUFDLENBQUM7QUFFdEU7Ozs7Ozs7Ozs7Ozs7R0FhRztBQUNILE1BQWEsWUFBYSxTQUFRLHFCQUFTO0lBK0R6QyxZQUFzQixLQUFVLEVBQUUsV0FBbUIsRUFBRSxNQUFrQjtRQUN2RSxxQ0FBcUM7UUFDckMsS0FBSyxDQUFDLEtBQUssRUFBRSxNQUFNLEVBQUUsV0FBVyxDQUFDLENBQUM7UUFFbEMsSUFBSSxDQUFDLGlCQUFpQixHQUFHLElBQUksR0FBRyxFQUFzQixDQUFDO1FBQ3ZELElBQUksQ0FBQyxXQUFXLEdBQUcsYUFBSyxDQUFDLEVBQUUsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUVwQyxNQUFNLENBQUMsY0FBYyxDQUFDLElBQUksRUFBRSxvQkFBb0IsRUFBRSxFQUFFLEtBQUssRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO0lBQ3JFLENBQUM7SUF0RUQ7O09BRUc7SUFDSSxNQUFNLENBQUMsY0FBYyxDQUFDLENBQWM7UUFDekMsT0FBTyxvQkFBb0IsSUFBSSxDQUFDLENBQUM7SUFDbkMsQ0FBQztJQUVEOzs7Ozs7Ozs7T0FTRztJQUNJLE1BQU0sQ0FBQyxHQUFHLENBQUMsTUFBa0IsRUFBRSxTQUFpQjtRQUNyRCxPQUFPLFlBQVksQ0FBQyxrQkFBa0IsQ0FBQyxNQUFNLEVBQUUsU0FBUyxFQUFFLEdBQUcsRUFBRTtZQUM3RCxNQUFNLFlBQVksR0FBRyxTQUFTLEtBQUssS0FBSyxDQUFDLENBQUMsQ0FBQyxFQUFFLEdBQUcsRUFBRSxNQUFNLENBQUMsU0FBUyxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsWUFBWSxFQUFFLENBQUUsTUFBTSxDQUFDLFNBQVMsRUFBRSxTQUFTLENBQUUs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QUFDO0lBQ0wsQ0FBQzs7QUFySEgsb0NBc0hDO0FBbkZDOztHQUVHO0FBQ1ksMkJBQWMsR0FBRyxJQUFJLEdBQUcsRUFBd0MsQ0FBQztBQXFGbEYsb0NBQWlDO0FBQ2pDLG9DQUFpQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFJlZmVyZW5jZSB9IGZyb20gJy4uL3JlZmVyZW5jZSc7XG5cbmNvbnN0IENGTl9SRUZFUkVOQ0VfU1lNQk9MID0gU3ltYm9sLmZvcignQGF3cy1jZGsvY29yZS5DZm5SZWZlcmVuY2UnKTtcblxuLyoqXG4gKiBBIFRva2VuIHRoYXQgcmVwcmVzZW50cyBhIENsb3VkRm9ybWF0aW9uIHJlZmVyZW5jZSB0byBhbm90aGVyIHJlc291cmNlXG4gKlxuICogSWYgdGhlc2UgcmVmZXJlbmNlcyBhcmUgdXNlZCBpbiBhIGRpZmZlcmVudCBzdGFjayBmcm9tIHdoZXJlIHRoZXkgYXJlXG4gKiBkZWZpbmVkLCBhcHByb3ByaWF0ZSBDbG91ZEZvcm1hdGlvbiBgRXhwb3J0YHMgYW5kIGBGbjo6SW1wb3J0VmFsdWVgcyB3aWxsIGJlXG4gKiBzeW50aGVzaXplZCBhdXRvbWF0aWNhbGx5IGluc3RlYWQgb2YgdGhlIHJlZ3VsYXIgQ2xvdWRGb3JtYXRpb24gcmVmZXJlbmNlcy5cbiAqXG4gKiBBZGRpdGlvbmFsbHksIHRoZSBkZXBlbmRlbmN5IGJldHdlZW4gdGhlIHN0YWNrcyB3aWxsIGJlIHJlY29yZGVkLCBhbmQgdGhlIHRvb2xraXRcbiAqIHdpbGwgbWFrZSBzdXJlIHRvIGRlcGxveSBwcm9kdWNpbmcgc3RhY2sgYmVmb3JlIHRoZSBjb25zdW1pbmcgc3RhY2suXG4gKlxuICogVGhpcyBtYWdpYyBoYXBwZW5zIGluIHRoZSBwcmVwYXJlKCkgcGhhc2UsIHdoZXJlIGNvbnN1bWluZyBzdGFja3Mgd2lsbCBjYWxsXG4gKiBgY29uc3VtZUZyb21TdGFja2Agb24gdGhlc2UgVG9rZW5zIGFuZCBpZiB0aGV5IGhhcHBlbiB0byBiZSBleHBvcnRlZCBieSBhIGRpZmZlcmVudFxuICogU3RhY2ssIHdlJ2xsIHJlZ2lzdGVyIHRoZSBkZXBlbmRlbmN5LlxuICovXG5leHBvcnQgY2xhc3MgQ2ZuUmVmZXJlbmNlIGV4dGVuZHMgUmVmZXJlbmNlIHtcbiAgLyoqXG4gICAqIENoZWNrIHdoZXRoZXIgdGhpcyBpcyBhY3R1YWxseSBhIFJlZmVyZW5jZVxuICAgKi9cbiAgcHVibGljIHN0YXRpYyBpc0NmblJlZmVyZW5jZSh4OiBJUmVzb2x2YWJsZSk6IHggaXMgQ2ZuUmVmZXJlbmNlIHtcbiAgICByZXR1cm4gQ0ZOX1JFRkVSRU5DRV9TWU1CT0wgaW4geDtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm4gdGhlIENmblJlZmVyZW5jZSBmb3IgdGhlIGluZGljYXRlZCB0YXJnZXRcbiAgICpcbiAgICogV2lsbCBtYWtlIHN1cmUgdGhhdCBtdWx0aXBsZSBpbnZvY2F0aW9ucyBmb3IgdGhlIHNhbWUgdGFyZ2V0IGFuZCBpbnRyaW5zaWNcbiAgICogcmV0dXJuIHRoZSBzYW1lIENmblJlZmVyZW5jZS4gQmVjYXVzZSBDZm5SZWZlcmVuY2VzIGFjY3VtdWxhdGUgc3RhdGUgaW5cbiAgICogdGhlIHByZXBhcmUoKSBwaGFzZSAoZm9yIHRoZSBwdXJwb3NlIG9mIGNyb3NzLXN0YWNrIHJlZmVyZW5jZXMpLCBpdCdzXG4gICAqIGltcG9ydGFudCB0aGF0IHRoZSBzdGF0ZSBpc24ndCBsb3N0IGlmIGl0J3MgbGF6aWx5IGNyZWF0ZWQsIGxpa2Ugc286XG4gICAqXG4gICAqICAgICBMYXp5LnN0cmluZ1ZhbHVlKHsgcHJvZHVjZTogKCkgPT4gbmV3IENmblJlZmVyZW5jZSguLi4pIH0pXG4gICAqL1xuICBwdWJsaWMgc3RhdGljIGZvcih0YXJnZXQ6IENmbkVsZW1lbnQsIGF0dHJpYnV0ZTogc3RyaW5nKSB7XG4gICAgcmV0dXJuIENmblJlZmVyZW5jZS5zaW5nbGV0b25SZWZlcmVuY2UodGFyZ2V0LCBhdHRyaWJ1dGUsICgpID0+IHtcbiAgICAgIGNvbnN0IGNmbkludHJpbnNpYyA9IGF0dHJpYnV0ZSA9PT0gJ1JlZicgPyB7IFJlZjogdGFyZ2V0LmxvZ2ljYWxJZCB9IDogeyAnRm46OkdldEF0dCc6IFsgdGFyZ2V0LmxvZ2ljYWxJZCwgYXR0cmlidXRlIF19O1xuICAgICAgcmV0dXJuIG5ldyBDZm5SZWZlcmVuY2UoY2ZuSW50cmluc2ljLCBhdHRyaWJ1dGUsIHRhcmdldCk7XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJuIGEgQ2ZuUmVmZXJlbmNlIHRoYXQgcmVmZXJlbmNlcyBhIHBzZXVkbyByZWZlcmVuY2RcbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgZm9yUHNldWRvKHBzZXVkb05hbWU6IHN0cmluZywgc2NvcGU6IENvbnN0cnVjdCkge1xuICAgIHJldHVybiBDZm5SZWZlcmVuY2Uuc2luZ2xldG9uUmVmZXJlbmNlKHNjb3BlLCBgUHNldWRvOiR7cHNldWRvTmFtZX1gLCAoKSA9PiB7XG4gICAgICBjb25zdCBjZm5JbnRyaW5zaWMgPSB7IFJlZjogcHNldWRvTmFtZSB9O1xuICAgICAgcmV0dXJuIG5ldyBDZm5SZWZlcmVuY2UoY2ZuSW50cmluc2ljLCBwc2V1ZG9OYW1lLCBzY29wZSk7XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogU3RhdGljIHRhYmxlIHdoZXJlIHdlIGtlZXAgc2luZ2xldG9uIENmblJlZmVyZW5jZSBpbnN0YW5jZXNcbiAgICovXG4gIHByaXZhdGUgc3RhdGljIHJlZmVyZW5jZVRhYmxlID0gbmV3IE1hcDxDb25zdHJ1Y3QsIE1hcDxzdHJpbmcsIENmblJlZmVyZW5jZT4+KCk7XG5cbiAgLyoqXG4gICAqIEdldCBvciBjcmVhdGUgdGhlIHRhYmxlXG4gICAqL1xuICBwcml2YXRlIHN0YXRpYyBzaW5nbGV0b25SZWZlcmVuY2UodGFyZ2V0OiBDb25zdHJ1Y3QsIGF0dHJpYktleTogc3RyaW5nLCBmcmVzaDogKCkgPT4gQ2ZuUmVmZXJlbmNlKSB7XG4gICAgbGV0IGF0dHJpYnMgPSBDZm5SZWZlcmVuY2UucmVmZXJlbmNlVGFibGUuZ2V0KHRhcmdldCk7XG4gICAgaWYgKCFhdHRyaWJzKSB7XG4gICAgICBhdHRyaWJzID0gbmV3IE1hcCgpO1xuICAgICAgQ2ZuUmVmZXJlbmNlLnJlZmVyZW5jZVRhYmxlLnNldCh0YXJnZXQsIGF0dHJpYnMpO1xuICAgIH1cbiAgICBsZXQgcmVmID0gYXR0cmlicy5nZXQoYXR0cmliS2V5KTtcbiAgICBpZiAoIXJlZikge1xuICAgICAgcmVmID0gZnJlc2goKTtcbiAgICAgIGF0dHJpYnMuc2V0KGF0dHJpYktleSwgcmVmKTtcbiAgICB9XG4gICAgcmV0dXJuIHJlZjtcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGUgVG9rZW5zIHRoYXQgc2hvdWxkIGJlIHJldHVybmVkIGZvciBlYWNoIGNvbnN1bWluZyBzdGFjayAoYXMgZGVjaWRlZCBieSB0aGUgcHJvZHVjaW5nIFN0YWNrKVxuICAgKi9cbiAgcHJpdmF0ZSByZWFkb25seSByZXBsYWNlbWVudFRva2VuczogTWFwPFN0YWNrLCBJUmVzb2x2YWJsZT47XG4gIHByaXZhdGUgcmVhZG9ubHkgdGFyZ2V0U3RhY2s6IFN0YWNrO1xuXG4gIHByb3RlY3RlZCBjb25zdHJ1Y3Rvcih2YWx1ZTogYW55LCBkaXNwbGF5TmFtZTogc3RyaW5nLCB0YXJnZXQ6IElDb25zdHJ1Y3QpIHtcbiAgICAvLyBwcmVwZW5kIHNjb3BlIHBhdGggdG8gZGlzcGxheSBuYW1lXG4gICAgc3VwZXIodmFsdWUsIHRhcmdldCwgZGlzcGxheU5hbWUpO1xuXG4gICAgdGhpcy5yZXBsYWNlbWVudFRva2VucyA9IG5ldyBNYXA8U3RhY2ssIElSZXNvbHZhYmxlPigpO1xuICAgIHRoaXMudGFyZ2V0U3RhY2sgPSBTdGFjay5vZih0YXJnZXQpO1xuXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRoaXMsIENGTl9SRUZFUkVOQ0VfU1lNQk9MLCB7IHZhbHVlOiB0cnVlIH0pO1xuICB9XG5cbiAgcHVibGljIHJlc29sdmUoY29udGV4dDogSVJlc29sdmVDb250ZXh0KTogYW55IHtcbiAgICAvLyBJZiB3ZSBoYXZlIGEgc3BlY2lhbCB0b2tlbiBmb3IgdGhpcyBjb25zdW1pbmcgc3RhY2ssIHJlc29sdmUgdGhhdC4gT3RoZXJ3aXNlIHJlc29sdmUgYXMgaWZcbiAgICAvLyB3ZSBhcmUgaW4gdGhlIHNhbWUgc3RhY2suXG4gICAgY29uc3QgY29uc3VtaW5nU3RhY2sgPSBTdGFjay5vZihjb250ZXh0LnNjb3BlKTtcbiAgICBjb25zdCB0b2tlbiA9IHRoaXMucmVwbGFjZW1lbnRUb2tlbnMuZ2V0KGNvbnN1bWluZ1N0YWNrKTtcblxuICAgIC8vIGlmICghdG9rZW4gJiYgdGhpcy5pc0Nyb3NzU3RhY2tSZWZlcmVuY2UoY29uc3VtaW5nU3RhY2spICYmICFjb250ZXh0LnByZXBhcmluZykge1xuICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTptYXgtbGluZS1sZW5ndGhcbiAgICAvLyAgIHRocm93IG5ldyBFcnJvcihgQ3Jvc3Mtc3RhY2sgcmVmZXJlbmNlICgke2NvbnRleHQuc2NvcGUubm9kZS5wYXRofSAtPiAke3RoaXMudGFyZ2V0Lm5vZGUucGF0aH0pIGhhcyBub3QgYmVlbiBhc3NpZ25lZCBhIHZhbHVlLS1jYWxsIHByZXBhcmUoKSBmaXJzdGApO1xuICAgIC8vIH1cblxuICAgIGlmICh0b2tlbikge1xuICAgICAgcmV0dXJuIHRva2VuLnJlc29sdmUoY29udGV4dCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBzdXBlci5yZXNvbHZlKGNvbnRleHQpO1xuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBoYXNWYWx1ZUZvclN0YWNrKHN0YWNrOiBTdGFjaykge1xuICAgIGlmIChzdGFjayA9PT0gdGhpcy50YXJnZXRTdGFjaykge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMucmVwbGFjZW1lbnRUb2tlbnMuaGFzKHN0YWNrKTtcbiAgfVxuXG4gIHB1YmxpYyBhc3NpZ25WYWx1ZUZvclN0YWNrKHN0YWNrOiBTdGFjaywgdmFsdWU6IElSZXNvbHZhYmxlKSB7XG4gICAgaWYgKHN0YWNrID09PSB0aGlzLnRhcmdldFN0YWNrKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2Nhbm5vdCBhc3NpZ24gYSB2YWx1ZSBmb3IgdGhlIHNhbWUgc3RhY2snKTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5oYXNWYWx1ZUZvclN0YWNrKHN0YWNrKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdDYW5ub3QgYXNzaWduIGEgcmVmZXJlbmNlIHZhbHVlIHR3aWNlIHRvIHRoZSBzYW1lIHN0YWNrLiBVc2UgaGFzVmFsdWVGb3JTdGFjayB0byBjaGVjayBmaXJzdCcpO1xuICAgIH1cblxuICAgIHRoaXMucmVwbGFjZW1lbnRUb2tlbnMuc2V0KHN0YWNrLCB2YWx1ZSk7XG4gIH1cbiAgLyoqXG4gICAqIEltcGxlbWVudGF0aW9uIG9mIHRvU3RyaW5nKCkgdGhhdCB3aWxsIHVzZSB0aGUgZGlzcGxheSBuYW1lXG4gICAqL1xuICBwdWJsaWMgdG9TdHJpbmcoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gVG9rZW4uYXNTdHJpbmcodGhpcywge1xuICAgICAgZGlzcGxheUhpbnQ6IGAke3RoaXMudGFyZ2V0Lm5vZGUuaWR9LiR7dGhpcy5kaXNwbGF5TmFtZX1gLFxuICAgIH0pO1xuICB9XG59XG5cbmltcG9ydCB7IENmbkVsZW1lbnQgfSBmcm9tICcuLi9jZm4tZWxlbWVudCc7XG5pbXBvcnQgeyBDb25zdHJ1Y3QsIElDb25zdHJ1Y3QgfSBmcm9tICcuLi9jb25zdHJ1Y3QtY29tcGF0JztcbmltcG9ydCB7IElSZXNvbHZhYmxlLCBJUmVzb2x2ZUNvbnRleHQgfSBmcm9tICcuLi9yZXNvbHZhYmxlJztcbmltcG9ydCB7IFN0YWNrIH0gZnJvbSAnLi4vc3RhY2snO1xuaW1wb3J0IHsgVG9rZW4gfSBmcm9tICcuLi90b2tlbic7XG4iXX0=