UNPKG

@rzl-zone/utils-js

Version:

A modern, lightweight set of JavaScript utility functions with TypeScript support for everyday development, crafted to enhance code readability and maintainability.

270 lines (261 loc) 11.6 kB
/*! * ==================================================== * Rzl Utils-JS. * ---------------------------------------------------- * Version: 3.11.0. * Author: Rizalvin Dwiky. * Repository: https://github.com/rzl-zone/utils-js. * ==================================================== */ 'use strict'; var chunk7FGNVDEV_cjs = require('./chunk-7FGNVDEV.cjs'); var chunkBAV5T2E3_cjs = require('./chunk-BAV5T2E3.cjs'); var chunkDAPAK2W3_cjs = require('./chunk-DAPAK2W3.cjs'); var chunkSYHPSOUU_cjs = require('./chunk-SYHPSOUU.cjs'); var parseCustomDate = (dateString, format) => { if (!chunkSYHPSOUU_cjs.isNonEmptyString(dateString) || !chunkSYHPSOUU_cjs.isNonEmptyString(format)) { throw new TypeError( `Parameter \`dateString\` and \`format\` must be of type \`string\` and not empty-string, but received: "['dateString': \`${chunkSYHPSOUU_cjs.getPreciseType( dateString )}\` - (current value: \`${chunkDAPAK2W3_cjs.safeStableStringify(dateString, { keepUndefined: true })}\`), 'format': \`${chunkSYHPSOUU_cjs.getPreciseType( format )}\` - (current value: \`${chunkDAPAK2W3_cjs.safeStableStringify(format, { keepUndefined: true })}\`)]".` ); } const dateParts = dateString.split(/[-/]/).map(Number); if (dateParts.length !== 3 || dateParts.some(isNaN)) return null; let day, month, year; if (format === "DD/MM/YYYY") { [day, month, year] = dateParts; } else if (format === "MM/DD/YYYY") { [month, day, year] = dateParts; } else { return null; } month -= 1; const date = new Date(year, month, day); if (date.getFullYear() !== year || date.getMonth() !== month || date.getDate() !== day) { return null; } return date; }; var validateJsonParsingOptions = (optionsValue = {}) => { chunkSYHPSOUU_cjs.assertIsPlainObject(optionsValue, { message: ({ currentType, validType }) => `Second parameter (\`options\`) must be of type \`${validType}\`, but received: \`${currentType}\`.` }); const convertBooleans = chunkSYHPSOUU_cjs.hasOwnProp(optionsValue, "convertBooleans") ? optionsValue.convertBooleans : false; const convertDates = chunkSYHPSOUU_cjs.hasOwnProp(optionsValue, "convertDates") ? optionsValue.convertDates : false; const convertNumbers = chunkSYHPSOUU_cjs.hasOwnProp(optionsValue, "convertNumbers") ? optionsValue.convertNumbers : false; const loggingOnFail = chunkSYHPSOUU_cjs.hasOwnProp(optionsValue, "loggingOnFail") ? optionsValue.loggingOnFail : false; const removeEmptyArrays = chunkSYHPSOUU_cjs.hasOwnProp(optionsValue, "removeEmptyArrays") ? optionsValue.removeEmptyArrays : false; const removeEmptyObjects = chunkSYHPSOUU_cjs.hasOwnProp(optionsValue, "removeEmptyObjects") ? optionsValue.removeEmptyObjects : false; const removeNulls = chunkSYHPSOUU_cjs.hasOwnProp(optionsValue, "removeNulls") ? optionsValue.removeNulls : false; const removeUndefined = chunkSYHPSOUU_cjs.hasOwnProp(optionsValue, "removeUndefined") ? optionsValue.removeUndefined : false; const strictMode = chunkSYHPSOUU_cjs.hasOwnProp(optionsValue, "strictMode") ? optionsValue.strictMode : false; const checkSymbols = chunkSYHPSOUU_cjs.hasOwnProp(optionsValue, "checkSymbols") ? optionsValue.checkSymbols : false; const convertNaN = chunkSYHPSOUU_cjs.hasOwnProp(optionsValue, "convertNaN") ? optionsValue.convertNaN : false; const customDateFormats = chunkSYHPSOUU_cjs.hasOwnProp(optionsValue, "customDateFormats") ? optionsValue.customDateFormats : []; const onError = chunkSYHPSOUU_cjs.hasOwnProp(optionsValue, "onError") ? optionsValue.onError : chunkBAV5T2E3_cjs.noop; if (!(chunkSYHPSOUU_cjs.isBoolean(convertBooleans) && chunkSYHPSOUU_cjs.isBoolean(convertDates) && chunkSYHPSOUU_cjs.isBoolean(convertNumbers) && chunkSYHPSOUU_cjs.isBoolean(convertNaN) && chunkSYHPSOUU_cjs.isBoolean(checkSymbols) && chunkSYHPSOUU_cjs.isBoolean(loggingOnFail) && chunkSYHPSOUU_cjs.isBoolean(removeEmptyArrays) && chunkSYHPSOUU_cjs.isBoolean(removeEmptyObjects) && chunkSYHPSOUU_cjs.isBoolean(removeNulls) && chunkSYHPSOUU_cjs.isBoolean(removeUndefined) && chunkSYHPSOUU_cjs.isBoolean(strictMode) && chunkSYHPSOUU_cjs.isArray(customDateFormats) && chunkSYHPSOUU_cjs.isFunction(onError))) { throw new TypeError( `Invalid \`options\` parameter (second argument): \`convertBooleans\`, \`convertDates\`, \`convertNumbers\`, \`loggingOnFail\`, \`removeEmptyArrays\`, \`removeEmptyObjects\`, \`removeNulls\`, \`removeUndefined\`, \`strictMode\` expected to be a \`boolean\` type, \`customDateFormats\` expected to be a \`array\` type and \`onError\` expected to be a \`void function\` type. But received: ['convertBooleans': \`${chunkSYHPSOUU_cjs.getPreciseType( convertBooleans )}\`, 'convertDates': \`${chunkSYHPSOUU_cjs.getPreciseType( convertDates )}\`, 'convertNumbers': \`${chunkSYHPSOUU_cjs.getPreciseType( convertNumbers )}\`, 'loggingOnFail': \`${chunkSYHPSOUU_cjs.getPreciseType( loggingOnFail )}\`, 'removeEmptyArrays': \`${chunkSYHPSOUU_cjs.getPreciseType( removeEmptyArrays )}\`, 'removeEmptyObjects': \`${chunkSYHPSOUU_cjs.getPreciseType( removeEmptyObjects )}\`, 'removeNulls': \`${chunkSYHPSOUU_cjs.getPreciseType( removeNulls )}\`, 'removeUndefined': \`${chunkSYHPSOUU_cjs.getPreciseType( removeUndefined )}\`, 'strictMode': \`${chunkSYHPSOUU_cjs.getPreciseType( strictMode )}\`, 'customDateFormats': \`${chunkSYHPSOUU_cjs.getPreciseType( customDateFormats )}\`, 'onError': \`${chunkSYHPSOUU_cjs.getPreciseType(onError)}\`].` ); } return { convertBooleans, convertDates, convertNumbers, convertNaN, loggingOnFail, removeEmptyArrays, removeEmptyObjects, removeNulls, removeUndefined, strictMode, customDateFormats, onError, checkSymbols }; }; var cleanParsedData = (data, options = {}) => { const validOptions = validateJsonParsingOptions(options); if (chunkSYHPSOUU_cjs.isNull(data)) return validOptions.removeNulls ? void 0 : null; if (chunkSYHPSOUU_cjs.isUndefined(data)) return validOptions.removeUndefined ? void 0 : void 0; if (chunkSYHPSOUU_cjs.isString(data)) { const trimmed = data.trim(); if (validOptions.convertNaN && trimmed === "NaN") return NaN; if (validOptions.convertNumbers && !isNaN(Number(trimmed))) { return Number(trimmed); } if (validOptions.convertBooleans) { if (trimmed === "true") return true; if (trimmed === "false") return false; } if (validOptions.convertDates) { if (/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$/.test(trimmed)) { return new Date(trimmed); } if (validOptions.customDateFormats?.length) { for (const format of validOptions.customDateFormats) { const date = parseCustomDate(trimmed, format); if (date) return date; } } } return validOptions.strictMode ? void 0 : trimmed; } if (chunkSYHPSOUU_cjs.isArray(data)) { const cleanedArray = data.map((item) => cleanParsedData(item, validOptions)).filter((item) => !chunkSYHPSOUU_cjs.isUndefined(item)); return validOptions.removeEmptyArrays && chunk7FGNVDEV_cjs.isEmptyArray(cleanedArray) ? void 0 : cleanedArray; } if (chunkSYHPSOUU_cjs.isObject(data)) { const cleanedObject = {}; for (const key in data) { if (Object.prototype.hasOwnProperty.call(data, key)) { const cleanedValue = cleanParsedData(data[key], validOptions); if (!chunkSYHPSOUU_cjs.isUndefined(cleanedValue)) { cleanedObject[key] = cleanedValue; } } } return validOptions.removeEmptyObjects && chunk7FGNVDEV_cjs.isEmptyObject(cleanedObject, { checkSymbols: validOptions.checkSymbols }) ? void 0 : cleanedObject; } return validOptions.strictMode ? void 0 : data; }; var extractDigits = (value) => { if (!chunkSYHPSOUU_cjs.isString(value) && !chunkSYHPSOUU_cjs.isNumber(value)) return 0; const cleaned = String(value).trim().replace(/[^0-9]/g, ""); return Number(cleaned) || 0; }; function fixSingleQuotesEscapeBackslash(input) { const validEscapes = /* @__PURE__ */ new Set(["\\", '"', "/", "b", "f", "n", "r", "t", "u"]); let output = ""; let inSingleQuote = false; let inDoubleQuote = false; let escapeNext = false; for (let i = 0; i < input.length; i++) { const c = input[i]; if (escapeNext) { if (inSingleQuote) { if (c === "'") { output += "'"; } else if (validEscapes.has(c)) { if (c === "\\") { output += "\\\\"; } else if (c === '"') { output += '\\"'; } else { output += "\\" + c; } } else { output += "\\\\" + c; } } else if (inDoubleQuote) { if (c === '"') { output += '\\"'; } else if (validEscapes.has(c)) { output += "\\" + c; } else { output += "\\\\" + c; } } else { output += "\\" + c; } escapeNext = false; continue; } if (c === "\\") { escapeNext = true; continue; } if (!inSingleQuote && !inDoubleQuote) { if (c === "'") { output += '"'; inSingleQuote = true; continue; } if (c === '"') { output += '"'; inDoubleQuote = true; continue; } } else if (inSingleQuote) { if (c === "'") { output += '"'; inSingleQuote = false; continue; } } else if (inDoubleQuote) { if (c === '"') { output += '"'; inDoubleQuote = false; continue; } } output += c; } return output; } function safeJsonParse(value, options = {}) { if (chunkSYHPSOUU_cjs.isNull(value)) return null; const validOptions = validateJsonParsingOptions(options); if (validOptions.convertNaN && (chunkSYHPSOUU_cjs.isNaN(value) || chunkSYHPSOUU_cjs.isNonEmptyString(value) && value === "NaN")) { return NaN; } if (validOptions.convertNumbers && !chunkSYHPSOUU_cjs.isNaN(Number(value)) && chunkSYHPSOUU_cjs.isNumber(extractDigits(value))) { return Number(value); } if (!chunkSYHPSOUU_cjs.isString(value)) return void 0; try { let normalized = fixSingleQuotesEscapeBackslash(value); if (validOptions.removeUndefined) { normalized = normalized.replace(/,\s*"[^"]*"\s*:\s*undefined(?=\s*[},])/g, "").replace(/"[^"]*"\s*:\s*undefined\s*(,)?/g, ""); } else { normalized = normalized.replace(/:\s*undefined(?=\s*[,}])/g, ":null"); } if (validOptions.convertNaN) { normalized = normalized.replace(/:\s*NaN(?=\s*[,}])/g, ':"NaN"'); } else { normalized = normalized.replace(/:\s*NaN(?=\s*[,}])/g, ':"NaN"').replace(/,\s*"[^"]*"\s*:\s*NaN(?=\s*[},])/g, "").replace(/"[^"]*"\s*:\s*NaN\s*(,)?/g, ""); } normalized = normalized.replace(/,(\s*[}\]])/g, "$1"); const parsed = JSON.parse(normalized); return cleanParsedData(parsed, validOptions); } catch (error) { if (validOptions.loggingOnFail) { console.error("Failed to parsing at `safeJsonParse`:", error); } validOptions.onError( chunkSYHPSOUU_cjs.isError(error) ? new Error(error.message.replace(/^JSON\.parse:/, "Failed to parsing")) : new Error(String(error)) ); return void 0; } } exports.cleanParsedData = cleanParsedData; exports.extractDigits = extractDigits; exports.parseCustomDate = parseCustomDate; exports.safeJsonParse = safeJsonParse;