diff --git a/packages/@aws-cdk/core/lib/private/tree-metadata.ts b/packages/@aws-cdk/core/lib/private/tree-metadata.ts index bd529eb6be8d0..3d16481dff65f 100644 --- a/packages/@aws-cdk/core/lib/private/tree-metadata.ts +++ b/packages/@aws-cdk/core/lib/private/tree-metadata.ts @@ -2,7 +2,7 @@ import fs = require('fs'); import path = require('path'); import { ArtifactType } from '@aws-cdk/cx-api'; -import { Construct, IConstruct, ISynthesisSession } from '../construct'; +import { CfnResource, Construct, IConstruct, ISynthesisSession } from '../index'; const FILE_PATH = 'tree.json'; @@ -23,10 +23,13 @@ export class TreeMetadata extends Construct { const visit = (construct: IConstruct): Node => { const children = construct.node.children.map(visit); + const childrenMap = children.reduce((map, child) => Object.assign(map, { [child.id]: child }), {}); const node: Node = { id: construct.node.id || 'App', path: construct.node.path, - children: children.length === 0 ? undefined : children, + type: this.inferType(construct), + properties: this.inferProperties(construct), + children: children.length === 0 ? undefined : childrenMap, }; lookup[node.path] = node; @@ -49,10 +52,33 @@ export class TreeMetadata extends Construct { } }); } + + private inferType(construct: IConstruct): Type | undefined { + if (CfnResource.isCfnResource(construct)) { + return { + cfnResourceType: (construct as CfnResource).cfnResourceType + }; + } + return undefined; + } + + private inferProperties(construct: IConstruct): { [key: string]: any } | undefined { + if (CfnResource.isCfnResource(construct)) { + return (construct as any).cfnProperties; + } else { + return undefined; + } + } } interface Node { id: string; path: string; - children?: Node[]; + type?: Type; + properties?: { [key: string]: any }; + children?: { [key: string]: Node }; +} + +interface Type { + cfnResourceType?: string; } \ No newline at end of file diff --git a/packages/@aws-cdk/core/test/private/test.tree-metadata.ts b/packages/@aws-cdk/core/test/private/test.tree-metadata.ts index 6b3c5b407b28c..1696fea9c2190 100644 --- a/packages/@aws-cdk/core/test/private/test.tree-metadata.ts +++ b/packages/@aws-cdk/core/test/private/test.tree-metadata.ts @@ -1,17 +1,13 @@ import fs = require('fs'); import { Test } from 'nodeunit'; import path = require('path'); -import { App, Construct, Resource, Stack } from '../../lib/index'; +import { App, CfnResource, Construct, Stack } from '../../lib/index'; export = { - 'tree metadata is generated as expected'(test: Test) { + 'tree metadata for stacks and simple constructs'(test: Test) { const app = new App(); - const stack = new Stack(app, 'mystack'); - new Construct(stack, 'group1'); - const group2 = new Construct(stack, 'group2'); - - new MyResource(group2, 'resource3'); + new Construct(stack, 'myconstruct'); const assembly = app.synth(); const treeArtifact = assembly.tree(); @@ -22,41 +18,91 @@ export = { tree: { id: 'App', path: '', - children: [ - { + children: { + Tree: { id: 'Tree', - path: 'Tree' + path: 'Tree', }, - { + mystack: { id: 'mystack', path: 'mystack', - children: [ - { - id: 'group1', - path: 'mystack/group1' - }, - { - id: 'group2', - path: 'mystack/group2', - children: [ - { id: 'resource3', path: 'mystack/group2/resource3' } - ] + children: { + myconstruct: { + id: 'myconstruct', + path: 'mystack/myconstruct', } - ] + } + } + } + } + }); + test.done(); + }, + + 'tree metadata for Cfn* resources'(test: Test) { + class MyCfnResource extends CfnResource { + constructor(scope: Construct, id: string) { + super(scope, id, { + type: 'CDK::UnitTest::MyCfnResource', + }); + } + + protected get cfnProperties(): { [key: string]: any } { + return { + mystringpropkey: 'mystringpropval', + mylistpropkey: [ 'listitem1' ], + mystructpropkey: { + myboolpropkey: true, + mynumpropkey: 50, + } + }; + } + } + + const app = new App(); + const stack = new Stack(app, 'mystack'); + new MyCfnResource(stack, 'mycfnresource'); + + const assembly = app.synth(); + const treeArtifact = assembly.tree(); + test.ok(treeArtifact); + + test.deepEqual(readJson(assembly.directory, treeArtifact!.file), { + version: 'tree-0.1', + tree: { + id: 'App', + path: '', + children: { + Tree: { + id: 'Tree', + path: 'Tree', }, - ] + mystack: { + id: 'mystack', + path: 'mystack', + children: { + mycfnresource: { + id: 'mycfnresource', + path: 'mystack/mycfnresource', + type: { cfnResourceType: 'CDK::UnitTest::MyCfnResource' }, + properties: { + mystringpropkey: 'mystringpropval', + mylistpropkey: [ 'listitem1' ], + mystructpropkey: { + myboolpropkey: true, + mynumpropkey: 50, + } + } + } + } + } + } } }); test.done(); }, }; -class MyResource extends Resource { - constructor(scope: Construct, id: string) { - super(scope, id); - } -} - function readJson(outdir: string, file: string) { return JSON.parse(fs.readFileSync(path.join(outdir, file), 'utf-8')); } diff --git a/packages/@aws-cdk/core/test/test.synthesis.ts b/packages/@aws-cdk/core/test/test.synthesis.ts index ef4563b597c29..5780f31c83fed 100644 --- a/packages/@aws-cdk/core/test/test.synthesis.ts +++ b/packages/@aws-cdk/core/test/test.synthesis.ts @@ -36,9 +36,9 @@ export = { tree: { id: 'App', path: '', - children: [ - { id: 'Tree', path: 'Tree' } - ] + children: { + Tree: { id: 'Tree', path: 'Tree' } + } } }); test.done();