@joktec/mongo
Version:
JokTec - Mongo Service
174 lines • 7.18 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.MongoHelper = void 0;
const utils_1 = require("@joktec/utils");
const lodash_1 = require("lodash");
const models_1 = require("../models");
class MongoHelper {
static flatten(obj, omitKeys) {
const result = {};
function convert(obj) {
const firstOperator = Object.keys(obj).find(key => String(key).startsWith('$'));
if (!firstOperator)
return obj;
return obj;
}
function recurse(value, prefix = '') {
if (value instanceof models_1.ObjectId) {
result[prefix] = value;
return;
}
if ((0, lodash_1.isString)(value) && models_1.ObjectId.isValid(value)) {
result[prefix] = models_1.ObjectId.create(value);
return;
}
if ((0, lodash_1.isArray)(value)) {
result[prefix] = value.map(v => {
if (v instanceof models_1.ObjectId)
return v;
if ((0, lodash_1.isString)(v) && models_1.ObjectId.isValid(v))
return models_1.ObjectId.create(v);
return v;
});
return;
}
if (!value || (0, lodash_1.isDate)(value) || (0, lodash_1.isRegExp)(value) || !(0, lodash_1.isObject)(value)) {
result[prefix] = value;
return;
}
if ((0, lodash_1.isObject)(value) && omitKeys?.length) {
value = (0, lodash_1.omit)(value, omitKeys);
}
if (Object.keys(value).some(key => String(key).startsWith('$'))) {
result[prefix] = convert(value);
return;
}
Object.keys(value).forEach(key => {
if (key === 'id') {
value['_id'] = value['id'];
delete value['id'];
key = '_id';
}
const newKey = prefix ? `${prefix}.${key}` : key;
recurse(value[key], newKey);
});
}
const rootQuery = Object.keys(obj).filter(key => String(key).startsWith('$'));
Object.assign(result, (0, lodash_1.pick)(obj, rootQuery));
recurse((0, lodash_1.omit)(obj, rootQuery));
return result;
}
static parsePagination(query = {}) {
const limit = typeof query.limit === 'number' && query.limit > 0 ? query.limit : undefined;
const page = typeof query.page === 'number' && query.page > 0 ? query.page : undefined;
const offset = typeof query.offset === 'number' && query.offset >= 0 ? query.offset : undefined;
if (limit && page)
return { limit, offset: (page - 1) * limit };
if (limit)
return { limit, offset: offset ?? 0 };
return {};
}
static parseProjection(select) {
if ((0, lodash_1.isObject)(select))
return this.flatten(select);
return (0, utils_1.toArray)(select, { split: ',' }).reduce((acc, field) => {
const trimField = field.trim();
if (!trimField)
return acc;
if (trimField.startsWith('-'))
acc[trimField.slice(1)] = 0;
else
acc[trimField] = 1;
return acc;
}, {});
}
static parseSort(sort) {
const flattenSort = MongoHelper.flatten(sort);
return Object.entries(flattenSort).reduce((acc, [field, order]) => {
acc[field] = order === 'asc' || order === 1 || order === '1' ? 1 : -1;
return acc;
}, {});
}
static parseFilter(condition, flat = true) {
const flatObj = flat ? this.flatten(condition) : condition;
const keys = Object.keys(flatObj);
for (const key of keys) {
if ((0, lodash_1.isNil)(flatObj[key])) {
flatObj[key] = null;
continue;
}
if (flatObj[key] instanceof models_1.ObjectId) {
continue;
}
if ((0, lodash_1.isString)(flatObj[key]) && models_1.ObjectId.isValid(flatObj[key])) {
flatObj[key] = models_1.ObjectId.create(flatObj[key]);
continue;
}
if ((0, lodash_1.isDate)(flatObj[key]) || (0, lodash_1.isRegExp)(flatObj[key]) || !(0, lodash_1.isObject)(flatObj[key])) {
continue;
}
if (flatObj[key].hasOwnProperty('$like')) {
flatObj[key]['$regex'] = new RegExp(flatObj[key]['$like'], 'i');
delete flatObj[key]['$like'];
continue;
}
else if (flatObj[key].hasOwnProperty('$begin')) {
flatObj[key]['$regex'] = new RegExp(`^${flatObj[key]['$begin']}`, 'i');
delete flatObj[key]['$begin'];
continue;
}
else if (flatObj[key].hasOwnProperty('$end')) {
flatObj[key]['$regex'] = new RegExp(`${flatObj[key]['$end']}$`, 'i');
delete flatObj[key]['$end'];
continue;
}
else if (flatObj[key].hasOwnProperty('$nil')) {
flatObj[key] = null;
continue;
}
else if (flatObj[key].hasOwnProperty('$empty')) {
flatObj[key] = '';
continue;
}
flatObj[key] = this.parseFilter(flatObj[key], false);
}
return flatObj;
}
static parsePopulate(populate = {}) {
if ((0, lodash_1.isNil)(populate) || (0, lodash_1.isEmpty)(populate))
return [];
return Object.entries(populate).map(([path, populate]) => {
const populateOptions = { path, options: { lean: true } };
const options = populate === '*' ? {} : populate;
if (options.select)
populateOptions.select = options.select;
if (options.model)
populateOptions.model = options.model;
if (options.populate)
populateOptions.populate = this.parsePopulate(options.populate);
if (options.match)
populateOptions.match = options.match;
return populateOptions;
});
}
static parseSimpleCondition(cond) {
const condition = {};
switch (true) {
case models_1.ObjectId.isValid(String(cond)):
case (0, lodash_1.isString)(cond):
case (0, lodash_1.isNumber)(cond):
case (0, lodash_1.isBuffer)(cond):
Object.assign(condition, { _id: models_1.ObjectId.create(String(cond)) });
break;
case (0, lodash_1.isObject)(cond):
case (0, lodash_1.isArray)(cond):
Object.assign(condition, cond);
break;
default:
Object.assign(condition, { _id: models_1.ObjectId.create(String(cond)) });
}
return condition;
}
}
exports.MongoHelper = MongoHelper;
//# sourceMappingURL=mongo.helper.js.map