express-easy-curd
Version:
A lightweight helper library for building Express.js routes, controllers, and Redis-enhanced middleware with optional Redis support.
126 lines (125 loc) • 4.86 kB
JavaScript
;
var __rest = (this && this.__rest) || function (s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
t[p[i]] = s[p[i]];
}
return t;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.filterHelper = exports.paginationHelper = exports.pic = void 0;
// Supported operators for query
const operatorsMap = {
_gt: "$gt",
_lt: "$lt",
_gte: "$gte",
_lte: "$lte",
_ne: "$ne",
_in: "$in",
_nin: "$nin",
_regex: "$regex",
_exists: "$exists",
};
const toValue = (v) => {
if (v === "true")
return true;
if (v === "false")
return false;
if (v === "null")
return null;
if (!isNaN(+v) && v.trim() !== "")
return +v;
return v;
};
const toArray = (v) => (Array.isArray(v) ? v.map(toValue) : String(v).split(",").map(toValue));
/*######################## pic valid values ####################################*/
const pic = (obj, schemaFields) => {
const validKeys = Object.keys(obj).filter((key) => {
// Direct key match
if (schemaFields.includes(key))
return true;
// Operator match (e.g., amount_gt → amount)
return schemaFields.some((field) => Object.keys(operatorsMap).some((op) => key === `${field}${op}`));
});
return validKeys.reduce((acc, key) => {
if (Object.prototype.hasOwnProperty.call(obj, key) && obj[key] !== undefined) {
acc[key] = obj[key];
}
return acc;
}, {});
};
exports.pic = pic;
/*######################## Pagination helpers ####################################*/
const paginationHelper = (obj) => {
const { page = 1, limit = 10, sortBy = "createdAt", sortOrder = "desc", populate = "", } = (0, exports.pic)(obj, ["page", "limit", "sortBy", "sortOrder", "populate"]);
const parsedPage = Math.abs(Number(page)) || 1;
const parsedLimit = Math.min(Math.abs(Number(limit || 10)), 100);
const skip = (parsedPage - 1) * parsedLimit;
const validSortOrders = [1, -1, "asc", "ascending", "desc", "descending"];
const parsedSortOrder = validSortOrders.includes(sortOrder) ? sortOrder : "desc";
const sortCondition = { [sortBy]: parsedSortOrder };
return {
page: parsedPage,
limit: parsedLimit,
skip,
sortCondition,
populate,
};
};
exports.paginationHelper = paginationHelper;
/*######################## Filter Helper ####################################*/
const filterHelper = (reqQuery, partialSearching, schemaName) => {
const schemaKeys = Object.keys(schemaName.schema.obj);
const _a = (0, exports.pic)(reqQuery, ["search", ...schemaKeys]), { search } = _a, rest = __rest(_a, ["search"]);
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const conditions = [];
// Handle search queries (partial match)
if (search && partialSearching.length > 0) {
conditions.push({
$or: partialSearching.map((field) => ({
[field]: { $regex: search, $options: "i" },
})),
});
}
// Handle exact filters and operators (_gt, _lt, etc.)
Object.entries(rest).forEach(([key, val]) => {
if (val === undefined || val === null || val === "")
return;
const raw = val.toString().trim();
const opKey = Object.keys(operatorsMap).find((sfx) => key.endsWith(sfx));
const operator = opKey && operatorsMap[opKey];
const field = opKey ? key.slice(0, -opKey.length) : key;
if (operator) {
let val;
if (["$in", "$nin"].includes(operator)) {
val = toArray(raw);
}
else if (operator === "$exists") {
val = raw === "true" || raw === "1";
}
else if (operator === "$regex") {
val = new RegExp(raw, "i");
}
else if (["$gt", "$lt", "$gte", "$lte"].includes(operator)) {
const num = Number(raw);
if (isNaN(num))
return;
val = num;
}
else {
val = toValue(raw);
}
conditions.push({ [field]: { [operator]: val } });
}
else {
const val = typeof raw === "string" && raw.includes(",") ? { $in: toArray(raw) } : toValue(raw);
conditions.push({ [key]: val });
}
});
return conditions.length > 0 ? { $and: conditions } : {};
};
exports.filterHelper = filterHelper;