diff --git a/src/Schema.js b/src/Schema.js index 79e7ec8..6124f3a 100644 --- a/src/Schema.js +++ b/src/Schema.js @@ -158,6 +158,11 @@ class Schema { return; } + if (typeof errorMessage === 'object' && this.errors[key] && this.errors[key].length) { + this.errors[key][0] = mergeErrors(this.errors[key][0], errorMessage); + return; + } + this.errors[key].push(errorMessage); } diff --git a/src/Schema.test.js b/src/Schema.test.js index af54d35..f046b84 100644 --- a/src/Schema.test.js +++ b/src/Schema.test.js @@ -1938,102 +1938,111 @@ describe('Schema', () => { type: unitSchema, }, }); - const modelSchema = new Schema({ + const elementsSchema = new Schema({ elements: { type: [elementSchema], }, }); + const modelSchema = new Schema({ + test: { + type: elementsSchema, + }, + }); const data = { - elements: [ - { - name: 'test', - type: 'pallet', - height: { - value: '10', - unit: 'm', - }, - weight: { - value: '10', - unit: 'm', - }, - length: { - value: '10', - unit: 'm', - }, - }, - { - name: 'test', - type: 'pallet', - height: { - value: '', - unit: 'm', - }, - weight: { - value: '10', - unit: 'm', - }, - length: { - value: '10', - unit: 'm', - }, - }, - { - name: 'test1', - type: 'pallet', - height: { - value: '', - unit: 'm', + test: { + elements: [ + { + name: 'test', + type: 'pallet', + height: { + value: '10', + unit: 'm', + }, + weight: { + value: '10', + unit: 'm', + }, + length: { + value: '10', + unit: 'm', + }, }, - weight: { - value: '', - unit: 'm', + { + name: 'test', + type: 'pallet', + height: { + value: '', + unit: 'm', + }, + weight: { + value: '10', + unit: 'm', + }, + length: { + value: '10', + unit: 'm', + }, }, - length: { - value: '10', - unit: 'm', + { + name: 'test1', + type: 'pallet', + height: { + value: '', + unit: 'm', + }, + weight: { + value: '', + unit: 'm', + }, + length: { + value: '10', + unit: 'm', + }, }, - }, - ], + ], + }, }; modelSchema.addValidator((model, schema) => { - if (!model || !Array.isArray(model.elements)) return; + if (!model || !Array.isArray(model.test.elements)) return; const uniqueNames = new Set(); const errorMsg = 'duplicatedKey'; - model.elements.forEach((element, index) => { + model.test.elements.forEach((element, index) => { if (uniqueNames.has(element.name)) { - schema.setModelError(`elements.${index}.name`, errorMsg); + schema.setModelError(`test.elements.${index}.name`, errorMsg); + schema.setModelError(`test.elements.${index}.name`, errorMsg); } else { uniqueNames.add(element.name); } }); }); - expect(modelSchema.validate(data)).toEqual({ - elements: [ - undefined, - { - name: ['duplicatedKey'], - height: [ - { - value: ["Field 'value' is required"], - }, - ], - }, - { - height: [ - { - value: ["Field 'value' is required"], - }, - ], - weight: [ - { - value: ["Field 'value' is required"], - }, - ], - }, - ], + test: [{ + elements: [ + undefined, + { + name: ['duplicatedKey'], + height: [ + { + value: ["Field 'value' is required"], + }, + ], + }, + { + height: [ + { + value: ["Field 'value' is required"], + }, + ], + weight: [ + { + value: ["Field 'value' is required"], + }, + ], + }, + ], + }], }); }); diff --git a/src/helpers.js b/src/helpers.js index f79d176..d2c5404 100644 --- a/src/helpers.js +++ b/src/helpers.js @@ -88,6 +88,12 @@ const isObjectWithoutProps = (obj) => { && Object.keys(obj).length === 0; }; +const isObject = obj => ( + typeof obj === 'object' + && !Array.isArray(obj) + && obj !== null +); + const isArrayable = src => Array.isArray(src) || typeof src === 'string' || typeof src === 'undefined'; @@ -116,9 +122,15 @@ const castAsArray = (src) => { const mergeErrorsLists = (a, b) => { const merged = []; const maxLength = Math.max(a.length, b.length); - for (let i = 0; i < maxLength; i += 1) { - const value = b[i] || a[i]; + let value; + const currentErrors = a[i]; + const nextErrors = b[i]; + if (isObject(currentErrors) && isObject(nextErrors)) { + value = { ...currentErrors, ...nextErrors }; + } else { + value = b[i] || a[i]; + } if (value && !isObjectWithoutProps(value)) { merged[i] = value; }