diff --git a/lib/plugins/aws/package/compile/events/cloudWatchEvent/index.js b/lib/plugins/aws/package/compile/events/cloudWatchEvent/index.js index 2f6646423df..bba42f5e032 100644 --- a/lib/plugins/aws/package/compile/events/cloudWatchEvent/index.js +++ b/lib/plugins/aws/package/compile/events/cloudWatchEvent/index.js @@ -11,9 +11,37 @@ class AwsCompileCloudWatchEventEvents { 'package:compileEvents': this.compileCloudWatchEventEvents.bind(this), }; - // TODO: Complete schema, see https://github.com/serverless/serverless/issues/8026 this.serverless.configSchemaHandler.defineFunctionEvent('aws', 'cloudwatchEvent', { type: 'object', + properties: { + event: { type: 'object' }, + input: { + oneOf: [{ type: 'string', maxLength: 8192 }, { type: 'object' }], + }, + inputPath: { type: 'string', minLength: 1, maxLength: 256 }, + inputTransformer: { + type: 'object', + properties: { + inputPathsMap: { + type: 'object', + additionalProperties: { type: 'string', minLength: 1 }, + }, + inputTemplate: { type: 'string', minLength: 1, maxLength: 8192 }, + }, + required: ['inputTemplate'], + additionalProperties: false, + }, + description: { type: 'string', maxLength: 512 }, + name: { type: 'string', pattern: '[a-zA-Z0-9-_.]+', minLength: 1, maxLength: 64 }, + enabled: { type: 'boolean' }, + }, + oneOf: [ + { required: ['input'] }, + { required: ['inputPath'] }, + { required: ['inputTransformer'] }, + { required: [] }, + ], + additionalProperties: false, }); } @@ -26,60 +54,30 @@ class AwsCompileCloudWatchEventEvents { functionObj.events.forEach(event => { if (event.cloudwatchEvent) { cloudWatchEventNumberInFunction++; - let EventPattern; let State; let Input; - let InputPath; let InputTransformer; - let Description; - let Name; - - if (typeof event.cloudwatchEvent === 'object') { - if (!event.cloudwatchEvent.event) { - const errorMessage = [ - `Missing "event" property for cloudwatch event in function ${functionName}`, - ' Please check the docs for more info.', - ].join(''); - throw new this.serverless.classes.Error(errorMessage); - } - - EventPattern = JSON.stringify(event.cloudwatchEvent.event); - State = 'ENABLED'; - if (event.cloudwatchEvent.enabled === false) { - State = 'DISABLED'; - } - Input = event.cloudwatchEvent.input; - InputPath = event.cloudwatchEvent.inputPath; - InputTransformer = event.cloudwatchEvent.inputTransformer; - Description = event.cloudwatchEvent.description; - Name = event.cloudwatchEvent.name; - - const inputOptions = [Input, InputPath, InputTransformer].filter(i => i); - if (inputOptions.length > 1) { - const errorMessage = [ - 'You can only set one of input, inputPath, or inputTransformer ', - 'properties at the same time for cloudwatch events. ', - 'Please check the AWS docs for more info', - ].join(''); - throw new this.serverless.classes.Error(errorMessage); - } - if (Input && typeof Input === 'object') { - Input = JSON.stringify(Input); - } - if (Input && typeof Input === 'string') { - // escape quotes to favor JSON.parse - Input = Input.replace(/\"/g, '\\"'); // eslint-disable-line - } - if (InputTransformer) { - InputTransformer = this.formatInputTransformer(InputTransformer); - } - } else { - const errorMessage = [ - `CloudWatch event of function "${functionName}" is not an object`, - ' Please check the docs for more info.', - ].join(''); - throw new this.serverless.classes.Error(errorMessage); + const EventPattern = JSON.stringify(event.cloudwatchEvent.event); + State = 'ENABLED'; + if (event.cloudwatchEvent.enabled === false) { + State = 'DISABLED'; + } + const Name = event.cloudwatchEvent.name; + const InputPath = event.cloudwatchEvent.inputPath; + const Description = event.cloudwatchEvent.description; + Input = event.cloudwatchEvent.input; + InputTransformer = event.cloudwatchEvent.inputTransformer; + + if (Input && typeof Input === 'object') { + Input = JSON.stringify(Input); + } + if (Input && typeof Input === 'string') { + // escape quotes to favor JSON.parse + Input = Input.replace(/\"/g, '\\"'); // eslint-disable-line + } + if (InputTransformer) { + InputTransformer = this.formatInputTransformer(InputTransformer); } const lambdaLogicalId = this.provider.naming.getLambdaLogicalId(functionName); @@ -144,12 +142,6 @@ class AwsCompileCloudWatchEventEvents { } formatInputTransformer(inputTransformer) { - if (!inputTransformer.inputTemplate) { - throw new this.serverless.classes.Error( - 'The inputTemplate key is required when specifying an ' + - 'inputTransformer for a cloudwatchEvent event' - ); - } const cfmOutput = { // InputTemplate is required InputTemplate: inputTransformer.inputTemplate, diff --git a/lib/plugins/aws/package/compile/events/cloudWatchEvent/index.test.js b/lib/plugins/aws/package/compile/events/cloudWatchEvent/index.test.js index 685da854056..6c69a814c21 100644 --- a/lib/plugins/aws/package/compile/events/cloudWatchEvent/index.test.js +++ b/lib/plugins/aws/package/compile/events/cloudWatchEvent/index.test.js @@ -23,48 +23,6 @@ describe('awsCompileCloudWatchEventEvents', () => { }); describe('#compileCloudWatchEventEvents()', () => { - it('should throw an error if cloudwatch event type is not an object', () => { - awsCompileCloudWatchEventEvents.serverless.service.functions = { - first: { - events: [ - { - cloudwatchEvent: 42, - }, - ], - }, - }; - - expect(() => awsCompileCloudWatchEventEvents.compileCloudWatchEventEvents()).to.throw(Error); - - awsCompileCloudWatchEventEvents.serverless.service.functions = { - first: { - events: [ - { - cloudwatchEvent: '42', - }, - ], - }, - }; - - expect(() => awsCompileCloudWatchEventEvents.compileCloudWatchEventEvents()).to.throw(Error); - }); - - it('should throw an error if the "event" property is not given', () => { - awsCompileCloudWatchEventEvents.serverless.service.functions = { - first: { - events: [ - { - cloudwatchEvent: { - event: null, - }, - }, - ], - }, - }; - - expect(() => awsCompileCloudWatchEventEvents.compileCloudWatchEventEvents()).to.throw(Error); - }); - it('should create corresponding resources when cloudwatch events are given', () => { awsCompileCloudWatchEventEvents.serverless.service.functions = { first: { @@ -340,87 +298,6 @@ describe('awsCompileCloudWatchEventEvents', () => { ).to.equal('{"key":"value"}'); }); - it('should throw an error when both Input and InputPath are set', () => { - awsCompileCloudWatchEventEvents.serverless.service.functions = { - first: { - events: [ - { - cloudwatchEvent: { - event: { - 'source': ['aws.ec2'], - 'detail-type': ['EC2 Instance State-change Notification'], - 'detail': { state: ['pending'] }, - }, - enabled: false, - input: { - key: 'value', - }, - inputPath: '$.stageVariables', - }, - }, - ], - }, - }; - - expect(() => awsCompileCloudWatchEventEvents.compileCloudWatchEventEvents()).to.throw(Error); - }); - - it('should throw an error when both Input and InputTransformer are set', () => { - awsCompileCloudWatchEventEvents.serverless.service.functions = { - first: { - events: [ - { - cloudwatchEvent: { - event: { - 'source': ['aws.ec2'], - 'detail-type': ['EC2 Instance State-change Notification'], - 'detail': { state: ['pending'] }, - }, - enabled: false, - input: { - key: 'value', - }, - inputTransformer: { - inputPathsMap: { - eventTime: '$.time', - }, - inputTemplate: '{"time": , "key1": "value1"}', - }, - }, - }, - ], - }, - }; - - expect(() => awsCompileCloudWatchEventEvents.compileCloudWatchEventEvents()).to.throw(Error); - }); - - it('should throw an error when inputTransformer does not have inputTemplate', () => { - awsCompileCloudWatchEventEvents.serverless.service.functions = { - first: { - events: [ - { - cloudwatchEvent: { - event: { - 'source': ['aws.ec2'], - 'detail-type': ['EC2 Instance State-change Notification'], - 'detail': { state: ['pending'] }, - }, - enabled: false, - inputTransformer: { - inputPathsMap: { - eventTime: '$.time', - }, - }, - }, - }, - ], - }, - }; - - expect(() => awsCompileCloudWatchEventEvents.compileCloudWatchEventEvents()).to.throw(Error); - }); - it('should respect variables if multi-line variables is given', () => { awsCompileCloudWatchEventEvents.serverless.service.functions = { first: {