Skip to content

Commit

Permalink
fix en countDocuments
Browse files Browse the repository at this point in the history
  • Loading branch information
Juan Carlos Muñoz committed Sep 5, 2023
1 parent 5cba9d2 commit 83a3666
Show file tree
Hide file tree
Showing 4 changed files with 97 additions and 66 deletions.
33 changes: 33 additions & 0 deletions .eslintrc.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
module.exports = {
root: true,
env: {
node: true,
es2022: true
},
plugins: ["prettier"],
extends: ["plugin:prettier/recommended"],
rules: {
"no-console": 0,
"max-len": [
"error",
{
code: 120,
ignoreComments: true
}
],
"prettier/prettier": [
"warn",
{
printWidth: 120,
tabWidth: 2,
bracketSpacing: false,
trailingComma: "none",
arrowParens: "avoid"
}
]
},
parserOptions: {
ecmaVersion: 2022,
sourceType: "module"
}
};
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,4 @@ $RECYCLE.BIN/
node_modules/
.tmp
npm-debug.log
Session.vim
127 changes: 62 additions & 65 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ const get = require("lodash.get");
// Function typecheck helper
const isFunc = val => typeof val === "function";

const deepPath = function(schema, pathName) {
const deepPath = function (schema, pathName) {
let path;
const paths = pathName.split(".");

Expand All @@ -26,7 +26,7 @@ const deepPath = function(schema, pathName) {
};

// Export the mongoose plugin
module.exports = function(schema, options) {
module.exports = function (schema, options) {
options = options || {};
const type = options.type || "unique";
const message = options.message || "Error, expected `{PATH}` to be unique. Value: `{VALUE}`";
Expand All @@ -51,77 +51,74 @@ module.exports = function(schema, options) {
if (path) {
// Add an async validator
path.validate(
function() {
return new Promise(resolve => {
const isSubdocument = isFunc(this.ownerDocument) && this.ownerDocument() !== this;
const isQuery = this.constructor.name === "Query";
const parentDoc = isSubdocument ? this.ownerDocument() : this;
const isNew = typeof parentDoc.isNew === "boolean" ? parentDoc.isNew : !isQuery;

let conditions = {};
each(paths, name => {
let pathValue;

// If the doc is a query, this is a findAndUpdate
if (isQuery) {
pathValue = get(this, "_update." + name) || get(this, "_update.$set." + name);
} else {
pathValue = get(this, isSubdocument ? name.split(".").pop() : name);
}

// Wrap with case-insensitivity
if (get(path, "options.uniqueCaseInsensitive") || indexOptions.uniqueCaseInsensitive) {
//no escapar si es un arreglo
if(!Array.isArray(pathValue)){
// Escape RegExp chars
pathValue = pathValue.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
pathValue = new RegExp("^" + pathValue + "$", "i");
}
}
async function () {
const isSubdocument = isFunc(this.ownerDocument) && this.ownerDocument() !== this;
const isQuery = this.constructor.name === "Query";
const parentDoc = isSubdocument ? this.ownerDocument() : this;
const isNew = typeof parentDoc.isNew === "boolean" ? parentDoc.isNew : !isQuery;

conditions[name] = pathValue;
});

if (!isNew) {
// Use conditions the user has with find*AndUpdate
if (isQuery) {
each(this._conditions, (value, key) => {
conditions[key] = {$ne: value};
});
} else if (pathName !== "_id") {
// if it's not new then it always has _id
conditions._id = {$ne: this._id};
} else {
// if is not new and is not query and the pathName is _id then is the same document no need to check anything
return resolve(true);
}
}
const conditions = {};
each(paths, name => {
let pathValue;

// Obtain the model depending on context
// https://github.com/Automattic/mongoose/issues/3430
// https://github.com/Automattic/mongoose/issues/3589
let model;
// If the doc is a query, this is a findAndUpdate
if (isQuery) {
model = this.model;
} else if (isSubdocument) {
model = this.ownerDocument().model(this.ownerDocument().constructor.modelName);
} else if (this.constructor.modelName) {
// if the constructor has modelName then the constructor is the model
model = this.constructor;
pathValue = get(this, "_update." + name) || get(this, "_update.$set." + name);
} else {
pathValue = get(this, isSubdocument ? name.split(".").pop() : name);
}

// Is this model a discriminator and the unique index is on the whole collection,
// not just the instances of the discriminator? If so, use the base model to query.
// https://github.com/Automattic/mongoose/issues/4965
if (model.baseModelName && indexOptions.partialFilterExpression === null) {
model = model.db.model(model.baseModelName);
// Wrap with case-insensitivity
if (get(path, "options.uniqueCaseInsensitive") || indexOptions.uniqueCaseInsensitive) {
//no escapar si es un arreglo
if (!Array.isArray(pathValue)) {
// Escape RegExp chars
pathValue = pathValue.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
pathValue = new RegExp("^" + pathValue + "$", "i");
}
}
conditions = {$and: [conditions, indexOptions.partialFilterExpression || {}]};

model.find(conditions).countDocuments((err, count) => {
resolve(count === 0);
});
conditions[name] = pathValue;
});

if (!isNew) {
// Use conditions the user has with find*AndUpdate
if (isQuery) {
each(this._conditions, (value, key) => {
conditions[key] = {$ne: value};
});
} else if (pathName !== "_id") {
// if it's not new then it always has _id
conditions._id = {$ne: this._id};
} else {
// if is not new and is not query and the pathName is _id then is the same document no need to check anything
return resolve(true);
}
}

// Obtain the model depending on context
// https://github.com/Automattic/mongoose/issues/3430
// https://github.com/Automattic/mongoose/issues/3589
let model;
if (isQuery) {
model = this.model;
} else if (isSubdocument) {
model = this.ownerDocument().model(this.ownerDocument().constructor.modelName);
} else if (this.constructor.modelName) {
// if the constructor has modelName then the constructor is the model
model = this.constructor;
}

// Is this model a discriminator and the unique index is on the whole collection,
// not just the instances of the discriminator? If so, use the base model to query.
// https://github.com/Automattic/mongoose/issues/4965
if (model.baseModelName && indexOptions.partialFilterExpression === null) {
model = model.db.model(model.baseModelName);
}
conditions = {$and: [conditions, indexOptions.partialFilterExpression || {}]};

const count = await model.find(conditions).countDocuments();
return count === 0;
},
pathMessage,
type
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "mongoose-unique-validator",
"version": "2.1.3",
"version": "2.1.4",
"description": "mongoose-unique-validator is a plugin which adds pre-save validation for unique fields within a Mongoose schema.",
"main": "index.js",
"scripts": {
Expand Down

0 comments on commit 83a3666

Please sign in to comment.