Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: Automattic/mongoose
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: f90e73d89344257c365134d58ace0a5f81eb89d4
Choose a base ref
...
head repository: Automattic/mongoose
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: f1c433c0f90ad1a65c8b3795eefaaf02a64b849e
Choose a head ref
  • 20 commits
  • 14 files changed
  • 3 contributors

Commits on Nov 2, 2022

  1. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    74af5f5 View commit details
  2. fix(types): add UUID to types

    Fix #12593
    Re: #12268
    Re: #3208
    vkarpov15 committed Nov 2, 2022

    Partially verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    We cannot verify signatures from co-authors, and some of the co-authors attributed to this commit require their commits to be signed.
    Copy the full SHA
    0b78e82 View commit details
  3. Merge pull request #12642 from lpizzinidev/fix-12622

    fix(type): pre hook with deleteOne should resolve this as Query
    vkarpov15 authored Nov 2, 2022

    Partially verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    We cannot verify signatures from co-authors, and some of the co-authors attributed to this commit require their commits to be signed.
    Copy the full SHA
    8b0adf5 View commit details
  4. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    243e4d4 View commit details
  5. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    4ddeb46 View commit details

Commits on Nov 3, 2022

  1. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    4e953ea View commit details
  2. applied requested changes

    used applyPlugins option in discriminator helper instead of creating new option mergePlugins
    lpizzinidev committed Nov 3, 2022

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    9789338 View commit details
  3. test trigger

    lpizzinidev committed Nov 3, 2022

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    1ff2654 View commit details
  4. fix lint

    lpizzinidev committed Nov 3, 2022
    Copy the full SHA
    edca782 View commit details

Commits on Nov 4, 2022

  1. Copy the full SHA
    ae14d0e View commit details
  2. Copy the full SHA
    e559695 View commit details
  3. Merge pull request #12613 from lpizzinidev/feat-applyplugins

    feat(model): add `mergePlugins` option to `discriminator`
    vkarpov15 authored Nov 4, 2022
    Copy the full SHA
    5a40613 View commit details
  4. Merge pull request #12650 from Automattic/vkarpov15/gh-12593

    fix(types): add UUID to types
    vkarpov15 authored Nov 4, 2022
    Copy the full SHA
    cdfc84f View commit details
  5. Copy the full SHA
    a061ccd View commit details

Commits on Nov 7, 2022

  1. Copy the full SHA
    6c78334 View commit details
  2. Update test/types/models.test.ts

    Co-authored-by: hasezoey <hasezoey@gmail.com>
    vkarpov15 and hasezoey authored Nov 7, 2022
    Copy the full SHA
    f9fb612 View commit details
  3. Merge pull request #12659 from Automattic/vkarpov15/gh-12573

    fix(types): correct handling for model<any>
    vkarpov15 authored Nov 7, 2022
    Copy the full SHA
    5280b0c View commit details
  4. Copy the full SHA
    78b91b4 View commit details
  5. Merge pull request #12663 from Automattic/vkarpov15/gh-12590

    fix(types): set `this` to doc type in `SchemaType.prototype.validate()`
    vkarpov15 authored Nov 7, 2022
    Copy the full SHA
    4559282 View commit details
  6. chore: release 6.7.2

    vkarpov15 committed Nov 7, 2022
    Copy the full SHA
    f1c433c View commit details
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
6.7.2 / 2022-11-07
==================
* fix(discriminator): skip copying base schema plugins if `applyPlugins == false` #12613 #12604 [lpizzinidev](https://github.com/lpizzinidev)
* fix(types): add UUID to types #12650 #12593
* fix(types): allow setting SchemaTypeOptions' index property to IndexOptions #12562
* fix(types): set this to doc type in SchemaType.prototype.validate() #12663 #12590
* fix(types): correct handling for model<any> #12659 #12573
* fix(types): pre hook with deleteOne should resolve this as Query #12642 #12622 [lpizzinidev](https://github.com/lpizzinidev)

6.7.1 / 2022-11-02
==================
* fix(query): select Map field with select: false when explicitly requested #12616 #12603 [lpizzinidev](https://github.com/lpizzinidev)
9 changes: 6 additions & 3 deletions docs/loadSponsorData.js
Original file line number Diff line number Diff line change
@@ -5,9 +5,6 @@ const config = require('../.config');
const fs = require('fs');
const mongoose = require('../');

const poralHost = 'https://staging.poral.io';
const opencollectiveUrl = `${poralHost}/invoke/${config.poralId}/generateSponsors`;

run().catch(err => {
console.error(err);
process.exit(-1);
@@ -91,6 +88,12 @@ async function run() {
sponsor.alt = override.alt;
}
}

const additionalSponsors = await OpenCollectiveSponsor.find({}).
then(docs => docs.filter(doc => doc.openCollectiveId == null));
for (const sponsor of additionalSponsors) {
opencollectiveSponsors.push(sponsor);
}

if (opencollectiveSponsors != null) {
fs.writeFileSync(`${__dirname}/data/opencollective.json`, JSON.stringify(opencollectiveSponsors, null, ' '));
5 changes: 3 additions & 2 deletions lib/helpers/model/discriminator.js
Original file line number Diff line number Diff line change
@@ -184,8 +184,9 @@ module.exports = function discriminator(model, name, schema, tiedValue, applyPlu
if (mergeHooks) {
schema.s.hooks = model.schema.s.hooks.merge(schema.s.hooks);
}

schema.plugins = Array.prototype.slice.call(baseSchema.plugins);
if (applyPlugins) {
schema.plugins = Array.prototype.slice.call(baseSchema.plugins);
}
schema.callQueue = baseSchema.callQueue.concat(schema.callQueue);
delete schema._requiredpaths; // reset just in case Schema#requiredPaths() was called on either schema
}
4 changes: 3 additions & 1 deletion lib/model.js
Original file line number Diff line number Diff line change
@@ -1215,6 +1215,7 @@ Model.exists = function exists(filter, options, callback) {
* @param {Boolean} [options.clone=true] By default, `discriminator()` clones the given `schema`. Set to `false` to skip cloning.
* @param {Boolean} [options.overwriteModels=false] by default, Mongoose does not allow you to define a discriminator with the same name as another discriminator. Set this to allow overwriting discriminators with the same name.
* @param {Boolean} [options.mergeHooks=true] By default, Mongoose merges the base schema's hooks with the discriminator schema's hooks. Set this option to `false` to make Mongoose use the discriminator schema's hooks instead.
* @param {Boolean} [options.mergePlugins=true] By default, Mongoose merges the base schema's plugins with the discriminator schema's plugins. Set this option to `false` to make Mongoose use the discriminator schema's plugins instead.
* @return {Model} The newly created discriminator model
* @api public
*/
@@ -1232,6 +1233,7 @@ Model.discriminator = function(name, schema, options) {
options = options || {};
const value = utils.isPOJO(options) ? options.value : options;
const clone = typeof options.clone === 'boolean' ? options.clone : true;
const mergePlugins = typeof options.mergePlugins === 'boolean' ? options.mergePlugins : true;

_checkContext(this, 'discriminator');

@@ -1242,7 +1244,7 @@ Model.discriminator = function(name, schema, options) {
schema = schema.clone();
}

schema = discriminator(this, name, schema, value, true, options.mergeHooks);
schema = discriminator(this, name, schema, value, mergePlugins, options.mergeHooks);
if (this.db.models[name] && !schema.options.overwriteModels) {
throw new OverwriteModelError(name);
}
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "mongoose",
"description": "Mongoose MongoDB ODM",
"version": "6.7.1",
"version": "6.7.2",
"author": "Guillermo Rauch <guillermo@learnboost.com>",
"keywords": [
"mongodb",
38 changes: 38 additions & 0 deletions test/model.discriminator.test.js
Original file line number Diff line number Diff line change
@@ -2039,4 +2039,42 @@ describe('model', function() {
schema.pre('save', function testHook12472() {});
}
});

it('supports `mergePlugins` option to use the discriminator schema\'s plugins over the base schema\'s (gh-12604)', function() {
let pluginTimes = 0;
const shapeDef = { name: String };
const shapeSchema = Schema(shapeDef, { discriminatorKey: 'kind' });
shapeSchema.plugin(myPlugin, { opts1: true });

const Shape = db.model('Test', shapeSchema);

const triangleSchema = Schema({ ...shapeDef, sides: { type: Number, enum: [3] } });
triangleSchema.plugin(myPlugin, { opts2: true });
const Triangle = Shape.discriminator(
'Triangle',
triangleSchema
);

const squareSchema = Schema({ ...shapeDef, sides: { type: Number, enum: [4] } });
squareSchema.plugin(myPlugin, { opts3: true });
const Square = Shape.discriminator(
'Square',
squareSchema,
{ mergeHooks: false, mergePlugins: false }
);

assert.equal(Triangle.schema.s.hooks._pres.get('save').filter(hook => hook.fn.name === 'testHook12604').length, 2);
assert.equal(Square.schema.s.hooks._pres.get('save').filter(hook => hook.fn.name === 'testHook12604').length, 1);

const squareFilteredPlugins = Square.schema.plugins.filter((obj) => obj.fn.name === 'myPlugin');
assert.equal(squareFilteredPlugins.length, 1);
assert.equal(squareFilteredPlugins[0].opts['opts3'], true);

assert.equal(pluginTimes, 3);

function myPlugin(schema) {
pluginTimes += 1;
schema.pre('save', function testHook12604() {});
}
});
});
2 changes: 1 addition & 1 deletion test/types/discriminator.test.ts
Original file line number Diff line number Diff line change
@@ -21,7 +21,7 @@ doc.email = 'hello';
const Disc2 = Base.discriminator<IDiscriminatorTest>(
'Disc2',
new Schema({ email: { type: String } }),
{ value: 'test', mergeHooks: false }
{ value: 'test', mergeHooks: false, mergePlugins: false }
);

function test(): void {
16 changes: 16 additions & 0 deletions test/types/models.test.ts
Original file line number Diff line number Diff line change
@@ -192,6 +192,14 @@ projectSchema.post('save', function() {
// this => IProject
});

projectSchema.pre('deleteOne', function() {
this.model;
});

projectSchema.post('deleteOne', function() {
this.model;
});

projectSchema.methods.myMethod = () => 10;

projectSchema.statics.myStatic = () => 42;
@@ -553,3 +561,11 @@ function findWithId() {
TestModel.find(id);
TestModel.findOne(id);
}

function gh12573ModelAny() {
const TestModel = model<any>('Test', new Schema({}));
const doc = new TestModel();
expectType<any>(doc);
const { fieldA } = doc;
expectType<any>(fieldA);
}
66 changes: 66 additions & 0 deletions test/types/schema.test.ts
Original file line number Diff line number Diff line change
@@ -872,3 +872,69 @@ function gh12431() {
type Example = InferSchemaType<typeof testSchema>;
expectType<{ testDate?: Date, testDecimal?: Types.Decimal128 }>({} as Example);
}

async function gh12593() {
const testSchema = new Schema({ x: { type: Schema.Types.UUID } });

type Example = InferSchemaType<typeof testSchema>;
expectType<{ x?: Buffer }>({} as Example);

const Test = model('Test', testSchema);

const doc = await Test.findOne({ x: '4709e6d9-61fd-435e-b594-d748eb196d8f' }).orFail();
expectType<Buffer | undefined>(doc.x);

const doc2 = new Test({ x: '4709e6d9-61fd-435e-b594-d748eb196d8f' });
expectType<Buffer | undefined>(doc2.x);

const doc3 = await Test.findOne({}).orFail().lean();
expectType<Buffer | undefined>(doc3.x);

const arrSchema = new Schema({ arr: [{ type: Schema.Types.UUID }] });

type ExampleArr = InferSchemaType<typeof arrSchema>;
expectType<{ arr: Buffer[] }>({} as ExampleArr);
}

function gh12562() {
const emailRegExp = /@/;
const userSchema = new Schema(
{
email: {
type: String,
trim: true,
validate: {
validator: (value: string) => emailRegExp.test(value),
message: 'Email is not valid'
},
index: { // uncomment the index object and for me trim was throwing an error
partialFilterExpression: {
email: {
$exists: true,
$ne: null
}
}
},
select: false
}
}
);
}

function gh12590() {
const UserSchema = new Schema({
_password: String
});

type User = InferSchemaType<typeof UserSchema>;

expectType<SchemaType<User>>(UserSchema.path('hashed_password'));

UserSchema.path('hashed_password').validate(function(v) {
expectType<HydratedDocument<User>>(this);
if (this._password && this._password.length < 8) {
this.invalidate('password', 'Password must be at least 8 characters.');
}
});

}
15 changes: 7 additions & 8 deletions types/index.d.ts
Original file line number Diff line number Diff line change
@@ -258,8 +258,8 @@ declare module 'mongoose' {
obj: SchemaDefinition<SchemaDefinitionType<EnforcedDocType>>;

/** Gets/sets schema paths. */
path<ResultType extends SchemaType = SchemaType<any, HydratedDocument<DocType, TInstanceMethods>>>(path: string): ResultType;
path<pathGeneric extends keyof EnforcedDocType>(path: pathGeneric): SchemaType<EnforcedDocType[pathGeneric]>;
path<ResultType extends SchemaType = SchemaType>(path: string): ResultType;
path(path: string, constructor: any): this;

/** Lists all paths and their type in the schema. */
@@ -274,19 +274,19 @@ declare module 'mongoose' {
plugin<PFunc extends PluginFunction<DocType, M, any, any, any, any>, POptions extends Parameters<PFunc>[1] = Parameters<PFunc>[1]>(fn: PFunc, opts?: POptions): this;

/** Defines a post hook for the model. */
post<T = HydratedDocument<DocType, TInstanceMethods>>(method: MongooseDocumentMiddleware | MongooseDocumentMiddleware[] | RegExp, fn: PostMiddlewareFunction<T, T>): this;
post<T = HydratedDocument<DocType, TInstanceMethods>>(method: MongooseDocumentMiddleware | MongooseDocumentMiddleware[] | RegExp, options: SchemaPostOptions, fn: PostMiddlewareFunction<T, T>): this;
post<T = Query<any, any>>(method: MongooseQueryMiddleware | MongooseQueryMiddleware[] | RegExp, fn: PostMiddlewareFunction<T, QueryResultType<T>>): this;
post<T = Query<any, any>>(method: MongooseQueryMiddleware | MongooseQueryMiddleware[] | RegExp, options: SchemaPostOptions, fn: PostMiddlewareFunction<T, QueryResultType<T>>): this;
post<T = HydratedDocument<DocType, TInstanceMethods>>(method: MongooseDocumentMiddleware | MongooseDocumentMiddleware[] | RegExp, fn: PostMiddlewareFunction<T, T>): this;
post<T = HydratedDocument<DocType, TInstanceMethods>>(method: MongooseDocumentMiddleware | MongooseDocumentMiddleware[] | RegExp, options: SchemaPostOptions, fn: PostMiddlewareFunction<T, T>): this;
post<T extends Aggregate<any>>(method: 'aggregate' | RegExp, fn: PostMiddlewareFunction<T, Array<AggregateExtract<T>>>): this;
post<T extends Aggregate<any>>(method: 'aggregate' | RegExp, options: SchemaPostOptions, fn: PostMiddlewareFunction<T, Array<AggregateExtract<T>>>): this;
post<T = M>(method: 'insertMany' | RegExp, fn: PostMiddlewareFunction<T, T>): this;
post<T = M>(method: 'insertMany' | RegExp, options: SchemaPostOptions, fn: PostMiddlewareFunction<T, T>): this;

post<T = HydratedDocument<DocType, TInstanceMethods>>(method: MongooseDocumentMiddleware | MongooseDocumentMiddleware[] | RegExp, fn: ErrorHandlingMiddlewareFunction<T>): this;
post<T = HydratedDocument<DocType, TInstanceMethods>>(method: MongooseDocumentMiddleware | MongooseDocumentMiddleware[] | RegExp, options: SchemaPostOptions, fn: ErrorHandlingMiddlewareFunction<T>): this;
post<T = Query<any, any>>(method: MongooseQueryMiddleware | MongooseQueryMiddleware[] | RegExp, fn: ErrorHandlingMiddlewareFunction<T>): this;
post<T = Query<any, any>>(method: MongooseQueryMiddleware | MongooseQueryMiddleware[] | RegExp, options: SchemaPostOptions, fn: ErrorHandlingMiddlewareFunction<T>): this;
post<T = HydratedDocument<DocType, TInstanceMethods>>(method: MongooseDocumentMiddleware | MongooseDocumentMiddleware[] | RegExp, fn: ErrorHandlingMiddlewareFunction<T>): this;
post<T = HydratedDocument<DocType, TInstanceMethods>>(method: MongooseDocumentMiddleware | MongooseDocumentMiddleware[] | RegExp, options: SchemaPostOptions, fn: ErrorHandlingMiddlewareFunction<T>): this;
post<T extends Aggregate<any>>(method: 'aggregate' | RegExp, fn: ErrorHandlingMiddlewareFunction<T, Array<any>>): this;
post<T extends Aggregate<any>>(method: 'aggregate' | RegExp, options: SchemaPostOptions, fn: ErrorHandlingMiddlewareFunction<T, Array<any>>): this;
post<T = M>(method: 'insertMany' | RegExp, fn: ErrorHandlingMiddlewareFunction<T>): this;
@@ -295,10 +295,10 @@ declare module 'mongoose' {
/** Defines a pre hook for the model. */
pre<T = HydratedDocument<DocType, TInstanceMethods>>(method: 'save', fn: PreSaveMiddlewareFunction<T>): this;
pre<T = HydratedDocument<DocType, TInstanceMethods>>(method: 'save', options: SchemaPreOptions, fn: PreSaveMiddlewareFunction<T>): this;
pre<T = HydratedDocument<DocType, TInstanceMethods>>(method: MongooseDocumentMiddleware | MongooseDocumentMiddleware[] | RegExp, fn: PreMiddlewareFunction<T>): this;
pre<T = HydratedDocument<DocType, TInstanceMethods>>(method: MongooseDocumentMiddleware | MongooseDocumentMiddleware[] | RegExp, options: SchemaPreOptions, fn: PreMiddlewareFunction<T>): this;
pre<T = Query<any, any>>(method: MongooseQueryMiddleware | MongooseQueryMiddleware[] | RegExp, fn: PreMiddlewareFunction<T>): this;
pre<T = Query<any, any>>(method: MongooseQueryMiddleware | MongooseQueryMiddleware[] | RegExp, options: SchemaPreOptions, fn: PreMiddlewareFunction<T>): this;
pre<T = HydratedDocument<DocType, TInstanceMethods>>(method: MongooseDocumentMiddleware | MongooseDocumentMiddleware[] | RegExp, fn: PreMiddlewareFunction<T>): this;
pre<T = HydratedDocument<DocType, TInstanceMethods>>(method: MongooseDocumentMiddleware | MongooseDocumentMiddleware[] | RegExp, options: SchemaPreOptions, fn: PreMiddlewareFunction<T>): this;
pre<T extends Aggregate<any>>(method: 'aggregate' | RegExp, fn: PreMiddlewareFunction<T>): this;
pre<T extends Aggregate<any>>(method: 'aggregate' | RegExp, options: SchemaPreOptions, fn: PreMiddlewareFunction<T>): this;
pre<T = M>(method: 'insertMany' | RegExp, fn: (this: T, next: (err?: CallbackError) => void, docs: any | Array<any>) => void | Promise<void>): this;
@@ -551,7 +551,6 @@ declare module 'mongoose' {
export type SchemaDefinitionType<T> = T extends Document ? Omit<T, Exclude<keyof Document, '_id' | 'id' | '__v'>> : T;

// Helpers to simplify checks
type IfAny<IFTYPE, THENTYPE, ELSETYPE = IFTYPE> = 0 extends (1 & IFTYPE) ? THENTYPE : ELSETYPE;
type IfUnknown<IFTYPE, THENTYPE> = unknown extends IFTYPE ? THENTYPE : IFTYPE;

// tests for these two types are located in test/types/lean.test.ts
20 changes: 11 additions & 9 deletions types/inferschematype.d.ts
Original file line number Diff line number Diff line change
@@ -38,7 +38,7 @@ declare module 'mongoose' {
* // result
* type UserType = {userName?: string}
*/
type InferSchemaType<TSchema> = ObtainSchemaGeneric<TSchema, 'DocType'>;
type InferSchemaType<TSchema> = IfAny<TSchema, any, ObtainSchemaGeneric<TSchema, 'DocType'>>;

/**
* @summary Obtains schema Generic type by using generic alias.
@@ -177,11 +177,13 @@ type ResolvePathType<PathValueType, Options extends SchemaTypeOptions<PathValueT
PathValueType extends 'decimal128' | 'Decimal128' | typeof Schema.Types.Decimal128 ? Types.Decimal128 :
IfEquals<PathValueType, Schema.Types.Decimal128> extends true ? Types.Decimal128 :
IfEquals<PathValueType, Types.Decimal128> extends true ? Types.Decimal128 :
PathValueType extends MapConstructor ? Map<string, ResolvePathType<Options['of']>> :
PathValueType extends ArrayConstructor ? any[] :
PathValueType extends typeof Schema.Types.Mixed ? any:
IfEquals<PathValueType, ObjectConstructor> extends true ? any:
IfEquals<PathValueType, {}> extends true ? any:
PathValueType extends typeof SchemaType ? PathValueType['prototype'] :
PathValueType extends Record<string, any> ? ObtainDocumentType<PathValueType, any, TypeKey> :
unknown;
PathValueType extends 'uuid' | 'UUID' | typeof Schema.Types.UUID ? Buffer :
IfEquals<PathValueType, Schema.Types.UUID> extends true ? Buffer :
PathValueType extends MapConstructor ? Map<string, ResolvePathType<Options['of']>> :
PathValueType extends ArrayConstructor ? any[] :
PathValueType extends typeof Schema.Types.Mixed ? any:
IfEquals<PathValueType, ObjectConstructor> extends true ? any:
IfEquals<PathValueType, {}> extends true ? any:
PathValueType extends typeof SchemaType ? PathValueType['prototype'] :
PathValueType extends Record<string, any> ? ObtainDocumentType<PathValueType, any, TypeKey> :
unknown;
1 change: 1 addition & 0 deletions types/models.d.ts
Original file line number Diff line number Diff line change
@@ -6,6 +6,7 @@ declare module 'mongoose' {
clone?: boolean;
overwriteModels?: boolean;
mergeHooks?: boolean;
mergePlugins?: boolean;
}

export interface AcceptsDiscriminator {
17 changes: 13 additions & 4 deletions types/schematypes.d.ts
Original file line number Diff line number Diff line change
@@ -100,7 +100,7 @@ declare module 'mongoose' {
* If [truthy](https://masteringjs.io/tutorials/fundamentals/truthy), Mongoose will
* build an index on this path when the model is compiled.
*/
index?: boolean | IndexDirection;
index?: boolean | IndexDirection | IndexOptions;

/**
* If [truthy](https://masteringjs.io/tutorials/fundamentals/truthy), Mongoose
@@ -188,7 +188,11 @@ declare module 'mongoose' {
[other: string]: any;
}

class SchemaType<T = any> {
interface Validator {
message?: string; type?: string; validator?: Function
}

class SchemaType<T = any, DocType = any> {
/** SchemaType constructor */
constructor(path: string, options?: AnyObject, instance?: string);

@@ -270,10 +274,10 @@ declare module 'mongoose' {
unique(bool: boolean): this;

/** The validators that Mongoose should run to validate properties at this SchemaType's path. */
validators: { message?: string; type?: string; validator?: Function }[];
validators: Validator[];

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

namespace Schema {
@@ -422,6 +426,11 @@ declare module 'mongoose' {
/** Adds an uppercase [setter](http://mongoosejs.com/docs/api.html#schematype_SchemaType-set). */
uppercase(shouldApply?: boolean): this;
}

class UUID extends SchemaType {
/** This schema type's name, to defend against minifiers that mangle function names. */
static schemaName: 'UUID';
}
}
}
}
1 change: 1 addition & 0 deletions types/utility.d.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
declare module 'mongoose' {
type IfAny<IFTYPE, THENTYPE, ELSETYPE = IFTYPE> = 0 extends (1 & IFTYPE) ? THENTYPE : ELSETYPE;

type Unpacked<T> = T extends (infer U)[] ?
U :