From 1cf5dab0db3f1df6083293bf71bcab972da3b2d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9A=D0=B8=D1=80=D0=B8=D0=BB=D0=BA=D0=B8=D0=BD=20=D0=92?= =?UTF-8?q?=D0=BB=D0=B0=D0=B4=D0=B8=D0=BC=D0=B8=D1=80=20=D0=90=D0=BB=D0=B5?= =?UTF-8?q?=D0=BA=D1=81=D0=B5=D0=B5=D0=B2=D0=B8=D1=87?= Date: Wed, 19 Oct 2022 16:02:53 +0300 Subject: [PATCH 1/2] fix omit field names with dot #2643 --- CHANGELOG.md | 1 + packages/core/src/components/Form.tsx | 13 +++++++------ packages/core/test/Form_test.js | 22 +++++++++++----------- 3 files changed, 19 insertions(+), 17 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ac0549d27b..cb5d647465 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,6 +22,7 @@ should change the heading of the (upcoming) version to include a major version b ## @rjsf/core - Added the new generic, `S extends StrictRJSFSchema = RJSFSchema`, for `schema`/`rootSchema` to every component that needed it. +- Fix omitExtraData with field names with dots #2643 ## @rjsf/utils - Beta-only potentially BREAKING CHANGE: Changed all types that directly or indirectly defined `schema`/`rootSchema` to add the generic `S extends StrictRJSFSchema = RJSFSchema` and use `S` as the type for them. diff --git a/packages/core/src/components/Form.tsx b/packages/core/src/components/Form.tsx index e8b877e127..b8f491c1fe 100644 --- a/packages/core/src/components/Form.tsx +++ b/packages/core/src/components/Form.tsx @@ -453,12 +453,14 @@ export default class Form< * @param formData - The data for the `Form` * @param fields - The fields to keep while filtering */ - getUsedFormData = (formData: T, fields: string[]): T => { + getUsedFormData = (formData: T, fields: string[][]): T => { // For the case of a single input form if (fields.length === 0 && typeof formData !== "object") { return formData; } + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore _pick has incorrect type definition, it works with string[][], because lodash/hasIn supports it const data: GenericObjectType = _pick(formData, fields); if (Array.isArray(formData)) { return Object.keys(data).map((key: string) => data[key]) as unknown as T; @@ -472,15 +474,15 @@ export default class Form< * @param pathSchema - The `PathSchema` object for the form * @param formData - The form data to use while checking for empty objects/arrays */ - getFieldNames = (pathSchema: PathSchema, formData: T) => { + getFieldNames = (pathSchema: PathSchema, formData: T): string[][] => { const getAllPaths = ( _obj: GenericObjectType, - acc: string[] = [], - paths = [""] + acc: string[][] = [], + paths: string[][] = [[]] ) => { Object.keys(_obj).forEach((key: string) => { if (typeof _obj[key] === "object") { - const newPaths = paths.map((path) => `${path}.${key}`); + const newPaths = paths.map((path) => [...path, key]); // If an object is marked with additionalProperties, all its keys are valid if ( _obj[key][RJSF_ADDITONAL_PROPERTIES_FLAG] && @@ -492,7 +494,6 @@ export default class Form< } } else if (key === NAME_KEY && _obj[key] !== "") { paths.forEach((path) => { - path = path.replace(/^\./, ""); const formValue = _get(formData, path); // adds path to fieldNames if it points to a value // or an empty object/array diff --git a/packages/core/test/Form_test.js b/packages/core/test/Form_test.js index 26dd4e6c47..9454aaf611 100644 --- a/packages/core/test/Form_test.js +++ b/packages/core/test/Form_test.js @@ -3073,10 +3073,10 @@ describe("Form omitExtraData and liveOmit", () => { const fieldNames = comp.getFieldNames(pathSchema, formData); expect(fieldNames.sort()).eql( [ - "level1a", - "level1.level2", - "level1.anotherThing.anotherThingNested", - "level1.anotherThing.anotherThingNested2", + ["level1", "anotherThing", "anotherThingNested"], + ["level1", "anotherThing", "anotherThingNested2"], + ["level1", "level2"], + ["level1a"], ].sort() ); }); @@ -3124,7 +3124,7 @@ describe("Form omitExtraData and liveOmit", () => { const fieldNames = comp.getFieldNames(pathSchema, formData); expect(fieldNames.sort()).eql( - ["level1a", "level1.level2", "level1.mixedMap"].sort() + [["level1", "level2"], "level1.mixedMap", ["level1a"]].sort() ); }); @@ -3186,12 +3186,12 @@ describe("Form omitExtraData and liveOmit", () => { const fieldNames = comp.getFieldNames(pathSchema, formData); expect(fieldNames.sort()).eql( [ - "address_list.0.city", - "address_list.0.state", - "address_list.0.street_address", - "address_list.1.city", - "address_list.1.state", - "address_list.1.street_address", + ["address_list", "0", "city"], + ["address_list", "0", "state"], + ["address_list", "0", "street_address"], + ["address_list", "1", "city"], + ["address_list", "1", "state"], + ["address_list", "1", "street_address"], ].sort() ); }); From a947df7499baa64d60c96e4d19c906b0ae892be3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9A=D0=B8=D1=80=D0=B8=D0=BB=D0=BA=D0=B8=D0=BD=20=D0=92?= =?UTF-8?q?=D0=BB=D0=B0=D0=B4=D0=B8=D0=BC=D0=B8=D1=80=20=D0=90=D0=BB=D0=B5?= =?UTF-8?q?=D0=BA=D1=81=D0=B5=D0=B5=D0=B2=D0=B8=D1=87?= Date: Wed, 26 Oct 2022 13:20:52 +0300 Subject: [PATCH 2/2] add type casting --- packages/core/src/components/Form.tsx | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/packages/core/src/components/Form.tsx b/packages/core/src/components/Form.tsx index b8f491c1fe..96d1e97945 100644 --- a/packages/core/src/components/Form.tsx +++ b/packages/core/src/components/Form.tsx @@ -459,9 +459,11 @@ export default class Form< return formData; } - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-ignore _pick has incorrect type definition, it works with string[][], because lodash/hasIn supports it - const data: GenericObjectType = _pick(formData, fields); + // _pick has incorrect type definition, it works with string[][], because lodash/hasIn supports it + const data: GenericObjectType = _pick( + formData, + fields as unknown as string[] + ); if (Array.isArray(formData)) { return Object.keys(data).map((key: string) => data[key]) as unknown as T; }