mongoose-smart-query 1.1.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +101 -39
- package/dist/mongoose-smart-query.d.ts +24 -1
- package/dist/mongoose-smart-query.js +1 -1
- package/package.json +10 -16
package/README.md
CHANGED
|
@@ -3,49 +3,111 @@
|
|
|
3
3
|
[](https://badge.fury.io/js/mongoose-smart-query)
|
|
4
4
|

|
|
5
5
|
|
|
6
|
-
`mongoose-smart-query`
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
6
|
+
`mongoose-smart-query` takes an object (e.g., `req.query`) as input and interprets conditions to perform a "smart" query based on the Mongoose schema definition. Queries are executed entirely using the [aggregation pipeline](https://docs.mongodb.com/manual/aggregation).
|
|
7
|
+
|
|
8
|
+
## Support for TypeScript
|
|
9
|
+
|
|
10
|
+
Starting from version 1.1.0, this library includes TypeScript definitions out of the box.
|
|
11
|
+
|
|
12
|
+
## Installation
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
npm install mongoose-smart-query
|
|
16
|
+
# or
|
|
17
|
+
pnpm add mongoose-smart-query
|
|
18
|
+
# or
|
|
19
|
+
yarn add mongoose-smart-query
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Usage
|
|
23
|
+
|
|
24
|
+
Register the plugin in your Mongoose schema:
|
|
25
|
+
|
|
26
|
+
```typescript
|
|
27
|
+
import mongoose, { Schema, Model } from 'mongoose'
|
|
28
|
+
import mongooseSmartQuery, { SmartQueryStatics } from 'mongoose-smart-query'
|
|
29
|
+
|
|
30
|
+
interface IPerson {
|
|
31
|
+
name: string
|
|
32
|
+
age: number
|
|
33
|
+
// ... other fields
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// Extend your model type with SmartQueryStatics for proper typing
|
|
37
|
+
export type PersonModel = Model<IPerson> & SmartQueryStatics
|
|
38
|
+
|
|
39
|
+
const PersonSchema = new Schema<IPerson>({
|
|
38
40
|
name: String,
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
colours: [String],
|
|
42
|
-
password: String,
|
|
43
|
-
bestFriend: { type: mongoose.Types.ObjectId, ref: 'persons' },
|
|
41
|
+
age: Number,
|
|
42
|
+
// ...
|
|
44
43
|
})
|
|
44
|
+
|
|
45
45
|
PersonSchema.plugin(mongooseSmartQuery, {
|
|
46
46
|
defaultFields: 'name',
|
|
47
47
|
protectedFields: 'password',
|
|
48
|
-
fieldsForDefaultQuery: 'name
|
|
48
|
+
fieldsForDefaultQuery: 'name',
|
|
49
|
+
})
|
|
50
|
+
|
|
51
|
+
const Person = mongoose.model<IPerson, PersonModel>('Person', PersonSchema)
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### Auto Pagination
|
|
55
|
+
|
|
56
|
+
By default, `smartQuery` returns a simple array of documents. To get a paginated result with metadata (total count, pages, etc.), use the `autoPaginate: true` option.
|
|
57
|
+
|
|
58
|
+
> [!WARNING]
|
|
59
|
+
> **Upcoming Change:** In the next major version, `autoPaginate` will default to `true`.
|
|
60
|
+
|
|
61
|
+
```typescript
|
|
62
|
+
// Defined return type (recommended)
|
|
63
|
+
const result = await Person.smartQuery<IPerson>(req.query, {
|
|
64
|
+
autoPaginate: true,
|
|
49
65
|
})
|
|
50
|
-
|
|
66
|
+
|
|
67
|
+
// Result structure:
|
|
68
|
+
// {
|
|
69
|
+
// data: IPerson[],
|
|
70
|
+
// pagination: {
|
|
71
|
+
// total: number,
|
|
72
|
+
// page: number,
|
|
73
|
+
// pages: number,
|
|
74
|
+
// limit: number
|
|
75
|
+
// }
|
|
76
|
+
// }
|
|
51
77
|
```
|
|
78
|
+
|
|
79
|
+
### Simple Query (No Pagination)
|
|
80
|
+
|
|
81
|
+
If `autoPaginate` is false (default current behaviors), it returns `T[]`.
|
|
82
|
+
|
|
83
|
+
```typescript
|
|
84
|
+
const result = await Person.smartQuery<IPerson>(req.query)
|
|
85
|
+
// Result: IPerson[]
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## Plugin Configuration
|
|
89
|
+
|
|
90
|
+
These options are passed to the plugin during registration: `schema.plugin(mongooseSmartQuery, options)`.
|
|
91
|
+
|
|
92
|
+
| Key | Description | Default |
|
|
93
|
+
| ----------------------- | ------------------------------------------------------- | ----------- |
|
|
94
|
+
| `protectedFields` | Fields that should not be included in the query results | `''` |
|
|
95
|
+
| `defaultFields` | Fields included in the default query results | `'_id'` |
|
|
96
|
+
| `defaultSort` | Default sorting | `'-id'` |
|
|
97
|
+
| `defaultLimit` | Number of documents per query | `20` |
|
|
98
|
+
| `fieldsForDefaultQuery` | specific fields to filter when `'$q'` is present | `''` |
|
|
99
|
+
| `pageQueryName` | Key for pagination param in query object | `'$page'` |
|
|
100
|
+
| `limitQueryName` | Key for limit param in query object | `'$limit'` |
|
|
101
|
+
| `fieldsQueryName` | Key to project specific fields | `'$fields'` |
|
|
102
|
+
| `sortQueryName` | Key for sorting param | `$sort` |
|
|
103
|
+
| `searchQueryName` | Key for text search param | `'$search'` |
|
|
104
|
+
| `unwindName` | Key for unwind param | `'$unwind'` |
|
|
105
|
+
|
|
106
|
+
## Method Options
|
|
107
|
+
|
|
108
|
+
These options are passed as the second argument to `smartQuery(query, options)`.
|
|
109
|
+
|
|
110
|
+
| Key | Description | Default |
|
|
111
|
+
| -------------- | -------------------------------------------------------------------------------------- | ------- |
|
|
112
|
+
| `autoPaginate` | If true, returns `{ data, pagination }`. **Defaults to `true` in next major version.** | `false` |
|
|
113
|
+
| `prePipeline` | Array of aggregation stages to run before the main query logic | `[]` |
|
|
@@ -1,4 +1,27 @@
|
|
|
1
|
-
import { Schema } from 'mongoose';
|
|
1
|
+
import { Schema, PipelineStage } from 'mongoose';
|
|
2
|
+
interface SmartQueryOptions {
|
|
3
|
+
prePipeline?: PipelineStage[];
|
|
4
|
+
autoPaginate?: boolean;
|
|
5
|
+
}
|
|
6
|
+
interface SmartQueryPagination {
|
|
7
|
+
total: number;
|
|
8
|
+
page: number;
|
|
9
|
+
pages: number;
|
|
10
|
+
limit: number;
|
|
11
|
+
}
|
|
12
|
+
interface SmartQueryResult<T = any> {
|
|
13
|
+
data: T[];
|
|
14
|
+
pagination: SmartQueryPagination;
|
|
15
|
+
}
|
|
16
|
+
export interface SmartQueryStatics {
|
|
17
|
+
smartQuery<T = any>(query: Record<string, any> | undefined, options: SmartQueryOptions & {
|
|
18
|
+
autoPaginate: true;
|
|
19
|
+
}): Promise<SmartQueryResult<T>>;
|
|
20
|
+
smartQuery<T = any>(query?: Record<string, any>, options?: SmartQueryOptions & {
|
|
21
|
+
autoPaginate?: false;
|
|
22
|
+
}): Promise<T[]>;
|
|
23
|
+
smartCount(query?: Record<string, any>): Promise<number>;
|
|
24
|
+
}
|
|
2
25
|
interface PluginOptions {
|
|
3
26
|
/**
|
|
4
27
|
* Fields that should not be included in the query results. Default: `''`.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var __assign=this&&this.__assign||function(){return(__assign=Object.assign||function(e){for(var r,t=1,n=arguments.length;t<n;t++)for(var i in r=arguments[t])Object.prototype.hasOwnProperty.call(r,i)&&(e[i]=r[i]);return e}).apply(this,arguments)},__awaiter=this&&this.__awaiter||function(e,a,s,c){return new(s=s||Promise)(function(t,r){function n(e){try{o(c.next(e))}catch(e){r(e)}}function i(e){try{o(c.throw(e))}catch(e){r(e)}}function o(e){var r;e.done?t(e.value):((r=e.value)instanceof s?r:new s(function(e){e(r)})).then(n,i)}o((c=c.apply(e,a||[])).next())})},__generator=this&&this.__generator||function(n,i){var o,a,s,c={label:0,sent:function(){if(1&s[0])throw s[1];return s[1]},trys:[],ops:[]},u=Object.create(("function"==typeof Iterator?Iterator:Object).prototype);return u.next=e(0),u.throw=e(1),u.return=e(2),"function"==typeof Symbol&&(u[Symbol.iterator]=function(){return this}),u;function e(t){return function(e){var r=[t,e];if(o)throw new TypeError("Generator is already executing.");for(;c=u&&r[u=0]?0:c;)try{if(o=1,a&&(s=2&r[0]?a.return:r[0]?a.throw||((s=a.return)&&s.call(a),0):a.next)&&!(s=s.call(a,r[1])).done)return s;switch(a=0,(r=s?[2&r[0],s.value]:r)[0]){case 0:case 1:s=r;break;case 4:return c.label++,{value:r[1],done:!1};case 5:c.label++,a=r[1],r=[0];continue;case 7:r=c.ops.pop(),c.trys.pop();continue;default:if(!(s=0<(s=c.trys).length&&s[s.length-1])&&(6===r[0]||2===r[0])){c=0;continue}if(3===r[0]&&(!s||r[1]>s[0]&&r[1]<s[3]))c.label=r[1];else if(6===r[0]&&c.label<s[1])c.label=s[1],s=r;else{if(!(s&&c.label<s[2])){s[2]&&c.ops.pop(),c.trys.pop();continue}c.label=s[2],c.ops.push(r)}}r=i.call(n,c)}catch(e){r=[6,e],a=0}finally{o=s=0}if(5&r[0])throw r[1];return{value:r[0]?r[1]:void 0,done:!0}}}},__spreadArray=this&&this.__spreadArray||function(e,r,t){if(t||2===arguments.length)for(var n,i=0,o=r.length;i<o;i++)!n&&i in r||((n=n||Array.prototype.slice.call(r,0,i))[i]=r[i]);return e.concat(n||Array.prototype.slice.call(r))},mongoose_1=(Object.defineProperty(exports,"__esModule",{value:!0}),exports.stringToQuery=stringToQuery,exports.removeKeys=removeKeys,exports.default=default_1,require("mongoose")),reemplazarSubdoc=function(e,r,t){var n,i;t&&(n=e,(i=r.split(".")).forEach(function(e,r){r===i.length-1?null!=n&&n[e]&&(n[e]=t):n=null==n?void 0:n[e]}))},getCampo=function(e,r){var t=e;return r.split(".").forEach(function(e){return t=null==t?void 0:t[e]}),t};function stringToQuery(e,o){void 0===o&&(o="1");e=(e=void 0===e?"":e).replace(/(})(?!$| *})|([\w.]+)(?= *{)|([\w.]+)(?=$| *})|([\w.]+)/g,function(e,r,t,n,i){return r?r+",":t?'"'.concat(t,'":'):n?'"'.concat(n,'": ').concat(o):i?'"'.concat(i,'": ').concat(o,","):""});return JSON.parse("{ ".concat(e," }"))}function parseValue(e,r){switch(r){case"ObjectID":case"ObjectId":return new mongoose_1.Types.ObjectId(e);case"Date":return new Date(e);case"Number":return Number(e);case"Boolean":return"boolean"==typeof e?e:"true"===e;default:return e}}function removeKeys(e,r){var t,n=__assign({},e);for(t in r)!n[t]||"object"==typeof r[t]&&(n[t]=removeKeys(n[t],r[t]),0!==Object.keys(n[t]).length)||delete n[t];return n}function default_1(j,e){function $(i,o){function a(r,e,t){var n=s.find(function(e){return e.field===r});n?n.project=__assign(__assign({},n.project),t):s.push({field:r,from:e,project:t})}(o=void 0===o?"":o)&&(o+=".");var e,s=[];for(e in i=void 0===i?{}:i)(e=>{var r,t,n;if("object"!=typeof i[e])return(e.includes(".")||o)&&(r=e.split(/\.(.+)/),t=j.path(o+r[0]))&&t.options.ref&&((n=s.find(function(e){return e.field===r[0]}))?n.project[r[1]]=1:s.push({field:r[0],from:t.options.ref,project:((n={})[r[1]]=1,n)}));(t=j.path(o+e))&&t.options.ref?a(o+e,t.options.ref,i[e]):$(i[e],o+e).forEach(function(e){a(e.field,e.from,e.project)})})(e);return s}var r=e.protectedFields,b=void 0===r?"":r,r=e.defaultFields,O=void 0===r?"_id":r,r=e.defaultSort,x=void 0===r?"-_id":r,r=e.defaultLimit,A=void 0===r?20:r,r=e.pageQueryName,Q=void 0===r?"$page":r,r=e.limitQueryName,S=void 0===r?"$limit":r,r=e.fieldsQueryName,k=void 0===r?"$fields":r,r=e.sortQueryName,N=void 0===r?"$sort":r,r=e.queryName,T=void 0===r?"$q":r,r=e.unwindName,I=void 0===r?"$unwind":r,r=e.fieldsForDefaultQuery,P=void 0===r?"":r,r=e.allFieldsQueryName,E=void 0===r?"$getAllFields":r,r=e.fieldsForDefaultSearch,C=void 0===r?[]:r,r=e.searchQueryName,F=void 0===r?"$search":r,r=e.getAllFieldsByDefault,z=void 0!==r&&r,D=stringToQuery(b);j.statics.smartQuery=function(){return __awaiter(this,arguments,void 0,function(r){var t,n,i,o,a,s,c,u,l,f,p,d,_;return void 0===r&&(r={}),__generator(this,function(e){switch(e.label){case 0:return[4,this.__smartQueryGetPipeline(__assign({},r))];case 1:return t=e.sent(),n=t.pipeline,i=t.lookupsConfirmados,o=r.business?{business:new mongoose_1.Types.ObjectId(r.business)}:{},[4,this.aggregate(n)];case 2:return a=e.sent(),[4,Promise.all(i.map(function(t){var e=a.reduce(function(e,r){r=getCampo(r,t.field);return r&&e.push(r),e},[]);return 0!==e.length?mongoose_1.connection.collection(t.from).find(__assign({_id:{$in:e}},o)).project(t.project).toArray():[]}))];case 3:for(c in s=e.sent(),i)for(u=s[c],l=i[c],f=function(e){var r=getCampo(e,l.field);r&&reemplazarSubdoc(e,l.field,u.find(function(e){return e._id.equals(r)}))},p=0,d=a;p<d.length;p++)_=d[p],f(_);return[2,a]}})})},j.statics.smartCount=function(){return __awaiter(this,arguments,void 0,function(r){var t;return void 0===r&&(r={}),__generator(this,function(e){switch(e.label){case 0:return[4,this.__smartQueryGetPipeline(__assign({},r),!0)];case 1:return t=e.sent().pipeline,[4,this.aggregate(t)];case 2:return[2,0===(t=e.sent()).length?0:t[0].size]}})})},j.statics.__smartQueryGetPipeline=function(e){return __awaiter(this,arguments,void 0,function(w,s){var _,c,u,l,h,f,p,d,g,v,y,m=this;return void 0===s&&(s=!1),__generator(this,function(e){switch(e.label){case 0:return _=w.business?{business:new mongoose_1.Types.ObjectId(w.business)}:{},c=JSON.parse(JSON.stringify(w)),u=parseInt(w[Q])||1,l=parseInt(w[S])||A,h=function(){return __awaiter(m,void 0,void 0,function(){var m,$,b,r,t,n=this;return __generator(this,function(e){switch(e.label){case 0:for(t in m={},$={},b=[],r=function(e){var r,t=j.path(e);if(!t&&!e.includes("."))return"continue";var n,i,o=e,a=void 0,s=w[o],e=(e.includes(".")&&(p=(e=e.split("."))[0],e=e[1],n=j.path(p))&&n.options.ref&&(o=e,$[a=p]={collection:n.options.ref,$match:{}}),a?$[a].$match:m),c=/(?:\{(\$?[\w ]+)\})?([^{}\n]+)/g,u=[];if("string"==typeof s){var l={},f=s,p=f.startsWith("{$or}");for(p&&(f=f.replace("{$or}",""));null!==(i=c.exec(f));)u.push([i[0],i[1],i[2]]);for(var d=0,_=u;d<_.length;d++){var h=_[d],g=h[1],v=h[2];switch(g){case"$exists":l[o]={$exists:"false"!==v};break;case"$includes":l[o]={$regex:RegExp(v.replace(/[^\w]/g,"."),"i")};break;case"$in":case"$nin":var y=v.split(",").map(function(e){return parseValue(e.trim(),null==t?void 0:t.instance)});l[o]=((r={})[g]=y,r);break;default:y=parseValue(v,null==t?void 0:t.instance);g?"object"==typeof l[o]?l[o][g]=y:l[o]=((r={})[g]=y,r):"string"==typeof v&&v.includes("$exists")?l[o]={$exists:!0,$ne:[]}:l[o]=y}}p?b.push(l):Object.assign(e,l)}else e[o]=parseValue(s,null==t?void 0:t.instance)},w)r(t);return 0!==b.length&&(m.$or=b),0===Object.keys($).length?[3,2]:[4,Promise.all(Object.entries($).map(function(e){return __awaiter(n,[e],void 0,function(e){var r,t=e[0],n=e[1];return __generator(this,function(e){switch(e.label){case 0:return[4,mongoose_1.connection.collection(n.collection).find(__assign(__assign({},n.$match),_)).project({_id:1}).toArray()];case 1:return r=e.sent(),m[t]={$in:r.map(function(e){return e._id})},[2]}})})}))];case 1:e.sent(),e.label=2;case 2:return[2,m]}})})},f=function(){return w[I]?[{$unwind:{path:"$".concat(w[I]),preserveNullAndEmptyArrays:!0}}]:[]},[4,function(){return __awaiter(m,void 0,void 0,function(){var o,a,s,c,r,t,n,i,u,l,f,p,d=this;return __generator(this,function(e){switch(e.label){case 0:if(o={},a={},!w[T]||!P)return[3,2];for(l=P.split(" "),u=w[T].replace(/[()[\\\]]/g,".").replace(/[+]/g,"\\+").replace(/[*]/g,"\\*"),s=u.split(" "),c={$regex:RegExp(u,"i")},r=function(t){var e,r,n,i;j.path(t)?(o.$or||(o.$or=[]),0===s.length?o.$or.push(((n={})[t]=c,n)):o.$or.push({$and:s.map(function(e){var r={};return r[t]={$regex:RegExp(e,"i")},r})})):t.includes(".")&&(r=(n=t.split("."))[0],n=n[1],i=j.path(r))&&i.options.ref&&(a[r]?a[r].$match.$or.push(((e={})[n]=c,e)):a[r]={collection:i.options.ref,$match:{$or:[((e={})[n]=c,e)]}})},t=0,n=l;t<n.length;t++)i=n[t],r(i);return 0===Object.keys(a).length?[3,2]:[4,Promise.all(Object.entries(a).map(function(e){return __awaiter(d,[e],void 0,function(e){var r,t,n=e[0],i=e[1];return __generator(this,function(e){switch(e.label){case 0:return[4,mongoose_1.connection.collection(i.collection).find(__assign(__assign({},i.$match),_)).project({_id:1}).toArray()];case 1:return r=e.sent(),(r=r.map(function(e){return e._id})).length&&o.$or.push(((t={})[n]={$in:r},t)),[2]}})})}))];case 1:e.sent(),e.label=2;case 2:return w[F]&&0!==C.length&&(u=Array.isArray(C)?C:[C],1===(l=u.map(function(e){var r={};return r[e]={$regex:w[F].toLowerCase().replace(/[^a-z0-9]/g,"")},r})).length?o=l[0]:o.$or=l),[4,h()];case 3:return f=e.sent(),(p=f.$or)&&(delete f.$or,Array.isArray(o.$or)?o.$or=o.$or.concat(p):o.$or=p),[2,__assign(__assign({},o),f)]}})})}()];case 1:if(y=e.sent(),!(a=w)[k]&&O&&(a[k]=O),p=removeKeys(stringToQuery(a[k]),D),d=$(p),s)g=__spreadArray(__spreadArray(__spreadArray([],0!==Object.keys(y).length?[{$match:y}]:[],!0),f(),!0),[{$count:"size"}],!1);else if(v=(()=>{if(!w[N]){if(!x)return{};w[N]=x}for(var e=/(-)?([\w.]+)/g,r={},t={};null!==(i=e.exec(w[N]));){var n=i[1],i=i[2];!!j.path(i)?r[i]=n?-1:1:t[i]=n?-1:1}return{$localSort:0!==Object.keys(r).length?r:void 0,$foreignSort:0!==Object.keys(t).length?t:void 0}})(),g=__spreadArray(__spreadArray(__spreadArray(__spreadArray([],0!==Object.keys(y).length?[{$match:y}]:[],!0),v.$localSort?[{$sort:v.$localSort}]:[],!0),f(),!0),[{$skip:(u-1)*l},{$limit:l}],!1),!c[k]&&!0===z||"true"===(null==(y=w[E])?void 0:y.toString()))b&&g.push({$project:stringToQuery(b,"0")});else{var r=p;void 0===r&&(r={});for(var t=0,n=d;t<n.length;t++){var i=n[t];if(i.field.includes(".")||r[i.field])reemplazarSubdoc(r,i.field,1);else for(var o in r)o.startsWith(i.field+".")&&(delete r[o],r[i.field]=1)}g.push({$project:p})}return[2,{pipeline:g,lookupsConfirmados:d}]}var a})})}}
|
|
1
|
+
var __assign=this&&this.__assign||function(){return(__assign=Object.assign||function(e){for(var t,r=1,n=arguments.length;r<n;r++)for(var i in t=arguments[r])Object.prototype.hasOwnProperty.call(t,i)&&(e[i]=t[i]);return e}).apply(this,arguments)},__awaiter=this&&this.__awaiter||function(e,a,s,c){return new(s=s||Promise)(function(r,t){function n(e){try{o(c.next(e))}catch(e){t(e)}}function i(e){try{o(c.throw(e))}catch(e){t(e)}}function o(e){var t;e.done?r(e.value):((t=e.value)instanceof s?t:new s(function(e){e(t)})).then(n,i)}o((c=c.apply(e,a||[])).next())})},__generator=this&&this.__generator||function(n,i){var o,a,s,c={label:0,sent:function(){if(1&s[0])throw s[1];return s[1]},trys:[],ops:[]},u=Object.create(("function"==typeof Iterator?Iterator:Object).prototype);return u.next=e(0),u.throw=e(1),u.return=e(2),"function"==typeof Symbol&&(u[Symbol.iterator]=function(){return this}),u;function e(r){return function(e){var t=[r,e];if(o)throw new TypeError("Generator is already executing.");for(;c=u&&t[u=0]?0:c;)try{if(o=1,a&&(s=2&t[0]?a.return:t[0]?a.throw||((s=a.return)&&s.call(a),0):a.next)&&!(s=s.call(a,t[1])).done)return s;switch(a=0,(t=s?[2&t[0],s.value]:t)[0]){case 0:case 1:s=t;break;case 4:return c.label++,{value:t[1],done:!1};case 5:c.label++,a=t[1],t=[0];continue;case 7:t=c.ops.pop(),c.trys.pop();continue;default:if(!(s=0<(s=c.trys).length&&s[s.length-1])&&(6===t[0]||2===t[0])){c=0;continue}if(3===t[0]&&(!s||t[1]>s[0]&&t[1]<s[3]))c.label=t[1];else if(6===t[0]&&c.label<s[1])c.label=s[1],s=t;else{if(!(s&&c.label<s[2])){s[2]&&c.ops.pop(),c.trys.pop();continue}c.label=s[2],c.ops.push(t)}}t=i.call(n,c)}catch(e){t=[6,e],a=0}finally{o=s=0}if(5&t[0])throw t[1];return{value:t[0]?t[1]:void 0,done:!0}}}},__spreadArray=this&&this.__spreadArray||function(e,t,r){if(r||2===arguments.length)for(var n,i=0,o=t.length;i<o;i++)!n&&i in t||((n=n||Array.prototype.slice.call(t,0,i))[i]=t[i]);return e.concat(n||Array.prototype.slice.call(t))},mongoose_1=(Object.defineProperty(exports,"__esModule",{value:!0}),exports.stringToQuery=stringToQuery,exports.removeKeys=removeKeys,exports.default=default_1,require("mongoose")),reemplazarSubdoc=function(e,t,r){var n,i;r&&(n=e,(i=t.split(".")).forEach(function(e,t){t===i.length-1?null!=n&&n[e]&&(n[e]=r):n=null==n?void 0:n[e]}))},getCampo=function(e,t){var r=e;return t.split(".").forEach(function(e){return r=null==r?void 0:r[e]}),r};function stringToQuery(e,o){void 0===o&&(o="1");e=(e=void 0===e?"":e).replace(/(})(?!$| *})|([\w.]+)(?= *{)|([\w.]+)(?=$| *})|([\w.]+)/g,function(e,t,r,n,i){return t?t+",":r?'"'.concat(r,'":'):n?'"'.concat(n,'": ').concat(o):i?'"'.concat(i,'": ').concat(o,","):""});return JSON.parse("{ ".concat(e," }"))}var parseValue=function(e,t){switch(t){case"ObjectID":case"ObjectId":return new mongoose_1.Types.ObjectId(e);case"Date":return new Date(e);case"Number":return Number(e);case"Boolean":return"boolean"==typeof e?e:"true"===e;default:return e}};function removeKeys(e,t){var r,n=__assign({},e);for(r in t)!n[r]||"object"==typeof t[r]&&(n[r]=removeKeys(n[r],t[r]),0!==Object.keys(n[r]).length)||delete n[r];return n}function default_1(O,e){function A(i,o){function a(t,e,r){var n=s.find(function(e){return e.field===t});n?n.project=__assign(__assign({},n.project),r):s.push({field:t,from:e,project:r})}(o=void 0===o?"":o)&&(o+=".");var e,s=[];for(e in i=void 0===i?{}:i)(e=>{var t,r,n;if("object"!=typeof i[e])return(e.includes(".")||o)&&(t=e.split(/\.(.+)/),r=O.path(o+t[0]))&&r.options.ref&&((n=s.find(function(e){return e.field===t[0]}))?n.project[t[1]]=1:s.push({field:t[0],from:r.options.ref,project:((n={})[t[1]]=1,n)}));(r=O.path(o+e))&&r.options.ref?a(o+e,r.options.ref,i[e]):A(i[e],o+e).forEach(function(e){a(e.field,e.from,e.project)})})(e);return s}var t=e.protectedFields,S=void 0===t?"":t,t=e.defaultFields,Q=void 0===t?"_id":t,t=e.defaultSort,k=void 0===t?"-_id":t,t=e.defaultLimit,N=void 0===t?20:t,t=e.pageQueryName,P=void 0===t?"$page":t,t=e.limitQueryName,T=void 0===t?"$limit":t,t=e.fieldsQueryName,I=void 0===t?"$fields":t,t=e.sortQueryName,C=void 0===t?"$sort":t,t=e.queryName,E=void 0===t?"$q":t,t=e.unwindName,F=void 0===t?"$unwind":t,t=e.fieldsForDefaultQuery,z=void 0===t?"":t,t=e.allFieldsQueryName,D=void 0===t?"$getAllFields":t,t=e.fieldsForDefaultSearch,G=void 0===t?[]:t,t=e.searchQueryName,K=void 0===t?"$search":t,t=e.getAllFieldsByDefault,q=void 0!==t&&t,V=stringToQuery(S);O.statics.smartQuery=function(){return __awaiter(this,arguments,void 0,function(t,r){var n,i,o,a,s,c,u,l,p,f,d,h,_,g,v,y,m,$,b,w,j=this;return void 0===t&&(t={}),void 0===r&&(r={}),__generator(this,function(e){switch(e.label){case 0:return(n=r.prePipeline,n=void 0===n?[]:n,i=r.autoPaginate,o=[],a=null,i=void 0!==i&&i)?(c=this.__smartQueryGetPipeline(__assign({},t),!1,n).then(function(e){return __awaiter(j,[e],void 0,function(e){var t,r=e.pipeline,n=e.lookupsConfirmados;return __generator(this,function(e){switch(e.label){case 0:return t={},[4,this.aggregate(r)];case 1:return[2,(t.docs=e.sent(),t.lookups=n,t)]}})})}),u=this.__smartQueryGetPipeline(__assign({},t),!0,n).then(function(e){e=e.pipeline;return j.aggregate(e)}),[4,Promise.all([c,u])]):[3,2];case 1:return c=e.sent(),u=c[0],w=c[1],o=u.docs,s=u.lookups,w=(null==(w=w[0])?void 0:w.size)||0,f=parseInt(t[P])||1,l=parseInt(t[T])||N,p=Math.ceil(w/l),a={total:w,page:f,pages:p,limit:l},[3,5];case 2:return[4,this.__smartQueryGetPipeline(__assign({},t),!1,n)];case 3:return w=e.sent(),f=w.pipeline,s=w.lookupsConfirmados,[4,this.aggregate(f)];case 4:o=e.sent(),e.label=5;case 5:return d=t.business?{business:new mongoose_1.Types.ObjectId(t.business)}:{},[4,Promise.all(s.map(function(r){var e=o.reduce(function(e,t){t=getCampo(t,r.field);return t&&e.push(t),e},[]);return 0!==e.length?mongoose_1.connection.collection(r.from).find(__assign({_id:{$in:e}},d)).project(r.project).toArray():[]}))];case 6:for(_ in h=e.sent(),s)for(g=h[_],v=s[_],y=function(e){var t=getCampo(e,v.field);t&&reemplazarSubdoc(e,v.field,g.find(function(e){return e._id.equals(t)}))},m=0,$=o;m<$.length;m++)b=$[m],y(b);return i?[2,{data:o,pagination:a}]:[2,o]}})})},O.statics.smartCount=function(){return __awaiter(this,arguments,void 0,function(t){var r;return void 0===t&&(t={}),__generator(this,function(e){switch(e.label){case 0:return[4,this.__smartQueryGetPipeline(__assign({},t),!0)];case 1:return r=e.sent().pipeline,[4,this.aggregate(r)];case 2:return[2,0===(r=e.sent()).length?0:r[0].size]}})})},O.statics.__smartQueryGetPipeline=function(e){return __awaiter(this,arguments,void 0,function(w,s,c){var _,g,u,l,p,v,f,d,h,y,m,$,b,j,x=this;return void 0===s&&(s=!1),void 0===c&&(c=[]),__generator(this,function(e){switch(e.label){case 0:return _=this.schema.indexes().some(function(e){e=e[0];return Object.values(e).includes("text")}),g=w.business?{business:new mongoose_1.Types.ObjectId(w.business)}:{},u=JSON.parse(JSON.stringify(w)),l=parseInt(w[P])||1,p=parseInt(w[T])||N,v=function(){return __awaiter(x,void 0,void 0,function(){var m,$,b,t,r,n=this;return __generator(this,function(e){switch(e.label){case 0:for(r in m={},$={},b=[],t=function(e){var t,r=O.path(e);if(!r&&!e.includes("."))return"continue";var n,i,o=e,a=void 0,s=w[o],e=(e.includes(".")&&(f=(e=e.split("."))[0],e=e[1],n=O.path(f))&&n.options.ref&&(o=e,$[a=f]={collection:n.options.ref,$match:{}}),a?$[a].$match:m),c=/(?:\{(\$?[\w ]+)\})?([^{}\n]+)/g,u=[];if("string"==typeof s){var l={},p=s,f=p.startsWith("{$or}");for(f&&(p=p.replace("{$or}",""));null!==(i=c.exec(p));)u.push([i[0],i[1],i[2]]);for(var d=0,h=u;d<h.length;d++){var _=h[d],g=_[1],v=_[2];switch(g){case"$exists":l[o]={$exists:"false"!==v};break;case"$includes":l[o]={$regex:RegExp(v.replace(/[^\w]/g,"."),"i")};break;case"$in":case"$nin":var y=v.split(",").map(function(e){return parseValue(e.trim(),null==r?void 0:r.instance)});l[o]=((t={})[g]=y,t);break;default:y=parseValue(v,null==r?void 0:r.instance);g?"object"==typeof l[o]?l[o][g]=y:l[o]=((t={})[g]=y,t):"string"==typeof v&&v.includes("$exists")?l[o]={$exists:!0,$ne:[]}:l[o]=y}}f?b.push(l):Object.assign(e,l)}else e[o]=parseValue(s,null==r?void 0:r.instance)},w)t(r);return 0!==b.length&&(m.$or=b),0===Object.keys($).length?[3,2]:[4,Promise.all(Object.entries($).map(function(e){return __awaiter(n,[e],void 0,function(e){var t,r=e[0],n=e[1];return __generator(this,function(e){switch(e.label){case 0:return[4,mongoose_1.connection.collection(n.collection).find(__assign(__assign({},n.$match),g)).project({_id:1}).toArray()];case 1:return t=e.sent(),m[r]={$in:t.map(function(e){return e._id})},[2]}})})}))];case 1:e.sent(),e.label=2;case 2:return[2,m]}})})},f=function(){return w[F]?[{$unwind:{path:"$".concat(w[F]),preserveNullAndEmptyArrays:!0}}]:[]},[4,function(){return __awaiter(x,void 0,void 0,function(){var o,a,t,s,c,r,n,i,u,l,p,f,d,h=this;return __generator(this,function(e){switch(e.label){case 0:return(o={},t=!(a={}),_&&w[E])?(o={$text:{$search:w[E]}},t=!0,[3,3]):[3,1];case 1:if(!w[E]||!z)return[3,3];for(p=z.split(" "),l=w[E].replace(/[()[\\\]]/g,".").replace(/[+]/g,"\\+").replace(/[*]/g,"\\*"),s=l.split(" "),c={$regex:RegExp(l,"i")},r=function(r){var e,t,n,i;O.path(r)?(o.$or||(o.$or=[]),0===s.length?o.$or.push(((n={})[r]=c,n)):o.$or.push({$and:s.map(function(e){var t={};return t[r]={$regex:RegExp(e,"i")},t})})):r.includes(".")&&(t=(n=r.split("."))[0],n=n[1],i=O.path(t))&&i.options.ref&&(a[t]?a[t].$match.$or.push(((e={})[n]=c,e)):a[t]={collection:i.options.ref,$match:{$or:[((e={})[n]=c,e)]}})},n=0,i=p;n<i.length;n++)u=i[n],r(u);return 0===Object.keys(a).length?[3,3]:[4,Promise.all(Object.entries(a).map(function(e){return __awaiter(h,[e],void 0,function(e){var t,r,n=e[0],i=e[1];return __generator(this,function(e){switch(e.label){case 0:return[4,mongoose_1.connection.collection(i.collection).find(__assign(__assign({},i.$match),g)).project({_id:1}).toArray()];case 1:return t=e.sent(),(t=t.map(function(e){return e._id})).length&&o.$or.push(((r={})[n]={$in:t},r)),[2]}})})}))];case 2:e.sent(),e.label=3;case 3:return w[K]&&0!==G.length&&(l=Array.isArray(G)?G:[G],1===(p=l.map(function(e){var t={};return t[e]={$regex:w[K].toLowerCase().replace(/[^a-z0-9]/g,"")},t})).length?o=p[0]:o.$or=p),[4,v()];case 4:return f=e.sent(),(d=f.$or)&&(delete f.$or,Array.isArray(o.$or)?o.$or=o.$or.concat(d):o.$or=d),[2,{match:__assign(__assign({},f),o),usingTextSearch:t}]}})})}()];case 1:if(h=e.sent(),$=h.match,d=h.usingTextSearch,!(a=w)[I]&&Q&&(a[I]=Q),h=removeKeys(stringToQuery(a[I]),V),y=A(h),m=[],0!==Object.keys($).length&&m.push({$match:$}),m.push.apply(m,c),s)m.push.apply(m,__spreadArray(__spreadArray([],f(),!1),[{$count:"size"}],!1));else{if($=function(){if(d)return{$localSort:{score:{$meta:"textScore"},_id:-1}};if(!w[C]){if(!k)return{};w[C]=k}for(var e=/(-)?([\w.]+)/g,t={},r={};null!==(i=e.exec(w[C]));){var n=i[1],i=i[2];!!O.path(i)?t[i]=n?-1:1:r[i]=n?-1:1}return{$localSort:0!==Object.keys(t).length?t:void 0,$foreignSort:0!==Object.keys(r).length?r:void 0}}(),b=[],!u[I]&&!0===q||"true"===(null==(j=w[D])?void 0:j.toString()))S&&b.push({$project:stringToQuery(S,"0")}),d&&b.push({$addFields:{score:{$meta:"textScore"}}});else{var t=h;void 0===t&&(t={});for(var r=0,n=y;r<n.length;r++){var i=n[r];if(i.field.includes(".")||t[i.field])reemplazarSubdoc(t,i.field,1);else for(var o in t)o.startsWith(i.field+".")&&(delete t[o],t[i.field]=1)}j=__assign({},h),d&&(j.score={$meta:"textScore"}),b.push({$project:j})}m.push.apply(m,__spreadArray(__spreadArray(__spreadArray(__spreadArray([],$.$localSort?[{$sort:$.$localSort}]:[],!1),f(),!1),[{$skip:(l-1)*p},{$limit:p}],!1),b,!1))}return[2,{pipeline:m,lookupsConfirmados:y}]}var a})})}}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mongoose-smart-query",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"description": "Optimize rest requests",
|
|
5
5
|
"main": "./dist/mongoose-smart-query.js",
|
|
6
6
|
"types": "./dist/mongoose-smart-query.d.ts",
|
|
@@ -22,21 +22,15 @@
|
|
|
22
22
|
},
|
|
23
23
|
"homepage": "https://github.com/mgyugcha/mongoose-smart-query#readme",
|
|
24
24
|
"devDependencies": {
|
|
25
|
-
"@
|
|
26
|
-
"@types/
|
|
27
|
-
"@
|
|
28
|
-
"
|
|
29
|
-
"
|
|
30
|
-
"
|
|
31
|
-
"
|
|
32
|
-
"
|
|
33
|
-
"eslint
|
|
34
|
-
"eslint-plugin-node": "^11.1.0",
|
|
35
|
-
"eslint-plugin-promise": "^6.6.0",
|
|
36
|
-
"jest": "^29.7.0",
|
|
37
|
-
"mongoose": "^8",
|
|
38
|
-
"ts-jest": "^29.2.5",
|
|
39
|
-
"typescript": "^5.6.3",
|
|
25
|
+
"@eslint/js": "^10.0.1",
|
|
26
|
+
"@types/jest": "^30.0.0",
|
|
27
|
+
"@types/node": "^25.2.3",
|
|
28
|
+
"eslint": "^10.0.0",
|
|
29
|
+
"jest": "^30.2.0",
|
|
30
|
+
"mongoose": "^8.23.0",
|
|
31
|
+
"ts-jest": "^29.4.6",
|
|
32
|
+
"typescript": "^5.9.3",
|
|
33
|
+
"typescript-eslint": "^8.55.0",
|
|
40
34
|
"uglify-js": "^3.19.3"
|
|
41
35
|
},
|
|
42
36
|
"peerDependencies": {
|