Skip to content

Commit 1efd306

Browse files
committed
Extract omitExtraData functionality from Form.tsx (core) to utils
1 parent 294b9e3 commit 1efd306

File tree

4 files changed

+74
-0
lines changed

4 files changed

+74
-0
lines changed

packages/utils/src/createSchemaUtils.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import {
2727
sanitizeDataForNewSchema,
2828
toIdSchema,
2929
toPathSchema,
30+
omitExtraData,
3031
} from './schema';
3132

3233
/** The `SchemaUtils` class provides a wrapper around the publicly exported APIs in the `utils/schema` directory such
@@ -275,6 +276,10 @@ class SchemaUtils<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends Fo
275276
toPathSchema(schema: S, name?: string, formData?: T): PathSchema<T> {
276277
return toPathSchema<T, S, F>(this.validator, schema, name, this.rootSchema, formData);
277278
}
279+
280+
omitExtraData(schema: S, formData?: T): T | undefined {
281+
return omitExtraData<T, S, F>(this.validator, schema, this.rootSchema, formData);
282+
}
278283
}
279284

280285
/** Creates a `SchemaUtilsType` interface that is based around the given `validator` and `rootSchema` parameters. The

packages/utils/src/schema/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import retrieveSchema from './retrieveSchema';
1111
import sanitizeDataForNewSchema from './sanitizeDataForNewSchema';
1212
import toIdSchema from './toIdSchema';
1313
import toPathSchema from './toPathSchema';
14+
import omitExtraData from './omitExtraData';
1415

1516
export {
1617
getDefaultFormState,
@@ -22,6 +23,7 @@ export {
2223
isMultiSelect,
2324
isSelect,
2425
mergeValidationData,
26+
omitExtraData,
2527
retrieveSchema,
2628
sanitizeDataForNewSchema,
2729
toIdSchema,
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
import { FormContextType, GenericObjectType, PathSchema, RJSFSchema, StrictRJSFSchema, ValidatorType } from '../types';
2+
import _pick from 'lodash/pick';
3+
4+
import _get from 'lodash/get';
5+
import _isEmpty from 'lodash/isEmpty';
6+
import toPathSchema from './toPathSchema';
7+
import { NAME_KEY, RJSF_ADDITONAL_PROPERTIES_FLAG } from '../constants';
8+
9+
export function getFieldNames<T = any>(pathSchema: PathSchema<T>, formData?: T): string[][] {
10+
const getAllPaths = (_obj: GenericObjectType, acc: string[][] = [], paths: string[][] = [[]]) => {
11+
Object.keys(_obj).forEach((key: string) => {
12+
if (typeof _obj[key] === 'object') {
13+
const newPaths = paths.map((path) => [...path, key]);
14+
// If an object is marked with additionalProperties, all its keys are valid
15+
if (_obj[key][RJSF_ADDITONAL_PROPERTIES_FLAG] && _obj[key][NAME_KEY] !== '') {
16+
acc.push(_obj[key][NAME_KEY]);
17+
} else {
18+
getAllPaths(_obj[key], acc, newPaths);
19+
}
20+
} else if (key === NAME_KEY && _obj[key] !== '') {
21+
paths.forEach((path) => {
22+
const formValue = _get(formData, path);
23+
// adds path to fieldNames if it points to a value
24+
// or an empty object/array
25+
if (
26+
typeof formValue !== 'object' ||
27+
_isEmpty(formValue) ||
28+
(Array.isArray(formValue) && formValue.every((val) => typeof val !== 'object'))
29+
) {
30+
acc.push(path);
31+
}
32+
});
33+
}
34+
});
35+
return acc;
36+
};
37+
38+
return getAllPaths(pathSchema);
39+
}
40+
41+
export function getUsedFormData<T = any>(formData: T | undefined, fields: string[][]): T | undefined {
42+
// For the case of a single input form
43+
if (fields.length === 0 && typeof formData !== 'object') {
44+
return formData;
45+
}
46+
47+
// _pick has incorrect type definition, it works with string[][], because lodash/hasIn supports it
48+
const data: GenericObjectType = _pick(formData, fields as unknown as string[]);
49+
if (Array.isArray(formData)) {
50+
return Object.keys(data).map((key: string) => data[key]) as unknown as T;
51+
}
52+
53+
return data as T;
54+
}
55+
56+
export default function omitExtraData<
57+
T = any,
58+
S extends StrictRJSFSchema = RJSFSchema,
59+
F extends FormContextType = any
60+
>(validator: ValidatorType<T, S, F>, schema: S, rootSchema: S = {} as S, formData?: T): T | undefined {
61+
const pathSchema = toPathSchema(validator, schema, '', rootSchema, formData);
62+
const fieldNames = getFieldNames(pathSchema, formData);
63+
64+
return getUsedFormData(formData, fieldNames);
65+
}

packages/utils/src/types.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1157,4 +1157,6 @@ export interface SchemaUtilsType<T = any, S extends StrictRJSFSchema = RJSFSchem
11571157
* @returns - The `PathSchema` object for the `schema`
11581158
*/
11591159
toPathSchema(schema: S, name?: string, formData?: T): PathSchema<T>;
1160+
1161+
omitExtraData(schema: S, formData?: T, retrievedSchema?: S): T | undefined;
11601162
}

0 commit comments

Comments
 (0)