From 78f6e8b17d461a2669a18dc324895e470ed54545 Mon Sep 17 00:00:00 2001 From: corymhall <43035978+corymhall@users.noreply.github.com> Date: Fri, 5 May 2023 13:15:12 +0000 Subject: [PATCH 1/2] fix(cfn2ts): doesn't handle property types with the same type as a primitive type We currently do not account for cases where a property type can have a complex type that matches one of our primitive types. For example, [AWS::IoT::TopicRule.LocationAction](https://github.com/aws/aws-cdk/blob/a0ad49df7b2536d800b4890ae0116e6ce26e6c55/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_IoT.json#L1437-L1442) has a property `Timestamp` with a Type of [Timestamp](https://github.com/aws/aws-cdk/blob/a0ad49df7b2536d800b4890ae0116e6ce26e6c55/packages/@aws-cdk/cfnspec/spec-source/specification/000_cfn/000_official/000_AWS_IoT.json#L1727-L1742) When cfn2ts generates the TypeScript code it thinks that this is referring to the `PrimitiveType` `Timestamp` and coverts it to a `Date`. After running `gen` with these changes the only differences in the cfnspecs were `iot.generated.ts` ```diff @@ -10134,7 +10134,7 @@ export namespace CfnTopicRule { * * @link http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iot-topicrule-locationaction.html#cfn-iot-topicrule-locationaction-timestamp */ - readonly timestamp?: Date | cdk.IResolvable; + readonly timestamp?: CfnTopicRule.TimestampProperty | cdk.IResolvable; /** * The name of the tracker resource in Amazon Location in which the location is updated. * @@ -10165,7 +10165,7 @@ function CfnTopicRule_LocationActionPropertyValidator(properties: any): cdk.Vali errors.collect(cdk.propertyValidator('longitude', cdk.validateString)(properties.longitude)); errors.collect(cdk.propertyValidator('roleArn', cdk.requiredValidator)(properties.roleArn)); errors.collect(cdk.propertyValidator('roleArn', cdk.validateString)(properties.roleArn)); - errors.collect(cdk.propertyValidator('timestamp', cdk.validateDate)(properties.timestamp)); + errors.collect(cdk.propertyValidator('timestamp', CfnTopicRule_TimestampPropertyValidator)(properties.timestamp)); errors.collect(cdk.propertyValidator('trackerName', cdk.requiredValidator)(properties.trackerName)); errors.collect(cdk.propertyValidator('trackerName', cdk.validateString)(properties.trackerName)); return errors.wrap('supplied properties not correct for "LocationActionProperty"'); @@ -10187,7 +10187,7 @@ function cfnTopicRuleLocationActionPropertyToCloudFormation(properties: any): an Latitude: cdk.stringToCloudFormation(properties.latitude), Longitude: cdk.stringToCloudFormation(properties.longitude), RoleArn: cdk.stringToCloudFormation(properties.roleArn), - Timestamp: cdk.dateToCloudFormation(properties.timestamp), + Timestamp: cfnTopicRuleTimestampPropertyToCloudFormation(properties.timestamp), TrackerName: cdk.stringToCloudFormation(properties.trackerName), }; } @@ -10206,7 +10206,7 @@ function CfnTopicRuleLocationActionPropertyFromCloudFormation(properties: any): ret.addPropertyResult('latitude', 'Latitude', cfn_parse.FromCloudFormation.getString(properties.Latitude)); ret.addPropertyResult('longitude', 'Longitude', cfn_parse.FromCloudFormation.getString(properties.Longitude)); ret.addPropertyResult('roleArn', 'RoleArn', cfn_parse.FromCloudFormation.getString(properties.RoleArn)); - ret.addPropertyResult('timestamp', 'Timestamp', properties.Timestamp != null ? cfn_parse.FromCloudFormation.getDate(properties.Timestamp) : undefined); + ret.addPropertyResult('timestamp', 'Timestamp', properties.Timestamp != null ? CfnTopicRuleTimestampPropertyFromCloudFormation(properties.Timestamp) : undefined); ret.addPropertyResult('trackerName', 'TrackerName', cfn_parse.FromCloudFormation.getString(properties.TrackerName)); ret.addUnrecognizedPropertiesAsExtra(properties); return ret; ``` `sagemaker.generated.ts` ```diff @@ -2053,7 +2053,7 @@ export namespace CfnDataQualityJobDefinition { * * @link http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-sagemaker-dataqualityjobdefinition-datasetformat.html#cfn-sagemaker-dataqualityjobdefinition-datasetformat-json */ - readonly json?: any | cdk.IResolvable; + readonly json?: CfnDataQualityJobDefinition.JsonProperty | cdk.IResolvable; /** * `CfnDataQualityJobDefinition.DatasetFormatProperty.Parquet` * @@ -2077,7 +2077,7 @@ function CfnDataQualityJobDefinition_DatasetFormatPropertyValidator(properties: errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties))); } errors.collect(cdk.propertyValidator('csv', CfnDataQualityJobDefinition_CsvPropertyValidator)(properties.csv)); - errors.collect(cdk.propertyValidator('json', cdk.validateObject)(properties.json)); + errors.collect(cdk.propertyValidator('json', CfnDataQualityJobDefinition_JsonPropertyValidator)(properties.json)); errors.collect(cdk.propertyValidator('parquet', cdk.validateBoolean)(properties.parquet)); return errors.wrap('supplied properties not correct for "DatasetFormatProperty"'); } @@ -2095,7 +2095,7 @@ function cfnDataQualityJobDefinitionDatasetFormatPropertyToCloudFormation(proper CfnDataQualityJobDefinition_DatasetFormatPropertyValidator(properties).assertSuccess(); return { Csv: cfnDataQualityJobDefinitionCsvPropertyToCloudFormation(properties.csv), - Json: cdk.objectToCloudFormation(properties.json), + Json: cfnDataQualityJobDefinitionJsonPropertyToCloudFormation(properties.json), Parquet: cdk.booleanToCloudFormation(properties.parquet), }; } @@ -2111,7 +2111,7 @@ function CfnDataQualityJobDefinitionDatasetFormatPropertyFromCloudFormation(prop } const ret = new cfn_parse.FromCloudFormationPropertyObject(); ret.addPropertyResult('csv', 'Csv', properties.Csv != null ? CfnDataQualityJobDefinitionCsvPropertyFromCloudFormation(properties.Csv) : undefined); - ret.addPropertyResult('json', 'Json', properties.Json != null ? cfn_parse.FromCloudFormation.getAny(properties.Json) : undefined); + ret.addPropertyResult('json', 'Json', properties.Json != null ? CfnDataQualityJobDefinitionJsonPropertyFromCloudFormation(properties.Json) : undefined); ret.addPropertyResult('parquet', 'Parquet', properties.Parquet != null ? cfn_parse.FromCloudFormation.getBoolean(properties.Parquet) : undefined); ret.addUnrecognizedPropertiesAsExtra(properties); return ret; @@ -11470,7 +11470,7 @@ export namespace CfnModelBiasJobDefinition { * * @link http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-sagemaker-modelbiasjobdefinition-datasetformat.html#cfn-sagemaker-modelbiasjobdefinition-datasetformat-json */ - readonly json?: any | cdk.IResolvable; + readonly json?: CfnModelBiasJobDefinition.JsonProperty | cdk.IResolvable; /** * `CfnModelBiasJobDefinition.DatasetFormatProperty.Parquet` * @@ -11494,7 +11494,7 @@ function CfnModelBiasJobDefinition_DatasetFormatPropertyValidator(properties: an errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties))); } errors.collect(cdk.propertyValidator('csv', CfnModelBiasJobDefinition_CsvPropertyValidator)(properties.csv)); - errors.collect(cdk.propertyValidator('json', cdk.validateObject)(properties.json)); + errors.collect(cdk.propertyValidator('json', CfnModelBiasJobDefinition_JsonPropertyValidator)(properties.json)); errors.collect(cdk.propertyValidator('parquet', cdk.validateBoolean)(properties.parquet)); return errors.wrap('supplied properties not correct for "DatasetFormatProperty"'); } @@ -11512,7 +11512,7 @@ function cfnModelBiasJobDefinitionDatasetFormatPropertyToCloudFormation(properti CfnModelBiasJobDefinition_DatasetFormatPropertyValidator(properties).assertSuccess(); return { Csv: cfnModelBiasJobDefinitionCsvPropertyToCloudFormation(properties.csv), - Json: cdk.objectToCloudFormation(properties.json), + Json: cfnModelBiasJobDefinitionJsonPropertyToCloudFormation(properties.json), Parquet: cdk.booleanToCloudFormation(properties.parquet), }; } @@ -11528,7 +11528,7 @@ function CfnModelBiasJobDefinitionDatasetFormatPropertyFromCloudFormation(proper } const ret = new cfn_parse.FromCloudFormationPropertyObject(); ret.addPropertyResult('csv', 'Csv', properties.Csv != null ? CfnModelBiasJobDefinitionCsvPropertyFromCloudFormation(properties.Csv) : undefined); - ret.addPropertyResult('json', 'Json', properties.Json != null ? cfn_parse.FromCloudFormation.getAny(properties.Json) : undefined); + ret.addPropertyResult('json', 'Json', properties.Json != null ? CfnModelBiasJobDefinitionJsonPropertyFromCloudFormation(properties.Json) : undefined); ret.addPropertyResult('parquet', 'Parquet', properties.Parquet != null ? cfn_parse.FromCloudFormation.getBoolean(properties.Parquet) : undefined); ret.addUnrecognizedPropertiesAsExtra(properties); return ret; @@ -15402,7 +15402,7 @@ export namespace CfnModelExplainabilityJobDefinition { * * @link http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-sagemaker-modelexplainabilityjobdefinition-datasetformat.html#cfn-sagemaker-modelexplainabilityjobdefinition-datasetformat-json */ - readonly json?: any | cdk.IResolvable; + readonly json?: CfnModelExplainabilityJobDefinition.JsonProperty | cdk.IResolvable; /** * `CfnModelExplainabilityJobDefinition.DatasetFormatProperty.Parquet` * @@ -15426,7 +15426,7 @@ function CfnModelExplainabilityJobDefinition_DatasetFormatPropertyValidator(prop errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties))); } errors.collect(cdk.propertyValidator('csv', CfnModelExplainabilityJobDefinition_CsvPropertyValidator)(properties.csv)); - errors.collect(cdk.propertyValidator('json', cdk.validateObject)(properties.json)); + errors.collect(cdk.propertyValidator('json', CfnModelExplainabilityJobDefinition_JsonPropertyValidator)(properties.json)); errors.collect(cdk.propertyValidator('parquet', cdk.validateBoolean)(properties.parquet)); return errors.wrap('supplied properties not correct for "DatasetFormatProperty"'); } @@ -15444,7 +15444,7 @@ function cfnModelExplainabilityJobDefinitionDatasetFormatPropertyToCloudFormatio CfnModelExplainabilityJobDefinition_DatasetFormatPropertyValidator(properties).assertSuccess(); return { Csv: cfnModelExplainabilityJobDefinitionCsvPropertyToCloudFormation(properties.csv), - Json: cdk.objectToCloudFormation(properties.json), + Json: cfnModelExplainabilityJobDefinitionJsonPropertyToCloudFormation(properties.json), Parquet: cdk.booleanToCloudFormation(properties.parquet), }; } @@ -15460,7 +15460,7 @@ function CfnModelExplainabilityJobDefinitionDatasetFormatPropertyFromCloudFormat } const ret = new cfn_parse.FromCloudFormationPropertyObject(); ret.addPropertyResult('csv', 'Csv', properties.Csv != null ? CfnModelExplainabilityJobDefinitionCsvPropertyFromCloudFormation(properties.Csv) : undefined); - ret.addPropertyResult('json', 'Json', properties.Json != null ? cfn_parse.FromCloudFormation.getAny(properties.Json) : undefined); + ret.addPropertyResult('json', 'Json', properties.Json != null ? CfnModelExplainabilityJobDefinitionJsonPropertyFromCloudFormation(properties.Json) : undefined); ret.addPropertyResult('parquet', 'Parquet', properties.Parquet != null ? cfn_parse.FromCloudFormation.getBoolean(properties.Parquet) : undefined); ret.addUnrecognizedPropertiesAsExtra(properties); return ret; @@ -20808,7 +20808,7 @@ export namespace CfnModelQualityJobDefinition { * * @link http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-sagemaker-modelqualityjobdefinition-datasetformat.html#cfn-sagemaker-modelqualityjobdefinition-datasetformat-json */ - readonly json?: any | cdk.IResolvable; + readonly json?: CfnModelQualityJobDefinition.JsonProperty | cdk.IResolvable; /** * `CfnModelQualityJobDefinition.DatasetFormatProperty.Parquet` * @@ -20832,7 +20832,7 @@ function CfnModelQualityJobDefinition_DatasetFormatPropertyValidator(properties: errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties))); } errors.collect(cdk.propertyValidator('csv', CfnModelQualityJobDefinition_CsvPropertyValidator)(properties.csv)); - errors.collect(cdk.propertyValidator('json', cdk.validateObject)(properties.json)); + errors.collect(cdk.propertyValidator('json', CfnModelQualityJobDefinition_JsonPropertyValidator)(properties.json)); errors.collect(cdk.propertyValidator('parquet', cdk.validateBoolean)(properties.parquet)); return errors.wrap('supplied properties not correct for "DatasetFormatProperty"'); } @@ -20850,7 +20850,7 @@ function cfnModelQualityJobDefinitionDatasetFormatPropertyToCloudFormation(prope CfnModelQualityJobDefinition_DatasetFormatPropertyValidator(properties).assertSuccess(); return { Csv: cfnModelQualityJobDefinitionCsvPropertyToCloudFormation(properties.csv), - Json: cdk.objectToCloudFormation(properties.json), + Json: cfnModelQualityJobDefinitionJsonPropertyToCloudFormation(properties.json), Parquet: cdk.booleanToCloudFormation(properties.parquet), }; } @@ -20866,7 +20866,7 @@ function CfnModelQualityJobDefinitionDatasetFormatPropertyFromCloudFormation(pro } const ret = new cfn_parse.FromCloudFormationPropertyObject(); ret.addPropertyResult('csv', 'Csv', properties.Csv != null ? CfnModelQualityJobDefinitionCsvPropertyFromCloudFormation(properties.Csv) : undefined); - ret.addPropertyResult('json', 'Json', properties.Json != null ? cfn_parse.FromCloudFormation.getAny(properties.Json) : undefined); + ret.addPropertyResult('json', 'Json', properties.Json != null ? CfnModelQualityJobDefinitionJsonPropertyFromCloudFormation(properties.Json) : undefined); ret.addPropertyResult('parquet', 'Parquet', properties.Parquet != null ? cfn_parse.FromCloudFormation.getBoolean(properties.Parquet) : undefined); ret.addUnrecognizedPropertiesAsExtra(properties); return ret; @@ -22693,7 +22693,7 @@ export namespace CfnMonitoringSchedule { * * @link http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-sagemaker-monitoringschedule-datasetformat.html#cfn-sagemaker-monitoringschedule-datasetformat-json */ - readonly json?: any | cdk.IResolvable; + readonly json?: CfnMonitoringSchedule.JsonProperty | cdk.IResolvable; /** * `CfnMonitoringSchedule.DatasetFormatProperty.Parquet` * @@ -22717,7 +22717,7 @@ function CfnMonitoringSchedule_DatasetFormatPropertyValidator(properties: any): errors.collect(new cdk.ValidationResult('Expected an object, but received: ' + JSON.stringify(properties))); } errors.collect(cdk.propertyValidator('csv', CfnMonitoringSchedule_CsvPropertyValidator)(properties.csv)); - errors.collect(cdk.propertyValidator('json', cdk.validateObject)(properties.json)); + errors.collect(cdk.propertyValidator('json', CfnMonitoringSchedule_JsonPropertyValidator)(properties.json)); errors.collect(cdk.propertyValidator('parquet', cdk.validateBoolean)(properties.parquet)); return errors.wrap('supplied properties not correct for "DatasetFormatProperty"'); } @@ -22735,7 +22735,7 @@ function cfnMonitoringScheduleDatasetFormatPropertyToCloudFormation(properties: CfnMonitoringSchedule_DatasetFormatPropertyValidator(properties).assertSuccess(); return { Csv: cfnMonitoringScheduleCsvPropertyToCloudFormation(properties.csv), - Json: cdk.objectToCloudFormation(properties.json), + Json: cfnMonitoringScheduleJsonPropertyToCloudFormation(properties.json), Parquet: cdk.booleanToCloudFormation(properties.parquet), }; } @@ -22751,7 +22751,7 @@ function CfnMonitoringScheduleDatasetFormatPropertyFromCloudFormation(properties } const ret = new cfn_parse.FromCloudFormationPropertyObject(); ret.addPropertyResult('csv', 'Csv', properties.Csv != null ? CfnMonitoringScheduleCsvPropertyFromCloudFormation(properties.Csv) : undefined); - ret.addPropertyResult('json', 'Json', properties.Json != null ? cfn_parse.FromCloudFormation.getAny(properties.Json) : undefined); + ret.addPropertyResult('json', 'Json', properties.Json != null ? CfnMonitoringScheduleJsonPropertyFromCloudFormation(properties.Json) : undefined); ret.addPropertyResult('parquet', 'Parquet', properties.Parquet != null ? cfn_parse.FromCloudFormation.getBoolean(properties.Parquet) : undefined); ret.addUnrecognizedPropertiesAsExtra(properties); return ret; ``` --- tools/@aws-cdk/cfn2ts/lib/genspec.ts | 12 ++++----- tools/@aws-cdk/cfn2ts/lib/spec-utils.ts | 34 ++++++++++++++++++++----- 2 files changed, 34 insertions(+), 12 deletions(-) diff --git a/tools/@aws-cdk/cfn2ts/lib/genspec.ts b/tools/@aws-cdk/cfn2ts/lib/genspec.ts index a05daef0f54d9..d6896471934ce 100644 --- a/tools/@aws-cdk/cfn2ts/lib/genspec.ts +++ b/tools/@aws-cdk/cfn2ts/lib/genspec.ts @@ -282,13 +282,13 @@ export function isPrimitive(type: CodeName): boolean { || type.className === 'Date'; } -function specTypeToCodeType(resourceContext: CodeName, type: string): CodeName { +function specTypeToCodeType(resourceContext: CodeName, type: string, primitiveType: boolean): CodeName { if (type.endsWith('[]')) { - const itemType = specTypeToCodeType(resourceContext, type.slice(0, -2)); + const itemType = specTypeToCodeType(resourceContext, type.slice(0, -2), primitiveType); return CodeName.forPrimitive(`${itemType.className}[]`); } - if (schema.isPrimitiveType(type)) { - return specPrimitiveToCodePrimitive(type); + if (primitiveType) { + return specPrimitiveToCodePrimitive(type as schema.PrimitiveType); } else if (type === 'Tag') { // Tags are not considered primitive by the CloudFormation spec (even though they are intrinsic) // so we won't consider them primitive either. @@ -302,8 +302,8 @@ function specTypeToCodeType(resourceContext: CodeName, type: string): CodeName { /** * Translate a list of type references in a resource context to a list of code names */ -export function specTypesToCodeTypes(resourceContext: CodeName, types: string[]): CodeName[] { - return types.map(type => specTypeToCodeType(resourceContext, type)); +export function specTypesToCodeTypes(resourceContext: CodeName, types: { [name: string]: boolean }): CodeName[] { + return Object.entries(types).map(([name, primitive]) => specTypeToCodeType(resourceContext, name, primitive)); } export interface PropertyVisitor { diff --git a/tools/@aws-cdk/cfn2ts/lib/spec-utils.ts b/tools/@aws-cdk/cfn2ts/lib/spec-utils.ts index 7637bc199439a..bbed06bfa2a48 100644 --- a/tools/@aws-cdk/cfn2ts/lib/spec-utils.ts +++ b/tools/@aws-cdk/cfn2ts/lib/spec-utils.ts @@ -71,10 +71,21 @@ export class PropertyAttributeName extends SpecName { } /** - * Return a list of all allowable item types (either primitive or complex). + * Return a list of all allowable item types, separating out primitive and complex + * types because sometimes a complex type can have the same name as a primitive type. + * If we only return the names in this case then the primitive type will always override + * the complex type (not what we want). */ -export function itemTypeNames(spec: schema.CollectionProperty): string[] { - return complexItemTypeNames(spec).concat(primitiveItemTypeNames(spec)); +export function itemTypeNames(spec: schema.CollectionProperty): { [name: string]: boolean } { + const types = complexItemTypeNames(spec).map(type => { return { [type]: false }; }) + .concat(primitiveItemTypeNames(spec).map(type => { return { [type]: true }; })); + return types.reduce((prev, acc) => { + acc = { + ...prev, + ...acc, + }; + return acc; + }, {} as { [name: string]: boolean }); } function complexItemTypeNames(spec: schema.CollectionProperty): string[] { @@ -98,10 +109,21 @@ function primitiveItemTypeNames(spec: schema.CollectionProperty): string[] { } /** - * Return a list of all allowable types (either primitive or complex). + * Return a list of all allowable item types, separating out primitive and complex + * types because sometimes a complex type can have the same name as a primitive type. + * If we only return the names in this case then the primitive type will always override + * the complex type (not what we want). */ -export function scalarTypeNames(spec: schema.ScalarProperty): string[] { - return complexScalarTypeNames(spec).concat(primitiveScalarTypeNames(spec)); +export function scalarTypeNames(spec: schema.ScalarProperty): { [name: string]: boolean } { + const types = complexScalarTypeNames(spec).map(type => { return { [type]: false }; }) + .concat(primitiveScalarTypeNames(spec).map(type => { return { [type]: true }; })); + return types.reduce((prev, acc) => { + acc = { + ...prev, + ...acc, + }; + return acc; + }, {} as { [name: string]: boolean }); } function complexScalarTypeNames(spec: schema.ScalarProperty): string[] { From e70bfefdb3adca0992954d3f9f500973e15c429e Mon Sep 17 00:00:00 2001 From: corymhall <43035978+corymhall@users.noreply.github.com> Date: Fri, 5 May 2023 15:27:12 +0000 Subject: [PATCH 2/2] refactoring --- tools/@aws-cdk/cfn2ts/lib/genspec.ts | 16 +++++++++---- tools/@aws-cdk/cfn2ts/lib/spec-utils.ts | 30 ++++++++++--------------- 2 files changed, 24 insertions(+), 22 deletions(-) diff --git a/tools/@aws-cdk/cfn2ts/lib/genspec.ts b/tools/@aws-cdk/cfn2ts/lib/genspec.ts index d6896471934ce..c3a7476b71737 100644 --- a/tools/@aws-cdk/cfn2ts/lib/genspec.ts +++ b/tools/@aws-cdk/cfn2ts/lib/genspec.ts @@ -282,12 +282,17 @@ export function isPrimitive(type: CodeName): boolean { || type.className === 'Date'; } -function specTypeToCodeType(resourceContext: CodeName, type: string, primitiveType: boolean): CodeName { +/** + * @param resourceContext + * @param type the name of the type + * @param complexType whether the type is a complexType (true) or primitive type (false) + */ +function specTypeToCodeType(resourceContext: CodeName, type: string, complexType: boolean): CodeName { if (type.endsWith('[]')) { - const itemType = specTypeToCodeType(resourceContext, type.slice(0, -2), primitiveType); + const itemType = specTypeToCodeType(resourceContext, type.slice(0, -2), complexType); return CodeName.forPrimitive(`${itemType.className}[]`); } - if (primitiveType) { + if (!complexType) { return specPrimitiveToCodePrimitive(type as schema.PrimitiveType); } else if (type === 'Tag') { // Tags are not considered primitive by the CloudFormation spec (even though they are intrinsic) @@ -301,9 +306,12 @@ function specTypeToCodeType(resourceContext: CodeName, type: string, primitiveTy /** * Translate a list of type references in a resource context to a list of code names + * + * @param resourceContext + * @param types name and whether the type is a complex type (true) or primitive type (false) */ export function specTypesToCodeTypes(resourceContext: CodeName, types: { [name: string]: boolean }): CodeName[] { - return Object.entries(types).map(([name, primitive]) => specTypeToCodeType(resourceContext, name, primitive)); + return Object.entries(types).map(([name, complexType]) => specTypeToCodeType(resourceContext, name, complexType)); } export interface PropertyVisitor { diff --git a/tools/@aws-cdk/cfn2ts/lib/spec-utils.ts b/tools/@aws-cdk/cfn2ts/lib/spec-utils.ts index bbed06bfa2a48..affd3b2e56c9b 100644 --- a/tools/@aws-cdk/cfn2ts/lib/spec-utils.ts +++ b/tools/@aws-cdk/cfn2ts/lib/spec-utils.ts @@ -75,17 +75,14 @@ export class PropertyAttributeName extends SpecName { * types because sometimes a complex type can have the same name as a primitive type. * If we only return the names in this case then the primitive type will always override * the complex type (not what we want). + * + * @returns type name and whether the type is a complex type (true) or primitive type (false) */ export function itemTypeNames(spec: schema.CollectionProperty): { [name: string]: boolean } { - const types = complexItemTypeNames(spec).map(type => { return { [type]: false }; }) - .concat(primitiveItemTypeNames(spec).map(type => { return { [type]: true }; })); - return types.reduce((prev, acc) => { - acc = { - ...prev, - ...acc, - }; - return acc; - }, {} as { [name: string]: boolean }); + const types = complexItemTypeNames(spec).map(type => [type, true]) + .concat(primitiveItemTypeNames(spec).map(type => [type, false])); + + return Object.fromEntries(types); } function complexItemTypeNames(spec: schema.CollectionProperty): string[] { @@ -113,17 +110,14 @@ function primitiveItemTypeNames(spec: schema.CollectionProperty): string[] { * types because sometimes a complex type can have the same name as a primitive type. * If we only return the names in this case then the primitive type will always override * the complex type (not what we want). + * + * @returns type name and whether the type is a complex type (true) or primitive type (false) */ export function scalarTypeNames(spec: schema.ScalarProperty): { [name: string]: boolean } { - const types = complexScalarTypeNames(spec).map(type => { return { [type]: false }; }) - .concat(primitiveScalarTypeNames(spec).map(type => { return { [type]: true }; })); - return types.reduce((prev, acc) => { - acc = { - ...prev, - ...acc, - }; - return acc; - }, {} as { [name: string]: boolean }); + const types = complexScalarTypeNames(spec).map(type => [type, true] ) + .concat(primitiveScalarTypeNames(spec).map(type => [type, false])); + + return Object.fromEntries(types); } function complexScalarTypeNames(spec: schema.ScalarProperty): string[] {