From 0834b9c1c9d5909368da6fbe9414868df89b54c3 Mon Sep 17 00:00:00 2001 From: Mariusz Nowak Date: Mon, 21 Sep 2020 09:37:01 +0200 Subject: [PATCH 1/2] refactor(Config Schema): Do not pass obsolete arguments --- lib/classes/ConfigSchemaHandler/index.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lib/classes/ConfigSchemaHandler/index.js b/lib/classes/ConfigSchemaHandler/index.js index 5baf4931d72..d191ad1316e 100644 --- a/lib/classes/ConfigSchemaHandler/index.js +++ b/lib/classes/ConfigSchemaHandler/index.js @@ -79,9 +79,7 @@ class ConfigSchemaHandler { validate(userConfig); if (validate.errors) { - const messages = normalizeAjvErrors(validate.errors, userConfig, this.schema).map( - err => err.message - ); + const messages = normalizeAjvErrors(validate.errors).map(err => err.message); this.handleErrorMessages(messages); } } From 074dd7fe0c95270066e676c4167aac5c14283abc Mon Sep 17 00:00:00 2001 From: Mariusz Nowak Date: Mon, 21 Sep 2020 09:53:44 +0200 Subject: [PATCH 2/2] fix(Config Schema): Treat explicit `null` or `undefined` as no value Workaround for https://github.com/ajv-validator/ajv/issues/1287 --- lib/classes/ConfigSchemaHandler/index.js | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/lib/classes/ConfigSchemaHandler/index.js b/lib/classes/ConfigSchemaHandler/index.js index d191ad1316e..02cf3128d62 100644 --- a/lib/classes/ConfigSchemaHandler/index.js +++ b/lib/classes/ConfigSchemaHandler/index.js @@ -23,6 +23,28 @@ const normalizeSchemaObject = (object, instanceSchema) => { } }; +// Normalizer is introduced to workaround https://github.com/ajv-validator/ajv/issues/1287 +// normalizedObjectsMap allows to handle circular structures without issues +const normalizedObjectsMap = new WeakMap(); +const normalizeUserConfig = object => { + if (normalizedObjectsMap.has(object)) return normalizedObjectsMap.get(object); + if (Array.isArray(object)) { + const normalizedObject = []; + normalizedObjectsMap.set(object, normalizedObject); + for (const value of object) { + normalizedObject.push(_.isObject(value) ? normalizeUserConfig(value) : value); + } + return normalizedObject; + } + const normalizedObject = Object.create(null); + normalizedObjectsMap.set(object, normalizedObject); + for (const [key, value] of Object.entries(object)) { + if (value == null) continue; + normalizedObject[key] = _.isObject(value) ? normalizeUserConfig(value) : value; + } + return normalizedObject; +}; + class ConfigSchemaHandler { constructor(serverless) { this.serverless = serverless; @@ -77,7 +99,7 @@ class ConfigSchemaHandler { normalizeSchemaObject(this.schema, this.schema); const validate = ajv.compile(this.schema); - validate(userConfig); + validate(normalizeUserConfig(userConfig)); if (validate.errors) { const messages = normalizeAjvErrors(validate.errors).map(err => err.message); this.handleErrorMessages(messages);