packages/awslint/lib/rules/cloudwatch-events.ts (64 lines of code) (raw):
import * as reflect from 'jsii-reflect';
import { ConstructReflection } from './construct';
import { CoreTypes } from './core-types';
import { Linter } from '../linter';
export const eventsLinter = new Linter<EventsReflection>(assembly => assembly.classes
.filter(t => CoreTypes.isConstructClass(t))
.map(construct => new EventsReflection(construct)));
export class EventsReflection extends ConstructReflection {
public get directEventMethods() {
return this.classType.allMethods.filter(isDirectEventMethod);
}
public get cloudTrailEventMethods() {
return this.classType.allMethods.filter(isCloudTrailEventMethod);
}
}
const ON_EVENT_OPTIONS_FQN = 'aws-cdk-lib.aws_events.OnEventOptions';
const EVENT_RULE_FQN = 'aws-cdk-lib.aws_events.Rule';
eventsLinter.add({
code: 'events-in-interface',
message: '\'onXxx()\' methods should also be defined on construct interface',
eval: e => {
for (const method of e.ctx.directEventMethods.concat(e.ctx.cloudTrailEventMethods)) {
e.assert(!e.ctx.interfaceType || e.ctx.interfaceType.allMethods.filter(m => !m.protected).some(m => m.name === method.name), `${e.ctx.fqn}.${method.name}`);
}
},
});
eventsLinter.add({
code: 'events-generic',
message: 'if there are specific \'onXxx()\' methods, there should also be a generic \'onEvent()\' method',
eval: e => {
e.assert(e.ctx.directEventMethods.length === 0 || e.ctx.classType.allMethods.some(m => m.name === 'onEvent'), e.ctx.fqn);
},
});
eventsLinter.add({
code: 'events-generic-cloudtrail',
message: 'if there are specific \'onCloudTrailXxx()\' methods, there should also be a generic \'onCloudTrailEvent()\' method',
eval: e => {
e.assert(e.ctx.cloudTrailEventMethods.length === 0 || e.ctx.classType.allMethods.some(m => m.name === 'onCloudTrailEvent'), e.ctx.fqn);
},
});
eventsLinter.add({
code: 'events-method-signature',
message: 'all \'onXxx()\' methods should have the CloudWatch Events signature (id: string, options: events.OnEventOptions = {}) => events.Rule',
eval: e => {
for (const method of e.ctx.directEventMethods) {
// give slack to protected methods like "onSynthesize", "onPrepare", ...
if (method.protected) {
continue;
}
e.assertSignature(method, {
parameters: [
{ type: 'string' },
{ type: ON_EVENT_OPTIONS_FQN, subtypeAllowed: true, optional: true },
],
returns: EVENT_RULE_FQN,
});
}
},
});
function isDirectEventMethod(m: reflect.Method) {
return !m.protected && m.name.startsWith('on') && ! m.name.startsWith('onCloudTrail');
}
function isCloudTrailEventMethod(m: reflect.Method) {
return m.name.startsWith('onCloudTrail');
}