From a6ff964d84834985f485ae657e8fc5ecd6801958 Mon Sep 17 00:00:00 2001 From: Mariusz Nowak Date: Thu, 1 Oct 2020 15:24:37 +0200 Subject: [PATCH] feat: Coerce primitive config values to arrays, when array is expected --- lib/classes/ConfigSchemaHandler/index.js | 2 +- lib/configSchema.js | 1 - .../aws/package/compile/events/alb/index.js | 16 +++--- .../package/compile/events/httpApi/index.js | 4 +- lib/plugins/aws/provider/awsProvider.js | 52 +++++-------------- 5 files changed, 21 insertions(+), 54 deletions(-) diff --git a/lib/classes/ConfigSchemaHandler/index.js b/lib/classes/ConfigSchemaHandler/index.js index 9a53368100d..b42925cc7a4 100644 --- a/lib/classes/ConfigSchemaHandler/index.js +++ b/lib/classes/ConfigSchemaHandler/index.js @@ -91,7 +91,7 @@ class ConfigSchemaHandler { this.relaxProviderSchema(); } - const ajv = new Ajv({ allErrors: true, coerceTypes: true, verbose: true }); + const ajv = new Ajv({ allErrors: true, coerceTypes: 'array', verbose: true }); require('ajv-keywords')(ajv, 'regexp'); // Workaround https://github.com/ajv-validator/ajv/issues/1255 normalizeSchemaObject(this.schema, this.schema); diff --git a/lib/configSchema.js b/lib/configSchema.js index f035a16f011..fd063bc1bdf 100644 --- a/lib/configSchema.js +++ b/lib/configSchema.js @@ -17,7 +17,6 @@ const schema = { disabledDeprecations: { anyOf: [ { const: '*' }, - { $ref: '#/definitions/errorCode' }, { type: 'array', items: { $ref: '#/definitions/errorCode' }, diff --git a/lib/plugins/aws/package/compile/events/alb/index.js b/lib/plugins/aws/package/compile/events/alb/index.js index ebf3be3e69f..dbcc45dae30 100644 --- a/lib/plugins/aws/package/compile/events/alb/index.js +++ b/lib/plugins/aws/package/compile/events/alb/index.js @@ -7,10 +7,8 @@ const compileTargetGroups = require('./lib/targetGroups'); const compileListenerRules = require('./lib/listenerRules'); const compilePermissions = require('./lib/permissions'); -function arrayOrSingleSchema(schema) { - return { - oneOf: [schema, { type: 'array', items: schema }], - }; +function defineArray(schema) { + return { type: 'array', items: schema }; } class AwsCompileAlbEvents { @@ -37,7 +35,7 @@ class AwsCompileAlbEvents { this.serverless.configSchemaHandler.defineFunctionEvent('aws', 'alb', { type: 'object', properties: { - authorizer: arrayOrSingleSchema({ type: 'string' }), + authorizer: defineArray({ type: 'string' }), conditions: { type: 'object', properties: { @@ -50,19 +48,19 @@ class AwsCompileAlbEvents { additionalProperties: false, required: ['name', 'values'], }, - host: arrayOrSingleSchema({ + host: defineArray({ type: 'string', pattern: '^[A-Za-z0-9*?.-]+$', maxLength: 128, }), - ip: arrayOrSingleSchema({ + ip: defineArray({ oneOf: [ { type: 'string', format: 'ipv4' }, { type: 'string', format: 'ipv6' }, ], }), - method: arrayOrSingleSchema({ type: 'string', pattern: '^[A-Z_-]+$', maxLength: 40 }), - path: arrayOrSingleSchema({ + method: defineArray({ type: 'string', pattern: '^[A-Z_-]+$', maxLength: 40 }), + path: defineArray({ type: 'string', pattern: '^([A-Za-z0-9*?_.$/~"\'@:+-]|&)+$', maxLength: 128, diff --git a/lib/plugins/aws/package/compile/events/httpApi/index.js b/lib/plugins/aws/package/compile/events/httpApi/index.js index 150f362a218..e065387526a 100644 --- a/lib/plugins/aws/package/compile/events/httpApi/index.js +++ b/lib/plugins/aws/package/compile/events/httpApi/index.js @@ -68,9 +68,7 @@ class HttpApiEvents { anyOf: [{ type: 'string' }, { $ref: '#/definitions/awsCfFunction' }], }, name: { type: 'string' }, - scopes: { - oneOf: [{ type: 'string' }, { type: 'array', items: { type: 'string' } }], - }, + scopes: { type: 'array', items: { type: 'string' } }, }, oneOf: [{ required: ['id'] }, { required: ['name'] }], additionalProperties: false, diff --git a/lib/plugins/aws/provider/awsProvider.js b/lib/plugins/aws/provider/awsProvider.js index 1b285dfb991..34fb45409b2 100644 --- a/lib/plugins/aws/provider/awsProvider.js +++ b/lib/plugins/aws/provider/awsProvider.js @@ -282,9 +282,7 @@ class AwsProvider { required: ['Fn::Sub'], additionalProperties: false, }, - awsIamPolicyAction: { - anyOf: [{ type: 'string' }, { type: 'array', items: { type: 'string' } }], - }, + awsIamPolicyAction: { type: 'array', items: { type: 'string' } }, awsIamPolicyPrincipal: { anyOf: [ { const: '*' }, @@ -294,30 +292,19 @@ class AwsProvider { AWS: { anyOf: [ { const: '*' }, - { $ref: '#/definitions/awsArn' }, { type: 'array', items: { $ref: '#/definitions/awsArn' } }, ], }, - Federated: { - anyOf: [{ type: 'string' }, { type: 'array', items: { type: 'string' } }], - }, - Service: { - anyOf: [{ type: 'string' }, { type: 'array', items: { type: 'string' } }], - }, - CanonicalUser: { - anyOf: [{ type: 'string' }, { type: 'array', items: { type: 'string' } }], - }, + Federated: { type: 'array', items: { type: 'string' } }, + Service: { type: 'array', items: { type: 'string' } }, + CanonicalUser: { type: 'array', items: { type: 'string' } }, }, additionalProperties: false, }, ], }, awsIamPolicyResource: { - anyOf: [ - { const: '*' }, - { $ref: '#/definitions/awsArn' }, - { type: 'array', items: { $ref: '#/definitions/awsArn' } }, - ], + anyOf: [{ const: '*' }, { type: 'array', items: { $ref: '#/definitions/awsArn' } }], }, // Definition of Statement taken from https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_grammar.html#policies-grammar-bnf awsIamPolicyStatements: { @@ -405,9 +392,7 @@ class AwsProvider { pattern: '^[/#A-Za-z0-9-_.]+$', }, awsResourceCondition: { type: 'string' }, - awsResourceDependsOn: { - oneOf: [{ type: 'string' }, { type: 'array', items: { type: 'string' } }], - }, + awsResourceDependsOn: { type: 'array', items: { type: 'string' } }, awsResourceProperties: { Properties: { type: 'object' }, CreationPolicy: { type: 'object' }, @@ -489,13 +474,8 @@ class AwsProvider { identitySource: { $ref: '#/definitions/awsCfInstruction' }, issuerUrl: { $ref: '#/definitions/awsCfInstruction' }, audience: { - oneOf: [ - { $ref: '#/definitions/awsCfInstruction' }, - { - type: 'array', - items: { $ref: '#/definitions/awsCfInstruction' }, - }, - ], + type: 'array', + items: { $ref: '#/definitions/awsCfInstruction' }, }, }, required: ['identitySource', 'issuerUrl', 'audience'], @@ -509,18 +489,10 @@ class AwsProvider { type: 'object', properties: { allowCredentials: { type: 'boolean' }, - allowedHeaders: { - oneOf: [{ type: 'string' }, { type: 'array', items: { type: 'string' } }], - }, - allowedMethods: { - oneOf: [{ type: 'string' }, { type: 'array', items: { type: 'string' } }], - }, - allowedOrigins: { - oneOf: [{ type: 'string' }, { type: 'array', items: { type: 'string' } }], - }, - exposedResponseHeaders: { - oneOf: [{ type: 'string' }, { type: 'array', items: { type: 'string' } }], - }, + allowedHeaders: { type: 'array', items: { type: 'string' } }, + allowedMethods: { type: 'array', items: { type: 'string' } }, + allowedOrigins: { type: 'array', items: { type: 'string' } }, + exposedResponseHeaders: { type: 'array', items: { type: 'string' } }, maxAge: { type: 'integer', minimum: 0 }, }, additionalProperties: false,