@strapi/strapi 4.0.0-beta.17 → 4.0.0-beta.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -39,7 +39,11 @@ const applyUserExtension = async plugins => {
|
|
|
39
39
|
for (const ctName in plugin.contentTypes) {
|
|
40
40
|
const extendedSchema = get([pluginName, 'content-types', ctName, 'schema'], extendedSchemas);
|
|
41
41
|
if (extendedSchema) {
|
|
42
|
-
plugin.contentTypes[ctName].schema =
|
|
42
|
+
plugin.contentTypes[ctName].schema = Object.assign(
|
|
43
|
+
{},
|
|
44
|
+
plugin.contentTypes[ctName].schema,
|
|
45
|
+
extendedSchema
|
|
46
|
+
);
|
|
43
47
|
}
|
|
44
48
|
}
|
|
45
49
|
// second: execute strapi-server extension
|
|
@@ -202,9 +202,14 @@ const createDefaultImplementation = ({ strapi, db, eventHub, entityValidator })
|
|
|
202
202
|
|
|
203
203
|
const isDraft = contentTypesUtils.isDraft(entityToUpdate, model);
|
|
204
204
|
|
|
205
|
-
const validData = await entityValidator.validateEntityUpdate(
|
|
206
|
-
|
|
207
|
-
|
|
205
|
+
const validData = await entityValidator.validateEntityUpdate(
|
|
206
|
+
model,
|
|
207
|
+
data,
|
|
208
|
+
{
|
|
209
|
+
isDraft,
|
|
210
|
+
},
|
|
211
|
+
entityToUpdate
|
|
212
|
+
);
|
|
208
213
|
|
|
209
214
|
const query = transformParamsToQuery(uid, pickSelectionParams(wrappedParams));
|
|
210
215
|
|
|
@@ -12,8 +12,11 @@ const { yup, validateYupSchema } = strapiUtils;
|
|
|
12
12
|
const { isMediaAttribute, isScalarAttribute, getWritableAttributes } = strapiUtils.contentTypes;
|
|
13
13
|
const { ValidationError } = strapiUtils.errors;
|
|
14
14
|
|
|
15
|
-
const addMinMax = (
|
|
16
|
-
if (
|
|
15
|
+
const addMinMax = (validator, { attr, updatedAttribute }) => {
|
|
16
|
+
if (
|
|
17
|
+
Number.isInteger(attr.min) &&
|
|
18
|
+
(attr.required || (Array.isArray(updatedAttribute.value) && updatedAttribute.value.length > 0))
|
|
19
|
+
) {
|
|
17
20
|
validator = validator.min(attr.min);
|
|
18
21
|
}
|
|
19
22
|
if (Number.isInteger(attr.max)) {
|
|
@@ -22,7 +25,7 @@ const addMinMax = (attr, validator, data) => {
|
|
|
22
25
|
return validator;
|
|
23
26
|
};
|
|
24
27
|
|
|
25
|
-
const addRequiredValidation = createOrUpdate => (
|
|
28
|
+
const addRequiredValidation = createOrUpdate => (validator, { attr: { required } }) => {
|
|
26
29
|
if (required) {
|
|
27
30
|
if (createOrUpdate === 'creation') {
|
|
28
31
|
validator = validator.notNil();
|
|
@@ -35,7 +38,7 @@ const addRequiredValidation = createOrUpdate => (required, validator) => {
|
|
|
35
38
|
return validator;
|
|
36
39
|
};
|
|
37
40
|
|
|
38
|
-
const addDefault = createOrUpdate => (
|
|
41
|
+
const addDefault = createOrUpdate => (validator, { attr }) => {
|
|
39
42
|
if (createOrUpdate === 'creation') {
|
|
40
43
|
if (
|
|
41
44
|
((attr.type === 'component' && attr.repeatable) || attr.type === 'dynamiczone') &&
|
|
@@ -54,7 +57,7 @@ const addDefault = createOrUpdate => (attr, validator) => {
|
|
|
54
57
|
|
|
55
58
|
const preventCast = validator => validator.transform((val, originalVal) => originalVal);
|
|
56
59
|
|
|
57
|
-
const createComponentValidator = createOrUpdate => (attr,
|
|
60
|
+
const createComponentValidator = createOrUpdate => ({ attr, updatedAttribute }, { isDraft }) => {
|
|
58
61
|
let validator;
|
|
59
62
|
|
|
60
63
|
const model = strapi.getModel(attr.component);
|
|
@@ -66,19 +69,23 @@ const createComponentValidator = createOrUpdate => (attr, data, { isDraft }) =>
|
|
|
66
69
|
validator = yup
|
|
67
70
|
.array()
|
|
68
71
|
.of(
|
|
69
|
-
yup.lazy(item =>
|
|
72
|
+
yup.lazy(item =>
|
|
73
|
+
createModelValidator(createOrUpdate)({ model, data: item }, { isDraft }).notNull()
|
|
74
|
+
)
|
|
70
75
|
);
|
|
71
|
-
validator = addRequiredValidation(createOrUpdate)(
|
|
72
|
-
validator = addMinMax(
|
|
76
|
+
validator = addRequiredValidation(createOrUpdate)(validator, { attr: { required: true } });
|
|
77
|
+
validator = addMinMax(validator, { attr, updatedAttribute });
|
|
73
78
|
} else {
|
|
74
|
-
validator = createModelValidator(createOrUpdate)(model,
|
|
75
|
-
validator = addRequiredValidation(createOrUpdate)(
|
|
79
|
+
validator = createModelValidator(createOrUpdate)({ model, updatedAttribute }, { isDraft });
|
|
80
|
+
validator = addRequiredValidation(createOrUpdate)(validator, {
|
|
81
|
+
attr: { required: !isDraft && attr.required },
|
|
82
|
+
});
|
|
76
83
|
}
|
|
77
84
|
|
|
78
85
|
return validator;
|
|
79
86
|
};
|
|
80
87
|
|
|
81
|
-
const createDzValidator = createOrUpdate => (attr,
|
|
88
|
+
const createDzValidator = createOrUpdate => ({ attr, updatedAttribute }, { isDraft }) => {
|
|
82
89
|
let validator;
|
|
83
90
|
|
|
84
91
|
validator = yup.array().of(
|
|
@@ -95,76 +102,85 @@ const createDzValidator = createOrUpdate => (attr, data, { isDraft }) => {
|
|
|
95
102
|
.notNull();
|
|
96
103
|
|
|
97
104
|
return model
|
|
98
|
-
? schema.concat(createModelValidator(createOrUpdate)(model, item, { isDraft }))
|
|
105
|
+
? schema.concat(createModelValidator(createOrUpdate)({ model, data: item }, { isDraft }))
|
|
99
106
|
: schema;
|
|
100
107
|
})
|
|
101
108
|
);
|
|
102
|
-
validator = addRequiredValidation(createOrUpdate)(
|
|
103
|
-
validator = addMinMax(
|
|
109
|
+
validator = addRequiredValidation(createOrUpdate)(validator, { attr: { required: true } });
|
|
110
|
+
validator = addMinMax(validator, { attr, updatedAttribute });
|
|
104
111
|
|
|
105
112
|
return validator;
|
|
106
113
|
};
|
|
107
114
|
|
|
108
|
-
const createRelationValidator = createOrUpdate => (attr,
|
|
115
|
+
const createRelationValidator = createOrUpdate => ({ attr, updatedAttribute }, { isDraft }) => {
|
|
109
116
|
let validator;
|
|
110
117
|
|
|
111
|
-
if (Array.isArray(
|
|
118
|
+
if (Array.isArray(updatedAttribute.value)) {
|
|
112
119
|
validator = yup.array().of(yup.mixed());
|
|
113
120
|
} else {
|
|
114
121
|
validator = yup.mixed();
|
|
115
122
|
}
|
|
116
|
-
|
|
123
|
+
|
|
124
|
+
validator = addRequiredValidation(createOrUpdate)(validator, {
|
|
125
|
+
attr: { required: !isDraft && attr.required },
|
|
126
|
+
});
|
|
117
127
|
|
|
118
128
|
return validator;
|
|
119
129
|
};
|
|
120
130
|
|
|
121
|
-
const createScalarAttributeValidator = createOrUpdate => (
|
|
131
|
+
const createScalarAttributeValidator = createOrUpdate => (metas, options) => {
|
|
122
132
|
let validator;
|
|
123
133
|
|
|
124
|
-
if (has(attr.type, validators)) {
|
|
125
|
-
validator = validators[attr.type](
|
|
134
|
+
if (has(metas.attr.type, validators)) {
|
|
135
|
+
validator = validators[metas.attr.type](metas, options);
|
|
126
136
|
} else {
|
|
127
137
|
// No validators specified - fall back to mixed
|
|
128
138
|
validator = yup.mixed();
|
|
129
139
|
}
|
|
130
140
|
|
|
131
|
-
validator = addRequiredValidation(createOrUpdate)(
|
|
141
|
+
validator = addRequiredValidation(createOrUpdate)(validator, {
|
|
142
|
+
attr: { required: !options.isDraft && metas.attr.required },
|
|
143
|
+
});
|
|
132
144
|
|
|
133
145
|
return validator;
|
|
134
146
|
};
|
|
135
147
|
|
|
136
|
-
const createAttributeValidator = createOrUpdate => (
|
|
148
|
+
const createAttributeValidator = createOrUpdate => (metas, options) => {
|
|
137
149
|
let validator;
|
|
138
150
|
|
|
139
|
-
if (isMediaAttribute(attr)) {
|
|
151
|
+
if (isMediaAttribute(metas.attr)) {
|
|
140
152
|
validator = yup.mixed();
|
|
141
|
-
} else if (isScalarAttribute(attr)) {
|
|
142
|
-
validator = createScalarAttributeValidator(createOrUpdate)(
|
|
153
|
+
} else if (isScalarAttribute(metas.attr)) {
|
|
154
|
+
validator = createScalarAttributeValidator(createOrUpdate)(metas, options);
|
|
143
155
|
} else {
|
|
144
|
-
if (attr.type === 'component') {
|
|
145
|
-
validator = createComponentValidator(createOrUpdate)(
|
|
146
|
-
} else if (attr.type === 'dynamiczone') {
|
|
147
|
-
validator = createDzValidator(createOrUpdate)(
|
|
156
|
+
if (metas.attr.type === 'component') {
|
|
157
|
+
validator = createComponentValidator(createOrUpdate)(metas, options);
|
|
158
|
+
} else if (metas.attr.type === 'dynamiczone') {
|
|
159
|
+
validator = createDzValidator(createOrUpdate)(metas, options);
|
|
148
160
|
} else {
|
|
149
|
-
validator = createRelationValidator(createOrUpdate)(
|
|
161
|
+
validator = createRelationValidator(createOrUpdate)(metas, options);
|
|
150
162
|
}
|
|
151
163
|
|
|
152
164
|
validator = preventCast(validator);
|
|
153
165
|
}
|
|
154
166
|
|
|
155
|
-
validator = addDefault(createOrUpdate)(
|
|
167
|
+
validator = addDefault(createOrUpdate)(validator, metas);
|
|
156
168
|
|
|
157
169
|
return validator;
|
|
158
170
|
};
|
|
159
171
|
|
|
160
|
-
const createModelValidator = createOrUpdate => (model, data,
|
|
172
|
+
const createModelValidator = createOrUpdate => ({ model, data, entity }, options) => {
|
|
161
173
|
const writableAttributes = model ? getWritableAttributes(model) : [];
|
|
162
174
|
|
|
163
175
|
const schema = writableAttributes.reduce((validators, attributeName) => {
|
|
164
176
|
const validator = createAttributeValidator(createOrUpdate)(
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
177
|
+
{
|
|
178
|
+
attr: model.attributes[attributeName],
|
|
179
|
+
updatedAttribute: { name: attributeName, value: prop(attributeName, data) },
|
|
180
|
+
model,
|
|
181
|
+
entity,
|
|
182
|
+
},
|
|
183
|
+
options
|
|
168
184
|
);
|
|
169
185
|
|
|
170
186
|
return assoc(attributeName, validator)(validators);
|
|
@@ -173,7 +189,12 @@ const createModelValidator = createOrUpdate => (model, data, { isDraft }) => {
|
|
|
173
189
|
return yup.object().shape(schema);
|
|
174
190
|
};
|
|
175
191
|
|
|
176
|
-
const createValidateEntity = createOrUpdate => async (
|
|
192
|
+
const createValidateEntity = createOrUpdate => async (
|
|
193
|
+
model,
|
|
194
|
+
data,
|
|
195
|
+
{ isDraft = false } = {},
|
|
196
|
+
entity = null
|
|
197
|
+
) => {
|
|
177
198
|
if (!isObject(data)) {
|
|
178
199
|
const { displayName } = model.info;
|
|
179
200
|
|
|
@@ -182,7 +203,14 @@ const createValidateEntity = createOrUpdate => async (model, data, { isDraft = f
|
|
|
182
203
|
);
|
|
183
204
|
}
|
|
184
205
|
|
|
185
|
-
const validator = createModelValidator(createOrUpdate)(
|
|
206
|
+
const validator = createModelValidator(createOrUpdate)(
|
|
207
|
+
{
|
|
208
|
+
model,
|
|
209
|
+
data,
|
|
210
|
+
entity,
|
|
211
|
+
},
|
|
212
|
+
{ isDraft }
|
|
213
|
+
).required();
|
|
186
214
|
return validateYupSchema(validator, { strict: false, abortEarly: false })(data);
|
|
187
215
|
};
|
|
188
216
|
|
|
@@ -4,72 +4,155 @@ const _ = require('lodash');
|
|
|
4
4
|
|
|
5
5
|
const { yup } = require('@strapi/utils');
|
|
6
6
|
|
|
7
|
+
/**
|
|
8
|
+
* @type {import('yup').StringSchema} StringSchema
|
|
9
|
+
* @type {import('yup').NumberSchema} NumberSchema
|
|
10
|
+
* @type {import('yup').AnySchema} AnySchema
|
|
11
|
+
*/
|
|
12
|
+
|
|
7
13
|
/**
|
|
8
14
|
* Utility function to compose validators
|
|
9
15
|
*/
|
|
10
|
-
const composeValidators = (...fns) => (
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
16
|
+
const composeValidators = (...fns) => (...args) => {
|
|
17
|
+
let validator = yup.mixed();
|
|
18
|
+
|
|
19
|
+
// if we receive a schema then use it as base schema for nested composition
|
|
20
|
+
if (yup.isSchema(args[0])) {
|
|
21
|
+
validator = args[0];
|
|
22
|
+
args = args.slice(1);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
return fns.reduce((validator, fn) => fn(validator, ...args), validator);
|
|
14
26
|
};
|
|
15
27
|
|
|
16
28
|
/* Validator utils */
|
|
17
29
|
|
|
18
30
|
/**
|
|
19
31
|
* Adds minLength validator
|
|
20
|
-
* @param {
|
|
21
|
-
* @param {Object}
|
|
32
|
+
* @param {StringSchema} validator yup validator
|
|
33
|
+
* @param {Object} metas
|
|
34
|
+
* @param {{ minLength: Number }} metas.attr model attribute
|
|
35
|
+
* @param {Object} options
|
|
36
|
+
* @param {boolean} options.isDraft
|
|
37
|
+
*
|
|
38
|
+
* @returns {StringSchema}
|
|
22
39
|
*/
|
|
23
|
-
const addMinLengthValidator = ({
|
|
24
|
-
_.isInteger(minLength) && !isDraft ? validator.min(minLength) : validator;
|
|
40
|
+
const addMinLengthValidator = (validator, { attr }, { isDraft }) =>
|
|
41
|
+
_.isInteger(attr.minLength) && !isDraft ? validator.min(attr.minLength) : validator;
|
|
25
42
|
|
|
26
43
|
/**
|
|
27
44
|
* Adds maxLength validator
|
|
28
|
-
* @param {
|
|
29
|
-
* @param {Object}
|
|
45
|
+
* @param {StringSchema} validator yup validator
|
|
46
|
+
* @param {Object} metas
|
|
47
|
+
* @param {{ maxLength: Number }} metas.attr model attribute
|
|
48
|
+
*
|
|
49
|
+
* @returns {StringSchema}
|
|
30
50
|
*/
|
|
31
|
-
const addMaxLengthValidator = ({
|
|
32
|
-
_.isInteger(maxLength) ? validator.max(maxLength) : validator;
|
|
51
|
+
const addMaxLengthValidator = (validator, { attr }) =>
|
|
52
|
+
_.isInteger(attr.maxLength) ? validator.max(attr.maxLength) : validator;
|
|
33
53
|
|
|
34
54
|
/**
|
|
35
55
|
* Adds min integer validator
|
|
36
|
-
* @param {
|
|
37
|
-
* @param {Object}
|
|
56
|
+
* @param {NumberSchema} validator yup validator
|
|
57
|
+
* @param {Object} metas
|
|
58
|
+
* @param {{ min: Number }} metas.attr model attribute
|
|
59
|
+
*
|
|
60
|
+
* @returns {NumberSchema}
|
|
38
61
|
*/
|
|
39
|
-
const addMinIntegerValidator = ({
|
|
40
|
-
_.isNumber(min) ? validator.min(_.toInteger(min)) : validator;
|
|
62
|
+
const addMinIntegerValidator = (validator, { attr }) =>
|
|
63
|
+
_.isNumber(attr.min) ? validator.min(_.toInteger(attr.min)) : validator;
|
|
41
64
|
|
|
42
65
|
/**
|
|
43
66
|
* Adds max integer validator
|
|
44
|
-
* @param {
|
|
45
|
-
* @param {Object}
|
|
67
|
+
* @param {NumberSchema} validator yup validator
|
|
68
|
+
* @param {Object} metas
|
|
69
|
+
* @param {{ max: Number }} metas.attr model attribute
|
|
70
|
+
*
|
|
71
|
+
* @returns {NumberSchema}
|
|
46
72
|
*/
|
|
47
|
-
const addMaxIntegerValidator = ({
|
|
48
|
-
_.isNumber(max) ? validator.max(_.toInteger(max)) : validator;
|
|
73
|
+
const addMaxIntegerValidator = (validator, { attr }) =>
|
|
74
|
+
_.isNumber(attr.max) ? validator.max(_.toInteger(attr.max)) : validator;
|
|
49
75
|
|
|
50
76
|
/**
|
|
51
77
|
* Adds min float/decimal validator
|
|
52
|
-
* @param {
|
|
53
|
-
* @param {Object}
|
|
78
|
+
* @param {NumberSchema} validator yup validator
|
|
79
|
+
* @param {Object} metas
|
|
80
|
+
* @param {{ min: Number }} metas.attr model attribute
|
|
81
|
+
*
|
|
82
|
+
* @returns {NumberSchema}
|
|
54
83
|
*/
|
|
55
|
-
const addMinFloatValidator = ({
|
|
56
|
-
_.isNumber(min) ? validator.min(min) : validator;
|
|
84
|
+
const addMinFloatValidator = (validator, { attr }) =>
|
|
85
|
+
_.isNumber(attr.min) ? validator.min(attr.min) : validator;
|
|
57
86
|
|
|
58
87
|
/**
|
|
59
88
|
* Adds max float/decimal validator
|
|
60
|
-
* @param {
|
|
61
|
-
* @param {Object}
|
|
89
|
+
* @param {NumberSchema} validator yup validator
|
|
90
|
+
* @param {Object} metas model attribute
|
|
91
|
+
* @param {{ max: Number }} metas.attr
|
|
92
|
+
*
|
|
93
|
+
* @returns {NumberSchema}
|
|
62
94
|
*/
|
|
63
|
-
const addMaxFloatValidator = ({
|
|
64
|
-
_.isNumber(max) ? validator.max(max) : validator;
|
|
95
|
+
const addMaxFloatValidator = (validator, { attr }) =>
|
|
96
|
+
_.isNumber(attr.max) ? validator.max(attr.max) : validator;
|
|
65
97
|
|
|
66
98
|
/**
|
|
67
99
|
* Adds regex validator
|
|
68
|
-
* @param {
|
|
69
|
-
* @param {Object}
|
|
100
|
+
* @param {StringSchema} validator yup validator
|
|
101
|
+
* @param {Object} metas model attribute
|
|
102
|
+
* @param {{ regex: RegExp }} metas.attr
|
|
103
|
+
*
|
|
104
|
+
* @returns {StringSchema}
|
|
70
105
|
*/
|
|
71
|
-
const addStringRegexValidator = ({
|
|
72
|
-
_.isUndefined(regex) ? validator : validator.matches(new RegExp(regex));
|
|
106
|
+
const addStringRegexValidator = (validator, { attr }) =>
|
|
107
|
+
_.isUndefined(attr.regex) ? validator : validator.matches(new RegExp(attr.regex));
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
*
|
|
111
|
+
* @param {AnySchema} validator
|
|
112
|
+
* @param {Object} metas
|
|
113
|
+
* @param {{ unique: Boolean, type: String }} metas.attr
|
|
114
|
+
* @param {{ uid: String }} metas.model
|
|
115
|
+
* @param {{ name: String, value: any }} metas.updatedAttribute
|
|
116
|
+
* @param {Object} metas.entity
|
|
117
|
+
*
|
|
118
|
+
* @returns {AnySchema}
|
|
119
|
+
*/
|
|
120
|
+
const addUniqueValidator = (validator, { attr, model, updatedAttribute, entity }) => {
|
|
121
|
+
if (!attr.unique && attr.type !== 'uid') {
|
|
122
|
+
return validator;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
return validator.test('unique', 'This attribute must be unique', async value => {
|
|
126
|
+
/**
|
|
127
|
+
* If the attribute value is `null` we want to skip the unique validation.
|
|
128
|
+
* Otherwise it'll only accept a single `null` entry in the database.
|
|
129
|
+
*/
|
|
130
|
+
if (updatedAttribute.value === null) {
|
|
131
|
+
return true;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* If the attribute is unchanged we skip the unique verification. This will
|
|
136
|
+
* prevent the validator to be triggered in case the user activated the
|
|
137
|
+
* unique constraint after already creating multiple entries with
|
|
138
|
+
* the same attribute value for that field.
|
|
139
|
+
*/
|
|
140
|
+
if (entity && updatedAttribute.value === entity[updatedAttribute.name]) {
|
|
141
|
+
return true;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
let whereParams = entity
|
|
145
|
+
? { $and: [{ [updatedAttribute.name]: value }, { $not: { id: entity.id } }] }
|
|
146
|
+
: { [updatedAttribute.name]: value };
|
|
147
|
+
|
|
148
|
+
const record = await strapi.db.query(model.uid).findOne({
|
|
149
|
+
select: ['id'],
|
|
150
|
+
where: whereParams,
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
return !record;
|
|
154
|
+
});
|
|
155
|
+
};
|
|
73
156
|
|
|
74
157
|
/* Type validators */
|
|
75
158
|
|
|
@@ -77,29 +160,32 @@ const stringValidator = composeValidators(
|
|
|
77
160
|
() => yup.string().transform((val, originalVal) => originalVal),
|
|
78
161
|
addMinLengthValidator,
|
|
79
162
|
addMaxLengthValidator,
|
|
80
|
-
addStringRegexValidator
|
|
163
|
+
addStringRegexValidator,
|
|
164
|
+
addUniqueValidator
|
|
81
165
|
);
|
|
82
166
|
|
|
83
|
-
const emailValidator = composeValidators(stringValidator,
|
|
167
|
+
const emailValidator = composeValidators(stringValidator, validator => validator.email());
|
|
84
168
|
|
|
85
|
-
const uidValidator = composeValidators(stringValidator,
|
|
169
|
+
const uidValidator = composeValidators(stringValidator, validator =>
|
|
86
170
|
validator.matches(new RegExp('^[A-Za-z0-9-_.~]*$'))
|
|
87
171
|
);
|
|
88
172
|
|
|
89
|
-
const enumerationValidator = attr => {
|
|
173
|
+
const enumerationValidator = ({ attr }) => {
|
|
90
174
|
return yup.string().oneOf((Array.isArray(attr.enum) ? attr.enum : [attr.enum]).concat(null));
|
|
91
175
|
};
|
|
92
176
|
|
|
93
177
|
const integerValidator = composeValidators(
|
|
94
178
|
() => yup.number().integer(),
|
|
95
179
|
addMinIntegerValidator,
|
|
96
|
-
addMaxIntegerValidator
|
|
180
|
+
addMaxIntegerValidator,
|
|
181
|
+
addUniqueValidator
|
|
97
182
|
);
|
|
98
183
|
|
|
99
184
|
const floatValidator = composeValidators(
|
|
100
185
|
() => yup.number(),
|
|
101
186
|
addMinFloatValidator,
|
|
102
|
-
addMaxFloatValidator
|
|
187
|
+
addMaxFloatValidator,
|
|
188
|
+
addUniqueValidator
|
|
103
189
|
);
|
|
104
190
|
|
|
105
191
|
module.exports = {
|
|
@@ -113,11 +199,11 @@ module.exports = {
|
|
|
113
199
|
uid: uidValidator,
|
|
114
200
|
json: () => yup.mixed(),
|
|
115
201
|
integer: integerValidator,
|
|
116
|
-
biginteger: ()
|
|
202
|
+
biginteger: composeValidators(addUniqueValidator),
|
|
117
203
|
float: floatValidator,
|
|
118
204
|
decimal: floatValidator,
|
|
119
|
-
date: ()
|
|
120
|
-
time: ()
|
|
121
|
-
datetime: ()
|
|
122
|
-
timestamp: ()
|
|
205
|
+
date: composeValidators(addUniqueValidator),
|
|
206
|
+
time: composeValidators(addUniqueValidator),
|
|
207
|
+
datetime: composeValidators(addUniqueValidator),
|
|
208
|
+
timestamp: composeValidators(addUniqueValidator),
|
|
123
209
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@strapi/strapi",
|
|
3
|
-
"version": "4.0.0-beta.
|
|
3
|
+
"version": "4.0.0-beta.18",
|
|
4
4
|
"description": "An open source headless CMS solution to create and manage your own API. It provides a powerful dashboard and features to make your life easier. Databases supported: MySQL, MariaDB, PostgreSQL, SQLite",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"strapi",
|
|
@@ -79,16 +79,16 @@
|
|
|
79
79
|
"dependencies": {
|
|
80
80
|
"@koa/cors": "3.1.0",
|
|
81
81
|
"@koa/router": "10.1.1",
|
|
82
|
-
"@strapi/admin": "4.0.0-beta.
|
|
83
|
-
"@strapi/database": "4.0.0-beta.
|
|
84
|
-
"@strapi/generate-new": "4.0.0-beta.
|
|
85
|
-
"@strapi/generators": "4.0.0-beta.
|
|
86
|
-
"@strapi/logger": "4.0.0-beta.
|
|
87
|
-
"@strapi/plugin-content-manager": "4.0.0-beta.
|
|
88
|
-
"@strapi/plugin-content-type-builder": "4.0.0-beta.
|
|
89
|
-
"@strapi/plugin-email": "4.0.0-beta.
|
|
90
|
-
"@strapi/plugin-upload": "4.0.0-beta.
|
|
91
|
-
"@strapi/utils": "4.0.0-beta.
|
|
82
|
+
"@strapi/admin": "4.0.0-beta.18",
|
|
83
|
+
"@strapi/database": "4.0.0-beta.18",
|
|
84
|
+
"@strapi/generate-new": "4.0.0-beta.18",
|
|
85
|
+
"@strapi/generators": "4.0.0-beta.18",
|
|
86
|
+
"@strapi/logger": "4.0.0-beta.18",
|
|
87
|
+
"@strapi/plugin-content-manager": "4.0.0-beta.18",
|
|
88
|
+
"@strapi/plugin-content-type-builder": "4.0.0-beta.18",
|
|
89
|
+
"@strapi/plugin-email": "4.0.0-beta.18",
|
|
90
|
+
"@strapi/plugin-upload": "4.0.0-beta.18",
|
|
91
|
+
"@strapi/utils": "4.0.0-beta.18",
|
|
92
92
|
"bcryptjs": "2.4.3",
|
|
93
93
|
"boxen": "5.1.2",
|
|
94
94
|
"chalk": "4.1.2",
|
|
@@ -134,5 +134,5 @@
|
|
|
134
134
|
"node": ">=12.x.x <=16.x.x",
|
|
135
135
|
"npm": ">=6.0.0"
|
|
136
136
|
},
|
|
137
|
-
"gitHead": "
|
|
137
|
+
"gitHead": "3e9e3f13cb85822e6d92b0e448ae0b94d440dac1"
|
|
138
138
|
}
|