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.

260 lines (253 loc) 9.04 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. */ 'use strict'; var net = require('net'); function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; } var net__default = /*#__PURE__*/_interopDefault(net); var __defProp = Object.defineProperty; var __name = (target, value) => __defProp(target, "name", { value, configurable: true }); var PORT_REGEX = /^[0-9]{1,5}$/; var UUID_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i; var PHONE_ALLOWED_CHARS_REGEX = /^[+]?[0-9\s().-]+$/; var ALPHANUMERIC_REGEX = /^[A-Za-z0-9]+$/; var HEX_COLOR_REGEX = /^#([a-f0-9]{6}|[a-f0-9]{3})$/i; var ISO_DATE_REGEX = /^\d{4}-\d{2}-\d{2}(T\d{2}:\d{2}:\d{2}(\.\d+)?(Z|[+-]\d{2}:\d{2})?)?$/; var BASE64_REGEX = /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/; var DOT_ATOM_REGEX = /^[A-Za-z0-9!#$%&'*+/=?^_`{|}~-]+(\.[A-Za-z0-9!#$%&'*+/=?^_`{|}~-]+)*$/; var QUOTED_LOCAL_REGEX = /^"([\s\x21\x23-\x5B\x5D-\x7E]|\\[\x20-\x7E])*"$/; var TLD_REGEX = /^[A-Za-z]{2,63}$/; function isPort(value) { if (typeof value === "number") return Number.isInteger(value) && value > 0 && value <= 65535; if (!value || typeof value !== "string") return false; const str = value.trim(); if (!PORT_REGEX.test(str)) return false; const port = Number(str); return Number.isInteger(port) && port > 0 && port <= 65535; } __name(isPort, "isPort"); function isEmail(str) { if (!str || typeof str !== "string" || str.length > 254) return false; const atIndex = str.indexOf("@"); if (atIndex === -1 || atIndex !== str.lastIndexOf("@")) return false; const local = str.slice(0, atIndex); const domain = str.slice(atIndex + 1); if (!local || !domain) return false; if (!DOT_ATOM_REGEX.test(local) && !QUOTED_LOCAL_REGEX.test(local)) return false; if (domain.includes("..")) return false; const labels = domain.split("."); if (labels.some((l) => !l.length)) return false; if (labels.length < 2) return false; const labelRegex = /^[A-Za-z0-9-]{1,63}$/; for (const label of labels) { if (!labelRegex.test(label)) return false; if (label.startsWith("-") || label.endsWith("-")) return false; } const tld = labels.at(-1) || ""; if (!TLD_REGEX.test(tld)) return false; return true; } __name(isEmail, "isEmail"); function isUUID(str) { return UUID_REGEX.test(str); } __name(isUUID, "isUUID"); function isURL(str, allowedProtocols = [ "http", "https", "ws", "wss" ]) { if (!str || typeof str !== "string") return false; try { const url = new URL(str); return allowedProtocols.includes(url.protocol.replace(":", "")); } catch { return false; } } __name(isURL, "isURL"); function isPhone(str) { if (!str || typeof str !== "string") return false; const digits = str.replace(/\D/g, ""); if (digits.length < 6 || digits.length > 15) return false; return PHONE_ALLOWED_CHARS_REGEX.test(str); } __name(isPhone, "isPhone"); function isAlphanumeric(str) { if (!str || typeof str !== "string") return false; return ALPHANUMERIC_REGEX.test(str); } __name(isAlphanumeric, "isAlphanumeric"); function isNumeric(value) { if (typeof value === "number") return Number.isFinite(value); if (!value || typeof value !== "string") return false; const str = value.trim(); if (str === "" || str.length > 16) return false; const num = Number(str); return Number.isFinite(num); } __name(isNumeric, "isNumeric"); function isHexColor(str) { if (!str || typeof str !== "string") return false; return HEX_COLOR_REGEX.test(str); } __name(isHexColor, "isHexColor"); function isISODate(str) { if (!str || typeof str !== "string") return false; if (!ISO_DATE_REGEX.test(str)) return false; const date = new Date(str); return !Number.isNaN(date.getTime()); } __name(isISODate, "isISODate"); function isLengthBetween(str, min, max) { if (typeof str !== "string") return false; return str.length >= min && str.length <= max; } __name(isLengthBetween, "isLengthBetween"); function isNumberBetween(value, min, max) { if (typeof value !== "number" || !Number.isFinite(value)) return false; return value >= min && value <= max; } __name(isNumberBetween, "isNumberBetween"); function isAlpha(str) { if (!str || typeof str !== "string") return false; return /^[a-zA-Z]+$/.test(str); } __name(isAlpha, "isAlpha"); function isStrongPassword(str) { if (str.length < 8) return false; const hasUpperCase = /[A-Z]/.test(str); const hasLowerCase = /[a-z]/.test(str); const hasNumbers = /[0-9]/.test(str); const hasSpecialChar = /[!@#$%^&*()_+\-=[\]{};':"\\|,.<>?]/.test(str); return hasUpperCase && hasLowerCase && hasNumbers && hasSpecialChar; } __name(isStrongPassword, "isStrongPassword"); function isIPv4(str) { if (!str || typeof str !== "string") return false; const parts = str.split("."); if (parts.length !== 4) return false; return parts.every((p) => { if (p.length > 3 || p.startsWith("0") && p.length > 1) return false; const n = Number(p); return Number.isInteger(n) && n >= 0 && n <= 255; }); } __name(isIPv4, "isIPv4"); function isIPv6(str) { if (!str || typeof str !== "string" || str.length > 45) return false; try { return net__default.default.isIP(str) === 6; } catch { return false; } } __name(isIPv6, "isIPv6"); function isCreditCard(str) { if (!str || typeof str !== "string") return false; const s = str.replace(/\D/g, ""); if (s.length < 13 || s.length > 19) return false; let sum = 0; for (let i = 0, dbl = false; i < s.length; i++, dbl = !dbl) { let d = s.charCodeAt(s.length - 1 - i) - 48; if (dbl) { d *= 2; if (d > 9) d -= 9; } sum += d; } return sum % 10 === 0; } __name(isCreditCard, "isCreditCard"); function isValidJSON(str) { if (!str || typeof str !== "string") return false; try { JSON.parse(str); return true; } catch { return false; } } __name(isValidJSON, "isValidJSON"); function isArray(value, itemGuard) { if (!Array.isArray(value)) return false; return !itemGuard || value.every((item) => itemGuard(item)); } __name(isArray, "isArray"); function isBase64(str) { if (!str || typeof str !== "string") return false; return BASE64_REGEX.test(str); } __name(isBase64, "isBase64"); function hasRequiredProps(obj, requiredProps) { if (!obj || typeof obj !== "object") return false; return requiredProps.every((prop) => Object.hasOwn(obj, prop) && obj[prop] != null); } __name(hasRequiredProps, "hasRequiredProps"); function isDateInRange(date, minDate, maxDate) { if (!(date instanceof Date) || !Number.isFinite(date.getTime())) return false; if (minDate && date < minDate) return false; if (maxDate && date > maxDate) return false; return true; } __name(isDateInRange, "isDateInRange"); function matchesPattern(str, pattern) { if (typeof str !== "string") return false; return pattern.test(str); } __name(matchesPattern, "matchesPattern"); function validateAll(value, validators) { if (!Array.isArray(validators)) return false; return validators.every((fn) => { try { return fn(value); } catch { return false; } }); } __name(validateAll, "validateAll"); exports.hasRequiredProps = hasRequiredProps; exports.isAlpha = isAlpha; exports.isAlphanumeric = isAlphanumeric; exports.isArray = isArray; exports.isBase64 = isBase64; exports.isCreditCard = isCreditCard; exports.isDateInRange = isDateInRange; exports.isEmail = isEmail; exports.isHexColor = isHexColor; exports.isIPv4 = isIPv4; exports.isIPv6 = isIPv6; exports.isISODate = isISODate; exports.isLengthBetween = isLengthBetween; exports.isNumberBetween = isNumberBetween; exports.isNumeric = isNumeric; exports.isPhone = isPhone; exports.isPort = isPort; exports.isStrongPassword = isStrongPassword; exports.isURL = isURL; exports.isUUID = isUUID; exports.isValidJSON = isValidJSON; exports.matchesPattern = matchesPattern; exports.validateAll = validateAll;