181 lines
4.8 KiB
JavaScript
Raw Normal View History

2019-11-06 17:46:31 +01:00
import { get, isBoolean, isNaN } from 'lodash';
2019-07-18 16:53:12 +02:00
import * as yup from 'yup';
2019-09-06 16:01:36 +02:00
import { translatedErrors as errorsTrads } from 'strapi-helper-plugin';
2019-07-18 16:53:12 +02:00
2019-08-09 16:08:02 +02:00
yup.addMethod(yup.mixed, 'defined', function() {
return this.test(
'defined',
errorsTrads.required,
value => value !== undefined
);
});
2019-07-19 09:32:36 +02:00
const getAttributes = data => get(data, ['schema', 'attributes'], {});
2019-07-18 16:53:12 +02:00
2019-07-19 09:32:36 +02:00
const createYupSchema = (model, { groups }) => {
const attributes = getAttributes(model);
2019-07-18 16:53:12 +02:00
2019-07-19 09:32:36 +02:00
return yup.object().shape(
Object.keys(attributes).reduce((acc, current) => {
const attribute = attributes[current];
if (attribute.type !== 'relation' && attribute.type !== 'group') {
const formatted = createYupSchemaAttribute(attribute.type, attribute);
acc[current] = formatted;
}
2019-07-18 16:53:12 +02:00
2019-07-19 09:32:36 +02:00
if (attribute.type === 'relation') {
acc[current] = [
'oneWay',
'oneToOne',
'manyToOne',
'oneToManyMorph',
'oneToOneMorph',
].includes(attribute.relationType)
? yup.object().nullable()
: yup.array().nullable();
2019-07-19 09:32:36 +02:00
}
2019-07-18 16:53:12 +02:00
2019-07-19 09:32:36 +02:00
if (attribute.type === 'group') {
2019-08-21 17:35:13 +02:00
const groupFieldSchema = createYupSchema(groups[attribute.group], {
2019-07-19 09:32:36 +02:00
groups,
});
2019-08-21 17:35:13 +02:00
if (attribute.repeatable === true) {
const groupSchema =
attribute.required === true
? yup
.array()
.of(groupFieldSchema)
.defined()
: yup
.array()
.of(groupFieldSchema)
.nullable();
acc[current] = groupSchema;
return acc;
} else {
const groupSchema = yup.lazy(obj => {
if (obj !== undefined) {
return attribute.required === true
? groupFieldSchema.defined()
: groupFieldSchema.nullable();
}
return attribute.required === true
? yup.object().defined()
: yup.object().nullable();
});
acc[current] = groupSchema;
return acc;
}
2019-07-19 09:32:36 +02:00
}
2019-08-21 17:35:13 +02:00
2019-07-19 09:32:36 +02:00
return acc;
}, {})
2019-07-18 16:53:12 +02:00
);
};
const createYupSchemaAttribute = (type, validations) => {
let schema = yup.mixed();
2019-08-09 13:48:31 +02:00
if (
['string', 'text', 'richtext', 'email', 'password', 'enumeration'].includes(
type
)
) {
2019-07-18 16:53:12 +02:00
schema = yup.string();
}
if (type === 'json') {
schema = yup
.mixed(errorsTrads.json)
.test('isJSON', errorsTrads.json, value => {
2019-11-06 17:46:31 +01:00
if (value === undefined) {
return true;
}
2019-11-06 17:46:31 +01:00
try {
JSON.parse(value);
return true;
} catch (err) {
return false;
}
})
.nullable();
2019-07-18 16:53:12 +02:00
}
2019-07-18 16:53:12 +02:00
if (type === 'email') {
schema = schema.email(errorsTrads.email);
}
2019-08-23 16:07:34 +02:00
if (['number', 'integer', 'biginteger', 'float', 'decimal'].includes(type)) {
2019-07-18 16:53:12 +02:00
schema = yup
.number()
.transform(cv => (isNaN(cv) ? undefined : cv))
.typeError();
}
if (['date', 'datetime'].includes(type)) {
2019-09-13 14:46:31 +02:00
schema = yup.date();
2019-07-18 16:53:12 +02:00
}
2019-08-09 13:48:31 +02:00
2019-07-18 16:53:12 +02:00
Object.keys(validations).forEach(validation => {
const validationValue = validations[validation];
if (
!!validationValue ||
((!isBoolean(validationValue) &&
Number.isInteger(Math.floor(validationValue))) ||
validationValue === 0)
) {
switch (validation) {
case 'required':
schema = schema.required(errorsTrads.required);
break;
case 'max':
schema = schema.max(validationValue, errorsTrads.max);
break;
case 'maxLength':
schema = schema.max(validationValue, errorsTrads.maxLength);
break;
case 'min':
schema = schema.min(validationValue, errorsTrads.min);
break;
case 'minLength':
schema = schema.min(validationValue, errorsTrads.minLength);
break;
case 'regex':
schema = schema.matches(validationValue, errorsTrads.regex);
break;
case 'lowercase':
if (['text', 'textarea', 'email', 'string'].includes(type)) {
schema = schema.strict().lowercase();
}
break;
case 'uppercase':
if (['text', 'textarea', 'email', 'string'].includes(type)) {
schema = schema.strict().uppercase();
}
break;
case 'positive':
if (
['number', 'integer', 'bigint', 'float', 'decimal'].includes(type)
) {
schema = schema.positive();
}
break;
case 'negative':
if (
['number', 'integer', 'bigint', 'float', 'decimal'].includes(type)
) {
schema = schema.negative();
}
break;
default:
2019-07-18 18:14:29 +02:00
schema = schema.nullable();
2019-07-18 16:53:12 +02:00
}
}
});
return schema;
};
export default createYupSchema;