不要怂,就是干,撸起袖子干!

Commit 7b671d28 by Andy Edwards Committed by GitHub

refactor(instance-validator): asyncify methods (#12127)

1 parent 2924eba1
Showing with 52 additions and 47 deletions
...@@ -63,19 +63,19 @@ class InstanceValidator { ...@@ -63,19 +63,19 @@ class InstanceValidator {
* @returns {Promise} * @returns {Promise}
* @private * @private
*/ */
_validate() { async _validate() {
if (this.inProgress) throw new Error('Validations already in progress.'); if (this.inProgress) throw new Error('Validations already in progress.');
this.inProgress = true; this.inProgress = true;
return Promise.all([ await Promise.all([
this._perAttributeValidators(), this._perAttributeValidators(),
this._customValidators() this._customValidators()
]).then(() => { ]);
if (this.errors.length) {
throw new sequelizeError.ValidationError(null, this.errors); if (this.errors.length) {
} throw new sequelizeError.ValidationError(null, this.errors);
}); }
} }
/** /**
...@@ -88,8 +88,8 @@ class InstanceValidator { ...@@ -88,8 +88,8 @@ class InstanceValidator {
* @returns {Promise} * @returns {Promise}
* @private * @private
*/ */
validate() { async validate() {
return this.options.hooks ? this._validateAndRunHooks() : this._validate(); return await (this.options.hooks ? this._validateAndRunHooks() : this._validate());
} }
/** /**
...@@ -102,15 +102,19 @@ class InstanceValidator { ...@@ -102,15 +102,19 @@ class InstanceValidator {
* @returns {Promise} * @returns {Promise}
* @private * @private
*/ */
_validateAndRunHooks() { async _validateAndRunHooks() {
const runHooks = this.modelInstance.constructor.runHooks.bind(this.modelInstance.constructor); const runHooks = this.modelInstance.constructor.runHooks.bind(this.modelInstance.constructor);
return runHooks('beforeValidate', this.modelInstance, this.options) await runHooks('beforeValidate', this.modelInstance, this.options);
.then(() =>
this._validate() try {
.catch(error => runHooks('validationFailed', this.modelInstance, this.options, error) await this._validate();
.then(newError => { throw newError || error; })) } catch (error) {
) const newError = await runHooks('validationFailed', this.modelInstance, this.options, error);
.then(() => runHooks('afterValidate', this.modelInstance, this.options)).then(() => this.modelInstance); throw newError || error;
}
await runHooks('afterValidate', this.modelInstance, this.options);
return this.modelInstance;
} }
/** /**
...@@ -119,7 +123,7 @@ class InstanceValidator { ...@@ -119,7 +123,7 @@ class InstanceValidator {
* @returns {Promise<Array>} * @returns {Promise<Array>}
* @private * @private
*/ */
_perAttributeValidators() { async _perAttributeValidators() {
// promisify all attribute invocations // promisify all attribute invocations
const validators = []; const validators = [];
...@@ -144,7 +148,7 @@ class InstanceValidator { ...@@ -144,7 +148,7 @@ class InstanceValidator {
} }
}); });
return Promise.all(validators); return await Promise.all(validators);
} }
/** /**
...@@ -153,7 +157,7 @@ class InstanceValidator { ...@@ -153,7 +157,7 @@ class InstanceValidator {
* @returns {Promise<Array>} * @returns {Promise<Array>}
* @private * @private
*/ */
_customValidators() { async _customValidators() {
const validators = []; const validators = [];
_.each(this.modelInstance._modelOptions.validate, (validator, validatorType) => { _.each(this.modelInstance._modelOptions.validate, (validator, validatorType) => {
if (this.options.skip.includes(validatorType)) { if (this.options.skip.includes(validatorType)) {
...@@ -167,7 +171,7 @@ class InstanceValidator { ...@@ -167,7 +171,7 @@ class InstanceValidator {
validators.push(valprom); validators.push(valprom);
}); });
return Promise.all(validators); return await Promise.all(validators);
} }
/** /**
...@@ -181,11 +185,11 @@ class InstanceValidator { ...@@ -181,11 +185,11 @@ class InstanceValidator {
* *
* @returns {Promise} A promise, will always resolve, auto populates error on this.error local object. * @returns {Promise} A promise, will always resolve, auto populates error on this.error local object.
*/ */
_singleAttrValidate(value, field, allowNull) { async _singleAttrValidate(value, field, allowNull) {
// If value is null and allowNull is false, no validators should run (see #9143) // If value is null and allowNull is false, no validators should run (see #9143)
if ((value === null || value === undefined) && !allowNull) { if ((value === null || value === undefined) && !allowNull) {
// The schema validator (_validateSchema) has already generated the validation error. Nothing to do here. // The schema validator (_validateSchema) has already generated the validation error. Nothing to do here.
return Promise.resolve(); return;
} }
// Promisify each validator // Promisify each validator
...@@ -240,8 +244,7 @@ class InstanceValidator { ...@@ -240,8 +244,7 @@ class InstanceValidator {
* *
* @returns {Promise} A promise. * @returns {Promise} A promise.
*/ */
_invokeCustomValidator(validator, validatorType, optAttrDefined, optValue, optField) { async _invokeCustomValidator(validator, validatorType, optAttrDefined, optValue, optField) {
let validatorFunction = null; // the validation function to call
let isAsync = false; let isAsync = false;
const validatorArity = validator.length; const validatorArity = validator.length;
...@@ -259,17 +262,21 @@ class InstanceValidator { ...@@ -259,17 +262,21 @@ class InstanceValidator {
} }
if (isAsync) { if (isAsync) {
if (optAttrDefined) { try {
validatorFunction = promisify(validator.bind(this.modelInstance, invokeArgs)); if (optAttrDefined) {
} else { return await promisify(validator.bind(this.modelInstance, invokeArgs))();
validatorFunction = promisify(validator.bind(this.modelInstance)); }
return await promisify(validator.bind(this.modelInstance))();
} catch (e) {
return this._pushError(false, errorKey, e, optValue, validatorType);
} }
return validatorFunction()
.catch(e => this._pushError(false, errorKey, e, optValue, validatorType));
} }
return Promise
.try(() => validator.call(this.modelInstance, invokeArgs)) try {
.catch(e => this._pushError(false, errorKey, e, optValue, validatorType)); return await validator.call(this.modelInstance, invokeArgs);
} catch (e) {
return this._pushError(false, errorKey, e, optValue, validatorType);
}
} }
/** /**
...@@ -284,21 +291,19 @@ class InstanceValidator { ...@@ -284,21 +291,19 @@ class InstanceValidator {
* *
* @returns {object} An object with specific keys to invoke the validator. * @returns {object} An object with specific keys to invoke the validator.
*/ */
_invokeBuiltinValidator(value, test, validatorType, field) { async _invokeBuiltinValidator(value, test, validatorType, field) {
return Promise.try(() => { // Cast value as string to pass new Validator.js string requirement
// Cast value as string to pass new Validator.js string requirement const valueString = String(value);
const valueString = String(value); // check if Validator knows that kind of validation test
// check if Validator knows that kind of validation test if (typeof validator[validatorType] !== 'function') {
if (typeof validator[validatorType] !== 'function') { throw new Error(`Invalid validator function: ${validatorType}`);
throw new Error(`Invalid validator function: ${validatorType}`); }
}
const validatorArgs = this._extractValidatorArgs(test, validatorType, field); const validatorArgs = this._extractValidatorArgs(test, validatorType, field);
if (!validator[validatorType](valueString, ...validatorArgs)) { if (!validator[validatorType](valueString, ...validatorArgs)) {
throw Object.assign(new Error(test.msg || `Validation ${validatorType} on ${field} failed`), { validatorName: validatorType, validatorArgs }); throw Object.assign(new Error(test.msg || `Validation ${validatorType} on ${field} failed`), { validatorName: validatorType, validatorArgs });
} }
});
} }
/** /**
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!