diff --git a/.npmignore b/.npmignore index b0c70479..2c62d1af 100644 --- a/.npmignore +++ b/.npmignore @@ -22,3 +22,5 @@ dist tsconfig.tsbuildinfo /.eslintrc.json !.jsii +/scripts/ +.projenrc.ts diff --git a/.projenrc.ts b/.projenrc.ts index 25c874aa..b525228e 100644 --- a/.projenrc.ts +++ b/.projenrc.ts @@ -81,5 +81,6 @@ project.buildWorkflow?.addPostBuildJobCommands( { checkoutRepo: true }, ); +project.npmignore?.exclude('/scripts/', '.projenrc.ts'); project.synth(); diff --git a/src/construct.ts b/src/construct.ts index 9260a59a..1888384b 100644 --- a/src/construct.ts +++ b/src/construct.ts @@ -77,7 +77,12 @@ export class Node { * Components are separated by '/'. */ public get path(): string { - const components = this.scopes.filter(c => c.node.id).map(c => c.node.id); + const components = []; + for (const scope of this.scopes) { + if (scope.node.id) { + components.push(scope.node.id); + } + } return components.join(Node.PATH_SEP); } @@ -417,21 +422,13 @@ export class Node { throw new Error(`Cannot add children to "${this.path}" during synthesis`); } - if (childName in this._children) { + if (this._children[childName]) { const name = this.id ?? ''; const typeName = this.host.constructor.name; throw new Error(`There is already a Construct with name '${childName}' in ${typeName}${name.length > 0 ? ' [' + name + ']' : ''}`); } - if (!childName && this.id) { - throw new Error(`cannot add a nameless construct to the named scope: ${this.path}`); - } - this._children[childName] = child; - - if (Object.keys(this._children).length > 1 && Object.keys(this._children).filter(x => !x).length > 0) { - throw new Error('only a single construct is allowed in a scope if it has an empty name'); - } } } diff --git a/test/evaluate-cfn.ts b/test/evaluate-cfn.ts deleted file mode 100644 index 2ea80e52..00000000 --- a/test/evaluate-cfn.ts +++ /dev/null @@ -1,71 +0,0 @@ -/** - * Simple function to evaluate CloudFormation intrinsics. - * - * Note that this function is not production quality, it exists to support tests. - */ - -export function evaluateCFN(object: any, context: {[key: string]: string} = {}): any { - const intrinsics: any = { - 'Fn::Join'(separator: string, args: string[]) { - return args.map(evaluate).join(separator); - }, - - 'Ref'(logicalId: string) { - if (!(logicalId in context)) { - throw new Error(`Trying to evaluate Ref of '${logicalId}' but not in context!`); - } - return context[logicalId]; - }, - - 'Fn::GetAtt'(logicalId: string, attributeName: string) { - const key = `${logicalId}.${attributeName}`; - if (!(key in context)) { - throw new Error(`Trying to evaluate Fn::GetAtt of '${logicalId}.${attributeName}' but not in context!`); - } - return context[key]; - }, - }; - - return evaluate(object); - - function evaluate(obj: any): any { - if (Array.isArray(obj)) { - return obj.map(evaluate); - } - - if (typeof obj === 'object') { - const keys = Object.keys(obj); - if (keys.length === 1 && (isNameOfCloudFormationIntrinsic(keys[0]) || keys[0] === 'Ref')) { - return evaluateIntrinsic(keys[0], obj[keys[0]]); - } - - const ret: {[key: string]: any} = {}; - for (const key of keys) { - ret[key] = evaluateCFN(obj[key]); - } - return ret; - } - - return obj; - } - - function evaluateIntrinsic(name: string, args: any) { - if (!(name in intrinsics)) { - throw new Error(`Intrinsic ${name} not supported here`); - } - - if (!Array.isArray(args)) { - args = [args]; - } - - return intrinsics[name].apply(intrinsics, args); - } -} - -function isNameOfCloudFormationIntrinsic(name: string): boolean { - if (!name.startsWith('Fn::')) { - return false; - } - // these are 'fake' intrinsics, only usable inside the parameter overrides of a CFN CodePipeline Action - return name !== 'Fn::GetArtifactAtt' && name !== 'Fn::GetParam'; -}