UNPKG

@daitanjs/manipulation

Version:
364 lines (358 loc) 13.2 kB
var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // src/manipulation/src/index.js var src_exports = {}; __export(src_exports, { addEscapes: () => addEscapes, cleanJSONString: () => cleanJSONString, convertUSDateToUKDate: () => convertUSDateToUKDate, deepCleanJSON: () => deepCleanJSON, escapeObjectStrings: () => escapeObjectStrings, isAlpha: () => isAlpha, isAlphanumeric: () => isAlphanumeric, isNumeric: () => isNumeric, reverseString: () => reverseString, safeParseJSON: () => safeParseJSON, toTitleCase: () => toTitleCase, truncate: () => truncate, validateJSON: () => validateJSON }); module.exports = __toCommonJS(src_exports); var import_development4 = require("@daitanjs/development"); // src/manipulation/src/dates.js var import_development = require("@daitanjs/development"); var import_error = require("@daitanjs/error"); var logger = (0, import_development.getLogger)("daitan-manipulation-dates"); function convertUSDateToUKDate(usDate) { const callId = `usToUkDate-${Date.now().toString(36)}`; logger.debug( `[${callId}] convertUSDateToUKDate: Attempting to convert date "${usDate}".` ); if (typeof usDate !== "string" || !usDate.trim()) { const errMsg = "Input date string cannot be empty."; logger.error(`[${callId}] ${errMsg}`, { input: usDate }); throw new import_error.DaitanInvalidInputError(errMsg, { inputDate: usDate }); } const parts = usDate.trim().split("/"); if (parts.length !== 3) { const errMsg = `Invalid US date format: "${usDate}". Expected MM/DD/YYYY.`; logger.error(`[${callId}] ${errMsg}`); throw new import_error.DaitanInvalidInputError(errMsg, { inputDate: usDate }); } const [monthStr, dayStr, yearStr] = parts; if (monthStr.length < 1 || monthStr.length > 2 || dayStr.length < 1 || dayStr.length > 2 || yearStr.length !== 4) { const errMsg = `Invalid US date component lengths in "${usDate}". Ensure MM (1-2 digits), DD (1-2 digits), YYYY (4 digits).`; logger.error(`[${callId}] ${errMsg}`); throw new import_error.DaitanInvalidInputError(errMsg, { inputDate: usDate, parsedParts: { monthStr, dayStr, yearStr } }); } const monthNum = parseInt(monthStr, 10); const dayNum = parseInt(dayStr, 10); const yearNum = parseInt(yearStr, 10); if (isNaN(monthNum) || isNaN(dayNum) || isNaN(yearNum)) { const errMsg = `Invalid numeric components in US date "${usDate}". Ensure MM, DD, YYYY are numbers.`; logger.error(`[${callId}] ${errMsg}`); throw new import_error.DaitanInvalidInputError(errMsg, { inputDate: usDate, parsedParts: { monthStr, dayStr, yearStr } }); } if (monthNum < 1 || monthNum > 12 || dayNum < 1 || dayNum > 31) { const errMsg = `Month or day out of valid range in US date "${usDate}". Month: ${monthNum}, Day: ${dayNum}.`; logger.error(`[${callId}] ${errMsg}`); throw new import_error.DaitanInvalidInputError(errMsg, { inputDate: usDate, month: monthNum, day: dayNum }); } const testDate = new Date(yearNum, monthNum - 1, dayNum); if (testDate.getFullYear() !== yearNum || testDate.getMonth() !== monthNum - 1 || testDate.getDate() !== dayNum) { const errMsg = `The date "${usDate}" is not a valid calendar date (e.g., Feb 30).`; logger.error(`[${callId}] ${errMsg}`); throw new import_error.DaitanInvalidInputError(errMsg, { inputDate: usDate }); } const ukDay = dayStr.padStart(2, "0"); const ukMonth = monthStr.padStart(2, "0"); const ukDate = `${ukDay}/${ukMonth}/${yearStr}`; logger.info( `[${callId}] Successfully converted "${usDate}" (US) to "${ukDate}" (UK).` ); return ukDate; } // src/manipulation/src/json.js var import_development2 = require("@daitanjs/development"); var import_error2 = require("@daitanjs/error"); var logger2 = (0, import_development2.getLogger)("daitan-manipulation-json"); function generateJSONErrorDetails(error, jsonString) { const positionMatch = error.message.match(/position (\d+)/i); let enhancedError = `JSON Error: ${error.message}`; if (positionMatch && positionMatch[1]) { const position = parseInt(positionMatch[1], 10); if (!isNaN(position)) { const contextChars = 25; const start = Math.max(0, position - contextChars); const end = Math.min(jsonString.length, position + 1 + contextChars); let nearText = jsonString.substring(start, end); nearText = nearText.replace(/\n/g, "\\n").replace(/\r/g, "\\r"); const pointerOffset = position - start; const pointerLine = " ".repeat(pointerOffset) + "^"; enhancedError += ` Context: "${nearText}" ${pointerLine}`; } } return enhancedError; } function cleanJSONString(input) { if (typeof input !== "string" || !input.trim()) { if (typeof input === "string" && input.length > 0 && !input.trim()) { logger2.debug( "cleanJSONString: Input string is whitespace only. Returning empty string." ); return ""; } logger2.debug( "cleanJSONString: Input is not a string or is effectively empty. Returning as is.", { inputType: typeof input } ); return input; } let cleaned = input; const originalLength = cleaned.length; const firstBracket = cleaned.indexOf("{"); const firstSquareBracket = cleaned.indexOf("["); let startIndex = -1; if (firstBracket !== -1 && firstSquareBracket !== -1) { startIndex = Math.min(firstBracket, firstSquareBracket); } else { startIndex = Math.max(firstBracket, firstSquareBracket); } if (startIndex !== -1) { const lastBracket = cleaned.lastIndexOf("}"); const lastSquareBracket = cleaned.lastIndexOf("]"); const endIndex = Math.max(lastBracket, lastSquareBracket); if (endIndex > startIndex) { cleaned = cleaned.substring(startIndex, endIndex + 1); } } cleaned = cleaned.replace(/[\u200B-\u200D\uFEFF]/g, ""); cleaned = cleaned.replace(/\/\/[^\n]*\n?/g, ""); cleaned = cleaned.replace(/,\s*([}\]])/g, "$1"); cleaned = cleaned.trim(); if (cleaned.length !== originalLength && logger2.isLevelEnabled("debug")) { logger2.debug( "cleanJSONString: String was modified by cleaning heuristics.", { originalLength, cleanedLength: cleaned.length, originalPreview: input.substring(0, 100) + (input.length > 100 ? "..." : ""), cleanedPreview: cleaned.substring(0, 100) + (cleaned.length > 100 ? "..." : "") } ); } return cleaned; } function deepCleanJSON(data) { if (typeof data === "string") { return cleanJSONString(data); } else if (Array.isArray(data)) { return data.map((item) => deepCleanJSON(item)); } else if (data && typeof data === "object") { const cleanedObject = {}; for (const [key, value] of Object.entries(data)) { cleanedObject[key] = deepCleanJSON(value); } return cleanedObject; } else if (data === null || typeof data === "number" || typeof data === "boolean" || data === void 0) { return data; } logger2.warn( `deepCleanJSON: Unsupported data type encountered: ${typeof data}. Returning as is.` ); return data; } function safeParseJSON(jsonString, options = {}) { const { attemptClean = true } = options; if (typeof jsonString !== "string") { const errMsg = "Input to safeParseJSON must be a string."; logger2.error(errMsg, { inputType: typeof jsonString }); throw new import_error2.DaitanInvalidInputError(errMsg, { input: jsonString }); } let stringToParse = attemptClean ? cleanJSONString(jsonString) : jsonString; try { return JSON.parse(stringToParse); } catch (error) { const detailedMessage = generateJSONErrorDetails(error, stringToParse); logger2.error( `safeParseJSON: Failed to parse JSON string. ${detailedMessage}` ); throw new import_error2.DaitanOperationError( `JSON parsing failed: ${error.message}`, { inputStringPreview: stringToParse.substring(0, 200) + (stringToParse.length > 200 ? "..." : ""), attemptedClean }, error ); } } function validateJSON(jsonString, options = {}) { const { attemptClean = true } = options; if (typeof jsonString !== "string") { return { isValid: false, parsedJson: null, error: "Input must be a string to validate as JSON." }; } if (!jsonString.trim()) { return { isValid: false, parsedJson: null, error: "Input JSON string is empty or contains only whitespace." }; } const stringToValidate = attemptClean ? cleanJSONString(jsonString) : jsonString; try { const parsed = JSON.parse(stringToValidate); return { isValid: true, parsedJson: parsed, error: null }; } catch (e) { return { isValid: false, parsedJson: null, error: generateJSONErrorDetails(e, stringToValidate) }; } } // src/manipulation/src/strings.js var import_development3 = require("@daitanjs/development"); var import_error3 = require("@daitanjs/error"); var logger3 = (0, import_development3.getLogger)("daitan-manipulation-strings"); var addEscapes = (str) => { if (typeof str !== "string") { throw new import_error3.DaitanInvalidInputError("Input to addEscapes must be a string."); } return str.replace(/\\/g, "\\\\").replace(/"/g, '\\"').replace(/\n/g, "\\n").replace(/\r/g, "\\r").replace(/\t/g, "\\t").replace(/\f/g, "\\f").replace(/\b/g, "\\b"); }; var escapeObjectStrings = (data) => { if (typeof data === "string") { return addEscapes(data); } else if (Array.isArray(data)) { return data.map((item) => escapeObjectStrings(item)); } else if (data && typeof data === "object") { const escapedObject = {}; for (const key in data) { if (Object.prototype.hasOwnProperty.call(data, key)) { escapedObject[key] = escapeObjectStrings(data[key]); } } return escapedObject; } return data; }; var truncate = (str, maxLength = 100, ellipsis = "...") => { if (typeof str !== "string") { throw new import_error3.DaitanInvalidInputError( "Input `str` to truncate must be a string." ); } if (typeof maxLength !== "number" || isNaN(maxLength) || maxLength <= 0) { throw new import_error3.DaitanInvalidInputError( "maxLength for truncate must be a positive number." ); } if (typeof ellipsis !== "string") { throw new import_error3.DaitanInvalidInputError( "ellipsis for truncate must be a string." ); } if (str.length <= maxLength) { return str; } if (maxLength <= ellipsis.length) { return ellipsis.substring(0, maxLength); } return str.substring(0, maxLength - ellipsis.length) + ellipsis; }; var toTitleCase = (str) => { if (typeof str !== "string") { throw new import_error3.DaitanInvalidInputError( "Input `str` to toTitleCase must be a string." ); } if (!str.trim()) return ""; return str.toLowerCase().replace(/\b\w/g, (char) => char.toUpperCase()); }; var isAlpha = (str) => { if (typeof str !== "string") { throw new import_error3.DaitanInvalidInputError( "Input `str` to isAlpha must be a string." ); } return /^[a-zA-Z]+$/.test(str); }; var isAlphanumeric = (str) => { if (typeof str !== "string") { throw new import_error3.DaitanInvalidInputError( "Input `str` to isAlphanumeric must be a string." ); } return /^[a-zA-Z0-9]+$/.test(str); }; var isNumeric = (str) => { if (typeof str !== "string") { throw new import_error3.DaitanInvalidInputError( "Input `str` to isNumeric must be a string." ); } return /^[0-9]+$/.test(str); }; var reverseString = (str) => { if (typeof str !== "string") { throw new import_error3.DaitanInvalidInputError( "Input `str` to reverseString must be a string." ); } return str.split("").reverse().join(""); }; // src/manipulation/src/index.js var manipulationIndexLogger = (0, import_development4.getLogger)("daitan-manipulation-index"); manipulationIndexLogger.debug("Exporting DaitanJS Manipulation utilities..."); manipulationIndexLogger.info( "DaitanJS Manipulation module exports configured and ready." ); // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { addEscapes, cleanJSONString, convertUSDateToUKDate, deepCleanJSON, escapeObjectStrings, isAlpha, isAlphanumeric, isNumeric, reverseString, safeParseJSON, toTitleCase, truncate, validateJSON }); //# sourceMappingURL=index.cjs.map