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,175 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.hasUnindexedFields = exports.buildTypesenseSearchParameters = void 0;
4
+ var buildTypesenseSearchParameters = function (query, tsSchema, options) {
5
+ var _a, _b, _c;
6
+ var _d = options.queryName, queryName = _d === void 0 ? '$q' : _d, _e = options.pageQueryName, pageQueryName = _e === void 0 ? '$page' : _e, _f = options.limitQueryName, limitQueryName = _f === void 0 ? '$limit' : _f, _g = options.defaultLimit, defaultLimit = _g === void 0 ? 20 : _g, _h = options.fieldsForDefaultQuery, fieldsForDefaultQuery = _h === void 0 ? '' : _h, _j = options.sortQueryName, sortQueryName = _j === void 0 ? '$sort' : _j, _k = options.fieldsQueryName, fieldsQueryName = _k === void 0 ? '$fields' : _k, _l = options.unwindName, unwindName = _l === void 0 ? '$unwind' : _l, _m = options.textQueryName, textQueryName = _m === void 0 ? '$text' : _m, _o = options.allFieldsQueryName, allFieldsQueryName = _o === void 0 ? '$getAllFields' : _o, _p = options.defaultSort, defaultSort = _p === void 0 ? '-_id' : _p;
7
+ var $q = query[queryName] || '*';
8
+ var page = parseInt(query[pageQueryName]) || 1;
9
+ var limit = parseInt(query[limitQueryName]) || defaultLimit;
10
+ var queryByFields = (_a = tsSchema.fields) === null || _a === void 0 ? void 0 : _a.filter(function (f) { return f.type.includes('string') && f.name !== 'id' && !f.facet; }).map(function (f) { return f.name; });
11
+ if (fieldsForDefaultQuery) {
12
+ queryByFields = fieldsForDefaultQuery
13
+ .split(' ')
14
+ .map(function (mongoField) {
15
+ var _a;
16
+ var field = (_a = tsSchema.fields) === null || _a === void 0 ? void 0 : _a.find(function (f) { return (f.mongoField || f.name) === mongoField; });
17
+ return field ? field.name : mongoField;
18
+ })
19
+ .filter(function (field) { var _a; return (_a = tsSchema.fields) === null || _a === void 0 ? void 0 : _a.some(function (f) { return f.name === field; }); });
20
+ }
21
+ var searchParams = {
22
+ q: $q,
23
+ query_by: (queryByFields === null || queryByFields === void 0 ? void 0 : queryByFields.length) ? queryByFields.join(',') : '*',
24
+ page: page,
25
+ per_page: limit,
26
+ };
27
+ var filterBy = [];
28
+ var _loop_1 = function (key) {
29
+ if ([
30
+ pageQueryName,
31
+ limitQueryName,
32
+ sortQueryName,
33
+ queryName,
34
+ fieldsQueryName,
35
+ unwindName,
36
+ textQueryName,
37
+ allFieldsQueryName,
38
+ ].includes(key)) {
39
+ return "continue";
40
+ }
41
+ var field = (_b = tsSchema.fields) === null || _b === void 0 ? void 0 : _b.find(function (f) { return (f.mongoField || f.name) === key; });
42
+ if (!field)
43
+ return "continue";
44
+ var tsFieldName = field.name;
45
+ var val = query[key];
46
+ if (typeof val !== 'string')
47
+ return "continue";
48
+ var queryRegex = /(?:\{(\$?[\w ]+)\})?([^{}\n]+)/g;
49
+ var match = void 0;
50
+ var values = [];
51
+ var valor = val;
52
+ if (valor.startsWith('{$or}'))
53
+ valor = valor.replace('{$or}', '');
54
+ while ((match = queryRegex.exec(valor)) !== null) {
55
+ values.push([match[0], match[1], match[2]]);
56
+ }
57
+ for (var _i = 0, values_1 = values; _i < values_1.length; _i++) {
58
+ var _q = values_1[_i], operator = _q[1], value = _q[2];
59
+ var finalValue = value;
60
+ if (field.type.includes('int') || field.type.includes('float')) {
61
+ var parsedDate = Date.parse(value);
62
+ if (!isNaN(parsedDate) && value.includes('-')) {
63
+ finalValue = parsedDate.toString();
64
+ }
65
+ }
66
+ var tsValue = finalValue.includes(' ') || finalValue.includes('-')
67
+ ? "`".concat(finalValue, "`")
68
+ : finalValue;
69
+ var tsValues = finalValue
70
+ .split(',')
71
+ .map(function (v) {
72
+ var vTrim = v.trim();
73
+ var parsedTrim = vTrim;
74
+ if (field.type.includes('int') || field.type.includes('float')) {
75
+ var pDate = Date.parse(vTrim);
76
+ if (!isNaN(pDate) && vTrim.includes('-')) {
77
+ parsedTrim = pDate.toString();
78
+ }
79
+ }
80
+ return parsedTrim.includes(' ') || parsedTrim.includes('-')
81
+ ? "`".concat(parsedTrim, "`")
82
+ : parsedTrim;
83
+ })
84
+ .join(',');
85
+ switch (operator) {
86
+ case '$in':
87
+ filterBy.push("".concat(tsFieldName, ":=[").concat(tsValues, "]"));
88
+ break;
89
+ case '$nin':
90
+ filterBy.push("".concat(tsFieldName, ":!=[").concat(tsValues, "]"));
91
+ break;
92
+ case '$gte':
93
+ filterBy.push("".concat(tsFieldName, ":>=").concat(finalValue));
94
+ break;
95
+ case '$gt':
96
+ filterBy.push("".concat(tsFieldName, ":>").concat(finalValue));
97
+ break;
98
+ case '$lte':
99
+ filterBy.push("".concat(tsFieldName, ":<=").concat(finalValue));
100
+ break;
101
+ case '$lt':
102
+ filterBy.push("".concat(tsFieldName, ":<").concat(finalValue));
103
+ break;
104
+ case '$ne':
105
+ filterBy.push("".concat(tsFieldName, ":!=").concat(tsValue));
106
+ break;
107
+ case '$exists':
108
+ case '$includes':
109
+ // Typesense doesn't natively support $exists or $includes in filter_by efficiently
110
+ break;
111
+ default:
112
+ if (finalValue.includes('$exists'))
113
+ break;
114
+ filterBy.push("".concat(tsFieldName, ":=").concat(tsValue));
115
+ break;
116
+ }
117
+ }
118
+ };
119
+ for (var key in query) {
120
+ _loop_1(key);
121
+ }
122
+ if (filterBy.length > 0) {
123
+ searchParams.filter_by = filterBy.join(' && ');
124
+ }
125
+ if (query[sortQueryName] || defaultSort) {
126
+ var sortQuery = query[sortQueryName] || defaultSort;
127
+ var regex = /(-)?([\w.]+)/g;
128
+ var matched = void 0;
129
+ var sortBy = [];
130
+ var _loop_2 = function () {
131
+ var order = matched[1] ? 'desc' : 'asc';
132
+ var localfield = matched[2];
133
+ var field = (_c = tsSchema.fields) === null || _c === void 0 ? void 0 : _c.find(function (f) { return (f.mongoField || f.name) === localfield; });
134
+ if (field) {
135
+ sortBy.push("".concat(field.name, ":").concat(order));
136
+ }
137
+ };
138
+ while ((matched = regex.exec(sortQuery)) !== null) {
139
+ _loop_2();
140
+ }
141
+ if (sortBy.length > 0) {
142
+ searchParams.sort_by = sortBy.join(',');
143
+ }
144
+ }
145
+ return searchParams;
146
+ };
147
+ exports.buildTypesenseSearchParameters = buildTypesenseSearchParameters;
148
+ var hasUnindexedFields = function (query, tsSchema, options) {
149
+ var _a;
150
+ var _b = options.queryName, queryName = _b === void 0 ? '$q' : _b, _c = options.pageQueryName, pageQueryName = _c === void 0 ? '$page' : _c, _d = options.limitQueryName, limitQueryName = _d === void 0 ? '$limit' : _d, _e = options.sortQueryName, sortQueryName = _e === void 0 ? '$sort' : _e, _f = options.fieldsQueryName, fieldsQueryName = _f === void 0 ? '$fields' : _f, _g = options.unwindName, unwindName = _g === void 0 ? '$unwind' : _g, _h = options.textQueryName, textQueryName = _h === void 0 ? '$text' : _h, _j = options.allFieldsQueryName, allFieldsQueryName = _j === void 0 ? '$getAllFields' : _j;
151
+ var specialKeys = [
152
+ pageQueryName,
153
+ limitQueryName,
154
+ sortQueryName,
155
+ queryName,
156
+ fieldsQueryName,
157
+ unwindName,
158
+ textQueryName,
159
+ allFieldsQueryName,
160
+ ];
161
+ var _loop_3 = function (key) {
162
+ if (specialKeys.includes(key))
163
+ return "continue";
164
+ var field = (_a = tsSchema.fields) === null || _a === void 0 ? void 0 : _a.find(function (f) { return (f.mongoField || f.name) === key; });
165
+ if (!field)
166
+ return { value: true };
167
+ };
168
+ for (var key in query) {
169
+ var state_1 = _loop_3(key);
170
+ if (typeof state_1 === "object")
171
+ return state_1.value;
172
+ }
173
+ return false;
174
+ };
175
+ exports.hasUnindexedFields = hasUnindexedFields;
@@ -0,0 +1,4 @@
1
+ import { Client as TypesenseClient } from 'typesense';
2
+ import type { ConfigurationOptions } from 'typesense/lib/Typesense/Configuration';
3
+ export declare let globalTypesenseClient: TypesenseClient | null;
4
+ export declare function setTypesenseConfig(options: ConfigurationOptions): void;
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.globalTypesenseClient = void 0;
4
+ exports.setTypesenseConfig = setTypesenseConfig;
5
+ var typesense_1 = require("typesense");
6
+ exports.globalTypesenseClient = null;
7
+ function setTypesenseConfig(options) {
8
+ exports.globalTypesenseClient = new typesense_1.Client(options);
9
+ }
@@ -0,0 +1,2 @@
1
+ export * from './config';
2
+ export * from './builder';
@@ -0,0 +1,18 @@
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
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./config"), exports);
18
+ __exportStar(require("./builder"), exports);
@@ -0,0 +1,27 @@
1
+ import { Types } from 'mongoose';
2
+ import type { TObject } from '../types';
3
+ /**
4
+ * Normalizes text for search indexing and querying.
5
+ * Converts to lowercase, removes diacritics/accents, and removes any non-alphanumeric character (except the spacer).
6
+ * Multiple spaces/spacers are collapsed into one.
7
+ * @param input String or array of strings to concatenate and normalize.
8
+ * @param spacer String used to join array values or replace spaces. Default is ' '.
9
+ * @returns The normalized string.
10
+ */
11
+ export declare function normalizeSearchText(input: string | Array<string | undefined>, spacer?: string, maxSearchLength?: number): string;
12
+ /**
13
+ * Converts a string to object. Example:
14
+ * 'name age friends { name }' => { name: 1, age: 1, friends: { name: 1 } }
15
+ * @param query String to convert to object.
16
+ * @returns The resulting object.
17
+ */
18
+ export declare function stringToQuery(query?: string, value?: string): object;
19
+ export declare const parseValue: (value: string, instance?: string) => string | number | boolean | Date | Types.ObjectId;
20
+ /**
21
+ * Remove the keys from the initial object. If after this process the property
22
+ * is empty it is removed
23
+ * @param initial The main object
24
+ * @param toRemove The object with the keys to remove
25
+ * @returns The object without the keys
26
+ */
27
+ export declare function removeKeys(initial: TObject, toRemove: TObject): TObject;
@@ -0,0 +1,116 @@
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.parseValue = void 0;
15
+ exports.normalizeSearchText = normalizeSearchText;
16
+ exports.stringToQuery = stringToQuery;
17
+ exports.removeKeys = removeKeys;
18
+ var mongoose_1 = require("mongoose");
19
+ /**
20
+ * Normalizes text for search indexing and querying.
21
+ * Converts to lowercase, removes diacritics/accents, and removes any non-alphanumeric character (except the spacer).
22
+ * Multiple spaces/spacers are collapsed into one.
23
+ * @param input String or array of strings to concatenate and normalize.
24
+ * @param spacer String used to join array values or replace spaces. Default is ' '.
25
+ * @returns The normalized string.
26
+ */
27
+ function normalizeSearchText(input, spacer, maxSearchLength) {
28
+ if (spacer === void 0) { spacer = ' '; }
29
+ if (maxSearchLength === void 0) { maxSearchLength = 900; }
30
+ if (!input)
31
+ return '';
32
+ var processStr = function (s) {
33
+ return s
34
+ .toLowerCase()
35
+ .normalize('NFD') // Decompose combined graphemes into the combination of simple ones
36
+ .replace(/[\u0300-\u036f]/g, '') // Remove diacritics
37
+ .replace(/[^a-z0-9 ]/g, '') // Remove symbols down to alphanumeric and spaces
38
+ .trim()
39
+ .replace(/\s+/g, spacer);
40
+ }; // Collapse multiple spaces and apply spacer
41
+ if (Array.isArray(input)) {
42
+ return input
43
+ .map(function (item) { return (item ? processStr(item) : ''); })
44
+ .filter(Boolean)
45
+ .join(spacer);
46
+ }
47
+ return processStr(input).substring(0, maxSearchLength);
48
+ }
49
+ /**
50
+ * Converts a string to object. Example:
51
+ * 'name age friends { name }' => { name: 1, age: 1, friends: { name: 1 } }
52
+ * @param query String to convert to object.
53
+ * @returns The resulting object.
54
+ */
55
+ function stringToQuery(query, value) {
56
+ if (query === void 0) { query = ''; }
57
+ if (value === void 0) { value = '1'; }
58
+ var regex = /(})(?!$| *})|([\w.]+)(?= *\{)|([\w.]+)(?=$| *})|([\w.]+)/g;
59
+ var preJSON = query.replace(regex, function (match, p1, p2, p3, p4) {
60
+ if (p1) {
61
+ return p1 + ',';
62
+ }
63
+ else if (p2) {
64
+ return "\"".concat(p2, "\":");
65
+ }
66
+ else if (p3) {
67
+ return "\"".concat(p3, "\": ").concat(value);
68
+ }
69
+ else if (p4) {
70
+ return "\"".concat(p4, "\": ").concat(value, ",");
71
+ }
72
+ else {
73
+ return '';
74
+ }
75
+ });
76
+ return JSON.parse("{ ".concat(preJSON, " }"));
77
+ }
78
+ var parseValue = function (value, instance) {
79
+ switch (instance) {
80
+ case 'ObjectID':
81
+ case 'ObjectId':
82
+ return new mongoose_1.Types.ObjectId(value);
83
+ case 'Date':
84
+ return new Date(value);
85
+ case 'Number':
86
+ return Number(value);
87
+ case 'Boolean':
88
+ return typeof value === 'boolean' ? value : value === 'true';
89
+ default:
90
+ return value;
91
+ }
92
+ };
93
+ exports.parseValue = parseValue;
94
+ /**
95
+ * Remove the keys from the initial object. If after this process the property
96
+ * is empty it is removed
97
+ * @param initial The main object
98
+ * @param toRemove The object with the keys to remove
99
+ * @returns The object without the keys
100
+ */
101
+ function removeKeys(initial, toRemove) {
102
+ var principal = __assign({}, initial);
103
+ for (var key in toRemove) {
104
+ if (!principal[key])
105
+ continue;
106
+ if (typeof toRemove[key] === 'object') {
107
+ principal[key] = removeKeys(principal[key], toRemove[key]);
108
+ if (Object.keys(principal[key]).length === 0)
109
+ delete principal[key];
110
+ }
111
+ else {
112
+ delete principal[key];
113
+ }
114
+ }
115
+ return principal;
116
+ }
@@ -0,0 +1,3 @@
1
+ export * from './helpers';
2
+ export * from './object';
3
+ export * from './lookups';
@@ -0,0 +1,19 @@
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
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./helpers"), exports);
18
+ __exportStar(require("./object"), exports);
19
+ __exportStar(require("./lookups"), exports);
@@ -0,0 +1,12 @@
1
+ import { Schema } from 'mongoose';
2
+ import type { TObject, LookupConfirmado } from '../types';
3
+ /**
4
+ * Gets a list of possible fields that could allow a $lookup. This list is
5
+ * obtained from the nested fields of the object.
6
+ * @param schema The mongoose schema to resolve paths
7
+ * @param $project The $project's pipeline that can contains possible $lookup.
8
+ * @param padre Parent path context
9
+ * @returns An array with the fields with a possible $lookup.
10
+ */
11
+ export declare const getListOfPossibleLookups: (schema: Schema, $project?: TObject, padre?: string) => LookupConfirmado[];
12
+ export declare const asignarLookups: (lookup: TObject | undefined, confirmados: LookupConfirmado[]) => void;
@@ -0,0 +1,97 @@
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.asignarLookups = exports.getListOfPossibleLookups = void 0;
15
+ var object_1 = require("./object");
16
+ /**
17
+ * Gets a list of possible fields that could allow a $lookup. This list is
18
+ * obtained from the nested fields of the object.
19
+ * @param schema The mongoose schema to resolve paths
20
+ * @param $project The $project's pipeline that can contains possible $lookup.
21
+ * @param padre Parent path context
22
+ * @returns An array with the fields with a possible $lookup.
23
+ */
24
+ var getListOfPossibleLookups = function (schema, $project, padre) {
25
+ if ($project === void 0) { $project = {}; }
26
+ if (padre === void 0) { padre = ''; }
27
+ padre && (padre = padre + '.');
28
+ var confirmados = [];
29
+ var addCampos = function (field, from, project) {
30
+ var existente = confirmados.find(function (item) { return item.field === field; });
31
+ if (existente) {
32
+ existente.project = __assign(__assign({}, existente.project), project);
33
+ }
34
+ else {
35
+ confirmados.push({ field: field, from: from, project: project });
36
+ }
37
+ };
38
+ var _loop_1 = function (key) {
39
+ var _a;
40
+ if (typeof $project[key] === 'object') {
41
+ var path = schema.path(padre + key);
42
+ if (path && path.options.ref) {
43
+ addCampos(padre + key, path.options.ref, $project[key]);
44
+ }
45
+ else {
46
+ var subkeys = (0, exports.getListOfPossibleLookups)(schema, $project[key], padre + key);
47
+ subkeys.forEach(function (result) {
48
+ addCampos(result.field, result.from, result.project);
49
+ });
50
+ }
51
+ }
52
+ else if (key.includes('.') || padre) {
53
+ var splited_1 = key.split(/\.(.+)/);
54
+ var path = schema.path(padre + splited_1[0]);
55
+ if (path && path.options.ref) {
56
+ var existente = confirmados.find(function (item) { return item.field === splited_1[0]; });
57
+ if (existente) {
58
+ existente.project[splited_1[1]] = 1;
59
+ }
60
+ else {
61
+ confirmados.push({
62
+ field: splited_1[0],
63
+ from: path.options.ref,
64
+ project: (_a = {}, _a[splited_1[1]] = 1, _a),
65
+ });
66
+ }
67
+ }
68
+ return "continue";
69
+ }
70
+ else {
71
+ return "continue";
72
+ }
73
+ };
74
+ for (var key in $project) {
75
+ _loop_1(key);
76
+ }
77
+ return confirmados;
78
+ };
79
+ exports.getListOfPossibleLookups = getListOfPossibleLookups;
80
+ var asignarLookups = function (lookup, confirmados) {
81
+ if (lookup === void 0) { lookup = {}; }
82
+ for (var _i = 0, confirmados_1 = confirmados; _i < confirmados_1.length; _i++) {
83
+ var confirmado = confirmados_1[_i];
84
+ if (confirmado.field.includes('.') || lookup[confirmado.field]) {
85
+ (0, object_1.reemplazarSubdoc)(lookup, confirmado.field, 1);
86
+ }
87
+ else {
88
+ for (var key in lookup) {
89
+ if (key.startsWith(confirmado.field + '.')) {
90
+ delete lookup[key];
91
+ lookup[confirmado.field] = 1;
92
+ }
93
+ }
94
+ }
95
+ }
96
+ };
97
+ exports.asignarLookups = asignarLookups;
@@ -0,0 +1,3 @@
1
+ import type { TObject } from '../types';
2
+ export declare const reemplazarSubdoc: (data: TObject, path: string, reemplazo?: any) => void;
3
+ export declare const getCampo: (data: TObject, path: string) => TObject;
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getCampo = exports.reemplazarSubdoc = void 0;
4
+ var reemplazarSubdoc = function (data, path, reemplazo) {
5
+ if (!reemplazo)
6
+ return;
7
+ var tmp = data;
8
+ var campos = path.split('.');
9
+ campos.forEach(function (campo, index) {
10
+ if (index === campos.length - 1) {
11
+ if (tmp === null || tmp === void 0 ? void 0 : tmp[campo])
12
+ tmp[campo] = reemplazo;
13
+ }
14
+ else {
15
+ tmp = tmp === null || tmp === void 0 ? void 0 : tmp[campo];
16
+ }
17
+ });
18
+ };
19
+ exports.reemplazarSubdoc = reemplazarSubdoc;
20
+ var getCampo = function (data, path) {
21
+ var tmp = data;
22
+ var campos = path.split('.');
23
+ campos.forEach(function (campo) { return (tmp = tmp === null || tmp === void 0 ? void 0 : tmp[campo]); });
24
+ return tmp;
25
+ };
26
+ exports.getCampo = getCampo;
package/package.json CHANGED
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "name": "mongoose-smart-query",
3
- "version": "1.3.3",
3
+ "version": "1.4.1",
4
4
  "description": "Optimize rest requests",
5
- "main": "./dist/mongoose-smart-query.js",
6
- "types": "./dist/mongoose-smart-query.d.ts",
5
+ "main": "./dist/index.js",
6
+ "types": "./dist/index.d.ts",
7
7
  "repository": {
8
8
  "type": "git",
9
9
  "url": "git+https://github.com/mgyugcha/mongoose-smart-query.git"
@@ -24,21 +24,21 @@
24
24
  "devDependencies": {
25
25
  "@eslint/js": "^10.0.1",
26
26
  "@types/jest": "^30.0.0",
27
- "@types/node": "^25.5.2",
28
- "eslint": "^10.2.0",
29
- "jest": "^30.3.0",
30
- "mongoose": "^8.23.0",
27
+ "@types/node": "^25.7.0",
28
+ "eslint": "^10.3.0",
29
+ "jest": "^30.4.2",
30
+ "mongoose": "^8.23.1",
31
31
  "ts-jest": "^29.4.9",
32
32
  "typescript": "^5.9.3",
33
- "typescript-eslint": "^8.58.1",
34
- "uglify-js": "^3.19.3"
33
+ "typescript-eslint": "^8.59.3",
34
+ "typesense": "^3.0.6"
35
35
  },
36
36
  "peerDependencies": {
37
- "mongoose": "^8"
37
+ "mongoose": "^8",
38
+ "typesense": "^3.0.6"
38
39
  },
39
40
  "scripts": {
40
41
  "build": "tsc",
41
- "postbuild": "uglifyjs --compress --mangle --output dist/mongoose-smart-query.js -- dist/mongoose-smart-query.js",
42
42
  "test": "jest",
43
43
  "test:coverage": "jest --coverage",
44
44
  "precommit": "pnpm run lint",
@@ -1 +0,0 @@
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.normalizeSearchText=normalizeSearchText,exports.stringToQuery=stringToQuery,exports.removeKeys=removeKeys,exports.default=default_1,require("mongoose"));function normalizeSearchText(e,t,r){var n;return void 0===t&&(t=" "),void 0===r&&(r=900),e?(n=function(e){return e.toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g,"").replace(/[^a-z0-9 ]/g,"").trim().replace(/\s+/g,t)},Array.isArray(e)?e.map(function(e){return e?n(e):""}).filter(Boolean).join(t):n(e).substring(0,r)):""}var 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(x,e){function S(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=x.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=x.path(o+e))&&r.options.ref?a(o+e,r.options.ref,i[e]):S(i[e],o+e).forEach(function(e){a(e.field,e.from,e.project)})})(e);return s}var t=e.protectedFields,O=void 0===t?"":t,t=e.defaultFields,A=void 0===t?"_id":t,t=e.defaultSort,Q=void 0===t?"-_id":t,t=e.defaultLimit,k=void 0===t?20:t,t=e.fieldsForDefaultQuery,T=void 0===t?"":t,t=e.pageQueryName,P=void 0===t?"$page":t,t=e.limitQueryName,z=void 0===t?"$limit":t,t=e.fieldsQueryName,N=void 0===t?"$fields":t,t=e.sortQueryName,I=void 0===t?"$sort":t,t=e.queryName,C=void 0===t?"$q":t,t=e.textQueryName,E=void 0===t?"$text":t,t=e.unwindName,F=void 0===t?"$unwind":t,t=e.allFieldsQueryName,G=void 0===t?"$getAllFields":t,t=e.normalizeSearchQuery,D=void 0!==t&&t,K=e.collation,q=stringToQuery(O);x.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,m,y,$,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,n=e.pipeline,i=e.lookupsConfirmados;return __generator(this,function(e){switch(e.label){case 0:return t=this.aggregate(n),K&&t.collation(K),r={},[4,t];case 1:return[2,(r.docs=e.sent(),r.lookups=i,r)]}})})}),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,p=parseInt(t[P])||1,l=parseInt(t[z])||k,f=Math.ceil(w/l),a={total:w,page:p,pages:f,limit:l},[3,5];case 2:return[4,this.__smartQueryGetPipeline(__assign({},t),!1,n)];case 3:return w=e.sent(),p=w.pipeline,s=w.lookupsConfirmados,f=this.aggregate(p),K&&f.collation(K),[4,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[_],m=function(e){var t=getCampo(e,v.field);t&&reemplazarSubdoc(e,v.field,g.find(function(e){return e._id.equals(t)}))},y=0,$=o;y<$.length;y++)b=$[y],m(b);return i?[2,{data:o,pagination:a}]:[2,o]}})})},x.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]}})})},x.statics.__smartQueryGetPipeline=function(e){return __awaiter(this,arguments,void 0,function(w,s,c){var h,_,u,l,g,p,f,d,v,m,y,$,b,j=this;return void 0===s&&(s=!1),void 0===c&&(c=[]),__generator(this,function(e){switch(e.label){case 0:return h=this.schema.indexes().some(function(e){e=e[0];return Object.values(e).includes("text")}),_=w.business?{business:new mongoose_1.Types.ObjectId(w.business)}:{},u=parseInt(w[P])||1,l=parseInt(w[z])||k,g=function(){return __awaiter(j,void 0,void 0,function(){var y,$,b,t,r,n=this;return __generator(this,function(e){switch(e.label){case 0:for(r in y={},$={},b=[],t=function(e){var t,r=x.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=x.path(f))&&n.options.ref&&(o=e,$[a=f]={collection:n.options.ref,$match:{}}),a?$[a].$match:y),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 m=v.split(",").map(function(e){return parseValue(e.trim(),null==r?void 0:r.instance)});l[o]=((t={})[g]=m,t);break;default:m=parseValue(v,null==r?void 0:r.instance);g?"object"==typeof l[o]?l[o][g]=m:l[o]=((t={})[g]=m,t):"string"==typeof v&&v.includes("$exists")?l[o]={$exists:!0,$ne:[]}:l[o]=m}}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&&(y.$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),_)).project({_id:1}).toArray()];case 1:return t=e.sent(),y[r]={$in:t.map(function(e){return e._id})},[2]}})})}))];case 1:e.sent(),e.label=2;case 2:return[2,y]}})})},p=function(){return w[F]?[{$unwind:{path:"$".concat(w[F]),preserveNullAndEmptyArrays:!0}}]:[]},[4,function(){return __awaiter(j,void 0,void 0,function(){var o,a,t,s,c,u,r,n,i,l,p,f,d=this;return __generator(this,function(e){switch(e.label){case 0:return(o={},t=!(a={}),h&&w[E])?(o={$text:{$search:w[E]}},t=!0,[3,3]):[3,1];case 1:if(!w[C]||!T)return[3,3];for(f=T.split(" "),p=D?normalizeSearchText(w[C]):w[C],p=p.replace(/[()[\\\]]/g,".").replace(/[+]/g,"\\+").replace(/[*]/g,"\\*"),s=p.split(" "),c=D?"":"i",u={$regex:RegExp(p,c)},r=function(r){var e,t,n,i;x.path(r)?(o.$or||(o.$or=[]),s.length<=1?o.$or.push(((n={})[r]=u,n)):o.$or.push({$and:s.map(function(e){var t={};return t[r]={$regex:RegExp(e,c)},t})})):r.includes(".")&&(t=(n=r.split("."))[0],n=n[1],i=x.path(t))&&i.options.ref&&(a[t]?a[t].$match.$or.push(((e={})[n]=u,e)):a[t]={collection:i.options.ref,$match:{$or:[((e={})[n]=u,e)]}})},n=0,i=f;n<i.length;n++)l=i[n],r(l);return 0===Object.keys(a).length?[3,3]:[4,Promise.all(Object.entries(a).map(function(e){return __awaiter(d,[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),_)).project({_id:1}).toArray()];case 1:return t=e.sent(),(t=t.map(function(e){return e._id})).length&&(o.$or||(o.$or=[]),o.$or.push(((r={})[n]={$in:t},r))),[2]}})})}))];case 2:e.sent(),e.label=3;case 3:return[4,g()];case 4:return p=e.sent(),(f=p.$or)&&(delete p.$or,Array.isArray(o.$or)?o.$or=o.$or.concat(f):o.$or=f),[2,{match:__assign(__assign({},p),o),usingTextSearch:t}]}})})}()];case 1:if(d=e.sent(),y=d.match,f=d.usingTextSearch,!(a=w)[N]&&A&&(a[N]=A),d=removeKeys(stringToQuery(a[N]),q),v=S(d),m=[],0!==Object.keys(y).length&&m.push({$match:y}),m.push.apply(m,c),s)m.push.apply(m,__spreadArray(__spreadArray([],p(),!1),[{$count:"size"}],!1));else{if(y=function(){if(f)return{$localSort:{score:{$meta:"textScore"},_id:-1}};if(!w[I]){if(!Q)return{};w[I]=Q}for(var e=/(-)?([\w.]+)/g,t={},r={};null!==(i=e.exec(w[I]));){var n=i[1],i=i[2];!!x.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}}(),$=[],"true"!==(null==(b=w[G])?void 0:b.toString())){var t=d;void 0===t&&(t={});for(var r=0,n=v;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)}b=__assign({},d),f&&(b.score={$meta:"textScore"}),$.push({$project:b})}else O&&$.push({$project:stringToQuery(O,"0")}),f&&$.push({$addFields:{score:{$meta:"textScore"}}});m.push.apply(m,__spreadArray(__spreadArray(__spreadArray(__spreadArray([],y.$localSort?[{$sort:y.$localSort}]:[],!1),p(),!1),[{$skip:(u-1)*l},{$limit:l}],!1),$,!1))}return[2,{pipeline:m,lookupsConfirmados:v}]}var a})})}}