Skip to content

Commit

Permalink
fix: SAM spec type is wrong for Serverless Function Policies (#636)
Browse files Browse the repository at this point in the history
The apparent contract we didn't implement correctly was that the fields
named `Inclusive*ItemTypes` need to be respected, regardless of whether
the top-level type includes `List` or not.

So force that behavior.
  • Loading branch information
rix0rrr authored Oct 25, 2023
1 parent 05f4047 commit b0717b8
Show file tree
Hide file tree
Showing 2 changed files with 91 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,18 @@ export class SAMSpecImporter extends ResourceSpecImporterBase<SAMResourceSpecifi
protected deriveType(spec: resourcespec.SAMTypeDefinition): PropertyType {
const self = this;

// Slight interpretation hack: if `Inclusive[Primitive]ItemTypes` are present,
// we need to honor them even if "List" is not present in the types. So
// if we detect them, add "List" to the `Types` array.
if (spec.InclusiveItemTypes || spec.InclusivePrimitiveItemTypes) {
if (spec.Type !== 'List' && !(spec.Types ?? []).includes('List')) {
spec = {
...spec,
Types: [...(spec.Types ?? []), 'List'],
};
}
}

return maybeUnion([
...(spec.PrimitiveTypes ?? []).map(primitiveType),
...(spec.Type ? [namedType(spec.Type)] : []),
Expand Down
79 changes: 79 additions & 0 deletions packages/@aws-cdk/service-spec-importers/test/sam-spec.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import { emptyDatabase } from '@aws-cdk/service-spec-types';
import { SAMSpecImporter } from '../src/importers/import-resource-spec';

/**
* Tests for the CloudFormation spec of SAM
*/

let db: ReturnType<typeof emptyDatabase>;
beforeEach(() => {
db = emptyDatabase();
});

test('respect InclusivePrimitiveItemTypes even if List is not given', () => {
SAMSpecImporter.importTypes({
db,
specification: {
ResourceSpecificationVersion: '2016-10-31',
ResourceSpecificationTransform: 'AWS::Serverless-2016-10-31',
ResourceTypes: {
'AWS::Some::Type': {
Properties: {
SomeParameter: {
UpdateType: 'Mutable',
PrimitiveTypes: ['String'],
Types: ['Type1'],
InclusivePrimitiveItemTypes: ['Integer'],
InclusiveItemTypes: ['Type2'],
},
},
},
},
PropertyTypes: {
'AWS::Some::Type.Type1': {
Properties: {
Field: { UpdateType: 'Mutable', PrimitiveType: 'String' },
},
},
'AWS::Some::Type.Type2': {
Properties: {
Field: { UpdateType: 'Mutable', PrimitiveType: 'String' },
},
},
},
},
});

const resource = db.lookup('resource', 'cloudFormationType', 'equals', 'AWS::Some::Type').only();
expect(resource.properties.SomeParameter.type).toEqual({
type: 'union',
types: [
{
type: 'string',
},
{
reference: {
$ref: '2',
},
type: 'ref',
},
{
element: {
type: 'union',
types: [
{
type: 'integer',
},
{
reference: {
$ref: '3',
},
type: 'ref',
},
],
},
type: 'array',
},
],
});
});

0 comments on commit b0717b8

Please sign in to comment.