Skip to content

Commit

Permalink
Merge pull request #14434 from Automattic/IslandRhythms/gh-6910
Browse files Browse the repository at this point in the history
Add function `SchemaType.prototype.validateAll`
  • Loading branch information
vkarpov15 authored Mar 18, 2024
2 parents 92b2544 + 399531b commit dc9810b
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 4 deletions.
19 changes: 18 additions & 1 deletion lib/schemaType.js
Original file line number Diff line number Diff line change
Expand Up @@ -803,6 +803,21 @@ SchemaType.prototype.get = function(fn) {
return this;
};

/**
* Adds multiple validators for this document path.
* Calls `validate()` for every element in validators.
*
* @param {Array<RegExp|Function|Object>} validators
* @returns this
*/

SchemaType.prototype.validateAll = function(validators) {
for (let i = 0; i < validators.length; i++) {
this.validate(validators[i]);
}
return this;
};

/**
* Adds validator(s) for this document path.
*
Expand Down Expand Up @@ -1285,6 +1300,9 @@ SchemaType.prototype.select = function select(val) {
SchemaType.prototype.doValidate = function(value, fn, scope, options) {
let err = false;
const path = this.path;
if (typeof fn !== 'function') {
throw new TypeError(`Must pass callback function to doValidate(), got ${typeof fn}`);
}

// Avoid non-object `validators`
const validators = this.validators.
Expand Down Expand Up @@ -1419,7 +1437,6 @@ SchemaType.prototype.doValidateSync = function(value, scope, options) {
let i = 0;
const len = validators.length;
for (i = 0; i < len; ++i) {

const v = validators[i];

if (v === null || typeof v !== 'object') {
Expand Down
34 changes: 34 additions & 0 deletions test/schematype.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -281,4 +281,38 @@ describe('schematype', function() {
});
});
});
it('demonstrates the `validateAll()` function (gh-6910)', function() {
const validateSchema = new Schema({ name: String, password: String });
validateSchema.path('name').validate({
validator: function(v) {
return v.length > 5;
},
message: 'name must be longer than 5 characters'
});
validateSchema.path('password').validateAll([
{
validator: function(v) {
return this.name !== v;
},
message: 'password must not equal name'
},
{
validator: function(v) {
return v.length > 5;
},
message: 'password must be at least six characters'
}
]);
assert.equal(validateSchema.path('password').validators.length, 2);

const passwordPath = validateSchema.path('password');
assert.throws(
() => { throw passwordPath.doValidateSync('john', { name: 'john' }); },
/password must not equal name/
);
assert.throws(
() => { throw passwordPath.doValidateSync('short', { name: 'john' }); },
/password must be at least six characters/
);
});
});
13 changes: 10 additions & 3 deletions types/schematypes.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -192,10 +192,14 @@ declare module 'mongoose' {
[other: string]: any;
}

interface Validator {
message?: string; type?: string; validator?: Function
interface Validator<DocType = any> {
message?: string;
type?: string;
validator?: ValidatorFunction<DocType>;
}

type ValidatorFunction<DocType = any> = (this: DocType, value: any, validatorProperties?: Validator) => any;

class SchemaType<T = any, DocType = any> {
/** SchemaType constructor */
constructor(path: string, options?: AnyObject, instance?: string);
Expand Down Expand Up @@ -281,7 +285,10 @@ declare module 'mongoose' {
validators: Validator[];

/** Adds validator(s) for this document path. */
validate(obj: RegExp | ((this: DocType, value: any, validatorProperties?: Validator) => any), errorMsg?: string, type?: string): this;
validate(obj: RegExp | ValidatorFunction<DocType> | Validator<DocType>, errorMsg?: string, type?: string): this;

/** Adds multiple validators for this document path. */
validateAll(validators: Array<RegExp | ValidatorFunction<DocType> | Validator<DocType>>): this;

/** Default options for this SchemaType */
defaultOptions?: Record<string, any>;
Expand Down

0 comments on commit dc9810b

Please sign in to comment.