Skip to content

Commit 197f85d

Browse files
committed
feat(renderer): add function for collecting all validates from schema
1 parent c299b84 commit 197f85d

File tree

5 files changed

+148
-0
lines changed

5 files changed

+148
-0
lines changed
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { Schema, AnyObject, ComponentMapper } from "../common-types";
2+
import { ActionMapper } from "../form-renderer";
3+
4+
export interface GetValidatesOptions {
5+
values: AnyObject;
6+
componentMapper: ComponentMapper;
7+
actionMapper: ActionMapper;
8+
}
9+
10+
declare function getValidates(schema: Schema, options: GetValidatesOptions, validations?: AnyObject): AnyObject;
11+
12+
export default getValidates;
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import get from 'lodash/get';
2+
3+
import prepareComponentProps from '../prepare-component-props';
4+
5+
const getValidates = (schema, { componentMapper, actionMapper, values }, validations = {}) => {
6+
if (Array.isArray(schema)) {
7+
schema.map((field) => getValidates(field, { componentMapper, actionMapper, values }, validations));
8+
} else {
9+
if (schema.component) {
10+
let validate;
11+
12+
const { componentProps, overrideProps, mergedResolveProps } = prepareComponentProps({
13+
component: schema.component,
14+
rest: schema,
15+
componentMapper,
16+
actionMapper
17+
});
18+
19+
let resolveProps = mergedResolveProps || overrideProps.resolveProps || componentProps.resolveProps;
20+
21+
// fake form state with only values
22+
if (resolveProps) {
23+
const { validate: resolvePropsValidate } = resolveProps(
24+
schema,
25+
{ input: { value: get(values, schema.name) }, meta: {} },
26+
{ getState: () => ({ values }) }
27+
);
28+
29+
validate = resolvePropsValidate;
30+
}
31+
32+
validate = validate || overrideProps.validate || componentProps.validate;
33+
34+
if (validate) {
35+
if (validations[schema.name]) {
36+
validations[schema.name].push(validate);
37+
} else {
38+
validations[schema.name] = [validate];
39+
}
40+
}
41+
}
42+
43+
if (schema.fields) {
44+
getValidates(schema.fields, { componentMapper, actionMapper, values }, validations);
45+
}
46+
}
47+
48+
return validations;
49+
};
50+
51+
export default getValidates;
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export { default } from './get-validates';
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export { default } from './get-validates';
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
import getValidates from '../../get-validates';
2+
3+
describe('getValidates', () => {
4+
const noop = () => {};
5+
6+
it('returns all the validates from the schema', () => {
7+
const values = { x: 'value-of-x' };
8+
9+
const componentMapper = {
10+
default: noop,
11+
complexResolve: {
12+
component: noop,
13+
resolveProps: () => ({
14+
validate: [{ type: 'complexResolve' }]
15+
})
16+
},
17+
componentDefault: {
18+
component: noop,
19+
validate: [{ type: 'componentDefault' }]
20+
},
21+
componentActions: {
22+
component: noop,
23+
actions: {
24+
validate: ['componentAction']
25+
}
26+
},
27+
componentActionsResolve: {
28+
component: noop,
29+
actions: {
30+
resolveProps: ['returnValidate']
31+
}
32+
}
33+
};
34+
35+
const schema = {
36+
fields: [
37+
{ name: 'no-validate' },
38+
{ name: 'no-validate-1', component: 'default' },
39+
{ name: 'simple', component: 'default', validate: [{ type: 'simple' }] },
40+
{ name: 'double', component: 'default', validate: [{ type: 'double-1' }] },
41+
{ name: 'double', component: 'default', validate: [{ type: 'double-2' }] },
42+
{ fields: [{ name: 'simple-2', component: 'default', validate: [{ type: 'simple-2' }] }] },
43+
{ name: 'component-default', component: 'componentDefault' },
44+
{ name: 'component-default-override', component: 'componentDefault', validate: [{ type: 'override' }] },
45+
{ name: 'component-actions', component: 'componentActions' },
46+
{ name: 'component-actions-resolve', component: 'componentActionsResolve' },
47+
{ name: 'complex-resolve', component: 'complexResolve' },
48+
{ name: 'simple-resolve', component: 'default', resolveProps: () => ({ validate: [{ type: 'from-resolve-props' }] }) },
49+
{ name: 'x', component: 'componentDefault', resolveProps: (_props, { input: { value } }) => ({ validate: [{ type: value }] }) },
50+
{
51+
name: 'xx',
52+
component: 'componentDefault',
53+
resolveProps: (_props, _inputMeta, { getState }) => ({ validate: [{ type: getState().values['x'] }] })
54+
}
55+
]
56+
};
57+
58+
const actionMapper = {
59+
componentAction: () => [{ type: 'from-action' }],
60+
returnValidate: () => () => ({ validate: [{ type: 'actions>resolveProps' }] })
61+
};
62+
63+
expect(
64+
getValidates(schema, {
65+
componentMapper,
66+
actionMapper,
67+
values
68+
})
69+
).toEqual({
70+
'complex-resolve': [[{ type: 'complexResolve' }]],
71+
'component-actions': [[{ type: 'from-action' }]],
72+
'component-default': [[{ type: 'componentDefault' }]],
73+
'component-default-override': [[{ type: 'override' }]],
74+
double: [[{ type: 'double-1' }], [{ type: 'double-2' }]],
75+
simple: [[{ type: 'simple' }]],
76+
'simple-2': [[{ type: 'simple-2' }]],
77+
'simple-resolve': [[{ type: 'from-resolve-props' }]],
78+
'component-actions-resolve': [[{ type: 'actions>resolveProps' }]],
79+
x: [[{ type: 'value-of-x' }]],
80+
xx: [[{ type: 'value-of-x' }]]
81+
});
82+
});
83+
});

0 commit comments

Comments
 (0)