Skip to content

Commit b7137c5

Browse files
authored
fix(cfn2ts): correctly choose between string and object without required properties in a union (#12954)
In our code generation, in the validation functions for CFN complex types, we never checked whether the argument we received is an object. Because of that, passing a string was actually a correct candidate for a union with a complex type that had no required properties. Fix that by checking for that error explicitly, which removes the complex type without required properties from the candidates for the union type when a string is passed. Fixes #12854 ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
1 parent 50e597b commit b7137c5

File tree

3 files changed

+36
-0
lines changed

3 files changed

+36
-0
lines changed
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import '@aws-cdk/assert/jest';
2+
import * as cdk from '@aws-cdk/core';
3+
import * as sam from '../lib';
4+
5+
test("correctly chooses a string array from the type unions of the 'policies' property", () => {
6+
const stack = new cdk.Stack();
7+
8+
new sam.CfnFunction(stack, 'MyFunction', {
9+
codeUri: {
10+
bucket: 'my-bucket',
11+
key: 'my-key',
12+
},
13+
runtime: 'nodejs-12.x',
14+
handler: 'index.handler',
15+
policies: ['AWSLambdaExecute'],
16+
});
17+
18+
expect(stack).toHaveResourceLike('AWS::Serverless::Function', {
19+
CodeUri: {
20+
Bucket: 'my-bucket',
21+
Key: 'my-key',
22+
},
23+
Handler: 'index.handler',
24+
Runtime: 'nodejs-12.x',
25+
Policies: ['AWSLambdaExecute'],
26+
});
27+
});

tools/cfn2ts/lib/codegen.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -684,6 +684,15 @@ export default class CodeGenerator {
684684

685685
this.code.line(`const errors = new ${CORE}.ValidationResults();`);
686686

687+
// check that the argument is an object
688+
// normally, we would have to explicitly check for null here,
689+
// as typeof null is 'object' in JavaScript,
690+
// but validators are never called with null
691+
// (as evidenced by the code below accessing properties of the argument without checking for null)
692+
this.code.openBlock("if (typeof properties !== 'object')");
693+
this.code.line(`errors.collect(new ${CORE}.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties)));`);
694+
this.code.closeBlock();
695+
687696
Object.keys(propSpecs).forEach(cfnPropName => {
688697
const propSpec = propSpecs[cfnPropName];
689698
const propName = nameConversionTable[cfnPropName];

0 commit comments

Comments
 (0)