forked from alibaba/lowcode-engine
-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathcheck-prop-types.ts
More file actions
89 lines (82 loc) · 2.57 KB
/
check-prop-types.ts
File metadata and controls
89 lines (82 loc) · 2.57 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
import * as ReactIs from 'react-is';
import { default as ReactPropTypesSecret } from 'prop-types/lib/ReactPropTypesSecret';
import { default as factoryWithTypeCheckers } from 'prop-types/factoryWithTypeCheckers';
import { IPublicTypePropType } from '@felce/lowcode-types';
import { isRequiredPropType } from './check-types/is-required-prop-type';
import { Logger } from './logger';
const PropTypes2 = factoryWithTypeCheckers(ReactIs.isElement, true);
const logger = new Logger({ level: 'warn', bizName: 'utils' });
export function transformPropTypesRuleToString(rule: IPublicTypePropType | string): string {
if (!rule) {
return 'PropTypes.any';
}
if (typeof rule === 'string') {
return rule.startsWith('PropTypes.') ? rule : `PropTypes.${rule}`;
}
if (isRequiredPropType(rule)) {
const { type, isRequired } = rule;
return `PropTypes.${type}${isRequired ? '.isRequired' : ''}`;
}
const { type, value } = rule;
switch (type) {
case 'oneOf':
return `PropTypes.oneOf([${value.map((item: any) => `"${item}"`).join(',')}])`;
case 'oneOfType':
return `PropTypes.oneOfType([${value
.map((item: any) => transformPropTypesRuleToString(item))
.join(', ')}])`;
case 'arrayOf':
case 'objectOf':
return `PropTypes.${type}(${transformPropTypesRuleToString(value)})`;
case 'shape':
case 'exact':
return `PropTypes.${type}({${value
.map((item: any) => `${item.name}: ${transformPropTypesRuleToString(item.propType)}`)
.join(',')}})`;
default:
logger.error(`Unknown prop type: ${type}`);
}
return 'PropTypes.any';
}
export function checkPropTypes(
value: any,
name: string,
rule: any,
componentName: string,
): boolean {
let ruleFunction = rule;
if (typeof rule === 'object') {
// eslint-disable-next-line no-new-func
ruleFunction = new Function(
`"use strict"; const PropTypes = arguments[0]; return ${transformPropTypesRuleToString(
rule,
)}`,
)(PropTypes2);
}
if (typeof rule === 'string') {
// eslint-disable-next-line no-new-func
ruleFunction = new Function(
`"use strict"; const PropTypes = arguments[0]; return ${transformPropTypesRuleToString(
rule,
)}`,
)(PropTypes2);
}
if (!ruleFunction || typeof ruleFunction !== 'function') {
logger.warn('checkPropTypes should have a function type rule argument');
return true;
}
const err = ruleFunction(
{
[name]: value,
},
name,
componentName,
'prop',
null,
ReactPropTypesSecret,
);
if (err) {
logger.warn(err);
}
return !err;
}