Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add function SchemaType.prototype.validateAll #14434

Merged
merged 5 commits into from Mar 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
19 changes: 18 additions & 1 deletion lib/schemaType.js
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
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
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