@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.
215 lines (209 loc) • 7.33 kB
JavaScript
/*
* 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.
*/
;
var exception = require('@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 exception.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 exception.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 exception.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 exception.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;
})({});
exports.SortDirection = SortDirection;
exports.extractFilterParams = extractFilterParams;
exports.extractPaginationParams = extractPaginationParams;
exports.extractSortParams = extractSortParams;
exports.getPaginationParams = getPaginationParams;
exports.parseBooleanParam = parseBooleanParam;
exports.parseNumberParam = parseNumberParam;