UNPKG

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
"use strict"; 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;