import * as camelcase from 'camelcase' ; import * as reflect from 'jsii-reflect' ; import { Linter } from '../linter' ; import { CoreTypes } from './core-types' ; import { ResourceReflection } from './resource' ; export const cfnResourceLinter = new Linter ( a => CfnResourceReflection . findAll ( a ) ) ; cfnResourceLinter . add ( { code : 'resource-class' , message : 'every resource must have a resource class (L2), add \'@resource %s\' to its docstring' , warning : true , eval : e => { const l2 = ResourceReflection . findAll ( e . ctx . classType . assembly ) . find ( r => r . cfn . fullname === e . ctx . fullname ) ; e . assert ( l2 , e . ctx . fullname , e . ctx . fullname ) ; } , } ) ; export class CfnResourceReflection { param fullName public static findByName ( sys , fullName ) { for ( const cls of sys . classes ) { if ( cls . docs . customTag ( 'cloudformationResource' ) ?. toLocaleLowerCase ( ) === fullName . toLocaleLowerCase ( ) ) { return new CfnResourceReflection ( cls ) ; } } return undefined ; } /**
     * Returns all CFN resource classes within an assembly.
     */ public static findAll ( assembly ) { return assembly . classes . filter ( c => CoreTypes . isCfnResource ( c ) ) . map ( c => new CfnResourceReflection ( c ) ) ; } public readonly classType : reflect . ClassType ; public readonly fullname : string ; public readonly namespace : string ; public readonly basename : string ; public readonly attributeNames : string [ ] ; public readonly doc : string ; constructor ( cls ) { this . classType = cls ; this . basename = cls . name . substr ( 'Cfn' . length ) ; const initializerDoc = ( cls . initializer && cls . initializer . docs . docs . summary ) || '' ; const out = /a new `([^`]+)`/ . exec ( initializerDoc ) ; const fullname = out && out [ 1 ] ; if ( ! fullname ) { throw new Error ( `Unable to extract CloudFormation resource name from initializer documentation of ${ cls }` ) ; } this . fullname = fullname ; this . namespace = fullname . split ( '::' ) . slice ( 0 , 2 ) . join ( '::' ) ; this . attributeNames = cls . ownProperties . filter ( p => ( p . docs . docs . custom || { } ) . cloudformationAttribute ) . map ( p => p . docs . customTag ( 'cloudformationAttribute' ) || '<error>' ) . map ( p => this . attributePropertyNameFromCfnName ( p ) ) ; this . doc = cls . docs . docs . see || '' ; } private attributePropertyNameFromCfnName ( name ) { if ( this . basename === 'SecurityGroup' && name === 'GroupId' ) { return 'Id' ; } return camelcase ( name , { pascalCase : true } ) ; } }