Skip to content

Commit 1d3b416

Browse files
author
Leon Michalski
committed
Order by arn first
1 parent 8e3f3f4 commit 1d3b416

File tree

2 files changed

+63
-1
lines changed

2 files changed

+63
-1
lines changed

tools/@aws-cdk/spec2cdk/lib/cdk/resolver-builder.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,8 +77,13 @@ export class ResolverBuilder {
7777
// Generates code like:
7878
// For single value: (props.roleArn as IRoleRef)?.roleRef?.roleArn ?? (props.roleArn as IUserRef)?.userRef?.userArn ?? props.roleArn
7979
// For array: props.roleArns?.map((item: any) => (item as IRoleRef)?.roleRef?.roleArn ?? (item as IUserRef)?.userRef?.userArn ?? item)
80+
// Ensures that arn properties always appear first in the chain as they are more general
81+
const arnRels = relationships.filter(r => r.propName.toLowerCase().endsWith('arn'));
82+
const otherRels = relationships.filter(r => !r.propName.toLowerCase().endsWith('arn'));
83+
8084
const buildChain = (itemName: string) => [
81-
...relationships.map(r => `(${itemName} as ${r.referenceType})?.${r.referenceName}?.${r.propName}`),
85+
...[...arnRels, ...otherRels]
86+
.map(r => `(${itemName} as ${r.referenceType})?.${r.referenceName}?.${r.propName}`),
8287
itemName,
8388
].join(' ?? ');
8489
const resolver = (_: Expression) => {

tools/@aws-cdk/spec2cdk/test/relationships.test.ts

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,3 +272,60 @@ test('resource with nested relationship with type history', () => {
272272

273273
expect(rendered).toMatchSnapshot();
274274
});
275+
276+
test('relationship have arns appear first in the constructor chain', () => {
277+
// Target resource
278+
const roleResource = db.allocate('resource', {
279+
name: 'Role',
280+
primaryIdentifier: ['RoleName', 'OtherPrimaryId'],
281+
attributes: {
282+
RoleArn: {
283+
type: { type: 'string' },
284+
},
285+
},
286+
properties: {},
287+
cloudFormationType: 'AWS::IAM::Role',
288+
});
289+
db.link('hasResource', service, roleResource);
290+
291+
// Type definition with relationship
292+
const configType = db.allocate('typeDefinition', {
293+
name: 'ExecutionConfig',
294+
properties: {
295+
RoleArn: {
296+
type: { type: 'string' },
297+
relationshipRefs: [{
298+
cloudFormationType: 'AWS::IAM::Role',
299+
propertyName: 'RoleName',
300+
}, {
301+
cloudFormationType: 'AWS::IAM::Role',
302+
propertyName: 'RoleArn',
303+
}, {
304+
cloudFormationType: 'AWS::IAM::Role',
305+
propertyName: 'OtherPrimaryId',
306+
}],
307+
},
308+
},
309+
});
310+
311+
// Source resource with nested property
312+
const taskResource = db.allocate('resource', {
313+
name: 'Task',
314+
attributes: {},
315+
properties: {
316+
ExecutionConfig: {
317+
type: { type: 'ref', reference: { $ref: configType.$id } },
318+
},
319+
},
320+
cloudFormationType: 'AWS::IAM::Task',
321+
});
322+
db.link('hasResource', service, taskResource);
323+
db.link('usesType', taskResource, configType);
324+
325+
const ast = AstBuilder.forService(service, { db });
326+
const rendered = renderer.render(ast.module);
327+
328+
const chain = '"roleArn": (props.roleArn as IRoleRef)?.roleRef?.roleArn ?? (props.roleArn as IRoleRef)?.roleRef?.roleName ?? (props.roleArn as IRoleRef)?.roleRef?.otherPrimaryId ?? props.roleArn';
329+
330+
expect(rendered).toContain(chain);
331+
});

0 commit comments

Comments
 (0)