mongoose-smart-query 1.3.3 → 1.4.1

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.
@@ -0,0 +1,5 @@
1
+ import mongooseSmartQuery from './plugin';
2
+ export * from './types';
3
+ export * from './utils';
4
+ export * from './typesense';
5
+ export default mongooseSmartQuery;
package/dist/index.js ADDED
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ var __importDefault = (this && this.__importDefault) || function (mod) {
17
+ return (mod && mod.__esModule) ? mod : { "default": mod };
18
+ };
19
+ Object.defineProperty(exports, "__esModule", { value: true });
20
+ var plugin_1 = __importDefault(require("./plugin"));
21
+ __exportStar(require("./types"), exports);
22
+ __exportStar(require("./utils"), exports);
23
+ __exportStar(require("./typesense"), exports);
24
+ exports.default = plugin_1.default;
@@ -0,0 +1,3 @@
1
+ import { Schema } from 'mongoose';
2
+ import type { PluginOptions } from '../types';
3
+ export default function mongooseSmartQuery(schema: Schema, rawOptions: PluginOptions): void;
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ var __assign = (this && this.__assign) || function () {
3
+ __assign = Object.assign || function(t) {
4
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
5
+ s = arguments[i];
6
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7
+ t[p] = s[p];
8
+ }
9
+ return t;
10
+ };
11
+ return __assign.apply(this, arguments);
12
+ };
13
+ Object.defineProperty(exports, "__esModule", { value: true });
14
+ exports.default = mongooseSmartQuery;
15
+ var pipeline_1 = require("./pipeline");
16
+ var methods_1 = require("./methods");
17
+ function mongooseSmartQuery(schema, rawOptions) {
18
+ var options = __assign({ protectedFields: '', defaultFields: '_id', defaultSort: '-_id', defaultLimit: 20, fieldsForDefaultQuery: '', pageQueryName: '$page', limitQueryName: '$limit', fieldsQueryName: '$fields', sortQueryName: '$sort', queryName: '$q', textQueryName: '$text', unwindName: '$unwind', allFieldsQueryName: '$getAllFields', normalizeSearchQuery: false }, rawOptions);
19
+ schema.statics.__smartQueryGetPipeline = (0, pipeline_1.createSmartQueryGetPipeline)(schema, options);
20
+ schema.statics.smartQuery = (0, methods_1.createSmartQuery)(options);
21
+ schema.statics.smartCount = (0, methods_1.createSmartCount)(options);
22
+ }
@@ -0,0 +1,8 @@
1
+ import { Model } from 'mongoose';
2
+ import type { PluginOptions, SmartQueryOptions, SmartQueryResult } from '../types';
3
+ export declare function createSmartQuery(options: PluginOptions): <T>(this: Model<T>, query?: {
4
+ [key: string]: string;
5
+ }, smartOptions?: SmartQueryOptions) => Promise<T[] | SmartQueryResult<T>>;
6
+ export declare function createSmartCount(options: PluginOptions): <T>(this: Model<T>, query?: {
7
+ [key: string]: string;
8
+ }) => Promise<any>;
@@ -0,0 +1,253 @@
1
+ "use strict";
2
+ var __assign = (this && this.__assign) || function () {
3
+ __assign = Object.assign || function(t) {
4
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
5
+ s = arguments[i];
6
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7
+ t[p] = s[p];
8
+ }
9
+ return t;
10
+ };
11
+ return __assign.apply(this, arguments);
12
+ };
13
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
14
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
15
+ return new (P || (P = Promise))(function (resolve, reject) {
16
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
17
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
18
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
19
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
20
+ });
21
+ };
22
+ var __generator = (this && this.__generator) || function (thisArg, body) {
23
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
24
+ return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
25
+ function verb(n) { return function (v) { return step([n, v]); }; }
26
+ function step(op) {
27
+ if (f) throw new TypeError("Generator is already executing.");
28
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
29
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
30
+ if (y = 0, t) op = [op[0] & 2, t.value];
31
+ switch (op[0]) {
32
+ case 0: case 1: t = op; break;
33
+ case 4: _.label++; return { value: op[1], done: false };
34
+ case 5: _.label++; y = op[1]; op = [0]; continue;
35
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
36
+ default:
37
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
38
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
39
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
40
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
41
+ if (t[2]) _.ops.pop();
42
+ _.trys.pop(); continue;
43
+ }
44
+ op = body.call(thisArg, _);
45
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
46
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
47
+ }
48
+ };
49
+ Object.defineProperty(exports, "__esModule", { value: true });
50
+ exports.createSmartQuery = createSmartQuery;
51
+ exports.createSmartCount = createSmartCount;
52
+ var mongoose_1 = require("mongoose");
53
+ var utils_1 = require("../utils");
54
+ var typesense_1 = require("../typesense");
55
+ function createSmartQuery(options) {
56
+ var _a = options.defaultLimit, defaultLimit = _a === void 0 ? 20 : _a, _b = options.pageQueryName, pageQueryName = _b === void 0 ? '$page' : _b, _c = options.limitQueryName, limitQueryName = _c === void 0 ? '$limit' : _c, collation = options.collation, typesense = options.typesense;
57
+ return function () {
58
+ return __awaiter(this, arguments, void 0, function (query, smartOptions) {
59
+ var _a, prePipeline, _b, autoPaginate, docs, pagination, lookupsConfirmados, useMongoDirectly, typesenseIds, typesenseTotal, searchParams, searchResults, error_1, tsIdsArg, dataPromise, countPromise, _c, dataResult, countResult, total, page, limit, pages, tsIdsArg, _d, pipeline, lookups, agg, queryEmpresa, foraneos, index, docsEx, confirmado, _loop_1, _i, docs_1, doc;
60
+ var _this = this;
61
+ var _e, _f;
62
+ if (query === void 0) { query = {}; }
63
+ if (smartOptions === void 0) { smartOptions = {}; }
64
+ return __generator(this, function (_g) {
65
+ switch (_g.label) {
66
+ case 0:
67
+ _a = smartOptions.prePipeline, prePipeline = _a === void 0 ? [] : _a, _b = smartOptions.autoPaginate, autoPaginate = _b === void 0 ? false : _b;
68
+ docs = [];
69
+ pagination = null;
70
+ useMongoDirectly = true;
71
+ typesenseIds = [];
72
+ typesenseTotal = 0;
73
+ if (!(typesense_1.globalTypesenseClient && typesense)) return [3 /*break*/, 4];
74
+ if (!!(0, typesense_1.hasUnindexedFields)(query, typesense.schema, options)) return [3 /*break*/, 4];
75
+ _g.label = 1;
76
+ case 1:
77
+ _g.trys.push([1, 3, , 4]);
78
+ searchParams = (0, typesense_1.buildTypesenseSearchParameters)(query, typesense.schema, options);
79
+ return [4 /*yield*/, typesense_1.globalTypesenseClient
80
+ .collections(typesense.schema.name)
81
+ .documents()
82
+ .search(searchParams)];
83
+ case 2:
84
+ searchResults = _g.sent();
85
+ typesenseIds =
86
+ ((_e = searchResults.hits) === null || _e === void 0 ? void 0 : _e.map(function (h) { return h.document.id; })) || [];
87
+ typesenseTotal = searchResults.found || 0;
88
+ useMongoDirectly = false;
89
+ return [3 /*break*/, 4];
90
+ case 3:
91
+ error_1 = _g.sent();
92
+ console.error('Error fetching from Typesense, falling back to MongoDB:', error_1);
93
+ useMongoDirectly = true;
94
+ return [3 /*break*/, 4];
95
+ case 4:
96
+ if (!useMongoDirectly && typesenseTotal === 0) {
97
+ if (autoPaginate) {
98
+ return [2 /*return*/, {
99
+ data: [],
100
+ pagination: {
101
+ total: 0,
102
+ page: parseInt(query[pageQueryName]) || 1,
103
+ pages: 0,
104
+ limit: parseInt(query[limitQueryName]) || defaultLimit,
105
+ },
106
+ }];
107
+ }
108
+ return [2 /*return*/, []];
109
+ }
110
+ if (!autoPaginate) return [3 /*break*/, 6];
111
+ tsIdsArg = useMongoDirectly ? undefined : typesenseIds;
112
+ dataPromise = this
113
+ .__smartQueryGetPipeline(__assign({}, query), false, prePipeline, tsIdsArg)
114
+ .then(function (_a) { return __awaiter(_this, [_a], void 0, function (_b) {
115
+ var agg;
116
+ var _c;
117
+ var pipeline = _b.pipeline, lookups = _b.lookupsConfirmados;
118
+ return __generator(this, function (_d) {
119
+ switch (_d.label) {
120
+ case 0:
121
+ agg = this.aggregate(pipeline);
122
+ if (collation)
123
+ agg.collation(collation);
124
+ _c = {};
125
+ return [4 /*yield*/, agg];
126
+ case 1: return [2 /*return*/, (_c.docs = _d.sent(),
127
+ _c.lookups = lookups,
128
+ _c)];
129
+ }
130
+ });
131
+ }); });
132
+ countPromise = void 0;
133
+ if (!useMongoDirectly) {
134
+ countPromise = Promise.resolve([{ size: typesenseTotal }]);
135
+ }
136
+ else {
137
+ countPromise = this
138
+ .__smartQueryGetPipeline(__assign({}, query), true, // forCount
139
+ prePipeline)
140
+ .then(function (_a) {
141
+ var pipeline = _a.pipeline;
142
+ return _this.aggregate(pipeline);
143
+ });
144
+ }
145
+ return [4 /*yield*/, Promise.all([
146
+ dataPromise,
147
+ countPromise,
148
+ ])];
149
+ case 5:
150
+ _c = _g.sent(), dataResult = _c[0], countResult = _c[1];
151
+ docs = dataResult.docs;
152
+ lookupsConfirmados = dataResult.lookups;
153
+ total = ((_f = countResult[0]) === null || _f === void 0 ? void 0 : _f.size) || 0;
154
+ page = parseInt(query[pageQueryName]) || 1;
155
+ limit = parseInt(query[limitQueryName]) || defaultLimit;
156
+ pages = Math.ceil(total / limit);
157
+ pagination = { total: total, page: page, pages: pages, limit: limit };
158
+ return [3 /*break*/, 9];
159
+ case 6:
160
+ tsIdsArg = useMongoDirectly ? undefined : typesenseIds;
161
+ return [4 /*yield*/, this.__smartQueryGetPipeline(__assign({}, query), false, prePipeline, tsIdsArg)];
162
+ case 7:
163
+ _d = _g.sent(), pipeline = _d.pipeline, lookups = _d.lookupsConfirmados;
164
+ lookupsConfirmados = lookups;
165
+ agg = this.aggregate(pipeline);
166
+ if (collation)
167
+ agg.collation(collation);
168
+ return [4 /*yield*/, agg];
169
+ case 8:
170
+ docs = _g.sent();
171
+ _g.label = 9;
172
+ case 9:
173
+ queryEmpresa = query.business
174
+ ? { business: new mongoose_1.Types.ObjectId(query.business) }
175
+ : {};
176
+ return [4 /*yield*/, Promise.all(lookupsConfirmados.map(function (item) {
177
+ var ids = docs.reduce(function (acc, val) {
178
+ var valor = (0, utils_1.getCampo)(val, item.field);
179
+ if (valor)
180
+ acc.push(valor);
181
+ return acc;
182
+ }, []);
183
+ return ids.length !== 0
184
+ ? mongoose_1.connection
185
+ .collection(item.from)
186
+ .find(__assign({ _id: { $in: ids } }, queryEmpresa))
187
+ .project(item.project)
188
+ .toArray()
189
+ : [];
190
+ }))];
191
+ case 10:
192
+ foraneos = _g.sent();
193
+ for (index in lookupsConfirmados) {
194
+ docsEx = foraneos[index];
195
+ confirmado = lookupsConfirmados[index];
196
+ _loop_1 = function (doc) {
197
+ var keyPrincipal = (0, utils_1.getCampo)(doc, confirmado.field);
198
+ if (keyPrincipal)
199
+ (0, utils_1.reemplazarSubdoc)(doc, confirmado.field, docsEx.find(function (item) { return item._id.equals(keyPrincipal); }));
200
+ };
201
+ for (_i = 0, docs_1 = docs; _i < docs_1.length; _i++) {
202
+ doc = docs_1[_i];
203
+ _loop_1(doc);
204
+ }
205
+ }
206
+ if (autoPaginate) {
207
+ return [2 /*return*/, { data: docs, pagination: pagination }];
208
+ }
209
+ return [2 /*return*/, docs];
210
+ }
211
+ });
212
+ });
213
+ };
214
+ }
215
+ function createSmartCount(options) {
216
+ var typesense = options.typesense;
217
+ return function () {
218
+ return __awaiter(this, arguments, void 0, function (query) {
219
+ var searchParams, searchResults, error_2, pipeline, result;
220
+ if (query === void 0) { query = {}; }
221
+ return __generator(this, function (_a) {
222
+ switch (_a.label) {
223
+ case 0:
224
+ if (!(typesense_1.globalTypesenseClient &&
225
+ typesense &&
226
+ !(0, typesense_1.hasUnindexedFields)(query, typesense.schema, options))) return [3 /*break*/, 4];
227
+ _a.label = 1;
228
+ case 1:
229
+ _a.trys.push([1, 3, , 4]);
230
+ searchParams = (0, typesense_1.buildTypesenseSearchParameters)(query, typesense.schema, options);
231
+ return [4 /*yield*/, typesense_1.globalTypesenseClient
232
+ .collections(typesense.schema.name)
233
+ .documents()
234
+ .search(searchParams)];
235
+ case 2:
236
+ searchResults = _a.sent();
237
+ return [2 /*return*/, searchResults.found || 0];
238
+ case 3:
239
+ error_2 = _a.sent();
240
+ console.error('Error fetching count from Typesense, falling back to MongoDB:', error_2);
241
+ return [3 /*break*/, 4];
242
+ case 4: return [4 /*yield*/, this.__smartQueryGetPipeline(__assign({}, query), true)];
243
+ case 5:
244
+ pipeline = (_a.sent()).pipeline;
245
+ return [4 /*yield*/, this.aggregate(pipeline)];
246
+ case 6:
247
+ result = _a.sent();
248
+ return [2 /*return*/, result.length === 0 ? 0 : result[0].size];
249
+ }
250
+ });
251
+ });
252
+ };
253
+ }
@@ -0,0 +1,8 @@
1
+ import { Model, PipelineStage, Schema } from 'mongoose';
2
+ import type { PluginOptions } from '../types';
3
+ export declare function createSmartQueryGetPipeline(schema: Schema, options: PluginOptions): <T>(this: Model<T>, query: {
4
+ [key: string]: string;
5
+ }, forCount?: boolean, prePipeline?: PipelineStage[], typesenseIds?: string[]) => Promise<{
6
+ pipeline: PipelineStage[];
7
+ lookupsConfirmados: import("../types").LookupConfirmado[];
8
+ }>;