diff --git a/packages/docs/docs/api-reference/utility-functions.md b/packages/docs/docs/api-reference/utility-functions.md index 1e6a9812ff..79935921bb 100644 --- a/packages/docs/docs/api-reference/utility-functions.md +++ b/packages/docs/docs/api-reference/utility-functions.md @@ -1172,7 +1172,7 @@ For more information about how to specify the path see the [eslint lodash plugin #### Parameters - errorOrList: string | string[] - The error or list of errors to add into the `ErrorSchema` -- [pathOfError]: string | string[] | undefined - The optional path into the `ErrorSchema` at which to add the error(s) +- [pathOfError]: string | (string | number)[] | undefined - The optional path into the `ErrorSchema` at which to add the error(s) #### Returns @@ -1186,7 +1186,7 @@ For more information about how to specify the path see the [eslint lodash plugin #### Parameters - errorOrList: string | string[] - The error or list of errors to add into the `ErrorSchema` -- [pathOfError]: string | string[] | undefined - The optional path into the `ErrorSchema` at which to add the error(s) +- [pathOfError]: string | (string | number)[] | undefined - The optional path into the `ErrorSchema` at which to add the error(s) #### Returns @@ -1199,7 +1199,7 @@ For more information about how to specify the path see the [eslint lodash plugin #### Parameters -- [pathOfError]: string | string[] | undefined - The optional path into the `ErrorSchema` at which to add the error(s) +- [pathOfError]: string | (string | number)[] | undefined - The optional path into the `ErrorSchema` at which to add the error(s) #### Returns diff --git a/packages/utils/src/ErrorSchemaBuilder.ts b/packages/utils/src/ErrorSchemaBuilder.ts index d6a6ad2cab..ab9cc2169d 100644 --- a/packages/utils/src/ErrorSchemaBuilder.ts +++ b/packages/utils/src/ErrorSchemaBuilder.ts @@ -1,6 +1,7 @@ import cloneDeep from 'lodash/cloneDeep'; import get from 'lodash/get'; import set from 'lodash/set'; +import setWith from 'lodash/setWith'; import { ErrorSchema } from './types'; import { ERRORS_KEY } from './constants'; @@ -37,12 +38,12 @@ export default class ErrorSchemaBuilder { * @returns - The error block for the given `pathOfError` or the root if not provided * @private */ - private getOrCreateErrorBlock(pathOfError?: string | string[]) { + private getOrCreateErrorBlock(pathOfError?: string | (string | number)[]) { const hasPath = (Array.isArray(pathOfError) && pathOfError.length > 0) || typeof pathOfError === 'string'; let errorBlock: ErrorSchema = hasPath ? get(this.errorSchema, pathOfError) : this.errorSchema; if (!errorBlock && pathOfError) { errorBlock = {}; - set(this.errorSchema, pathOfError, errorBlock); + setWith(this.errorSchema, pathOfError, errorBlock, Object); } return errorBlock; } @@ -65,7 +66,7 @@ export default class ErrorSchemaBuilder { * @param [pathOfError] - The optional path into the `ErrorSchema` at which to add the error(s) * @returns - The `ErrorSchemaBuilder` object for chaining purposes */ - addErrors(errorOrList: string | string[], pathOfError?: string | string[]) { + addErrors(errorOrList: string | string[], pathOfError?: string | (string | number)[]) { const errorBlock: ErrorSchema = this.getOrCreateErrorBlock(pathOfError); let errorsList = get(errorBlock, ERRORS_KEY); if (!Array.isArray(errorsList)) { @@ -89,7 +90,7 @@ export default class ErrorSchemaBuilder { * @param [pathOfError] - The optional path into the `ErrorSchema` at which to set the error(s) * @returns - The `ErrorSchemaBuilder` object for chaining purposes */ - setErrors(errorOrList: string | string[], pathOfError?: string | string[]) { + setErrors(errorOrList: string | string[], pathOfError?: string | (string | number)[]) { const errorBlock: ErrorSchema = this.getOrCreateErrorBlock(pathOfError); // Effectively clone the array being given to prevent accidental outside manipulation of the given list const listToAdd = Array.isArray(errorOrList) ? [...errorOrList] : [errorOrList]; @@ -104,7 +105,7 @@ export default class ErrorSchemaBuilder { * @param [pathOfError] - The optional path into the `ErrorSchema` at which to clear the error(s) * @returns - The `ErrorSchemaBuilder` object for chaining purposes */ - clearErrors(pathOfError?: string | string[]) { + clearErrors(pathOfError?: string | (string | number)[]) { const errorBlock: ErrorSchema = this.getOrCreateErrorBlock(pathOfError); set(errorBlock, ERRORS_KEY, []); return this; diff --git a/packages/utils/test/ErrorSchemaBuilder.test.ts b/packages/utils/test/ErrorSchemaBuilder.test.ts index 09a587020d..54d587e0b1 100644 --- a/packages/utils/test/ErrorSchemaBuilder.test.ts +++ b/packages/utils/test/ErrorSchemaBuilder.test.ts @@ -153,6 +153,90 @@ describe('ErrorSchemaBuilder', () => { }, }); }); + it('adding error string with a (string | number)[] path puts it at the path', () => { + expect(builder.addErrors(AN_ERROR, ['arr', 0, 'qux']).ErrorSchema).toEqual({ + [ERRORS_KEY]: [], + [STRING_PATH]: { + [ERRORS_KEY]: [], + }, + [ARRAY_PATH[0]]: { + [ARRAY_PATH[1]]: { + [ERRORS_KEY]: [], + }, + }, + another: { + path: { + [ERRORS_KEY]: [AN_ERROR], + }, + }, + newPath: { + [ERRORS_KEY]: [], + }, + arr: { + '0': { + qux: { + [ERRORS_KEY]: [AN_ERROR], + }, + }, + }, + }); + }); + it('setting error string with a new path with number set errors at the path', () => { + expect(builder.setErrors(SOME_ERRORS, ['arr', 0, 'qux']).ErrorSchema).toEqual({ + [ERRORS_KEY]: [], + [STRING_PATH]: { + [ERRORS_KEY]: [], + }, + [ARRAY_PATH[0]]: { + [ARRAY_PATH[1]]: { + [ERRORS_KEY]: [], + }, + }, + another: { + path: { + [ERRORS_KEY]: [AN_ERROR], + }, + }, + newPath: { + [ERRORS_KEY]: [], + }, + arr: { + '0': { + qux: { + [ERRORS_KEY]: SOME_ERRORS, + }, + }, + }, + }); + }); + it('clearing errors with a (string | number)[] path clears them the path', () => { + expect(builder.clearErrors(['arr', 0, 'qux']).ErrorSchema).toEqual({ + [ERRORS_KEY]: [], + [STRING_PATH]: { + [ERRORS_KEY]: [], + }, + [ARRAY_PATH[0]]: { + [ARRAY_PATH[1]]: { + [ERRORS_KEY]: [], + }, + }, + another: { + path: { + [ERRORS_KEY]: [AN_ERROR], + }, + }, + newPath: { + [ERRORS_KEY]: [], + }, + arr: { + '0': { + qux: { + [ERRORS_KEY]: [], + }, + }, + }, + }); + }); it('resetting error restores things back to an empty object', () => { expect(builder.resetAllErrors().ErrorSchema).toEqual({}); });