UNPKG

@catbee/utils

Version:

A modular, production-grade utility toolkit for Node.js and TypeScript, designed for robust, scalable applications (including Express-based services). All utilities are tree-shakable and can be imported independently.

207 lines (202 loc) 7.1 kB
/* * The MIT License * * Copyright (c) 2026 Catbee Technologies. https://catbee.in/license * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ import { BadRequestException } from '@catbee/utils/exception'; var __defProp = Object.defineProperty; var __name = (target, value) => __defProp(target, "name", { value, configurable: true }); var getPaginationParams = /* @__PURE__ */ __name((req) => { const query = req.query; const { page, limit } = extractPaginationParams(query, 1, 20, 100); const { sortBy, sortOrder } = extractSortParams(query, []); const search = typeof query.search === "string" ? query.search : void 0; return { ...query, page, limit, sortBy, sortOrder, search }; }, "getPaginationParams"); function parseNumberParam(value, options = {}) { const { throwOnError = false, errorMessage = "Invalid number parameter", defaultValue, required = false } = options; if (value === void 0) { if (required) { const error = `Required number parameter is missing`; if (throwOnError) throw new BadRequestException(error); return { isValid: false, value: null, error }; } return { isValid: defaultValue !== void 0, value: defaultValue !== void 0 ? defaultValue : null, error: defaultValue === void 0 ? "Missing parameter with no default" : void 0 }; } const num = Number(value); if (Number.isNaN(num)) { if (throwOnError) throw new BadRequestException(errorMessage); return { isValid: false, value: null, error: errorMessage }; } return { isValid: true, value: num }; } __name(parseNumberParam, "parseNumberParam"); function parseBooleanParam(value, options = {}) { const { throwOnError = false, errorMessage = "Invalid boolean parameter", defaultValue, required = false } = options; if (value === void 0) { if (required) { const error = `Required boolean parameter is missing`; if (throwOnError) throw new BadRequestException(error); return { isValid: false, value: null, error }; } return { isValid: defaultValue !== void 0, value: defaultValue !== void 0 ? defaultValue : null, error: defaultValue === void 0 ? "Missing parameter with no default" : void 0 }; } const lowercaseValue = value.toLowerCase(); if ([ "true", "t", "yes", "y", "1" ].includes(lowercaseValue)) { return { isValid: true, value: true }; } if ([ "false", "f", "no", "n", "0" ].includes(lowercaseValue)) { return { isValid: true, value: false }; } if (throwOnError) throw new BadRequestException(errorMessage); return { isValid: false, value: null, error: errorMessage }; } __name(parseBooleanParam, "parseBooleanParam"); function extractPaginationParams(query, defaultPage = 1, defaultLimit = 20, maxLimitSize = 100) { const pageParam = typeof query.page === "string" ? query.page : void 0; const pageResult = parseNumberParam(pageParam, { defaultValue: defaultPage }); const limitParam = typeof query.limit === "string" ? query.limit : void 0; const limitResult = parseNumberParam(limitParam, { defaultValue: defaultLimit }); const page = pageResult.value && pageResult.value > 0 ? pageResult.value : defaultPage; const limit = limitResult.value && limitResult.value > 0 ? Math.min(limitResult.value, maxLimitSize) : defaultLimit; return { page, limit }; } __name(extractPaginationParams, "extractPaginationParams"); var DEFAULT_SORT = { sortBy: "createdAt", sortOrder: "desc" }; function extractSortParams(query, allowedFields, defaultSort = DEFAULT_SORT) { const inferredSortBy = getSortByFromQuery(query, defaultSort); let sortOrder = getSortOrderFromQuery(query, defaultSort); const explicit = applyExplicitSortOrder(query.sortOrder); if (explicit) { sortOrder = explicit; } const sortBy = validateSortField(inferredSortBy, allowedFields, defaultSort.sortBy); return { sortBy, sortOrder }; } __name(extractSortParams, "extractSortParams"); function getSortByFromQuery(query, defaultSort) { if (typeof query.sortBy === "string") return query.sortBy; if (Array.isArray(query.sortBy)) return query.sortBy[0]; if (typeof query.sort === "string") return query.sort.startsWith("-") ? query.sort.slice(1) : query.sort; if (Array.isArray(query.sort)) return query.sort[0].startsWith("-") ? query.sort[0].slice(1) : query.sort[0]; return defaultSort.sortBy; } __name(getSortByFromQuery, "getSortByFromQuery"); function getSortOrderFromQuery(query, defaultSort) { if (typeof query.sort === "string") return query.sort.startsWith("-") ? "desc" : "asc"; if (Array.isArray(query.sort)) return query.sort[0].startsWith("-") ? "desc" : "asc"; return defaultSort.sortOrder; } __name(getSortOrderFromQuery, "getSortOrderFromQuery"); function applyExplicitSortOrder(sortOrderParam) { if (typeof sortOrderParam !== "string") return null; const order = sortOrderParam.toLowerCase(); if (order === "asc" || order === "desc") return order; return null; } __name(applyExplicitSortOrder, "applyExplicitSortOrder"); function validateSortField(sortBy, allowedFields, defaultSortBy) { if (allowedFields.length && !allowedFields.includes(sortBy)) return defaultSortBy; return sortBy; } __name(validateSortField, "validateSortField"); function extractFilterParams(query, allowedFilters) { const filters = {}; for (const field of allowedFilters) { if (field in query) { filters[field] = query[field]; } } return filters; } __name(extractFilterParams, "extractFilterParams"); // src/types/api-response.ts var SortDirection = /* @__PURE__ */ (function(SortDirection2) { SortDirection2["ASC"] = "asc"; SortDirection2["DESC"] = "desc"; return SortDirection2; })({}); export { SortDirection, extractFilterParams, extractPaginationParams, extractSortParams, getPaginationParams, parseBooleanParam, parseNumberParam };