@lichens-innovation/ts-common 1.12.0 → 1.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -7
- package/dist/index.cjs +9 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +9 -3
- package/dist/index.js.map +1 -1
- package/dist/logger.cjs +2 -2
- package/dist/logger.cjs.map +1 -1
- package/dist/logger.js +2 -2
- package/dist/logger.js.map +1 -1
- package/dist/web.cjs +2 -2
- package/dist/web.cjs.map +1 -1
- package/dist/web.js +2 -2
- package/dist/web.js.map +1 -1
- package/package.json +6 -2
package/README.md
CHANGED
|
@@ -51,13 +51,16 @@ Table of content
|
|
|
51
51
|
|
|
52
52
|
| Command | Description |
|
|
53
53
|
|------------------------------|-----------------------------------------------------------------------------|
|
|
54
|
-
| `yarn
|
|
55
|
-
| `yarn
|
|
56
|
-
| `yarn clean:
|
|
57
|
-
| `yarn
|
|
58
|
-
| `yarn
|
|
59
|
-
| `yarn
|
|
60
|
-
| `yarn
|
|
54
|
+
| `yarn prepare` | Configures Husky (Git hooks). Runs automatically after `yarn install`. |
|
|
55
|
+
| `yarn build` | Compiles the project with tsup (outputs to `dist/`). |
|
|
56
|
+
| `yarn clean:node` | Removes `node_modules` and `yarn.lock`. |
|
|
57
|
+
| `yarn clean:dist` | Removes the `dist` directory. |
|
|
58
|
+
| `yarn typecheck` | Type-checks TypeScript without emitting files (`tsc --noEmit`). |
|
|
59
|
+
| `yarn lint` | Runs ESLint on the project. |
|
|
60
|
+
| `yarn lint:fix` | Runs ESLint and applies automatic fixes. |
|
|
61
|
+
| `yarn test` | Runs tests with Vitest and coverage report. |
|
|
62
|
+
| `yarn test:watch` | Runs tests in watch mode with Vitest. |
|
|
63
|
+
| `yarn test:coverage` | Runs tests with coverage report using Vitest. |
|
|
61
64
|
|
|
62
65
|
## Optional modules
|
|
63
66
|
|
package/dist/index.cjs
CHANGED
|
@@ -139,8 +139,8 @@ var getColorForPercentage = (percent) => {
|
|
|
139
139
|
if (percent < 0 || percent > 1) {
|
|
140
140
|
throw new Error(`Percentage must be between 0 and 1: ${percent}`);
|
|
141
141
|
}
|
|
142
|
-
let i =
|
|
143
|
-
for (
|
|
142
|
+
let i = 1;
|
|
143
|
+
for (; i < PERCENT_COLORS.length - 1; i++) {
|
|
144
144
|
if (percent < PERCENT_COLORS[i].pct) {
|
|
145
145
|
break;
|
|
146
146
|
}
|
|
@@ -210,6 +210,12 @@ var getErrorMessage = (error) => {
|
|
|
210
210
|
}
|
|
211
211
|
return JSON.stringify(error);
|
|
212
212
|
};
|
|
213
|
+
var toError = (error) => {
|
|
214
|
+
if (error instanceof Error) {
|
|
215
|
+
return error;
|
|
216
|
+
}
|
|
217
|
+
return new Error(getErrorMessage(error));
|
|
218
|
+
};
|
|
213
219
|
|
|
214
220
|
// src/utils/regex.ts
|
|
215
221
|
var REGEX_ALPHANUMERIC = /^[a-zA-Z0-9-_ $%#(){}:/.]+$/;
|
|
@@ -506,6 +512,7 @@ exports.roundToNiceNumber = roundToNiceNumber;
|
|
|
506
512
|
exports.roundUpToNearest10 = roundUpToNearest10;
|
|
507
513
|
exports.sleep = sleep;
|
|
508
514
|
exports.tickFormatter = tickFormatter;
|
|
515
|
+
exports.toError = toError;
|
|
509
516
|
exports.toFixed = toFixed;
|
|
510
517
|
exports.toFormString = toFormString;
|
|
511
518
|
exports.toFormStringInteger = toFormStringInteger;
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/utils/types.utils.ts","../src/utils/chart.utils.ts","../src/utils/color.utils.ts","../src/utils/date.utils.ts","../src/utils/errors.utils.ts","../src/utils/regex.ts","../src/utils/string.utils.ts","../src/utils/filename.utils.ts","../src/utils/form.utils.ts","../src/utils/http.utils.ts","../src/utils/number.utils.ts","../src/utils/runtime-env.utils.ts","../src/utils/thread.utils.ts","../src/utils/time.utils.ts","../src/utils/units.utils.ts","../src/utils/uri.utils.ts","../src/utils/websocket.utils.ts"],"names":["format"],"mappings":"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","file":"index.cjs","sourcesContent":["export const NO_OP: () => void = () => {};\n\nexport const isNullish = (value: unknown): value is null | undefined => value === null || value === undefined;\n\nexport const isNumber = (value?: unknown | null): value is number => {\n if (isNullish(value)) {\n return false;\n }\n\n if (typeof value !== 'number') {\n return false;\n }\n\n if (isNaN(value)) {\n return false;\n }\n\n return true;\n};\n\nexport const isString = (value?: unknown | null): value is string => {\n if (isNullish(value)) {\n return false;\n }\n\n if (typeof value !== 'string') {\n return false;\n }\n\n return true;\n};\n","import { isNullish } from \"./types.utils\";\n\nexport interface ToleranceArea {\n flow: number;\n toleranceRange: [number, number];\n}\n\n/**\n * A chart point with required x and y coordinates.\n */\nexport interface ChartPoint {\n x: number;\n y: number;\n}\n\n/**\n * A chart point with optional nullable x and y coordinates.\n */\nexport interface NullableChartPoint {\n x?: number | null;\n y?: number | null;\n}\n\nexport const getTickDomain = (ticks: number[]): [number, number] => [0, ticks.at(-1) ?? 0];\n\nexport const tickFormatter = (value: number): string => value.toFixed(0);\n\nexport const toToleranceLabel = (value: number): string => `±${(value * 100).toFixed(0)}%`;\n\nexport const tooltipValueFormatter = (data?: unknown | null): string => {\n if (isNullish(data)) {\n return '';\n }\n\n if (typeof data === 'number') {\n return data.toFixed(2);\n }\n\n if (Array.isArray(data) && data.length >= 2) {\n const [min, max] = data;\n if (typeof min === 'number' && typeof max === 'number') {\n return `[${min.toFixed(2)} … ${max.toFixed(2)}]`;\n }\n }\n\n return String(data ?? '');\n};\n\n/**\n * Rounds a raw value to a \"nice\" number for chart axis increments.\n * Nice numbers are easy to read: 1, 2, 2.5, 5, or 10 multiplied by a power of 10.\n *\n * @param rawValue - The raw value to round to a nice number\n * @returns A nice number close to the raw value\n *\n * @example\n * roundToNiceNumber(0.7) // returns 1\n * roundToNiceNumber(3) // returns 5\n * roundToNiceNumber(17) // returns 20\n * roundToNiceNumber(80) // returns 100\n */\nexport const roundToNiceNumber = (rawValue: number): number => {\n if (rawValue <= 0) return 0;\n\n // Get order of magnitude\n const magnitude = Math.pow(10, Math.floor(Math.log10(rawValue)));\n\n // Normalize to find the multiplier (between 1 and 10)\n const normalized = rawValue / magnitude;\n\n // Round to nice values: 1, 2, 2.5, 5, 10\n let niceMultiplier: number;\n if (normalized <= 1) niceMultiplier = 1;\n else if (normalized <= 2) niceMultiplier = 2;\n else if (normalized <= 2.5) niceMultiplier = 2.5;\n else if (normalized <= 5) niceMultiplier = 5;\n else niceMultiplier = 10;\n\n return niceMultiplier * magnitude;\n};\n\nconst roundToPrecision = (value: number, precision = 10): number => {\n const factor = 10 ** precision;\n return Math.round(value * factor) / factor;\n};\n\n/**\n * Builds an array of \"nice\" tick values for a chart axis.\n * The algorithm aims for approximately `targetTickCount` ticks with clean, readable values.\n *\n * @param max - The maximum value to display on the axis\n * @param targetTickCount - The desired number of ticks (default: 10)\n * @returns An array of tick values from 0 to at least `max`\n */\nexport const buildTicksForChart = (max: number, targetTickCount = 10): number[] => {\n if (max <= 0) return [0];\n\n // Calculate raw increment for desired tick count and round to nice value\n const rawIncrement = max / targetTickCount;\n const niceIncrement = roundToNiceNumber(rawIncrement);\n\n // Build ticks from 0 to just past max\n const ticks: number[] = [];\n for (let value = 0; value <= max + niceIncrement * 0.5; value += niceIncrement) {\n // Round to avoid floating point precision issues\n ticks.push(roundToPrecision(value));\n }\n\n // Ensure we have at least one tick >= max\n const lastTick = ticks[ticks.length - 1];\n if (lastTick < max) {\n ticks.push(roundToPrecision(lastTick + niceIncrement));\n }\n\n return ticks;\n};\n","export interface RgbColor {\n r: number;\n g: number;\n b: number;\n}\n\nexport interface RgbaColor extends RgbColor {\n a: number;\n}\n\nexport const rgbToHex = (r: number, g: number, b: number): string => {\n if (r > 255 || g > 255 || b > 255) {\n throw new Error(\"Invalid color component\");\n }\n\n return ((r << 16) | (g << 8) | b).toString(16).padStart(6, \"0\");\n};\n\nexport const hexToRgb = (hex: string): RgbColor => {\n const cleanHex = hex.replace(\"#\", \"\");\n\n const r = parseInt(cleanHex.substring(0, 2), 16);\n const g = parseInt(cleanHex.substring(2, 4), 16);\n const b = parseInt(cleanHex.substring(4, 6), 16);\n\n return { r, g, b };\n};\n\nexport const rgbaToHex = (color: RgbaColor): string => {\n return \"#\" + rgbToHex(color.r, color.g, color.b);\n};\n\nexport const getOpacityHexValue = (opacity: number): string => {\n if (opacity < 0 || opacity > 1) {\n throw new Error(\"Invalid opacity value\");\n }\n\n return Math.round(opacity * 255)\n .toString(16)\n .padStart(2, \"0\");\n};\n\nexport const rgbaToHexWithAlpha = (color: RgbaColor): string => {\n return rgbaToHex(color) + getOpacityHexValue(color.a);\n};\n\nexport const rgbToString = (color: RgbColor): string => {\n return `rgb(${color.r}, ${color.g}, ${color.b})`;\n};\n\nexport const rgbaToString = (color: RgbaColor): string => {\n return `rgba(${color.r}, ${color.g}, ${color.b}, ${color.a})`;\n};\n\nexport const getLuminance = (r: number, g: number, b: number): number => {\n return (0.299 * r + 0.587 * g + 0.114 * b) / 255;\n};\n\nexport const getContrastTextColor = (hexColor: string): string => {\n const { r, g, b } = hexToRgb(hexColor);\n return getLuminance(r, g, b) > 0.5 ? \"#000000\" : \"#ffffff\";\n};\n\n/**\n * Normalized RGB color with values between 0 and 1.\n * Useful for graphics libraries like Three.js.\n */\nexport interface NormalizedRgb {\n r: number;\n g: number;\n b: number;\n}\n\n/**\n * Convert a hex color string to normalized RGB values (0-1 range).\n * @param hex - Hex color string (with or without # prefix)\n * @returns Normalized RGB object with values between 0 and 1\n */\nexport const hexToNormalizedRgb = (hex: string): NormalizedRgb => {\n const result = /^#?([a-f\\d]{2})([a-f\\d]{2})([a-f\\d]{2})$/i.exec(hex);\n return result\n ? {\n r: parseInt(result[1], 16) / 255,\n g: parseInt(result[2], 16) / 255,\n b: parseInt(result[3], 16) / 255,\n }\n : { r: 0, g: 0, b: 0 };\n};\n\n/**\n * Determine if a color is light or dark based on relative luminance.\n * Useful for choosing contrasting text colors.\n * @param hex - Hex color string\n * @returns True if the color is considered light (luminance > 0.5)\n */\nexport const isLightColor = (hex: string): boolean => {\n const rgb = hexToNormalizedRgb(hex);\n // Calculate relative luminance using standard coefficients\n const luminance = 0.299 * rgb.r + 0.587 * rgb.g + 0.114 * rgb.b;\n return luminance > 0.5;\n};\n\nconst PERCENT_COLORS = [\n { pct: 0.0, color: { r: 0xff, g: 0x00, b: 0 } },\n { pct: 0.5, color: { r: 0xff, g: 0xff, b: 0 } },\n { pct: 1.0, color: { r: 0x00, g: 0xff, b: 0 } },\n] as const;\n\n// https://stackoverflow.com/a/7128796/704681\nexport const getColorForPercentage = (percent: number): string => {\n if (percent < 0 || percent > 1) {\n throw new Error(`Percentage must be between 0 and 1: ${percent}`);\n }\n\n let i = 0;\n for (i = 1; i < PERCENT_COLORS.length - 1; i++) {\n if (percent < PERCENT_COLORS[i].pct) {\n break;\n }\n }\n\n const lower = PERCENT_COLORS[i - 1];\n const upper = PERCENT_COLORS[i];\n const range = upper.pct - lower.pct;\n const rangePct = (percent - lower.pct) / range;\n const pctLower = 1 - rangePct;\n const pctUpper = rangePct;\n const color = {\n r: Math.floor(lower.color.r * pctLower + upper.color.r * pctUpper),\n g: Math.floor(lower.color.g * pctLower + upper.color.g * pctUpper),\n b: Math.floor(lower.color.b * pctLower + upper.color.b * pctUpper),\n };\n\n return \"rgb(\" + [color.r, color.g, color.b].join(\",\") + \")\";\n};\n","import { format } from \"date-fns\";\nimport { isNullish } from \"./types.utils\";\n\nexport type DateInput = Date | string | number | null;\n\nexport const dateAs_HHMMSS = (value?: DateInput) => {\n if (isNullish(value)) return \"\";\n return format(value, \"HH:mm:ss\");\n};\n\nexport const dateAs_YYYYMMDD = (value?: DateInput) => {\n if (isNullish(value)) return \"\";\n return format(value, \"yyyy-MM-dd\");\n};\n\nexport const dateAs_YYYYMMDD_HHMMSS = (value?: DateInput) => {\n if (isNullish(value)) return \"\";\n return format(value, \"yyyy-MM-dd HH:mm:ss\");\n};\n\nexport const nowAsTime = () => dateAs_HHMMSS(new Date());\nexport const nowAsDate = () => dateAs_YYYYMMDD(new Date());\nexport const nowAsDateTime = () => dateAs_YYYYMMDD_HHMMSS(new Date());\n\nexport const nowAsDateTimeForFilename = () => {\n return format(new Date(), \"yyyy-MM-dd_HH-mm-ss\");\n};\n\nconst DEFAULT_DATE_FORMAT = \"yyyy-MM-dd HH:mm:ss\";\n\n/**\n * Format a Unix timestamp (seconds since epoch) to a human-readable string.\n * @param timestamp - Unix timestamp in seconds\n * @param dateFormat - Date format string (default: \"yyyy-MM-dd HH:mm:ss\")\n * @returns Formatted date string or \"N/A\" if invalid or zero.\n */\nexport const formatUnixTimestamp = (\n timestamp: number,\n dateFormat: string = DEFAULT_DATE_FORMAT\n): string => {\n if (!timestamp) return \"N/A\";\n try {\n return format(new Date(timestamp * 1000), dateFormat);\n } catch {\n return \"Invalid date\";\n }\n};\n\n/**\n * Get the current Unix timestamp in seconds.\n * @returns Current Unix timestamp\n */\nexport const getCurrentUnixTimestamp = (): number => {\n return Math.floor(Date.now() / 1000);\n};\n\n/**\n * Check if a Unix timestamp has expired (is in the past).\n * @param timestamp - Unix timestamp in seconds\n * @returns True if the timestamp is in the past\n */\nexport const isExpiredTimestamp = (timestamp: number): boolean => {\n const now = getCurrentUnixTimestamp();\n return timestamp < now;\n};\n\n/**\n * Check if a Unix timestamp is active (current or past).\n * @param timestamp - Unix timestamp in seconds\n * @returns True if the timestamp is current or in the past\n */\nexport const isActiveTimestamp = (timestamp: number): boolean => {\n const now = getCurrentUnixTimestamp();\n return timestamp <= now;\n};\n","export const getErrorMessage = (error: unknown): string => {\n if (!error) {\n return \"\";\n }\n\n if (typeof error === \"string\") {\n return error;\n }\n\n if (typeof error === \"object\" && \"message\" in error) {\n return (error as { message: string }).message;\n }\n\n return JSON.stringify(error);\n};\n","export const REGEX_ALPHANUMERIC = /^[a-zA-Z0-9-_ $%#(){}:/.]+$/;\n\nexport const REGEX_IPV4 = /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/;\n","import { REGEX_ALPHANUMERIC } from './regex';\nimport { isNullish } from './types.utils';\n\nexport const isBlank = (str?: string | null): str is null | undefined | '' => {\n return isNullish(str) || str?.trim() === '';\n};\n\nexport const isNotBlank = (str?: string | null): str is string => {\n return !isBlank(str);\n};\n\nexport const isAlphanumeric = (value: string): boolean => {\n return REGEX_ALPHANUMERIC.test(value);\n};\n\n/**\n * Removes diacritical marks (e.g., accents, umlauts) from a string.\n * This method normalizes the input string to its canonical decomposition\n * form (NFD) and removes any combining diacritical marks.\n *\n * @param {string} value - The input string to normalize.\n * @returns {string} - The normalized string with diacritical marks removed.\n *\n * @example\n * const result = removeDiacriticalMarks(\"Ça va très bien, n'est-ce pas?\");\n * console.log(result); // \"Ca va tres bien, n'est-ce pas?\"\n */\nexport const removeDiacriticalMarks = (value: string): string => {\n if (!value) {\n return '';\n }\n\n return value.normalize('NFD').replace(/[\\u0300-\\u036f]/g, '');\n};\n\n/**\n * Capitalize the first letter of a string.\n * @param str - The input string\n * @returns The string with the first character uppercased\n */\nexport const capitalizeFirst = (str: string): string => {\n if (!str) return str;\n return str.charAt(0).toUpperCase() + str.slice(1);\n};\n\n/**\n * Count the number of words in a text string.\n * Words are separated by whitespace.\n * @param text - The text to count words in\n * @returns The number of words found\n */\nexport const countWords = (text: string): number => {\n if (!text || text.trim().length === 0) return 0;\n return text.split(/\\s+/).filter((word) => word.length > 0).length;\n};\n\n/**\n * Truncate a string to a maximum length, adding an ellipsis if truncated.\n * @param str - The string to truncate\n * @param maxLength - Maximum length before truncation\n * @param ellipsis - The ellipsis string to append (default: \"...\")\n * @returns The truncated string\n */\nexport const truncate = (str: string, maxLength: number, ellipsis = \"...\"): string => {\n if (!str || str.length <= maxLength) return str;\n return str.slice(0, maxLength - ellipsis.length) + ellipsis;\n};\n\n/**\n * Parses an optional comma-separated string into a trimmed, non-blank string array.\n */\nexport const parseCommaSeparatedList = (raw?: string | null): string[] => {\n if (isBlank(raw)) {\n return [];\n }\n\n return raw\n .split(\",\")\n .map((s: string) => s.trim())\n .filter(isNotBlank);\n};\n","import { isBlank } from \"./string.utils\";\n\nexport const getFileExtension = (filename?: string | null): string => {\n if (isBlank(filename)) {\n return \"\";\n }\n\n const lastDotIndex = filename.lastIndexOf(\".\");\n if (lastDotIndex <= 0) {\n // No dot (-1), or dot is at start (0)\n // hidden file without extension\n return lastDotIndex === 0 ? filename.slice(1).toLowerCase() : \"\";\n }\n\n return filename.slice(lastDotIndex + 1).toLowerCase();\n};\n","import { isBlank } from \"./string.utils\";\nimport { isNullish } from \"./types.utils\";\n\nexport const parseOptionalFormNumber = (value?: string | null): number | null => {\n if (isBlank(value)) return null;\n\n const n = Number(value);\n return Number.isFinite(n) ? n : null;\n};\n\nexport const toFormString = (n?: number | null): string => {\n if (isNullish(n)) return \"\";\n\n return Number.isFinite(n) ? String(n) : \"\";\n};\n\n/**\n * Converts a number to a form string, rounded to integer.\n * Avoids floating-point display noise (e.g. 3700.0000000000005).\n */\nexport const toFormStringInteger = (n?: number | null): string => {\n if (isNullish(n)) return \"\";\n if (!Number.isFinite(n)) return \"\";\n\n return String(Math.round(n));\n};\n","import { isNullish } from './types.utils';\n\nexport const isHttpSuccessStatus = (status?: number | null): boolean => {\n if (isNullish(status)) {\n return false;\n }\n\n return status >= 200 && status < 300;\n};\n\nexport const isHttpClientErrorStatus = (status?: number | null): boolean => {\n if (isNullish(status)) {\n return false;\n }\n\n return status >= 400 && status < 500;\n};\n\nexport const isHttpServerErrorStatus = (status?: number | null): boolean => {\n if (isNullish(status)) {\n return false;\n }\n\n return status >= 500;\n};\n","import { isBlank } from './string.utils';\nimport { isNullish, isNumber } from \"./types.utils\";\n\n/**\n * Returns true if the input string is a valid number (blank and non-numeric strings are invalid).\n */\nexport const isInputValidNumber = (value: string): boolean => {\n if (isBlank(value)) return false;\n const num = Number(value.trim());\n return Number.isFinite(num);\n};\n\n/**\n * Returns true if the input string is a valid integer (decimals like \"1500.5\" are invalid).\n */\nexport const isInputValidInteger = (value: string): boolean => {\n if (!isInputValidNumber(value)) return false;\n const num = Number(value.trim());\n return Number.isInteger(num);\n};\n\n/**\n * Returns true if the input string is a valid positive integer (decimals like \"1500.5\" are invalid).\n */\nexport const isInputValidPositiveInteger = (value: string): boolean => {\n if (!isInputValidInteger(value)) return false;\n const num = Number(value.trim());\n return num > 0;\n};\n\n/**\n * Returns true if the input string is a valid negative integer (decimals like \"1500.5\" are invalid).\n */\nexport const isInputValidNegativeInteger = (value: string): boolean => {\n if (!isInputValidInteger(value)) return false;\n const num = Number(value.trim());\n return num < 0;\n};\n\n/**\n * Formats a number as an integer display string (removes decimals).\n */\nexport const formatIntegerDisplay = (value?: number | null): string =>\n String(toFixed(value, 0));\n\n// Example: toFixed(3.14159, 3) // 3.142\nexport const toFixed = (value?: number | null, decimals = 0): number => {\n if (isNullish(value)) return 0;\n if (decimals < 0) throw new Error(\"[toFixed] decimals must be >= 0\");\n if (decimals === 0) return Math.round(value);\n\n const multiplier = Math.pow(10, decimals);\n return Math.round(value * multiplier) / multiplier;\n};\n\nexport const roundUpToNearest10 = (value?: number | null): number => {\n if (isNullish(value)) return 0;\n return Math.ceil(value / 10) * 10;\n};\n\nexport const getOrderOfMagnitudeExponent = (n?: number | null): number => {\n if (isNullish(n)) return 0;\n if (!isNumber(n)) return 0;\n\n const absValue = Math.abs(n); \n if (absValue === 0) {\n return 0;\n }\n \n const integerPart = Math.floor(absValue);\n return Math.floor(Math.log10(integerPart));\n}\n","import { isNullish } from \"./types.utils\";\n\n/**\n * Returns true when running in Node.js.\n * Checks for process.versions.node to avoid false positives in Web Workers.\n */\nexport const isRuntimeEnvNodeJs = (): boolean => {\n if (typeof window !== \"undefined\") return false;\n if (typeof process === \"undefined\") return false;\n if (isNullish(process?.versions?.node)) return false;\n\n return true;\n};\n","export const sleep = (milliseconds: number): Promise<void> =>\n new Promise((resolve) => setTimeout(resolve, milliseconds));\n\n/**\n * Yields to the main thread so the UI can process events and repaint.\n * Use during long-running synchronous work (e.g. report generation) to keep the app responsive.\n */\nexport const yieldToMainThread = (): Promise<void> => sleep(0);\n","const ONE_SECOND_IN_MS = 1000;\nconst ONE_MINUTE_IN_MS = 60 * ONE_SECOND_IN_MS;\nconst ONE_HOUR_IN_MS = 60 * ONE_MINUTE_IN_MS;\nconst ONE_DAY_IN_MS = 24 * ONE_HOUR_IN_MS;\n\nexport const PeriodsInMS = {\n oneSecond: ONE_SECOND_IN_MS,\n oneMinute: ONE_MINUTE_IN_MS,\n oneHour: ONE_HOUR_IN_MS,\n oneDay: ONE_DAY_IN_MS,\n} as const;\n","import { isNullish } from \"./types.utils\";\n\n/** m³/s to gallons per minute */\nexport const M3PS_TO_GPM = 15850.3;\n\n/** Pascals to feet of head (1 Pa = 1 N/m²) */\nexport const PA_TO_FT = 0.000334553;\n\n/** Watts to Horsepower */\nexport const W_TO_HP = 0.00134102;\n\n/** meters to inches */\nexport const M_TO_INCHES = 39.3701;\n\n/** Hz to RPM (for synchronous speed) */\nexport const HZ_TO_RPM = 60;\n\nexport const fromM3psToGPM = (value?: number | null): number => {\n if (isNullish(value)) return 0;\n\n return value * M3PS_TO_GPM;\n};\n\nexport const fromPaToFt = (value?: number | null): number => {\n if (isNullish(value)) return 0;\n\n return value * PA_TO_FT;\n};\n\nexport const fromWToHp = (value?: number | null): number => {\n if (isNullish(value)) return 0;\n\n return value * W_TO_HP;\n};\n\nexport const fromMToInches = (value?: number | null): number => {\n if (isNullish(value)) return 0;\n\n return value * M_TO_INCHES;\n};\n\nexport const fromHzToRpm = (value?: number | null): number => {\n if (isNullish(value)) return 0;\n\n return value * HZ_TO_RPM;\n};\n","export const SCHEME_PREFIXES = {\n file: 'file',\n content: 'content',\n http: 'http',\n https: 'https',\n ftp: 'ftp',\n ftps: 'ftps',\n sftp: 'sftp',\n smb: 'smb',\n} as const;\n\nconst SCHEME_PREFIXES_ARRAY = Object.values(SCHEME_PREFIXES);\n\nexport const hasScheme = (uri?: string | null): boolean => {\n if (!uri) {\n return false;\n }\n\n const lowerUri = uri.toLowerCase();\n return SCHEME_PREFIXES_ARRAY.some((prefix) => lowerUri.startsWith(`${prefix}://`));\n};\n\n/**\n * Extracts the base64 data from a data URI string.\n * Data URIs have the format: data:[<mediatype>][;base64],<data>\n * This function extracts everything after the first comma.\n *\n * @param dataUri - The data URI string (e.g., \"data:image/png;base64,iVBORw0KG...\")\n * @returns The base64 data without the data URI prefix, or the original string if no comma is found\n */\nexport const extractBase64FromDataUri = (dataUri: string): string => {\n return dataUri.split(',')[1] ?? dataUri;\n};\n","import { isNullish } from \"./types.utils\";\n\nconst WEBSOCKET_CONNECT_STATES: number[] = [WebSocket.CONNECTING, WebSocket.OPEN] as const;\n\nexport const isWsClosable = (ws?: WebSocket | null): ws is WebSocket => {\n if (isNullish(ws)) return false;\n return WEBSOCKET_CONNECT_STATES.includes(ws.readyState);\n};\n\nexport const isWsOpenOrConnecting = (ws?: WebSocket | null): ws is WebSocket => {\n if (isNullish(ws)) return false;\n return WEBSOCKET_CONNECT_STATES.includes(ws.readyState);\n};\n\nexport const closeWebSocket = (ws?: WebSocket | null) => {\n if (isNullish(ws) || !isWsClosable(ws)) return;\n\n try {\n ws.close();\n } catch {\n // do nothing (best effort to close, ignore unexpected errors)\n }\n};\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/utils/types.utils.ts","../src/utils/chart.utils.ts","../src/utils/color.utils.ts","../src/utils/date.utils.ts","../src/utils/errors.utils.ts","../src/utils/regex.ts","../src/utils/string.utils.ts","../src/utils/filename.utils.ts","../src/utils/form.utils.ts","../src/utils/http.utils.ts","../src/utils/number.utils.ts","../src/utils/runtime-env.utils.ts","../src/utils/thread.utils.ts","../src/utils/time.utils.ts","../src/utils/units.utils.ts","../src/utils/uri.utils.ts","../src/utils/websocket.utils.ts"],"names":["format"],"mappings":"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","file":"index.cjs","sourcesContent":["export const NO_OP: () => void = () => {};\n\nexport const isNullish = (value: unknown): value is null | undefined => value === null || value === undefined;\n\nexport const isNumber = (value?: unknown | null): value is number => {\n if (isNullish(value)) {\n return false;\n }\n\n if (typeof value !== 'number') {\n return false;\n }\n\n if (isNaN(value)) {\n return false;\n }\n\n return true;\n};\n\nexport const isString = (value?: unknown | null): value is string => {\n if (isNullish(value)) {\n return false;\n }\n\n if (typeof value !== 'string') {\n return false;\n }\n\n return true;\n};\n","import { isNullish } from \"./types.utils\";\n\nexport interface ToleranceArea {\n flow: number;\n toleranceRange: [number, number];\n}\n\n/**\n * A chart point with required x and y coordinates.\n */\nexport interface ChartPoint {\n x: number;\n y: number;\n}\n\n/**\n * A chart point with optional nullable x and y coordinates.\n */\nexport interface NullableChartPoint {\n x?: number | null;\n y?: number | null;\n}\n\nexport const getTickDomain = (ticks: number[]): [number, number] => [0, ticks.at(-1) ?? 0];\n\nexport const tickFormatter = (value: number): string => value.toFixed(0);\n\nexport const toToleranceLabel = (value: number): string => `±${(value * 100).toFixed(0)}%`;\n\nexport const tooltipValueFormatter = (data?: unknown | null): string => {\n if (isNullish(data)) {\n return '';\n }\n\n if (typeof data === 'number') {\n return data.toFixed(2);\n }\n\n if (Array.isArray(data) && data.length >= 2) {\n const [min, max] = data;\n if (typeof min === 'number' && typeof max === 'number') {\n return `[${min.toFixed(2)} … ${max.toFixed(2)}]`;\n }\n }\n\n return String(data ?? '');\n};\n\n/**\n * Rounds a raw value to a \"nice\" number for chart axis increments.\n * Nice numbers are easy to read: 1, 2, 2.5, 5, or 10 multiplied by a power of 10.\n *\n * @param rawValue - The raw value to round to a nice number\n * @returns A nice number close to the raw value\n *\n * @example\n * roundToNiceNumber(0.7) // returns 1\n * roundToNiceNumber(3) // returns 5\n * roundToNiceNumber(17) // returns 20\n * roundToNiceNumber(80) // returns 100\n */\nexport const roundToNiceNumber = (rawValue: number): number => {\n if (rawValue <= 0) return 0;\n\n // Get order of magnitude\n const magnitude = Math.pow(10, Math.floor(Math.log10(rawValue)));\n\n // Normalize to find the multiplier (between 1 and 10)\n const normalized = rawValue / magnitude;\n\n // Round to nice values: 1, 2, 2.5, 5, 10\n let niceMultiplier: number;\n if (normalized <= 1) niceMultiplier = 1;\n else if (normalized <= 2) niceMultiplier = 2;\n else if (normalized <= 2.5) niceMultiplier = 2.5;\n else if (normalized <= 5) niceMultiplier = 5;\n else niceMultiplier = 10;\n\n return niceMultiplier * magnitude;\n};\n\nconst roundToPrecision = (value: number, precision = 10): number => {\n const factor = 10 ** precision;\n return Math.round(value * factor) / factor;\n};\n\n/**\n * Builds an array of \"nice\" tick values for a chart axis.\n * The algorithm aims for approximately `targetTickCount` ticks with clean, readable values.\n *\n * @param max - The maximum value to display on the axis\n * @param targetTickCount - The desired number of ticks (default: 10)\n * @returns An array of tick values from 0 to at least `max`\n */\nexport const buildTicksForChart = (max: number, targetTickCount = 10): number[] => {\n if (max <= 0) return [0];\n\n // Calculate raw increment for desired tick count and round to nice value\n const rawIncrement = max / targetTickCount;\n const niceIncrement = roundToNiceNumber(rawIncrement);\n\n // Build ticks from 0 to just past max\n const ticks: number[] = [];\n for (let value = 0; value <= max + niceIncrement * 0.5; value += niceIncrement) {\n // Round to avoid floating point precision issues\n ticks.push(roundToPrecision(value));\n }\n\n // Ensure we have at least one tick >= max\n const lastTick = ticks[ticks.length - 1];\n if (lastTick < max) {\n ticks.push(roundToPrecision(lastTick + niceIncrement));\n }\n\n return ticks;\n};\n","export interface RgbColor {\n r: number;\n g: number;\n b: number;\n}\n\nexport interface RgbaColor extends RgbColor {\n a: number;\n}\n\nexport const rgbToHex = (r: number, g: number, b: number): string => {\n if (r > 255 || g > 255 || b > 255) {\n throw new Error(\"Invalid color component\");\n }\n\n return ((r << 16) | (g << 8) | b).toString(16).padStart(6, \"0\");\n};\n\nexport const hexToRgb = (hex: string): RgbColor => {\n const cleanHex = hex.replace(\"#\", \"\");\n\n const r = parseInt(cleanHex.substring(0, 2), 16);\n const g = parseInt(cleanHex.substring(2, 4), 16);\n const b = parseInt(cleanHex.substring(4, 6), 16);\n\n return { r, g, b };\n};\n\nexport const rgbaToHex = (color: RgbaColor): string => {\n return \"#\" + rgbToHex(color.r, color.g, color.b);\n};\n\nexport const getOpacityHexValue = (opacity: number): string => {\n if (opacity < 0 || opacity > 1) {\n throw new Error(\"Invalid opacity value\");\n }\n\n return Math.round(opacity * 255)\n .toString(16)\n .padStart(2, \"0\");\n};\n\nexport const rgbaToHexWithAlpha = (color: RgbaColor): string => {\n return rgbaToHex(color) + getOpacityHexValue(color.a);\n};\n\nexport const rgbToString = (color: RgbColor): string => {\n return `rgb(${color.r}, ${color.g}, ${color.b})`;\n};\n\nexport const rgbaToString = (color: RgbaColor): string => {\n return `rgba(${color.r}, ${color.g}, ${color.b}, ${color.a})`;\n};\n\nexport const getLuminance = (r: number, g: number, b: number): number => {\n return (0.299 * r + 0.587 * g + 0.114 * b) / 255;\n};\n\nexport const getContrastTextColor = (hexColor: string): string => {\n const { r, g, b } = hexToRgb(hexColor);\n return getLuminance(r, g, b) > 0.5 ? \"#000000\" : \"#ffffff\";\n};\n\n/**\n * Normalized RGB color with values between 0 and 1.\n * Useful for graphics libraries like Three.js.\n */\nexport interface NormalizedRgb {\n r: number;\n g: number;\n b: number;\n}\n\n/**\n * Convert a hex color string to normalized RGB values (0-1 range).\n * @param hex - Hex color string (with or without # prefix)\n * @returns Normalized RGB object with values between 0 and 1\n */\nexport const hexToNormalizedRgb = (hex: string): NormalizedRgb => {\n const result = /^#?([a-f\\d]{2})([a-f\\d]{2})([a-f\\d]{2})$/i.exec(hex);\n return result\n ? {\n r: parseInt(result[1], 16) / 255,\n g: parseInt(result[2], 16) / 255,\n b: parseInt(result[3], 16) / 255,\n }\n : { r: 0, g: 0, b: 0 };\n};\n\n/**\n * Determine if a color is light or dark based on relative luminance.\n * Useful for choosing contrasting text colors.\n * @param hex - Hex color string\n * @returns True if the color is considered light (luminance > 0.5)\n */\nexport const isLightColor = (hex: string): boolean => {\n const rgb = hexToNormalizedRgb(hex);\n // Calculate relative luminance using standard coefficients\n const luminance = 0.299 * rgb.r + 0.587 * rgb.g + 0.114 * rgb.b;\n return luminance > 0.5;\n};\n\nconst PERCENT_COLORS = [\n { pct: 0.0, color: { r: 0xff, g: 0x00, b: 0 } },\n { pct: 0.5, color: { r: 0xff, g: 0xff, b: 0 } },\n { pct: 1.0, color: { r: 0x00, g: 0xff, b: 0 } },\n] as const;\n\n// https://stackoverflow.com/a/7128796/704681\nexport const getColorForPercentage = (percent: number): string => {\n if (percent < 0 || percent > 1) {\n throw new Error(`Percentage must be between 0 and 1: ${percent}`);\n }\n\n let i = 1;\n for (; i < PERCENT_COLORS.length - 1; i++) {\n if (percent < PERCENT_COLORS[i].pct) {\n break;\n }\n }\n\n const lower = PERCENT_COLORS[i - 1];\n const upper = PERCENT_COLORS[i];\n const range = upper.pct - lower.pct;\n const rangePct = (percent - lower.pct) / range;\n const pctLower = 1 - rangePct;\n const pctUpper = rangePct;\n const color = {\n r: Math.floor(lower.color.r * pctLower + upper.color.r * pctUpper),\n g: Math.floor(lower.color.g * pctLower + upper.color.g * pctUpper),\n b: Math.floor(lower.color.b * pctLower + upper.color.b * pctUpper),\n };\n\n return \"rgb(\" + [color.r, color.g, color.b].join(\",\") + \")\";\n};\n","import { format } from \"date-fns\";\nimport { isNullish } from \"./types.utils\";\n\nexport type DateInput = Date | string | number | null;\n\nexport const dateAs_HHMMSS = (value?: DateInput) => {\n if (isNullish(value)) return \"\";\n return format(value, \"HH:mm:ss\");\n};\n\nexport const dateAs_YYYYMMDD = (value?: DateInput) => {\n if (isNullish(value)) return \"\";\n return format(value, \"yyyy-MM-dd\");\n};\n\nexport const dateAs_YYYYMMDD_HHMMSS = (value?: DateInput) => {\n if (isNullish(value)) return \"\";\n return format(value, \"yyyy-MM-dd HH:mm:ss\");\n};\n\nexport const nowAsTime = () => dateAs_HHMMSS(new Date());\nexport const nowAsDate = () => dateAs_YYYYMMDD(new Date());\nexport const nowAsDateTime = () => dateAs_YYYYMMDD_HHMMSS(new Date());\n\nexport const nowAsDateTimeForFilename = () => {\n return format(new Date(), \"yyyy-MM-dd_HH-mm-ss\");\n};\n\nconst DEFAULT_DATE_FORMAT = \"yyyy-MM-dd HH:mm:ss\";\n\n/**\n * Format a Unix timestamp (seconds since epoch) to a human-readable string.\n * @param timestamp - Unix timestamp in seconds\n * @param dateFormat - Date format string (default: \"yyyy-MM-dd HH:mm:ss\")\n * @returns Formatted date string or \"N/A\" if invalid or zero.\n */\nexport const formatUnixTimestamp = (\n timestamp: number,\n dateFormat: string = DEFAULT_DATE_FORMAT\n): string => {\n if (!timestamp) return \"N/A\";\n try {\n return format(new Date(timestamp * 1000), dateFormat);\n } catch {\n return \"Invalid date\";\n }\n};\n\n/**\n * Get the current Unix timestamp in seconds.\n * @returns Current Unix timestamp\n */\nexport const getCurrentUnixTimestamp = (): number => {\n return Math.floor(Date.now() / 1000);\n};\n\n/**\n * Check if a Unix timestamp has expired (is in the past).\n * @param timestamp - Unix timestamp in seconds\n * @returns True if the timestamp is in the past\n */\nexport const isExpiredTimestamp = (timestamp: number): boolean => {\n const now = getCurrentUnixTimestamp();\n return timestamp < now;\n};\n\n/**\n * Check if a Unix timestamp is active (current or past).\n * @param timestamp - Unix timestamp in seconds\n * @returns True if the timestamp is current or in the past\n */\nexport const isActiveTimestamp = (timestamp: number): boolean => {\n const now = getCurrentUnixTimestamp();\n return timestamp <= now;\n};\n","export const getErrorMessage = (error: unknown): string => {\n if (!error) {\n return \"\";\n }\n\n if (typeof error === \"string\") {\n return error;\n }\n\n if (typeof error === \"object\" && \"message\" in error) {\n return (error as { message: string }).message;\n }\n\n return JSON.stringify(error);\n};\n\nexport const toError = (error: unknown): Error => {\n if (error instanceof Error) {\n return error;\n }\n\n return new Error(getErrorMessage(error));\n};\n","export const REGEX_ALPHANUMERIC = /^[a-zA-Z0-9-_ $%#(){}:/.]+$/;\n\nexport const REGEX_IPV4 = /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/;\n","import { REGEX_ALPHANUMERIC } from './regex';\nimport { isNullish } from './types.utils';\n\nexport const isBlank = (str?: string | null): str is null | undefined | '' => {\n return isNullish(str) || str?.trim() === '';\n};\n\nexport const isNotBlank = (str?: string | null): str is string => {\n return !isBlank(str);\n};\n\nexport const isAlphanumeric = (value: string): boolean => {\n return REGEX_ALPHANUMERIC.test(value);\n};\n\n/**\n * Removes diacritical marks (e.g., accents, umlauts) from a string.\n * This method normalizes the input string to its canonical decomposition\n * form (NFD) and removes any combining diacritical marks.\n *\n * @param {string} value - The input string to normalize.\n * @returns {string} - The normalized string with diacritical marks removed.\n *\n * @example\n * const result = removeDiacriticalMarks(\"Ça va très bien, n'est-ce pas?\");\n * console.log(result); // \"Ca va tres bien, n'est-ce pas?\"\n */\nexport const removeDiacriticalMarks = (value: string): string => {\n if (!value) {\n return '';\n }\n\n return value.normalize('NFD').replace(/[\\u0300-\\u036f]/g, '');\n};\n\n/**\n * Capitalize the first letter of a string.\n * @param str - The input string\n * @returns The string with the first character uppercased\n */\nexport const capitalizeFirst = (str: string): string => {\n if (!str) return str;\n return str.charAt(0).toUpperCase() + str.slice(1);\n};\n\n/**\n * Count the number of words in a text string.\n * Words are separated by whitespace.\n * @param text - The text to count words in\n * @returns The number of words found\n */\nexport const countWords = (text: string): number => {\n if (!text || text.trim().length === 0) return 0;\n return text.split(/\\s+/).filter((word) => word.length > 0).length;\n};\n\n/**\n * Truncate a string to a maximum length, adding an ellipsis if truncated.\n * @param str - The string to truncate\n * @param maxLength - Maximum length before truncation\n * @param ellipsis - The ellipsis string to append (default: \"...\")\n * @returns The truncated string\n */\nexport const truncate = (str: string, maxLength: number, ellipsis = \"...\"): string => {\n if (!str || str.length <= maxLength) return str;\n return str.slice(0, maxLength - ellipsis.length) + ellipsis;\n};\n\n/**\n * Parses an optional comma-separated string into a trimmed, non-blank string array.\n */\nexport const parseCommaSeparatedList = (raw?: string | null): string[] => {\n if (isBlank(raw)) {\n return [];\n }\n\n return raw\n .split(\",\")\n .map((s: string) => s.trim())\n .filter(isNotBlank);\n};\n","import { isBlank } from \"./string.utils\";\n\nexport const getFileExtension = (filename?: string | null): string => {\n if (isBlank(filename)) {\n return \"\";\n }\n\n const lastDotIndex = filename.lastIndexOf(\".\");\n if (lastDotIndex <= 0) {\n // No dot (-1), or dot is at start (0)\n // hidden file without extension\n return lastDotIndex === 0 ? filename.slice(1).toLowerCase() : \"\";\n }\n\n return filename.slice(lastDotIndex + 1).toLowerCase();\n};\n","import { isBlank } from \"./string.utils\";\nimport { isNullish } from \"./types.utils\";\n\nexport const parseOptionalFormNumber = (value?: string | null): number | null => {\n if (isBlank(value)) return null;\n\n const n = Number(value);\n return Number.isFinite(n) ? n : null;\n};\n\nexport const toFormString = (n?: number | null): string => {\n if (isNullish(n)) return \"\";\n\n return Number.isFinite(n) ? String(n) : \"\";\n};\n\n/**\n * Converts a number to a form string, rounded to integer.\n * Avoids floating-point display noise (e.g. 3700.0000000000005).\n */\nexport const toFormStringInteger = (n?: number | null): string => {\n if (isNullish(n)) return \"\";\n if (!Number.isFinite(n)) return \"\";\n\n return String(Math.round(n));\n};\n","import { isNullish } from './types.utils';\n\nexport const isHttpSuccessStatus = (status?: number | null): boolean => {\n if (isNullish(status)) {\n return false;\n }\n\n return status >= 200 && status < 300;\n};\n\nexport const isHttpClientErrorStatus = (status?: number | null): boolean => {\n if (isNullish(status)) {\n return false;\n }\n\n return status >= 400 && status < 500;\n};\n\nexport const isHttpServerErrorStatus = (status?: number | null): boolean => {\n if (isNullish(status)) {\n return false;\n }\n\n return status >= 500;\n};\n","import { isBlank } from './string.utils';\nimport { isNullish, isNumber } from \"./types.utils\";\n\n/**\n * Returns true if the input string is a valid number (blank and non-numeric strings are invalid).\n */\nexport const isInputValidNumber = (value: string): boolean => {\n if (isBlank(value)) return false;\n const num = Number(value.trim());\n return Number.isFinite(num);\n};\n\n/**\n * Returns true if the input string is a valid integer (decimals like \"1500.5\" are invalid).\n */\nexport const isInputValidInteger = (value: string): boolean => {\n if (!isInputValidNumber(value)) return false;\n const num = Number(value.trim());\n return Number.isInteger(num);\n};\n\n/**\n * Returns true if the input string is a valid positive integer (decimals like \"1500.5\" are invalid).\n */\nexport const isInputValidPositiveInteger = (value: string): boolean => {\n if (!isInputValidInteger(value)) return false;\n const num = Number(value.trim());\n return num > 0;\n};\n\n/**\n * Returns true if the input string is a valid negative integer (decimals like \"1500.5\" are invalid).\n */\nexport const isInputValidNegativeInteger = (value: string): boolean => {\n if (!isInputValidInteger(value)) return false;\n const num = Number(value.trim());\n return num < 0;\n};\n\n/**\n * Formats a number as an integer display string (removes decimals).\n */\nexport const formatIntegerDisplay = (value?: number | null): string =>\n String(toFixed(value, 0));\n\n// Example: toFixed(3.14159, 3) // 3.142\nexport const toFixed = (value?: number | null, decimals = 0): number => {\n if (isNullish(value)) return 0;\n if (decimals < 0) throw new Error(\"[toFixed] decimals must be >= 0\");\n if (decimals === 0) return Math.round(value);\n\n const multiplier = Math.pow(10, decimals);\n return Math.round(value * multiplier) / multiplier;\n};\n\nexport const roundUpToNearest10 = (value?: number | null): number => {\n if (isNullish(value)) return 0;\n return Math.ceil(value / 10) * 10;\n};\n\nexport const getOrderOfMagnitudeExponent = (n?: number | null): number => {\n if (isNullish(n)) return 0;\n if (!isNumber(n)) return 0;\n\n const absValue = Math.abs(n); \n if (absValue === 0) {\n return 0;\n }\n \n const integerPart = Math.floor(absValue);\n return Math.floor(Math.log10(integerPart));\n}\n","import { isNullish } from \"./types.utils\";\n\n/**\n * Returns true when running in Node.js.\n * Checks for process.versions.node to avoid false positives in Web Workers.\n */\nexport const isRuntimeEnvNodeJs = (): boolean => {\n if (typeof window !== \"undefined\") return false;\n if (typeof process === \"undefined\") return false;\n if (isNullish(process?.versions?.node)) return false;\n\n return true;\n};\n","export const sleep = (milliseconds: number): Promise<void> =>\n new Promise((resolve) => setTimeout(resolve, milliseconds));\n\n/**\n * Yields to the main thread so the UI can process events and repaint.\n * Use during long-running synchronous work (e.g. report generation) to keep the app responsive.\n */\nexport const yieldToMainThread = (): Promise<void> => sleep(0);\n","const ONE_SECOND_IN_MS = 1000;\nconst ONE_MINUTE_IN_MS = 60 * ONE_SECOND_IN_MS;\nconst ONE_HOUR_IN_MS = 60 * ONE_MINUTE_IN_MS;\nconst ONE_DAY_IN_MS = 24 * ONE_HOUR_IN_MS;\n\nexport const PeriodsInMS = {\n oneSecond: ONE_SECOND_IN_MS,\n oneMinute: ONE_MINUTE_IN_MS,\n oneHour: ONE_HOUR_IN_MS,\n oneDay: ONE_DAY_IN_MS,\n} as const;\n","import { isNullish } from \"./types.utils\";\n\n/** m³/s to gallons per minute */\nexport const M3PS_TO_GPM = 15850.3;\n\n/** Pascals to feet of head (1 Pa = 1 N/m²) */\nexport const PA_TO_FT = 0.000334553;\n\n/** Watts to Horsepower */\nexport const W_TO_HP = 0.00134102;\n\n/** meters to inches */\nexport const M_TO_INCHES = 39.3701;\n\n/** Hz to RPM (for synchronous speed) */\nexport const HZ_TO_RPM = 60;\n\nexport const fromM3psToGPM = (value?: number | null): number => {\n if (isNullish(value)) return 0;\n\n return value * M3PS_TO_GPM;\n};\n\nexport const fromPaToFt = (value?: number | null): number => {\n if (isNullish(value)) return 0;\n\n return value * PA_TO_FT;\n};\n\nexport const fromWToHp = (value?: number | null): number => {\n if (isNullish(value)) return 0;\n\n return value * W_TO_HP;\n};\n\nexport const fromMToInches = (value?: number | null): number => {\n if (isNullish(value)) return 0;\n\n return value * M_TO_INCHES;\n};\n\nexport const fromHzToRpm = (value?: number | null): number => {\n if (isNullish(value)) return 0;\n\n return value * HZ_TO_RPM;\n};\n","export const SCHEME_PREFIXES = {\n file: 'file',\n content: 'content',\n http: 'http',\n https: 'https',\n ftp: 'ftp',\n ftps: 'ftps',\n sftp: 'sftp',\n smb: 'smb',\n} as const;\n\nconst SCHEME_PREFIXES_ARRAY = Object.values(SCHEME_PREFIXES);\n\nexport const hasScheme = (uri?: string | null): boolean => {\n if (!uri) {\n return false;\n }\n\n const lowerUri = uri.toLowerCase();\n return SCHEME_PREFIXES_ARRAY.some((prefix) => lowerUri.startsWith(`${prefix}://`));\n};\n\n/**\n * Extracts the base64 data from a data URI string.\n * Data URIs have the format: data:[<mediatype>][;base64],<data>\n * This function extracts everything after the first comma.\n *\n * @param dataUri - The data URI string (e.g., \"data:image/png;base64,iVBORw0KG...\")\n * @returns The base64 data without the data URI prefix, or the original string if no comma is found\n */\nexport const extractBase64FromDataUri = (dataUri: string): string => {\n return dataUri.split(',')[1] ?? dataUri;\n};\n","import { isNullish } from \"./types.utils\";\n\nconst WEBSOCKET_CONNECT_STATES: number[] = [WebSocket.CONNECTING, WebSocket.OPEN] as const;\n\nexport const isWsClosable = (ws?: WebSocket | null): ws is WebSocket => {\n if (isNullish(ws)) return false;\n return WEBSOCKET_CONNECT_STATES.includes(ws.readyState);\n};\n\nexport const isWsOpenOrConnecting = (ws?: WebSocket | null): ws is WebSocket => {\n if (isNullish(ws)) return false;\n return WEBSOCKET_CONNECT_STATES.includes(ws.readyState);\n};\n\nexport const closeWebSocket = (ws?: WebSocket | null) => {\n if (isNullish(ws) || !isWsClosable(ws)) return;\n\n try {\n ws.close();\n } catch {\n // do nothing (best effort to close, ignore unexpected errors)\n }\n};\n"]}
|
package/dist/index.d.cts
CHANGED
|
@@ -121,6 +121,7 @@ declare const isExpiredTimestamp: (timestamp: number) => boolean;
|
|
|
121
121
|
declare const isActiveTimestamp: (timestamp: number) => boolean;
|
|
122
122
|
|
|
123
123
|
declare const getErrorMessage: (error: unknown) => string;
|
|
124
|
+
declare const toError: (error: unknown) => Error;
|
|
124
125
|
|
|
125
126
|
declare const getFileExtension: (filename?: string | null) => string;
|
|
126
127
|
|
|
@@ -271,4 +272,4 @@ declare const isWsClosable: (ws?: WebSocket | null) => ws is WebSocket;
|
|
|
271
272
|
declare const isWsOpenOrConnecting: (ws?: WebSocket | null) => ws is WebSocket;
|
|
272
273
|
declare const closeWebSocket: (ws?: WebSocket | null) => void;
|
|
273
274
|
|
|
274
|
-
export { type ChartPoint, type DateInput, HZ_TO_RPM, M3PS_TO_GPM, M_TO_INCHES, NO_OP, type NormalizedRgb, type NullableChartPoint, PA_TO_FT, PeriodsInMS, REGEX_ALPHANUMERIC, REGEX_IPV4, type RgbColor, type RgbaColor, SCHEME_PREFIXES, type ToleranceArea, W_TO_HP, buildTicksForChart, capitalizeFirst, closeWebSocket, countWords, dateAs_HHMMSS, dateAs_YYYYMMDD, dateAs_YYYYMMDD_HHMMSS, extractBase64FromDataUri, formatIntegerDisplay, formatUnixTimestamp, fromHzToRpm, fromM3psToGPM, fromMToInches, fromPaToFt, fromWToHp, getColorForPercentage, getContrastTextColor, getCurrentUnixTimestamp, getErrorMessage, getFileExtension, getLuminance, getOpacityHexValue, getOrderOfMagnitudeExponent, getTickDomain, hasScheme, hexToNormalizedRgb, hexToRgb, isActiveTimestamp, isAlphanumeric, isBlank, isExpiredTimestamp, isHttpClientErrorStatus, isHttpServerErrorStatus, isHttpSuccessStatus, isInputValidInteger, isInputValidNegativeInteger, isInputValidNumber, isInputValidPositiveInteger, isLightColor, isNotBlank, isNullish, isNumber, isRuntimeEnvNodeJs, isString, isWsClosable, isWsOpenOrConnecting, nowAsDate, nowAsDateTime, nowAsDateTimeForFilename, nowAsTime, parseCommaSeparatedList, parseOptionalFormNumber, removeDiacriticalMarks, rgbToHex, rgbToString, rgbaToHex, rgbaToHexWithAlpha, rgbaToString, roundToNiceNumber, roundUpToNearest10, sleep, tickFormatter, toFixed, toFormString, toFormStringInteger, toToleranceLabel, tooltipValueFormatter, truncate, yieldToMainThread };
|
|
275
|
+
export { type ChartPoint, type DateInput, HZ_TO_RPM, M3PS_TO_GPM, M_TO_INCHES, NO_OP, type NormalizedRgb, type NullableChartPoint, PA_TO_FT, PeriodsInMS, REGEX_ALPHANUMERIC, REGEX_IPV4, type RgbColor, type RgbaColor, SCHEME_PREFIXES, type ToleranceArea, W_TO_HP, buildTicksForChart, capitalizeFirst, closeWebSocket, countWords, dateAs_HHMMSS, dateAs_YYYYMMDD, dateAs_YYYYMMDD_HHMMSS, extractBase64FromDataUri, formatIntegerDisplay, formatUnixTimestamp, fromHzToRpm, fromM3psToGPM, fromMToInches, fromPaToFt, fromWToHp, getColorForPercentage, getContrastTextColor, getCurrentUnixTimestamp, getErrorMessage, getFileExtension, getLuminance, getOpacityHexValue, getOrderOfMagnitudeExponent, getTickDomain, hasScheme, hexToNormalizedRgb, hexToRgb, isActiveTimestamp, isAlphanumeric, isBlank, isExpiredTimestamp, isHttpClientErrorStatus, isHttpServerErrorStatus, isHttpSuccessStatus, isInputValidInteger, isInputValidNegativeInteger, isInputValidNumber, isInputValidPositiveInteger, isLightColor, isNotBlank, isNullish, isNumber, isRuntimeEnvNodeJs, isString, isWsClosable, isWsOpenOrConnecting, nowAsDate, nowAsDateTime, nowAsDateTimeForFilename, nowAsTime, parseCommaSeparatedList, parseOptionalFormNumber, removeDiacriticalMarks, rgbToHex, rgbToString, rgbaToHex, rgbaToHexWithAlpha, rgbaToString, roundToNiceNumber, roundUpToNearest10, sleep, tickFormatter, toError, toFixed, toFormString, toFormStringInteger, toToleranceLabel, tooltipValueFormatter, truncate, yieldToMainThread };
|
package/dist/index.d.ts
CHANGED
|
@@ -121,6 +121,7 @@ declare const isExpiredTimestamp: (timestamp: number) => boolean;
|
|
|
121
121
|
declare const isActiveTimestamp: (timestamp: number) => boolean;
|
|
122
122
|
|
|
123
123
|
declare const getErrorMessage: (error: unknown) => string;
|
|
124
|
+
declare const toError: (error: unknown) => Error;
|
|
124
125
|
|
|
125
126
|
declare const getFileExtension: (filename?: string | null) => string;
|
|
126
127
|
|
|
@@ -271,4 +272,4 @@ declare const isWsClosable: (ws?: WebSocket | null) => ws is WebSocket;
|
|
|
271
272
|
declare const isWsOpenOrConnecting: (ws?: WebSocket | null) => ws is WebSocket;
|
|
272
273
|
declare const closeWebSocket: (ws?: WebSocket | null) => void;
|
|
273
274
|
|
|
274
|
-
export { type ChartPoint, type DateInput, HZ_TO_RPM, M3PS_TO_GPM, M_TO_INCHES, NO_OP, type NormalizedRgb, type NullableChartPoint, PA_TO_FT, PeriodsInMS, REGEX_ALPHANUMERIC, REGEX_IPV4, type RgbColor, type RgbaColor, SCHEME_PREFIXES, type ToleranceArea, W_TO_HP, buildTicksForChart, capitalizeFirst, closeWebSocket, countWords, dateAs_HHMMSS, dateAs_YYYYMMDD, dateAs_YYYYMMDD_HHMMSS, extractBase64FromDataUri, formatIntegerDisplay, formatUnixTimestamp, fromHzToRpm, fromM3psToGPM, fromMToInches, fromPaToFt, fromWToHp, getColorForPercentage, getContrastTextColor, getCurrentUnixTimestamp, getErrorMessage, getFileExtension, getLuminance, getOpacityHexValue, getOrderOfMagnitudeExponent, getTickDomain, hasScheme, hexToNormalizedRgb, hexToRgb, isActiveTimestamp, isAlphanumeric, isBlank, isExpiredTimestamp, isHttpClientErrorStatus, isHttpServerErrorStatus, isHttpSuccessStatus, isInputValidInteger, isInputValidNegativeInteger, isInputValidNumber, isInputValidPositiveInteger, isLightColor, isNotBlank, isNullish, isNumber, isRuntimeEnvNodeJs, isString, isWsClosable, isWsOpenOrConnecting, nowAsDate, nowAsDateTime, nowAsDateTimeForFilename, nowAsTime, parseCommaSeparatedList, parseOptionalFormNumber, removeDiacriticalMarks, rgbToHex, rgbToString, rgbaToHex, rgbaToHexWithAlpha, rgbaToString, roundToNiceNumber, roundUpToNearest10, sleep, tickFormatter, toFixed, toFormString, toFormStringInteger, toToleranceLabel, tooltipValueFormatter, truncate, yieldToMainThread };
|
|
275
|
+
export { type ChartPoint, type DateInput, HZ_TO_RPM, M3PS_TO_GPM, M_TO_INCHES, NO_OP, type NormalizedRgb, type NullableChartPoint, PA_TO_FT, PeriodsInMS, REGEX_ALPHANUMERIC, REGEX_IPV4, type RgbColor, type RgbaColor, SCHEME_PREFIXES, type ToleranceArea, W_TO_HP, buildTicksForChart, capitalizeFirst, closeWebSocket, countWords, dateAs_HHMMSS, dateAs_YYYYMMDD, dateAs_YYYYMMDD_HHMMSS, extractBase64FromDataUri, formatIntegerDisplay, formatUnixTimestamp, fromHzToRpm, fromM3psToGPM, fromMToInches, fromPaToFt, fromWToHp, getColorForPercentage, getContrastTextColor, getCurrentUnixTimestamp, getErrorMessage, getFileExtension, getLuminance, getOpacityHexValue, getOrderOfMagnitudeExponent, getTickDomain, hasScheme, hexToNormalizedRgb, hexToRgb, isActiveTimestamp, isAlphanumeric, isBlank, isExpiredTimestamp, isHttpClientErrorStatus, isHttpServerErrorStatus, isHttpSuccessStatus, isInputValidInteger, isInputValidNegativeInteger, isInputValidNumber, isInputValidPositiveInteger, isLightColor, isNotBlank, isNullish, isNumber, isRuntimeEnvNodeJs, isString, isWsClosable, isWsOpenOrConnecting, nowAsDate, nowAsDateTime, nowAsDateTimeForFilename, nowAsTime, parseCommaSeparatedList, parseOptionalFormNumber, removeDiacriticalMarks, rgbToHex, rgbToString, rgbaToHex, rgbaToHexWithAlpha, rgbaToString, roundToNiceNumber, roundUpToNearest10, sleep, tickFormatter, toError, toFixed, toFormString, toFormStringInteger, toToleranceLabel, tooltipValueFormatter, truncate, yieldToMainThread };
|
package/dist/index.js
CHANGED
|
@@ -137,8 +137,8 @@ var getColorForPercentage = (percent) => {
|
|
|
137
137
|
if (percent < 0 || percent > 1) {
|
|
138
138
|
throw new Error(`Percentage must be between 0 and 1: ${percent}`);
|
|
139
139
|
}
|
|
140
|
-
let i =
|
|
141
|
-
for (
|
|
140
|
+
let i = 1;
|
|
141
|
+
for (; i < PERCENT_COLORS.length - 1; i++) {
|
|
142
142
|
if (percent < PERCENT_COLORS[i].pct) {
|
|
143
143
|
break;
|
|
144
144
|
}
|
|
@@ -208,6 +208,12 @@ var getErrorMessage = (error) => {
|
|
|
208
208
|
}
|
|
209
209
|
return JSON.stringify(error);
|
|
210
210
|
};
|
|
211
|
+
var toError = (error) => {
|
|
212
|
+
if (error instanceof Error) {
|
|
213
|
+
return error;
|
|
214
|
+
}
|
|
215
|
+
return new Error(getErrorMessage(error));
|
|
216
|
+
};
|
|
211
217
|
|
|
212
218
|
// src/utils/regex.ts
|
|
213
219
|
var REGEX_ALPHANUMERIC = /^[a-zA-Z0-9-_ $%#(){}:/.]+$/;
|
|
@@ -432,6 +438,6 @@ var closeWebSocket = (ws) => {
|
|
|
432
438
|
}
|
|
433
439
|
};
|
|
434
440
|
|
|
435
|
-
export { HZ_TO_RPM, M3PS_TO_GPM, M_TO_INCHES, NO_OP, PA_TO_FT, PeriodsInMS, REGEX_ALPHANUMERIC, REGEX_IPV4, SCHEME_PREFIXES, W_TO_HP, buildTicksForChart, capitalizeFirst, closeWebSocket, countWords, dateAs_HHMMSS, dateAs_YYYYMMDD, dateAs_YYYYMMDD_HHMMSS, extractBase64FromDataUri, formatIntegerDisplay, formatUnixTimestamp, fromHzToRpm, fromM3psToGPM, fromMToInches, fromPaToFt, fromWToHp, getColorForPercentage, getContrastTextColor, getCurrentUnixTimestamp, getErrorMessage, getFileExtension, getLuminance, getOpacityHexValue, getOrderOfMagnitudeExponent, getTickDomain, hasScheme, hexToNormalizedRgb, hexToRgb, isActiveTimestamp, isAlphanumeric, isBlank, isExpiredTimestamp, isHttpClientErrorStatus, isHttpServerErrorStatus, isHttpSuccessStatus, isInputValidInteger, isInputValidNegativeInteger, isInputValidNumber, isInputValidPositiveInteger, isLightColor, isNotBlank, isNullish, isNumber, isRuntimeEnvNodeJs, isString, isWsClosable, isWsOpenOrConnecting, nowAsDate, nowAsDateTime, nowAsDateTimeForFilename, nowAsTime, parseCommaSeparatedList, parseOptionalFormNumber, removeDiacriticalMarks, rgbToHex, rgbToString, rgbaToHex, rgbaToHexWithAlpha, rgbaToString, roundToNiceNumber, roundUpToNearest10, sleep, tickFormatter, toFixed, toFormString, toFormStringInteger, toToleranceLabel, tooltipValueFormatter, truncate, yieldToMainThread };
|
|
441
|
+
export { HZ_TO_RPM, M3PS_TO_GPM, M_TO_INCHES, NO_OP, PA_TO_FT, PeriodsInMS, REGEX_ALPHANUMERIC, REGEX_IPV4, SCHEME_PREFIXES, W_TO_HP, buildTicksForChart, capitalizeFirst, closeWebSocket, countWords, dateAs_HHMMSS, dateAs_YYYYMMDD, dateAs_YYYYMMDD_HHMMSS, extractBase64FromDataUri, formatIntegerDisplay, formatUnixTimestamp, fromHzToRpm, fromM3psToGPM, fromMToInches, fromPaToFt, fromWToHp, getColorForPercentage, getContrastTextColor, getCurrentUnixTimestamp, getErrorMessage, getFileExtension, getLuminance, getOpacityHexValue, getOrderOfMagnitudeExponent, getTickDomain, hasScheme, hexToNormalizedRgb, hexToRgb, isActiveTimestamp, isAlphanumeric, isBlank, isExpiredTimestamp, isHttpClientErrorStatus, isHttpServerErrorStatus, isHttpSuccessStatus, isInputValidInteger, isInputValidNegativeInteger, isInputValidNumber, isInputValidPositiveInteger, isLightColor, isNotBlank, isNullish, isNumber, isRuntimeEnvNodeJs, isString, isWsClosable, isWsOpenOrConnecting, nowAsDate, nowAsDateTime, nowAsDateTimeForFilename, nowAsTime, parseCommaSeparatedList, parseOptionalFormNumber, removeDiacriticalMarks, rgbToHex, rgbToString, rgbaToHex, rgbaToHexWithAlpha, rgbaToString, roundToNiceNumber, roundUpToNearest10, sleep, tickFormatter, toError, toFixed, toFormString, toFormStringInteger, toToleranceLabel, tooltipValueFormatter, truncate, yieldToMainThread };
|
|
436
442
|
//# sourceMappingURL=index.js.map
|
|
437
443
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/utils/types.utils.ts","../src/utils/chart.utils.ts","../src/utils/color.utils.ts","../src/utils/date.utils.ts","../src/utils/errors.utils.ts","../src/utils/regex.ts","../src/utils/string.utils.ts","../src/utils/filename.utils.ts","../src/utils/form.utils.ts","../src/utils/http.utils.ts","../src/utils/number.utils.ts","../src/utils/runtime-env.utils.ts","../src/utils/thread.utils.ts","../src/utils/time.utils.ts","../src/utils/units.utils.ts","../src/utils/uri.utils.ts","../src/utils/websocket.utils.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["export const NO_OP: () => void = () => {};\n\nexport const isNullish = (value: unknown): value is null | undefined => value === null || value === undefined;\n\nexport const isNumber = (value?: unknown | null): value is number => {\n if (isNullish(value)) {\n return false;\n }\n\n if (typeof value !== 'number') {\n return false;\n }\n\n if (isNaN(value)) {\n return false;\n }\n\n return true;\n};\n\nexport const isString = (value?: unknown | null): value is string => {\n if (isNullish(value)) {\n return false;\n }\n\n if (typeof value !== 'string') {\n return false;\n }\n\n return true;\n};\n","import { isNullish } from \"./types.utils\";\n\nexport interface ToleranceArea {\n flow: number;\n toleranceRange: [number, number];\n}\n\n/**\n * A chart point with required x and y coordinates.\n */\nexport interface ChartPoint {\n x: number;\n y: number;\n}\n\n/**\n * A chart point with optional nullable x and y coordinates.\n */\nexport interface NullableChartPoint {\n x?: number | null;\n y?: number | null;\n}\n\nexport const getTickDomain = (ticks: number[]): [number, number] => [0, ticks.at(-1) ?? 0];\n\nexport const tickFormatter = (value: number): string => value.toFixed(0);\n\nexport const toToleranceLabel = (value: number): string => `±${(value * 100).toFixed(0)}%`;\n\nexport const tooltipValueFormatter = (data?: unknown | null): string => {\n if (isNullish(data)) {\n return '';\n }\n\n if (typeof data === 'number') {\n return data.toFixed(2);\n }\n\n if (Array.isArray(data) && data.length >= 2) {\n const [min, max] = data;\n if (typeof min === 'number' && typeof max === 'number') {\n return `[${min.toFixed(2)} … ${max.toFixed(2)}]`;\n }\n }\n\n return String(data ?? '');\n};\n\n/**\n * Rounds a raw value to a \"nice\" number for chart axis increments.\n * Nice numbers are easy to read: 1, 2, 2.5, 5, or 10 multiplied by a power of 10.\n *\n * @param rawValue - The raw value to round to a nice number\n * @returns A nice number close to the raw value\n *\n * @example\n * roundToNiceNumber(0.7) // returns 1\n * roundToNiceNumber(3) // returns 5\n * roundToNiceNumber(17) // returns 20\n * roundToNiceNumber(80) // returns 100\n */\nexport const roundToNiceNumber = (rawValue: number): number => {\n if (rawValue <= 0) return 0;\n\n // Get order of magnitude\n const magnitude = Math.pow(10, Math.floor(Math.log10(rawValue)));\n\n // Normalize to find the multiplier (between 1 and 10)\n const normalized = rawValue / magnitude;\n\n // Round to nice values: 1, 2, 2.5, 5, 10\n let niceMultiplier: number;\n if (normalized <= 1) niceMultiplier = 1;\n else if (normalized <= 2) niceMultiplier = 2;\n else if (normalized <= 2.5) niceMultiplier = 2.5;\n else if (normalized <= 5) niceMultiplier = 5;\n else niceMultiplier = 10;\n\n return niceMultiplier * magnitude;\n};\n\nconst roundToPrecision = (value: number, precision = 10): number => {\n const factor = 10 ** precision;\n return Math.round(value * factor) / factor;\n};\n\n/**\n * Builds an array of \"nice\" tick values for a chart axis.\n * The algorithm aims for approximately `targetTickCount` ticks with clean, readable values.\n *\n * @param max - The maximum value to display on the axis\n * @param targetTickCount - The desired number of ticks (default: 10)\n * @returns An array of tick values from 0 to at least `max`\n */\nexport const buildTicksForChart = (max: number, targetTickCount = 10): number[] => {\n if (max <= 0) return [0];\n\n // Calculate raw increment for desired tick count and round to nice value\n const rawIncrement = max / targetTickCount;\n const niceIncrement = roundToNiceNumber(rawIncrement);\n\n // Build ticks from 0 to just past max\n const ticks: number[] = [];\n for (let value = 0; value <= max + niceIncrement * 0.5; value += niceIncrement) {\n // Round to avoid floating point precision issues\n ticks.push(roundToPrecision(value));\n }\n\n // Ensure we have at least one tick >= max\n const lastTick = ticks[ticks.length - 1];\n if (lastTick < max) {\n ticks.push(roundToPrecision(lastTick + niceIncrement));\n }\n\n return ticks;\n};\n","export interface RgbColor {\n r: number;\n g: number;\n b: number;\n}\n\nexport interface RgbaColor extends RgbColor {\n a: number;\n}\n\nexport const rgbToHex = (r: number, g: number, b: number): string => {\n if (r > 255 || g > 255 || b > 255) {\n throw new Error(\"Invalid color component\");\n }\n\n return ((r << 16) | (g << 8) | b).toString(16).padStart(6, \"0\");\n};\n\nexport const hexToRgb = (hex: string): RgbColor => {\n const cleanHex = hex.replace(\"#\", \"\");\n\n const r = parseInt(cleanHex.substring(0, 2), 16);\n const g = parseInt(cleanHex.substring(2, 4), 16);\n const b = parseInt(cleanHex.substring(4, 6), 16);\n\n return { r, g, b };\n};\n\nexport const rgbaToHex = (color: RgbaColor): string => {\n return \"#\" + rgbToHex(color.r, color.g, color.b);\n};\n\nexport const getOpacityHexValue = (opacity: number): string => {\n if (opacity < 0 || opacity > 1) {\n throw new Error(\"Invalid opacity value\");\n }\n\n return Math.round(opacity * 255)\n .toString(16)\n .padStart(2, \"0\");\n};\n\nexport const rgbaToHexWithAlpha = (color: RgbaColor): string => {\n return rgbaToHex(color) + getOpacityHexValue(color.a);\n};\n\nexport const rgbToString = (color: RgbColor): string => {\n return `rgb(${color.r}, ${color.g}, ${color.b})`;\n};\n\nexport const rgbaToString = (color: RgbaColor): string => {\n return `rgba(${color.r}, ${color.g}, ${color.b}, ${color.a})`;\n};\n\nexport const getLuminance = (r: number, g: number, b: number): number => {\n return (0.299 * r + 0.587 * g + 0.114 * b) / 255;\n};\n\nexport const getContrastTextColor = (hexColor: string): string => {\n const { r, g, b } = hexToRgb(hexColor);\n return getLuminance(r, g, b) > 0.5 ? \"#000000\" : \"#ffffff\";\n};\n\n/**\n * Normalized RGB color with values between 0 and 1.\n * Useful for graphics libraries like Three.js.\n */\nexport interface NormalizedRgb {\n r: number;\n g: number;\n b: number;\n}\n\n/**\n * Convert a hex color string to normalized RGB values (0-1 range).\n * @param hex - Hex color string (with or without # prefix)\n * @returns Normalized RGB object with values between 0 and 1\n */\nexport const hexToNormalizedRgb = (hex: string): NormalizedRgb => {\n const result = /^#?([a-f\\d]{2})([a-f\\d]{2})([a-f\\d]{2})$/i.exec(hex);\n return result\n ? {\n r: parseInt(result[1], 16) / 255,\n g: parseInt(result[2], 16) / 255,\n b: parseInt(result[3], 16) / 255,\n }\n : { r: 0, g: 0, b: 0 };\n};\n\n/**\n * Determine if a color is light or dark based on relative luminance.\n * Useful for choosing contrasting text colors.\n * @param hex - Hex color string\n * @returns True if the color is considered light (luminance > 0.5)\n */\nexport const isLightColor = (hex: string): boolean => {\n const rgb = hexToNormalizedRgb(hex);\n // Calculate relative luminance using standard coefficients\n const luminance = 0.299 * rgb.r + 0.587 * rgb.g + 0.114 * rgb.b;\n return luminance > 0.5;\n};\n\nconst PERCENT_COLORS = [\n { pct: 0.0, color: { r: 0xff, g: 0x00, b: 0 } },\n { pct: 0.5, color: { r: 0xff, g: 0xff, b: 0 } },\n { pct: 1.0, color: { r: 0x00, g: 0xff, b: 0 } },\n] as const;\n\n// https://stackoverflow.com/a/7128796/704681\nexport const getColorForPercentage = (percent: number): string => {\n if (percent < 0 || percent > 1) {\n throw new Error(`Percentage must be between 0 and 1: ${percent}`);\n }\n\n let i = 0;\n for (i = 1; i < PERCENT_COLORS.length - 1; i++) {\n if (percent < PERCENT_COLORS[i].pct) {\n break;\n }\n }\n\n const lower = PERCENT_COLORS[i - 1];\n const upper = PERCENT_COLORS[i];\n const range = upper.pct - lower.pct;\n const rangePct = (percent - lower.pct) / range;\n const pctLower = 1 - rangePct;\n const pctUpper = rangePct;\n const color = {\n r: Math.floor(lower.color.r * pctLower + upper.color.r * pctUpper),\n g: Math.floor(lower.color.g * pctLower + upper.color.g * pctUpper),\n b: Math.floor(lower.color.b * pctLower + upper.color.b * pctUpper),\n };\n\n return \"rgb(\" + [color.r, color.g, color.b].join(\",\") + \")\";\n};\n","import { format } from \"date-fns\";\nimport { isNullish } from \"./types.utils\";\n\nexport type DateInput = Date | string | number | null;\n\nexport const dateAs_HHMMSS = (value?: DateInput) => {\n if (isNullish(value)) return \"\";\n return format(value, \"HH:mm:ss\");\n};\n\nexport const dateAs_YYYYMMDD = (value?: DateInput) => {\n if (isNullish(value)) return \"\";\n return format(value, \"yyyy-MM-dd\");\n};\n\nexport const dateAs_YYYYMMDD_HHMMSS = (value?: DateInput) => {\n if (isNullish(value)) return \"\";\n return format(value, \"yyyy-MM-dd HH:mm:ss\");\n};\n\nexport const nowAsTime = () => dateAs_HHMMSS(new Date());\nexport const nowAsDate = () => dateAs_YYYYMMDD(new Date());\nexport const nowAsDateTime = () => dateAs_YYYYMMDD_HHMMSS(new Date());\n\nexport const nowAsDateTimeForFilename = () => {\n return format(new Date(), \"yyyy-MM-dd_HH-mm-ss\");\n};\n\nconst DEFAULT_DATE_FORMAT = \"yyyy-MM-dd HH:mm:ss\";\n\n/**\n * Format a Unix timestamp (seconds since epoch) to a human-readable string.\n * @param timestamp - Unix timestamp in seconds\n * @param dateFormat - Date format string (default: \"yyyy-MM-dd HH:mm:ss\")\n * @returns Formatted date string or \"N/A\" if invalid or zero.\n */\nexport const formatUnixTimestamp = (\n timestamp: number,\n dateFormat: string = DEFAULT_DATE_FORMAT\n): string => {\n if (!timestamp) return \"N/A\";\n try {\n return format(new Date(timestamp * 1000), dateFormat);\n } catch {\n return \"Invalid date\";\n }\n};\n\n/**\n * Get the current Unix timestamp in seconds.\n * @returns Current Unix timestamp\n */\nexport const getCurrentUnixTimestamp = (): number => {\n return Math.floor(Date.now() / 1000);\n};\n\n/**\n * Check if a Unix timestamp has expired (is in the past).\n * @param timestamp - Unix timestamp in seconds\n * @returns True if the timestamp is in the past\n */\nexport const isExpiredTimestamp = (timestamp: number): boolean => {\n const now = getCurrentUnixTimestamp();\n return timestamp < now;\n};\n\n/**\n * Check if a Unix timestamp is active (current or past).\n * @param timestamp - Unix timestamp in seconds\n * @returns True if the timestamp is current or in the past\n */\nexport const isActiveTimestamp = (timestamp: number): boolean => {\n const now = getCurrentUnixTimestamp();\n return timestamp <= now;\n};\n","export const getErrorMessage = (error: unknown): string => {\n if (!error) {\n return \"\";\n }\n\n if (typeof error === \"string\") {\n return error;\n }\n\n if (typeof error === \"object\" && \"message\" in error) {\n return (error as { message: string }).message;\n }\n\n return JSON.stringify(error);\n};\n","export const REGEX_ALPHANUMERIC = /^[a-zA-Z0-9-_ $%#(){}:/.]+$/;\n\nexport const REGEX_IPV4 = /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/;\n","import { REGEX_ALPHANUMERIC } from './regex';\nimport { isNullish } from './types.utils';\n\nexport const isBlank = (str?: string | null): str is null | undefined | '' => {\n return isNullish(str) || str?.trim() === '';\n};\n\nexport const isNotBlank = (str?: string | null): str is string => {\n return !isBlank(str);\n};\n\nexport const isAlphanumeric = (value: string): boolean => {\n return REGEX_ALPHANUMERIC.test(value);\n};\n\n/**\n * Removes diacritical marks (e.g., accents, umlauts) from a string.\n * This method normalizes the input string to its canonical decomposition\n * form (NFD) and removes any combining diacritical marks.\n *\n * @param {string} value - The input string to normalize.\n * @returns {string} - The normalized string with diacritical marks removed.\n *\n * @example\n * const result = removeDiacriticalMarks(\"Ça va très bien, n'est-ce pas?\");\n * console.log(result); // \"Ca va tres bien, n'est-ce pas?\"\n */\nexport const removeDiacriticalMarks = (value: string): string => {\n if (!value) {\n return '';\n }\n\n return value.normalize('NFD').replace(/[\\u0300-\\u036f]/g, '');\n};\n\n/**\n * Capitalize the first letter of a string.\n * @param str - The input string\n * @returns The string with the first character uppercased\n */\nexport const capitalizeFirst = (str: string): string => {\n if (!str) return str;\n return str.charAt(0).toUpperCase() + str.slice(1);\n};\n\n/**\n * Count the number of words in a text string.\n * Words are separated by whitespace.\n * @param text - The text to count words in\n * @returns The number of words found\n */\nexport const countWords = (text: string): number => {\n if (!text || text.trim().length === 0) return 0;\n return text.split(/\\s+/).filter((word) => word.length > 0).length;\n};\n\n/**\n * Truncate a string to a maximum length, adding an ellipsis if truncated.\n * @param str - The string to truncate\n * @param maxLength - Maximum length before truncation\n * @param ellipsis - The ellipsis string to append (default: \"...\")\n * @returns The truncated string\n */\nexport const truncate = (str: string, maxLength: number, ellipsis = \"...\"): string => {\n if (!str || str.length <= maxLength) return str;\n return str.slice(0, maxLength - ellipsis.length) + ellipsis;\n};\n\n/**\n * Parses an optional comma-separated string into a trimmed, non-blank string array.\n */\nexport const parseCommaSeparatedList = (raw?: string | null): string[] => {\n if (isBlank(raw)) {\n return [];\n }\n\n return raw\n .split(\",\")\n .map((s: string) => s.trim())\n .filter(isNotBlank);\n};\n","import { isBlank } from \"./string.utils\";\n\nexport const getFileExtension = (filename?: string | null): string => {\n if (isBlank(filename)) {\n return \"\";\n }\n\n const lastDotIndex = filename.lastIndexOf(\".\");\n if (lastDotIndex <= 0) {\n // No dot (-1), or dot is at start (0)\n // hidden file without extension\n return lastDotIndex === 0 ? filename.slice(1).toLowerCase() : \"\";\n }\n\n return filename.slice(lastDotIndex + 1).toLowerCase();\n};\n","import { isBlank } from \"./string.utils\";\nimport { isNullish } from \"./types.utils\";\n\nexport const parseOptionalFormNumber = (value?: string | null): number | null => {\n if (isBlank(value)) return null;\n\n const n = Number(value);\n return Number.isFinite(n) ? n : null;\n};\n\nexport const toFormString = (n?: number | null): string => {\n if (isNullish(n)) return \"\";\n\n return Number.isFinite(n) ? String(n) : \"\";\n};\n\n/**\n * Converts a number to a form string, rounded to integer.\n * Avoids floating-point display noise (e.g. 3700.0000000000005).\n */\nexport const toFormStringInteger = (n?: number | null): string => {\n if (isNullish(n)) return \"\";\n if (!Number.isFinite(n)) return \"\";\n\n return String(Math.round(n));\n};\n","import { isNullish } from './types.utils';\n\nexport const isHttpSuccessStatus = (status?: number | null): boolean => {\n if (isNullish(status)) {\n return false;\n }\n\n return status >= 200 && status < 300;\n};\n\nexport const isHttpClientErrorStatus = (status?: number | null): boolean => {\n if (isNullish(status)) {\n return false;\n }\n\n return status >= 400 && status < 500;\n};\n\nexport const isHttpServerErrorStatus = (status?: number | null): boolean => {\n if (isNullish(status)) {\n return false;\n }\n\n return status >= 500;\n};\n","import { isBlank } from './string.utils';\nimport { isNullish, isNumber } from \"./types.utils\";\n\n/**\n * Returns true if the input string is a valid number (blank and non-numeric strings are invalid).\n */\nexport const isInputValidNumber = (value: string): boolean => {\n if (isBlank(value)) return false;\n const num = Number(value.trim());\n return Number.isFinite(num);\n};\n\n/**\n * Returns true if the input string is a valid integer (decimals like \"1500.5\" are invalid).\n */\nexport const isInputValidInteger = (value: string): boolean => {\n if (!isInputValidNumber(value)) return false;\n const num = Number(value.trim());\n return Number.isInteger(num);\n};\n\n/**\n * Returns true if the input string is a valid positive integer (decimals like \"1500.5\" are invalid).\n */\nexport const isInputValidPositiveInteger = (value: string): boolean => {\n if (!isInputValidInteger(value)) return false;\n const num = Number(value.trim());\n return num > 0;\n};\n\n/**\n * Returns true if the input string is a valid negative integer (decimals like \"1500.5\" are invalid).\n */\nexport const isInputValidNegativeInteger = (value: string): boolean => {\n if (!isInputValidInteger(value)) return false;\n const num = Number(value.trim());\n return num < 0;\n};\n\n/**\n * Formats a number as an integer display string (removes decimals).\n */\nexport const formatIntegerDisplay = (value?: number | null): string =>\n String(toFixed(value, 0));\n\n// Example: toFixed(3.14159, 3) // 3.142\nexport const toFixed = (value?: number | null, decimals = 0): number => {\n if (isNullish(value)) return 0;\n if (decimals < 0) throw new Error(\"[toFixed] decimals must be >= 0\");\n if (decimals === 0) return Math.round(value);\n\n const multiplier = Math.pow(10, decimals);\n return Math.round(value * multiplier) / multiplier;\n};\n\nexport const roundUpToNearest10 = (value?: number | null): number => {\n if (isNullish(value)) return 0;\n return Math.ceil(value / 10) * 10;\n};\n\nexport const getOrderOfMagnitudeExponent = (n?: number | null): number => {\n if (isNullish(n)) return 0;\n if (!isNumber(n)) return 0;\n\n const absValue = Math.abs(n); \n if (absValue === 0) {\n return 0;\n }\n \n const integerPart = Math.floor(absValue);\n return Math.floor(Math.log10(integerPart));\n}\n","import { isNullish } from \"./types.utils\";\n\n/**\n * Returns true when running in Node.js.\n * Checks for process.versions.node to avoid false positives in Web Workers.\n */\nexport const isRuntimeEnvNodeJs = (): boolean => {\n if (typeof window !== \"undefined\") return false;\n if (typeof process === \"undefined\") return false;\n if (isNullish(process?.versions?.node)) return false;\n\n return true;\n};\n","export const sleep = (milliseconds: number): Promise<void> =>\n new Promise((resolve) => setTimeout(resolve, milliseconds));\n\n/**\n * Yields to the main thread so the UI can process events and repaint.\n * Use during long-running synchronous work (e.g. report generation) to keep the app responsive.\n */\nexport const yieldToMainThread = (): Promise<void> => sleep(0);\n","const ONE_SECOND_IN_MS = 1000;\nconst ONE_MINUTE_IN_MS = 60 * ONE_SECOND_IN_MS;\nconst ONE_HOUR_IN_MS = 60 * ONE_MINUTE_IN_MS;\nconst ONE_DAY_IN_MS = 24 * ONE_HOUR_IN_MS;\n\nexport const PeriodsInMS = {\n oneSecond: ONE_SECOND_IN_MS,\n oneMinute: ONE_MINUTE_IN_MS,\n oneHour: ONE_HOUR_IN_MS,\n oneDay: ONE_DAY_IN_MS,\n} as const;\n","import { isNullish } from \"./types.utils\";\n\n/** m³/s to gallons per minute */\nexport const M3PS_TO_GPM = 15850.3;\n\n/** Pascals to feet of head (1 Pa = 1 N/m²) */\nexport const PA_TO_FT = 0.000334553;\n\n/** Watts to Horsepower */\nexport const W_TO_HP = 0.00134102;\n\n/** meters to inches */\nexport const M_TO_INCHES = 39.3701;\n\n/** Hz to RPM (for synchronous speed) */\nexport const HZ_TO_RPM = 60;\n\nexport const fromM3psToGPM = (value?: number | null): number => {\n if (isNullish(value)) return 0;\n\n return value * M3PS_TO_GPM;\n};\n\nexport const fromPaToFt = (value?: number | null): number => {\n if (isNullish(value)) return 0;\n\n return value * PA_TO_FT;\n};\n\nexport const fromWToHp = (value?: number | null): number => {\n if (isNullish(value)) return 0;\n\n return value * W_TO_HP;\n};\n\nexport const fromMToInches = (value?: number | null): number => {\n if (isNullish(value)) return 0;\n\n return value * M_TO_INCHES;\n};\n\nexport const fromHzToRpm = (value?: number | null): number => {\n if (isNullish(value)) return 0;\n\n return value * HZ_TO_RPM;\n};\n","export const SCHEME_PREFIXES = {\n file: 'file',\n content: 'content',\n http: 'http',\n https: 'https',\n ftp: 'ftp',\n ftps: 'ftps',\n sftp: 'sftp',\n smb: 'smb',\n} as const;\n\nconst SCHEME_PREFIXES_ARRAY = Object.values(SCHEME_PREFIXES);\n\nexport const hasScheme = (uri?: string | null): boolean => {\n if (!uri) {\n return false;\n }\n\n const lowerUri = uri.toLowerCase();\n return SCHEME_PREFIXES_ARRAY.some((prefix) => lowerUri.startsWith(`${prefix}://`));\n};\n\n/**\n * Extracts the base64 data from a data URI string.\n * Data URIs have the format: data:[<mediatype>][;base64],<data>\n * This function extracts everything after the first comma.\n *\n * @param dataUri - The data URI string (e.g., \"data:image/png;base64,iVBORw0KG...\")\n * @returns The base64 data without the data URI prefix, or the original string if no comma is found\n */\nexport const extractBase64FromDataUri = (dataUri: string): string => {\n return dataUri.split(',')[1] ?? dataUri;\n};\n","import { isNullish } from \"./types.utils\";\n\nconst WEBSOCKET_CONNECT_STATES: number[] = [WebSocket.CONNECTING, WebSocket.OPEN] as const;\n\nexport const isWsClosable = (ws?: WebSocket | null): ws is WebSocket => {\n if (isNullish(ws)) return false;\n return WEBSOCKET_CONNECT_STATES.includes(ws.readyState);\n};\n\nexport const isWsOpenOrConnecting = (ws?: WebSocket | null): ws is WebSocket => {\n if (isNullish(ws)) return false;\n return WEBSOCKET_CONNECT_STATES.includes(ws.readyState);\n};\n\nexport const closeWebSocket = (ws?: WebSocket | null) => {\n if (isNullish(ws) || !isWsClosable(ws)) return;\n\n try {\n ws.close();\n } catch {\n // do nothing (best effort to close, ignore unexpected errors)\n }\n};\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/utils/types.utils.ts","../src/utils/chart.utils.ts","../src/utils/color.utils.ts","../src/utils/date.utils.ts","../src/utils/errors.utils.ts","../src/utils/regex.ts","../src/utils/string.utils.ts","../src/utils/filename.utils.ts","../src/utils/form.utils.ts","../src/utils/http.utils.ts","../src/utils/number.utils.ts","../src/utils/runtime-env.utils.ts","../src/utils/thread.utils.ts","../src/utils/time.utils.ts","../src/utils/units.utils.ts","../src/utils/uri.utils.ts","../src/utils/websocket.utils.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["export const NO_OP: () => void = () => {};\n\nexport const isNullish = (value: unknown): value is null | undefined => value === null || value === undefined;\n\nexport const isNumber = (value?: unknown | null): value is number => {\n if (isNullish(value)) {\n return false;\n }\n\n if (typeof value !== 'number') {\n return false;\n }\n\n if (isNaN(value)) {\n return false;\n }\n\n return true;\n};\n\nexport const isString = (value?: unknown | null): value is string => {\n if (isNullish(value)) {\n return false;\n }\n\n if (typeof value !== 'string') {\n return false;\n }\n\n return true;\n};\n","import { isNullish } from \"./types.utils\";\n\nexport interface ToleranceArea {\n flow: number;\n toleranceRange: [number, number];\n}\n\n/**\n * A chart point with required x and y coordinates.\n */\nexport interface ChartPoint {\n x: number;\n y: number;\n}\n\n/**\n * A chart point with optional nullable x and y coordinates.\n */\nexport interface NullableChartPoint {\n x?: number | null;\n y?: number | null;\n}\n\nexport const getTickDomain = (ticks: number[]): [number, number] => [0, ticks.at(-1) ?? 0];\n\nexport const tickFormatter = (value: number): string => value.toFixed(0);\n\nexport const toToleranceLabel = (value: number): string => `±${(value * 100).toFixed(0)}%`;\n\nexport const tooltipValueFormatter = (data?: unknown | null): string => {\n if (isNullish(data)) {\n return '';\n }\n\n if (typeof data === 'number') {\n return data.toFixed(2);\n }\n\n if (Array.isArray(data) && data.length >= 2) {\n const [min, max] = data;\n if (typeof min === 'number' && typeof max === 'number') {\n return `[${min.toFixed(2)} … ${max.toFixed(2)}]`;\n }\n }\n\n return String(data ?? '');\n};\n\n/**\n * Rounds a raw value to a \"nice\" number for chart axis increments.\n * Nice numbers are easy to read: 1, 2, 2.5, 5, or 10 multiplied by a power of 10.\n *\n * @param rawValue - The raw value to round to a nice number\n * @returns A nice number close to the raw value\n *\n * @example\n * roundToNiceNumber(0.7) // returns 1\n * roundToNiceNumber(3) // returns 5\n * roundToNiceNumber(17) // returns 20\n * roundToNiceNumber(80) // returns 100\n */\nexport const roundToNiceNumber = (rawValue: number): number => {\n if (rawValue <= 0) return 0;\n\n // Get order of magnitude\n const magnitude = Math.pow(10, Math.floor(Math.log10(rawValue)));\n\n // Normalize to find the multiplier (between 1 and 10)\n const normalized = rawValue / magnitude;\n\n // Round to nice values: 1, 2, 2.5, 5, 10\n let niceMultiplier: number;\n if (normalized <= 1) niceMultiplier = 1;\n else if (normalized <= 2) niceMultiplier = 2;\n else if (normalized <= 2.5) niceMultiplier = 2.5;\n else if (normalized <= 5) niceMultiplier = 5;\n else niceMultiplier = 10;\n\n return niceMultiplier * magnitude;\n};\n\nconst roundToPrecision = (value: number, precision = 10): number => {\n const factor = 10 ** precision;\n return Math.round(value * factor) / factor;\n};\n\n/**\n * Builds an array of \"nice\" tick values for a chart axis.\n * The algorithm aims for approximately `targetTickCount` ticks with clean, readable values.\n *\n * @param max - The maximum value to display on the axis\n * @param targetTickCount - The desired number of ticks (default: 10)\n * @returns An array of tick values from 0 to at least `max`\n */\nexport const buildTicksForChart = (max: number, targetTickCount = 10): number[] => {\n if (max <= 0) return [0];\n\n // Calculate raw increment for desired tick count and round to nice value\n const rawIncrement = max / targetTickCount;\n const niceIncrement = roundToNiceNumber(rawIncrement);\n\n // Build ticks from 0 to just past max\n const ticks: number[] = [];\n for (let value = 0; value <= max + niceIncrement * 0.5; value += niceIncrement) {\n // Round to avoid floating point precision issues\n ticks.push(roundToPrecision(value));\n }\n\n // Ensure we have at least one tick >= max\n const lastTick = ticks[ticks.length - 1];\n if (lastTick < max) {\n ticks.push(roundToPrecision(lastTick + niceIncrement));\n }\n\n return ticks;\n};\n","export interface RgbColor {\n r: number;\n g: number;\n b: number;\n}\n\nexport interface RgbaColor extends RgbColor {\n a: number;\n}\n\nexport const rgbToHex = (r: number, g: number, b: number): string => {\n if (r > 255 || g > 255 || b > 255) {\n throw new Error(\"Invalid color component\");\n }\n\n return ((r << 16) | (g << 8) | b).toString(16).padStart(6, \"0\");\n};\n\nexport const hexToRgb = (hex: string): RgbColor => {\n const cleanHex = hex.replace(\"#\", \"\");\n\n const r = parseInt(cleanHex.substring(0, 2), 16);\n const g = parseInt(cleanHex.substring(2, 4), 16);\n const b = parseInt(cleanHex.substring(4, 6), 16);\n\n return { r, g, b };\n};\n\nexport const rgbaToHex = (color: RgbaColor): string => {\n return \"#\" + rgbToHex(color.r, color.g, color.b);\n};\n\nexport const getOpacityHexValue = (opacity: number): string => {\n if (opacity < 0 || opacity > 1) {\n throw new Error(\"Invalid opacity value\");\n }\n\n return Math.round(opacity * 255)\n .toString(16)\n .padStart(2, \"0\");\n};\n\nexport const rgbaToHexWithAlpha = (color: RgbaColor): string => {\n return rgbaToHex(color) + getOpacityHexValue(color.a);\n};\n\nexport const rgbToString = (color: RgbColor): string => {\n return `rgb(${color.r}, ${color.g}, ${color.b})`;\n};\n\nexport const rgbaToString = (color: RgbaColor): string => {\n return `rgba(${color.r}, ${color.g}, ${color.b}, ${color.a})`;\n};\n\nexport const getLuminance = (r: number, g: number, b: number): number => {\n return (0.299 * r + 0.587 * g + 0.114 * b) / 255;\n};\n\nexport const getContrastTextColor = (hexColor: string): string => {\n const { r, g, b } = hexToRgb(hexColor);\n return getLuminance(r, g, b) > 0.5 ? \"#000000\" : \"#ffffff\";\n};\n\n/**\n * Normalized RGB color with values between 0 and 1.\n * Useful for graphics libraries like Three.js.\n */\nexport interface NormalizedRgb {\n r: number;\n g: number;\n b: number;\n}\n\n/**\n * Convert a hex color string to normalized RGB values (0-1 range).\n * @param hex - Hex color string (with or without # prefix)\n * @returns Normalized RGB object with values between 0 and 1\n */\nexport const hexToNormalizedRgb = (hex: string): NormalizedRgb => {\n const result = /^#?([a-f\\d]{2})([a-f\\d]{2})([a-f\\d]{2})$/i.exec(hex);\n return result\n ? {\n r: parseInt(result[1], 16) / 255,\n g: parseInt(result[2], 16) / 255,\n b: parseInt(result[3], 16) / 255,\n }\n : { r: 0, g: 0, b: 0 };\n};\n\n/**\n * Determine if a color is light or dark based on relative luminance.\n * Useful for choosing contrasting text colors.\n * @param hex - Hex color string\n * @returns True if the color is considered light (luminance > 0.5)\n */\nexport const isLightColor = (hex: string): boolean => {\n const rgb = hexToNormalizedRgb(hex);\n // Calculate relative luminance using standard coefficients\n const luminance = 0.299 * rgb.r + 0.587 * rgb.g + 0.114 * rgb.b;\n return luminance > 0.5;\n};\n\nconst PERCENT_COLORS = [\n { pct: 0.0, color: { r: 0xff, g: 0x00, b: 0 } },\n { pct: 0.5, color: { r: 0xff, g: 0xff, b: 0 } },\n { pct: 1.0, color: { r: 0x00, g: 0xff, b: 0 } },\n] as const;\n\n// https://stackoverflow.com/a/7128796/704681\nexport const getColorForPercentage = (percent: number): string => {\n if (percent < 0 || percent > 1) {\n throw new Error(`Percentage must be between 0 and 1: ${percent}`);\n }\n\n let i = 1;\n for (; i < PERCENT_COLORS.length - 1; i++) {\n if (percent < PERCENT_COLORS[i].pct) {\n break;\n }\n }\n\n const lower = PERCENT_COLORS[i - 1];\n const upper = PERCENT_COLORS[i];\n const range = upper.pct - lower.pct;\n const rangePct = (percent - lower.pct) / range;\n const pctLower = 1 - rangePct;\n const pctUpper = rangePct;\n const color = {\n r: Math.floor(lower.color.r * pctLower + upper.color.r * pctUpper),\n g: Math.floor(lower.color.g * pctLower + upper.color.g * pctUpper),\n b: Math.floor(lower.color.b * pctLower + upper.color.b * pctUpper),\n };\n\n return \"rgb(\" + [color.r, color.g, color.b].join(\",\") + \")\";\n};\n","import { format } from \"date-fns\";\nimport { isNullish } from \"./types.utils\";\n\nexport type DateInput = Date | string | number | null;\n\nexport const dateAs_HHMMSS = (value?: DateInput) => {\n if (isNullish(value)) return \"\";\n return format(value, \"HH:mm:ss\");\n};\n\nexport const dateAs_YYYYMMDD = (value?: DateInput) => {\n if (isNullish(value)) return \"\";\n return format(value, \"yyyy-MM-dd\");\n};\n\nexport const dateAs_YYYYMMDD_HHMMSS = (value?: DateInput) => {\n if (isNullish(value)) return \"\";\n return format(value, \"yyyy-MM-dd HH:mm:ss\");\n};\n\nexport const nowAsTime = () => dateAs_HHMMSS(new Date());\nexport const nowAsDate = () => dateAs_YYYYMMDD(new Date());\nexport const nowAsDateTime = () => dateAs_YYYYMMDD_HHMMSS(new Date());\n\nexport const nowAsDateTimeForFilename = () => {\n return format(new Date(), \"yyyy-MM-dd_HH-mm-ss\");\n};\n\nconst DEFAULT_DATE_FORMAT = \"yyyy-MM-dd HH:mm:ss\";\n\n/**\n * Format a Unix timestamp (seconds since epoch) to a human-readable string.\n * @param timestamp - Unix timestamp in seconds\n * @param dateFormat - Date format string (default: \"yyyy-MM-dd HH:mm:ss\")\n * @returns Formatted date string or \"N/A\" if invalid or zero.\n */\nexport const formatUnixTimestamp = (\n timestamp: number,\n dateFormat: string = DEFAULT_DATE_FORMAT\n): string => {\n if (!timestamp) return \"N/A\";\n try {\n return format(new Date(timestamp * 1000), dateFormat);\n } catch {\n return \"Invalid date\";\n }\n};\n\n/**\n * Get the current Unix timestamp in seconds.\n * @returns Current Unix timestamp\n */\nexport const getCurrentUnixTimestamp = (): number => {\n return Math.floor(Date.now() / 1000);\n};\n\n/**\n * Check if a Unix timestamp has expired (is in the past).\n * @param timestamp - Unix timestamp in seconds\n * @returns True if the timestamp is in the past\n */\nexport const isExpiredTimestamp = (timestamp: number): boolean => {\n const now = getCurrentUnixTimestamp();\n return timestamp < now;\n};\n\n/**\n * Check if a Unix timestamp is active (current or past).\n * @param timestamp - Unix timestamp in seconds\n * @returns True if the timestamp is current or in the past\n */\nexport const isActiveTimestamp = (timestamp: number): boolean => {\n const now = getCurrentUnixTimestamp();\n return timestamp <= now;\n};\n","export const getErrorMessage = (error: unknown): string => {\n if (!error) {\n return \"\";\n }\n\n if (typeof error === \"string\") {\n return error;\n }\n\n if (typeof error === \"object\" && \"message\" in error) {\n return (error as { message: string }).message;\n }\n\n return JSON.stringify(error);\n};\n\nexport const toError = (error: unknown): Error => {\n if (error instanceof Error) {\n return error;\n }\n\n return new Error(getErrorMessage(error));\n};\n","export const REGEX_ALPHANUMERIC = /^[a-zA-Z0-9-_ $%#(){}:/.]+$/;\n\nexport const REGEX_IPV4 = /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/;\n","import { REGEX_ALPHANUMERIC } from './regex';\nimport { isNullish } from './types.utils';\n\nexport const isBlank = (str?: string | null): str is null | undefined | '' => {\n return isNullish(str) || str?.trim() === '';\n};\n\nexport const isNotBlank = (str?: string | null): str is string => {\n return !isBlank(str);\n};\n\nexport const isAlphanumeric = (value: string): boolean => {\n return REGEX_ALPHANUMERIC.test(value);\n};\n\n/**\n * Removes diacritical marks (e.g., accents, umlauts) from a string.\n * This method normalizes the input string to its canonical decomposition\n * form (NFD) and removes any combining diacritical marks.\n *\n * @param {string} value - The input string to normalize.\n * @returns {string} - The normalized string with diacritical marks removed.\n *\n * @example\n * const result = removeDiacriticalMarks(\"Ça va très bien, n'est-ce pas?\");\n * console.log(result); // \"Ca va tres bien, n'est-ce pas?\"\n */\nexport const removeDiacriticalMarks = (value: string): string => {\n if (!value) {\n return '';\n }\n\n return value.normalize('NFD').replace(/[\\u0300-\\u036f]/g, '');\n};\n\n/**\n * Capitalize the first letter of a string.\n * @param str - The input string\n * @returns The string with the first character uppercased\n */\nexport const capitalizeFirst = (str: string): string => {\n if (!str) return str;\n return str.charAt(0).toUpperCase() + str.slice(1);\n};\n\n/**\n * Count the number of words in a text string.\n * Words are separated by whitespace.\n * @param text - The text to count words in\n * @returns The number of words found\n */\nexport const countWords = (text: string): number => {\n if (!text || text.trim().length === 0) return 0;\n return text.split(/\\s+/).filter((word) => word.length > 0).length;\n};\n\n/**\n * Truncate a string to a maximum length, adding an ellipsis if truncated.\n * @param str - The string to truncate\n * @param maxLength - Maximum length before truncation\n * @param ellipsis - The ellipsis string to append (default: \"...\")\n * @returns The truncated string\n */\nexport const truncate = (str: string, maxLength: number, ellipsis = \"...\"): string => {\n if (!str || str.length <= maxLength) return str;\n return str.slice(0, maxLength - ellipsis.length) + ellipsis;\n};\n\n/**\n * Parses an optional comma-separated string into a trimmed, non-blank string array.\n */\nexport const parseCommaSeparatedList = (raw?: string | null): string[] => {\n if (isBlank(raw)) {\n return [];\n }\n\n return raw\n .split(\",\")\n .map((s: string) => s.trim())\n .filter(isNotBlank);\n};\n","import { isBlank } from \"./string.utils\";\n\nexport const getFileExtension = (filename?: string | null): string => {\n if (isBlank(filename)) {\n return \"\";\n }\n\n const lastDotIndex = filename.lastIndexOf(\".\");\n if (lastDotIndex <= 0) {\n // No dot (-1), or dot is at start (0)\n // hidden file without extension\n return lastDotIndex === 0 ? filename.slice(1).toLowerCase() : \"\";\n }\n\n return filename.slice(lastDotIndex + 1).toLowerCase();\n};\n","import { isBlank } from \"./string.utils\";\nimport { isNullish } from \"./types.utils\";\n\nexport const parseOptionalFormNumber = (value?: string | null): number | null => {\n if (isBlank(value)) return null;\n\n const n = Number(value);\n return Number.isFinite(n) ? n : null;\n};\n\nexport const toFormString = (n?: number | null): string => {\n if (isNullish(n)) return \"\";\n\n return Number.isFinite(n) ? String(n) : \"\";\n};\n\n/**\n * Converts a number to a form string, rounded to integer.\n * Avoids floating-point display noise (e.g. 3700.0000000000005).\n */\nexport const toFormStringInteger = (n?: number | null): string => {\n if (isNullish(n)) return \"\";\n if (!Number.isFinite(n)) return \"\";\n\n return String(Math.round(n));\n};\n","import { isNullish } from './types.utils';\n\nexport const isHttpSuccessStatus = (status?: number | null): boolean => {\n if (isNullish(status)) {\n return false;\n }\n\n return status >= 200 && status < 300;\n};\n\nexport const isHttpClientErrorStatus = (status?: number | null): boolean => {\n if (isNullish(status)) {\n return false;\n }\n\n return status >= 400 && status < 500;\n};\n\nexport const isHttpServerErrorStatus = (status?: number | null): boolean => {\n if (isNullish(status)) {\n return false;\n }\n\n return status >= 500;\n};\n","import { isBlank } from './string.utils';\nimport { isNullish, isNumber } from \"./types.utils\";\n\n/**\n * Returns true if the input string is a valid number (blank and non-numeric strings are invalid).\n */\nexport const isInputValidNumber = (value: string): boolean => {\n if (isBlank(value)) return false;\n const num = Number(value.trim());\n return Number.isFinite(num);\n};\n\n/**\n * Returns true if the input string is a valid integer (decimals like \"1500.5\" are invalid).\n */\nexport const isInputValidInteger = (value: string): boolean => {\n if (!isInputValidNumber(value)) return false;\n const num = Number(value.trim());\n return Number.isInteger(num);\n};\n\n/**\n * Returns true if the input string is a valid positive integer (decimals like \"1500.5\" are invalid).\n */\nexport const isInputValidPositiveInteger = (value: string): boolean => {\n if (!isInputValidInteger(value)) return false;\n const num = Number(value.trim());\n return num > 0;\n};\n\n/**\n * Returns true if the input string is a valid negative integer (decimals like \"1500.5\" are invalid).\n */\nexport const isInputValidNegativeInteger = (value: string): boolean => {\n if (!isInputValidInteger(value)) return false;\n const num = Number(value.trim());\n return num < 0;\n};\n\n/**\n * Formats a number as an integer display string (removes decimals).\n */\nexport const formatIntegerDisplay = (value?: number | null): string =>\n String(toFixed(value, 0));\n\n// Example: toFixed(3.14159, 3) // 3.142\nexport const toFixed = (value?: number | null, decimals = 0): number => {\n if (isNullish(value)) return 0;\n if (decimals < 0) throw new Error(\"[toFixed] decimals must be >= 0\");\n if (decimals === 0) return Math.round(value);\n\n const multiplier = Math.pow(10, decimals);\n return Math.round(value * multiplier) / multiplier;\n};\n\nexport const roundUpToNearest10 = (value?: number | null): number => {\n if (isNullish(value)) return 0;\n return Math.ceil(value / 10) * 10;\n};\n\nexport const getOrderOfMagnitudeExponent = (n?: number | null): number => {\n if (isNullish(n)) return 0;\n if (!isNumber(n)) return 0;\n\n const absValue = Math.abs(n); \n if (absValue === 0) {\n return 0;\n }\n \n const integerPart = Math.floor(absValue);\n return Math.floor(Math.log10(integerPart));\n}\n","import { isNullish } from \"./types.utils\";\n\n/**\n * Returns true when running in Node.js.\n * Checks for process.versions.node to avoid false positives in Web Workers.\n */\nexport const isRuntimeEnvNodeJs = (): boolean => {\n if (typeof window !== \"undefined\") return false;\n if (typeof process === \"undefined\") return false;\n if (isNullish(process?.versions?.node)) return false;\n\n return true;\n};\n","export const sleep = (milliseconds: number): Promise<void> =>\n new Promise((resolve) => setTimeout(resolve, milliseconds));\n\n/**\n * Yields to the main thread so the UI can process events and repaint.\n * Use during long-running synchronous work (e.g. report generation) to keep the app responsive.\n */\nexport const yieldToMainThread = (): Promise<void> => sleep(0);\n","const ONE_SECOND_IN_MS = 1000;\nconst ONE_MINUTE_IN_MS = 60 * ONE_SECOND_IN_MS;\nconst ONE_HOUR_IN_MS = 60 * ONE_MINUTE_IN_MS;\nconst ONE_DAY_IN_MS = 24 * ONE_HOUR_IN_MS;\n\nexport const PeriodsInMS = {\n oneSecond: ONE_SECOND_IN_MS,\n oneMinute: ONE_MINUTE_IN_MS,\n oneHour: ONE_HOUR_IN_MS,\n oneDay: ONE_DAY_IN_MS,\n} as const;\n","import { isNullish } from \"./types.utils\";\n\n/** m³/s to gallons per minute */\nexport const M3PS_TO_GPM = 15850.3;\n\n/** Pascals to feet of head (1 Pa = 1 N/m²) */\nexport const PA_TO_FT = 0.000334553;\n\n/** Watts to Horsepower */\nexport const W_TO_HP = 0.00134102;\n\n/** meters to inches */\nexport const M_TO_INCHES = 39.3701;\n\n/** Hz to RPM (for synchronous speed) */\nexport const HZ_TO_RPM = 60;\n\nexport const fromM3psToGPM = (value?: number | null): number => {\n if (isNullish(value)) return 0;\n\n return value * M3PS_TO_GPM;\n};\n\nexport const fromPaToFt = (value?: number | null): number => {\n if (isNullish(value)) return 0;\n\n return value * PA_TO_FT;\n};\n\nexport const fromWToHp = (value?: number | null): number => {\n if (isNullish(value)) return 0;\n\n return value * W_TO_HP;\n};\n\nexport const fromMToInches = (value?: number | null): number => {\n if (isNullish(value)) return 0;\n\n return value * M_TO_INCHES;\n};\n\nexport const fromHzToRpm = (value?: number | null): number => {\n if (isNullish(value)) return 0;\n\n return value * HZ_TO_RPM;\n};\n","export const SCHEME_PREFIXES = {\n file: 'file',\n content: 'content',\n http: 'http',\n https: 'https',\n ftp: 'ftp',\n ftps: 'ftps',\n sftp: 'sftp',\n smb: 'smb',\n} as const;\n\nconst SCHEME_PREFIXES_ARRAY = Object.values(SCHEME_PREFIXES);\n\nexport const hasScheme = (uri?: string | null): boolean => {\n if (!uri) {\n return false;\n }\n\n const lowerUri = uri.toLowerCase();\n return SCHEME_PREFIXES_ARRAY.some((prefix) => lowerUri.startsWith(`${prefix}://`));\n};\n\n/**\n * Extracts the base64 data from a data URI string.\n * Data URIs have the format: data:[<mediatype>][;base64],<data>\n * This function extracts everything after the first comma.\n *\n * @param dataUri - The data URI string (e.g., \"data:image/png;base64,iVBORw0KG...\")\n * @returns The base64 data without the data URI prefix, or the original string if no comma is found\n */\nexport const extractBase64FromDataUri = (dataUri: string): string => {\n return dataUri.split(',')[1] ?? dataUri;\n};\n","import { isNullish } from \"./types.utils\";\n\nconst WEBSOCKET_CONNECT_STATES: number[] = [WebSocket.CONNECTING, WebSocket.OPEN] as const;\n\nexport const isWsClosable = (ws?: WebSocket | null): ws is WebSocket => {\n if (isNullish(ws)) return false;\n return WEBSOCKET_CONNECT_STATES.includes(ws.readyState);\n};\n\nexport const isWsOpenOrConnecting = (ws?: WebSocket | null): ws is WebSocket => {\n if (isNullish(ws)) return false;\n return WEBSOCKET_CONNECT_STATES.includes(ws.readyState);\n};\n\nexport const closeWebSocket = (ws?: WebSocket | null) => {\n if (isNullish(ws) || !isWsClosable(ws)) return;\n\n try {\n ws.close();\n } catch {\n // do nothing (best effort to close, ignore unexpected errors)\n }\n};\n"]}
|
package/dist/logger.cjs
CHANGED
|
@@ -54,7 +54,7 @@ var buildMainArgs = ({ timestamp, label, color, msg, extraArgs, rest }) => {
|
|
|
54
54
|
const levelPart = ` ${label.toUpperCase()} `;
|
|
55
55
|
const hasRest = Object.keys(rest).length > 0;
|
|
56
56
|
const mainArgs = [`${prefix}%c${levelPart}%c`, color, "color: inherit"];
|
|
57
|
-
if (msg
|
|
57
|
+
if (!isNullish(msg)) mainArgs.push(msg);
|
|
58
58
|
if (extraArgs.length > 0) mainArgs.push(...extraArgs);
|
|
59
59
|
if (hasRest) mainArgs.push(rest);
|
|
60
60
|
return mainArgs;
|
|
@@ -104,7 +104,7 @@ var setLoggerMinimumLevel = (level) => {
|
|
|
104
104
|
pinoLogger.level = level;
|
|
105
105
|
};
|
|
106
106
|
var consoleMethodToPinoMethod = (level) => (message, payload) => {
|
|
107
|
-
if (payload
|
|
107
|
+
if (isNullish(payload)) {
|
|
108
108
|
pinoLogger[level](message);
|
|
109
109
|
} else {
|
|
110
110
|
pinoLogger[level](payload, message);
|
package/dist/logger.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/utils/types.utils.ts","../src/utils/runtime-env.utils.ts","../src/logger/logger.utils.ts"],"names":["pino"],"mappings":";;;;;;;;;;;AAEO,IAAM,SAAA,GAAY,CAAC,KAAA,KAA8C,KAAA,KAAU,QAAQ,KAAA,KAAU,MAAA;;;ACI7F,IAAM,qBAAqB,MAAe;AAC/C,EAAA,IAAI,OAAO,MAAA,KAAW,WAAA,EAAa,OAAO,KAAA;AAC1C,EAAA,IAAI,OAAO,OAAA,KAAY,WAAA,EAAa,OAAO,KAAA;AAC3C,EAAA,IAAI,SAAA,CAAU,OAAA,EAAS,QAAA,EAAU,IAAI,GAAG,OAAO,KAAA;AAE/C,EAAA,OAAO,IAAA;AACT,CAAA;;;
|
|
1
|
+
{"version":3,"sources":["../src/utils/types.utils.ts","../src/utils/runtime-env.utils.ts","../src/logger/logger.utils.ts"],"names":["pino"],"mappings":"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","file":"logger.cjs","sourcesContent":["export const NO_OP: () => void = () => {};\n\nexport const isNullish = (value: unknown): value is null | undefined => value === null || value === undefined;\n\nexport const isNumber = (value?: unknown | null): value is number => {\n if (isNullish(value)) {\n return false;\n }\n\n if (typeof value !== 'number') {\n return false;\n }\n\n if (isNaN(value)) {\n return false;\n }\n\n return true;\n};\n\nexport const isString = (value?: unknown | null): value is string => {\n if (isNullish(value)) {\n return false;\n }\n\n if (typeof value !== 'string') {\n return false;\n }\n\n return true;\n};\n","import { isNullish } from \"./types.utils\";\n\n/**\n * Returns true when running in Node.js.\n * Checks for process.versions.node to avoid false positives in Web Workers.\n */\nexport const isRuntimeEnvNodeJs = (): boolean => {\n if (typeof window !== \"undefined\") return false;\n if (typeof process === \"undefined\") return false;\n if (isNullish(process?.versions?.node)) return false;\n\n return true;\n};\n","import pino from \"pino\";\nimport { isRuntimeEnvNodeJs } from \"../utils/runtime-env.utils\";\nimport { isNullish } from \"../utils/types.utils\";\n\nconst LEVEL_LABELS: Record<number, string> = {\n 10: \"trace\",\n 20: \"debug\",\n 30: \"info\",\n 40: \"warn\",\n 50: \"error\",\n 60: \"fatal\",\n};\n\nconst LEVEL_COLORS: Record<string, string> = {\n trace: \"color: #94a3b8\",\n debug: \"color: #22d3ee\",\n info: \"color: #4ade80\",\n warn: \"color: #fbbf24\",\n error: \"color: #f87171\",\n fatal: \"color: #dc2626; font-weight: bold\",\n};\n\nconst MESSAGE_KEY = \"msg\";\n\ntype LogObject = Record<string, unknown> & { level?: number; time?: string; [MESSAGE_KEY]?: string };\n\nconst getLevelLabel = (levelNum: number): string => LEVEL_LABELS[levelNum] ?? \"info\";\n\nconst getLevelColor = (label: string): string => LEVEL_COLORS[label] ?? LEVEL_COLORS.info;\n\nconst getLogTimestamp = ({ time }: LogObject): string => (typeof time === \"string\" ? time : new Date().toISOString());\n\ntype ConsoleMethod = \"log\" | \"warn\" | \"error\";\nconst getConsoleMethod = (levelNum: number): ConsoleMethod => {\n if (levelNum >= 50) return \"error\";\n if (levelNum >= 40) return \"warn\";\n return \"log\";\n};\n\nconst getRestPayload = (obj: LogObject): Record<string, unknown> =>\n Object.keys(obj)\n .filter((k) => k !== \"level\" && k !== \"time\" && k !== MESSAGE_KEY)\n .reduce<Record<string, unknown>>((acc, k) => {\n acc[k] = obj[k];\n return acc;\n }, {});\n\ntype BuildMainArgsParams = {\n timestamp: string;\n label: string;\n color: string;\n msg: unknown;\n extraArgs: unknown[];\n rest: Record<string, unknown>;\n};\n\nconst buildMainArgs = ({ timestamp, label, color, msg, extraArgs, rest }: BuildMainArgsParams): unknown[] => {\n const prefix = `[${timestamp}]`;\n const levelPart = ` ${label.toUpperCase()} `;\n const hasRest = Object.keys(rest).length > 0;\n const mainArgs: unknown[] = [`${prefix}%c${levelPart}%c`, color, \"color: inherit\"];\n\n if (!isNullish(msg)) mainArgs.push(msg);\n if (extraArgs.length > 0) mainArgs.push(...extraArgs);\n if (hasRest) mainArgs.push(rest);\n\n return mainArgs;\n};\n\nconst baseOptions: pino.LoggerOptions = {\n timestamp: pino.stdTimeFunctions.isoTime,\n messageKey: MESSAGE_KEY,\n};\n\nconst browserOptions: pino.LoggerOptions = {\n ...baseOptions,\n browser: {\n write: (logObj: object, ...args: unknown[]) => {\n const obj = logObj as LogObject;\n const levelNum = obj.level ?? 30;\n const label = getLevelLabel(levelNum);\n const color = getLevelColor(label);\n const timestamp = getLogTimestamp(obj);\n const msg = obj[MESSAGE_KEY];\n const rest = getRestPayload(obj);\n const consoleMethod = getConsoleMethod(levelNum);\n const mainArgs = buildMainArgs({\n timestamp,\n label,\n color,\n msg,\n extraArgs: args,\n rest,\n });\n (console[consoleMethod] as (...a: unknown[]) => void)(...mainArgs);\n },\n },\n};\n\nconst createPinoLogger = (): pino.Logger => {\n if (isRuntimeEnvNodeJs()) {\n try {\n const transport = pino.transport({ target: \"pino-pretty\", options: { colorize: true } });\n return pino(baseOptions, transport);\n } catch (e: unknown) {\n console.warn(\"pino-pretty not installed, using default pino output\", e);\n return pino(baseOptions);\n }\n }\n\n return pino(browserOptions);\n};\n\nconst pinoLogger = createPinoLogger();\n\nexport type Level = \"trace\" | \"debug\" | \"info\" | \"warn\" | \"error\" | \"fatal\";\n\nexport const setLoggerMinimumLevel = (level: Level) => {\n pinoLogger.level = level;\n};\n\nconst consoleMethodToPinoMethod = (level: Level) => (message: string, payload?: Record<string, unknown>) => {\n if (isNullish(payload)) {\n pinoLogger[level](message);\n } else {\n pinoLogger[level](payload, message);\n }\n};\n\nexport const logger = {\n trace: consoleMethodToPinoMethod(\"trace\"),\n debug: consoleMethodToPinoMethod(\"debug\"),\n info: consoleMethodToPinoMethod(\"info\"),\n warn: consoleMethodToPinoMethod(\"warn\"),\n error: consoleMethodToPinoMethod(\"error\"),\n fatal: consoleMethodToPinoMethod(\"fatal\"),\n log: consoleMethodToPinoMethod(\"info\"),\n};\n"]}
|
package/dist/logger.js
CHANGED
|
@@ -48,7 +48,7 @@ var buildMainArgs = ({ timestamp, label, color, msg, extraArgs, rest }) => {
|
|
|
48
48
|
const levelPart = ` ${label.toUpperCase()} `;
|
|
49
49
|
const hasRest = Object.keys(rest).length > 0;
|
|
50
50
|
const mainArgs = [`${prefix}%c${levelPart}%c`, color, "color: inherit"];
|
|
51
|
-
if (msg
|
|
51
|
+
if (!isNullish(msg)) mainArgs.push(msg);
|
|
52
52
|
if (extraArgs.length > 0) mainArgs.push(...extraArgs);
|
|
53
53
|
if (hasRest) mainArgs.push(rest);
|
|
54
54
|
return mainArgs;
|
|
@@ -98,7 +98,7 @@ var setLoggerMinimumLevel = (level) => {
|
|
|
98
98
|
pinoLogger.level = level;
|
|
99
99
|
};
|
|
100
100
|
var consoleMethodToPinoMethod = (level) => (message, payload) => {
|
|
101
|
-
if (payload
|
|
101
|
+
if (isNullish(payload)) {
|
|
102
102
|
pinoLogger[level](message);
|
|
103
103
|
} else {
|
|
104
104
|
pinoLogger[level](payload, message);
|
package/dist/logger.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/utils/types.utils.ts","../src/utils/runtime-env.utils.ts","../src/logger/logger.utils.ts"],"names":[],"mappings":";;;;;AAEO,IAAM,SAAA,GAAY,CAAC,KAAA,KAA8C,KAAA,KAAU,QAAQ,KAAA,KAAU,MAAA;;;ACI7F,IAAM,qBAAqB,MAAe;AAC/C,EAAA,IAAI,OAAO,MAAA,KAAW,WAAA,EAAa,OAAO,KAAA;AAC1C,EAAA,IAAI,OAAO,OAAA,KAAY,WAAA,EAAa,OAAO,KAAA;AAC3C,EAAA,IAAI,SAAA,CAAU,OAAA,EAAS,QAAA,EAAU,IAAI,GAAG,OAAO,KAAA;AAE/C,EAAA,OAAO,IAAA;AACT,CAAA;;;
|
|
1
|
+
{"version":3,"sources":["../src/utils/types.utils.ts","../src/utils/runtime-env.utils.ts","../src/logger/logger.utils.ts"],"names":[],"mappings":"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","file":"logger.js","sourcesContent":["export const NO_OP: () => void = () => {};\n\nexport const isNullish = (value: unknown): value is null | undefined => value === null || value === undefined;\n\nexport const isNumber = (value?: unknown | null): value is number => {\n if (isNullish(value)) {\n return false;\n }\n\n if (typeof value !== 'number') {\n return false;\n }\n\n if (isNaN(value)) {\n return false;\n }\n\n return true;\n};\n\nexport const isString = (value?: unknown | null): value is string => {\n if (isNullish(value)) {\n return false;\n }\n\n if (typeof value !== 'string') {\n return false;\n }\n\n return true;\n};\n","import { isNullish } from \"./types.utils\";\n\n/**\n * Returns true when running in Node.js.\n * Checks for process.versions.node to avoid false positives in Web Workers.\n */\nexport const isRuntimeEnvNodeJs = (): boolean => {\n if (typeof window !== \"undefined\") return false;\n if (typeof process === \"undefined\") return false;\n if (isNullish(process?.versions?.node)) return false;\n\n return true;\n};\n","import pino from \"pino\";\nimport { isRuntimeEnvNodeJs } from \"../utils/runtime-env.utils\";\nimport { isNullish } from \"../utils/types.utils\";\n\nconst LEVEL_LABELS: Record<number, string> = {\n 10: \"trace\",\n 20: \"debug\",\n 30: \"info\",\n 40: \"warn\",\n 50: \"error\",\n 60: \"fatal\",\n};\n\nconst LEVEL_COLORS: Record<string, string> = {\n trace: \"color: #94a3b8\",\n debug: \"color: #22d3ee\",\n info: \"color: #4ade80\",\n warn: \"color: #fbbf24\",\n error: \"color: #f87171\",\n fatal: \"color: #dc2626; font-weight: bold\",\n};\n\nconst MESSAGE_KEY = \"msg\";\n\ntype LogObject = Record<string, unknown> & { level?: number; time?: string; [MESSAGE_KEY]?: string };\n\nconst getLevelLabel = (levelNum: number): string => LEVEL_LABELS[levelNum] ?? \"info\";\n\nconst getLevelColor = (label: string): string => LEVEL_COLORS[label] ?? LEVEL_COLORS.info;\n\nconst getLogTimestamp = ({ time }: LogObject): string => (typeof time === \"string\" ? time : new Date().toISOString());\n\ntype ConsoleMethod = \"log\" | \"warn\" | \"error\";\nconst getConsoleMethod = (levelNum: number): ConsoleMethod => {\n if (levelNum >= 50) return \"error\";\n if (levelNum >= 40) return \"warn\";\n return \"log\";\n};\n\nconst getRestPayload = (obj: LogObject): Record<string, unknown> =>\n Object.keys(obj)\n .filter((k) => k !== \"level\" && k !== \"time\" && k !== MESSAGE_KEY)\n .reduce<Record<string, unknown>>((acc, k) => {\n acc[k] = obj[k];\n return acc;\n }, {});\n\ntype BuildMainArgsParams = {\n timestamp: string;\n label: string;\n color: string;\n msg: unknown;\n extraArgs: unknown[];\n rest: Record<string, unknown>;\n};\n\nconst buildMainArgs = ({ timestamp, label, color, msg, extraArgs, rest }: BuildMainArgsParams): unknown[] => {\n const prefix = `[${timestamp}]`;\n const levelPart = ` ${label.toUpperCase()} `;\n const hasRest = Object.keys(rest).length > 0;\n const mainArgs: unknown[] = [`${prefix}%c${levelPart}%c`, color, \"color: inherit\"];\n\n if (!isNullish(msg)) mainArgs.push(msg);\n if (extraArgs.length > 0) mainArgs.push(...extraArgs);\n if (hasRest) mainArgs.push(rest);\n\n return mainArgs;\n};\n\nconst baseOptions: pino.LoggerOptions = {\n timestamp: pino.stdTimeFunctions.isoTime,\n messageKey: MESSAGE_KEY,\n};\n\nconst browserOptions: pino.LoggerOptions = {\n ...baseOptions,\n browser: {\n write: (logObj: object, ...args: unknown[]) => {\n const obj = logObj as LogObject;\n const levelNum = obj.level ?? 30;\n const label = getLevelLabel(levelNum);\n const color = getLevelColor(label);\n const timestamp = getLogTimestamp(obj);\n const msg = obj[MESSAGE_KEY];\n const rest = getRestPayload(obj);\n const consoleMethod = getConsoleMethod(levelNum);\n const mainArgs = buildMainArgs({\n timestamp,\n label,\n color,\n msg,\n extraArgs: args,\n rest,\n });\n (console[consoleMethod] as (...a: unknown[]) => void)(...mainArgs);\n },\n },\n};\n\nconst createPinoLogger = (): pino.Logger => {\n if (isRuntimeEnvNodeJs()) {\n try {\n const transport = pino.transport({ target: \"pino-pretty\", options: { colorize: true } });\n return pino(baseOptions, transport);\n } catch (e: unknown) {\n console.warn(\"pino-pretty not installed, using default pino output\", e);\n return pino(baseOptions);\n }\n }\n\n return pino(browserOptions);\n};\n\nconst pinoLogger = createPinoLogger();\n\nexport type Level = \"trace\" | \"debug\" | \"info\" | \"warn\" | \"error\" | \"fatal\";\n\nexport const setLoggerMinimumLevel = (level: Level) => {\n pinoLogger.level = level;\n};\n\nconst consoleMethodToPinoMethod = (level: Level) => (message: string, payload?: Record<string, unknown>) => {\n if (isNullish(payload)) {\n pinoLogger[level](message);\n } else {\n pinoLogger[level](payload, message);\n }\n};\n\nexport const logger = {\n trace: consoleMethodToPinoMethod(\"trace\"),\n debug: consoleMethodToPinoMethod(\"debug\"),\n info: consoleMethodToPinoMethod(\"info\"),\n warn: consoleMethodToPinoMethod(\"warn\"),\n error: consoleMethodToPinoMethod(\"error\"),\n fatal: consoleMethodToPinoMethod(\"fatal\"),\n log: consoleMethodToPinoMethod(\"info\"),\n};\n"]}
|
package/dist/web.cjs
CHANGED
|
@@ -87,8 +87,8 @@ var getRechartsSvgFromElement = ({
|
|
|
87
87
|
return rechartSvg;
|
|
88
88
|
};
|
|
89
89
|
var getSvgDimensions = (svgElement) => {
|
|
90
|
-
const width = svgElement.clientWidth
|
|
91
|
-
const height = svgElement.clientHeight
|
|
90
|
+
const width = svgElement.clientWidth ?? parseInt(svgElement.getAttribute("width") ?? "800", 10);
|
|
91
|
+
const height = svgElement.clientHeight ?? parseInt(svgElement.getAttribute("height") ?? "600", 10);
|
|
92
92
|
return { width, height };
|
|
93
93
|
};
|
|
94
94
|
var prepareSvgClone = ({ svgElement, dimensions }) => {
|
package/dist/web.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/web/browser.utils.ts","../src/utils/errors.utils.ts","../src/web/fetch.utils.ts","../src/web/image.utils.ts"],"names":[],"mappings":";;;AAAO,IAAM,gBAAgB,MAAc;AACzC,EAAA,IAAI,OAAO,WAAW,WAAA,EAAa;AACjC,IAAA,OAAO,EAAA;AAAA,EACT;AAEA,EAAA,OAAO,OAAO,QAAA,CAAS,IAAA;AACzB;;;ACNO,IAAM,eAAA,GAAkB,CAAC,KAAA,KAA2B;AACzD,EAAA,IAAI,CAAC,KAAA,EAAO;AACV,IAAA,OAAO,EAAA;AAAA,EACT;AAEA,EAAA,IAAI,OAAO,UAAU,QAAA,EAAU;AAC7B,IAAA,OAAO,KAAA;AAAA,EACT;AAEA,EAAA,IAAI,OAAO,KAAA,KAAU,QAAA,IAAY,SAAA,IAAa,KAAA,EAAO;AACnD,IAAA,OAAQ,KAAA,CAA8B,OAAA;AAAA,EACxC;AAEA,EAAA,OAAO,IAAA,CAAK,UAAU,KAAK,CAAA;AAC7B,CAAA;;;ACTO,IAAM,aAAA,GAAgB,CAAC,IAAA,KAAuC;AACnE,EAAA,OAAO,IAAI,OAAA,CAAQ,CAAC,OAAA,EAAS,MAAA,KAAW;AACtC,IAAA,MAAM,MAAA,GAAS,IAAI,UAAA,EAAW;AAE9B,IAAA,MAAA,CAAO,OAAA,GAAU,MAAM,MAAA,CAAO,MAAA,CAAO,KAAK,CAAA;AAC1C,IAAA,MAAA,CAAO,YAAY,MAAM;AACvB,MAAA,MAAM,EAAE,QAAO,GAAI,MAAA;AACnB,MAAA,OAAA,CAAQ,OAAO,MAAA,KAAW,QAAA,GAAW,MAAA,GAAS,IAAI,CAAA;AAAA,IACpD,CAAA;AAEA,IAAA,MAAA,CAAO,cAAc,IAAI,CAAA;AAAA,EAC3B,CAAC,CAAA;AACH;AAMO,IAAM,iBAAA,GAAoB,OAAO,GAAA,KAAwC;AAC9E,EAAA,IAAI;AACF,IAAA,MAAM,QAAA,GAAW,MAAM,KAAA,CAAM,GAAG,CAAA;AAChC,IAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AAChB,MAAA,OAAA,CAAQ,KAAK,CAAA,qCAAA,EAAwC,QAAA,CAAS,MAAM,CAAA,SAAA,EAAY,GAAG,CAAA,CAAA,CAAG,CAAA;AACtF,MAAA,OAAO,IAAA;AAAA,IACT;AAEA,IAAA,MAAM,IAAA,GAAO,MAAM,QAAA,CAAS,IAAA,EAAK;AACjC,IAAA,OAAO,cAAc,IAAI,CAAA;AAAA,EAC3B,SAAS,CAAA,EAAY;AACnB,IAAA,MAAM,OAAA,GAAU,gBAAgB,CAAC,CAAA;AACjC,IAAA,OAAA,CAAQ,MAAM,CAAA,qBAAA,EAAwB,OAAO,CAAA,SAAA,EAAY,GAAG,KAAK,CAAC,CAAA;AAClE,IAAA,OAAO,IAAA;AAAA,EACT;AACF;;;ACpCO,IAAM,mBAAA,GAAsB,CAAC,GAAA,KAAgC;AAClE,EAAA,OACE,IAAI,aAAA,CAAc,kBAAkB,MAAM,IAAA,IAC1C,GAAA,CAAI,cAAc,2BAA2B,CAAA,KAAM,IAAA,IACnD,GAAA,CAAI,cAAc,2BAA2B,CAAA,KAAM,QACnD,GAAA,CAAI,aAAA,CAAc,qBAAqB,CAAA,KAAM,IAAA;AAEjD;AAEO,IAAM,eAAA,GAAkB,CAAC,IAAA,KAA4E;AAC1G,EAAA,KAAA,MAAW,GAAA,IAAO,KAAA,CAAM,IAAA,CAAK,IAAI,CAAA,EAAG;AAClC,IAAA,IAAI,mBAAA,CAAoB,GAAG,CAAA,EAAG;AAC5B,MAAA,OAAO,GAAA;AAAA,IACT;AAAA,EACF;AAEA,EAAA,OAAO,IAAA;AACT;AAEO,IAAM,UAAA,GAAa,CAAC,EAAA,KAAmC;AAC5D,EAAA,MAAM,OAAA,GAAU,QAAA,EAAU,cAAA,CAAe,EAAE,CAAA;AAC3C,EAAA,IAAI,CAAC,OAAA,EAAS;AACZ,IAAA,OAAA,CAAQ,IAAA,CAAK,CAAA,8BAAA,EAAiC,EAAE,CAAA,WAAA,CAAa,CAAA;AAC7D,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,OAAO,OAAA;AACT;AAOO,IAAM,4BAA4B,CAAC;AAAA,EACxC,YAAA;AAAA,EACA;AACF,CAAA,KAA2D;AACzD,EAAA,MAAM,OAAA,GAAU,YAAA,CAAa,gBAAA,CAAgC,KAAK,CAAA;AAClE,EAAA,IAAI,OAAA,CAAQ,WAAW,CAAA,EAAG;AACxB,IAAA,OAAA,CAAQ,IAAA,CAAK,CAAA,0EAAA,EAA6E,cAAc,CAAA,CAAA,CAAG,CAAA;AAC3G,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,MAAM,UAAA,GAAa,gBAAgB,OAAO,CAAA;AAC1C,EAAA,IAAI,CAAC,UAAA,EAAY;AACf,IAAA,OAAA,CAAQ,IAAA,CAAK,CAAA,kFAAA,EAAqF,cAAc,CAAA,CAAA,CAAG,CAAA;AACnH,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,OAAO,UAAA;AACT;AAEO,IAAM,gBAAA,GAAmB,CAAC,UAAA,KAA0C;AACzE,EAAA,MAAM,KAAA,GAAQ,WAAW,WAAA,IAAe,QAAA,CAAS,WAAW,YAAA,CAAa,OAAO,CAAA,IAAK,KAAA,EAAO,EAAE,CAAA;AAC9F,EAAA,MAAM,MAAA,GAAS,WAAW,YAAA,IAAgB,QAAA,CAAS,WAAW,YAAA,CAAa,QAAQ,CAAA,IAAK,KAAA,EAAO,EAAE,CAAA;AACjG,EAAA,OAAO,EAAE,OAAO,MAAA,EAAO;AACzB;AAyBO,IAAM,eAAA,GAAkB,CAAC,EAAE,UAAA,EAAY,YAAW,KAA0C;AACjG,EAAA,MAAM,SAAA,GAAY,UAAA,CAAW,SAAA,CAAU,IAAI,CAAA;AAE3C,EAAA,IAAI,CAAC,SAAA,CAAU,YAAA,CAAa,OAAO,CAAA,EAAG;AACpC,IAAA,SAAA,CAAU,YAAA,CAAa,OAAA,EAAS,UAAA,CAAW,KAAA,CAAM,UAAU,CAAA;AAAA,EAC7D;AACA,EAAA,IAAI,CAAC,SAAA,CAAU,YAAA,CAAa,QAAQ,CAAA,EAAG;AACrC,IAAA,SAAA,CAAU,YAAA,CAAa,QAAA,EAAU,UAAA,CAAW,MAAA,CAAO,UAAU,CAAA;AAAA,EAC/D;AAEA,EAAA,OAAO,SAAA;AACT;AAEO,IAAM,mBAAA,GAAsB,CAAC,MAAA,KAA2B;AAC7D,EAAA,MAAM,OAAA,GAAU,IAAI,WAAA,EAAY;AAChC,EAAA,MAAM,IAAA,GAAO,OAAA,CAAQ,MAAA,CAAO,MAAM,CAAA;AAClC,EAAA,IAAI,YAAA,GAAe,EAAA;AACnB,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,IAAA,CAAK,QAAQ,CAAA,EAAA,EAAK;AACpC,IAAA,YAAA,IAAgB,MAAA,CAAO,YAAA,CAAa,IAAA,CAAK,CAAC,CAAC,CAAA;AAAA,EAC7C;AACA,EAAA,MAAM,MAAA,GAAS,KAAK,YAAY,CAAA;AAChC,EAAA,OAAO,6BAA6B,MAAM,CAAA,CAAA;AAC5C;AAYO,IAAM,eAAe,CAAC,EAAE,MAAA,EAAQ,WAAA,EAAa,cAAa,KAAgC;AAC/F,EAAA,MAAM,SAAA,GAAY,UAAU,WAAW,CAAA,CAAA,CAAA;AACvC,EAAA,MAAM,UAAA,GAAa,WAAW,YAAY,CAAA,CAAA,CAAA;AAE1C,EAAA,IAAI,MAAA,GAAS,MAAA,CAAO,OAAA,CAAQ,wBAAA,EAA0B,SAAS,CAAA;AAC/D,EAAA,IAAI,CAAC,aAAA,CAAc,IAAA,CAAK,MAAM,CAAA,EAAG;AAC/B,IAAA,MAAA,GAAS,MAAA,CAAO,OAAA,CAAQ,MAAA,EAAQ,CAAA,KAAA,EAAQ,SAAS,CAAA,CAAE,CAAA;AAAA,EACrD;AAEA,EAAA,MAAA,GAAS,MAAA,CAAO,OAAA,CAAQ,yBAAA,EAA2B,UAAU,CAAA;AAC7D,EAAA,IAAI,CAAC,cAAA,CAAe,IAAA,CAAK,MAAM,CAAA,EAAG;AAChC,IAAA,MAAA,GAAS,MAAA,CAAO,OAAA,CAAQ,MAAA,EAAQ,CAAA,KAAA,EAAQ,UAAU,CAAA,CAAE,CAAA;AAAA,EACtD;AAEA,EAAA,OAAO,MAAA;AACT;AAYO,IAAM,uBAAuB,OAAO;AAAA,EACzC,cAAA;AAAA,EACA,KAAA;AAAA,EACA;AACF,CAAA,KAAwD;AACtD,EAAA,IAAI,CAAC,cAAA,EAAgB;AACnB,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,MAAM,YAAA,GAAmC,WAAW,cAAc,CAAA;AAClE,EAAA,IAAI,CAAC,YAAA,EAAc;AACjB,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,MAAM,UAAA,GAAmC,yBAAA,CAA0B,EAAE,YAAA,EAAc,gBAAgB,CAAA;AACnG,EAAA,IAAI,CAAC,UAAA,EAAY;AACf,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,MAAM,MAAA,GAAiB,IAAI,aAAA,EAAc,CAAE,kBAAkB,UAAU,CAAA;AACvE,EAAA,MAAM,UAAA,GAAqB,aAAa,EAAE,MAAA,EAAQ,aAAa,KAAA,EAAO,YAAA,EAAc,QAAQ,CAAA;AAC5F,EAAA,MAAM,UAAA,GAAqB,oBAAoB,UAAU,CAAA;AAEzD,EAAA,OAAO,eAAA,CAAgB;AAAA,IACrB,UAAA;AAAA,IACA,UAAA,EAAY,EAAE,KAAA,EAAO,MAAA,EAAO;AAAA,IAC5B,eAAA,EAAiB;AAAA,GAClB,CAAA;AACH;AAOO,IAAM,qBAAA,GAAwB,CAAC,cAAA,KAA0C;AAC9E,EAAA,MAAM,MAAA,GAAS,iBAAiB,cAAc,CAAA;AAC9C,EAAA,IAAI,CAAC,MAAA,EAAQ;AACX,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,OAAO,oBAAoB,MAAM,CAAA;AACnC;AAEO,IAAM,gBAAA,GAAmB,CAAC,cAAA,KAA0C;AACzE,EAAA,IAAI,CAAC,cAAA,EAAgB;AACnB,IAAA,OAAA,CAAQ,KAAK,CAAA,+CAAA,CAAiD,CAAA;AAC9D,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,MAAM,YAAA,GAAmC,WAAW,cAAc,CAAA;AAClE,EAAA,IAAI,CAAC,YAAA,EAAc;AACjB,IAAA,OAAA,CAAQ,IAAA,CAAK,CAAA,oCAAA,EAAuC,cAAc,CAAA,WAAA,CAAa,CAAA;AAC/E,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,MAAM,UAAA,GAAmC,yBAAA,CAA0B,EAAE,YAAA,EAAc,gBAAgB,CAAA;AACnG,EAAA,IAAI,CAAC,UAAA,EAAY;AACf,IAAA,OAAA,CAAQ,IAAA,CAAK,CAAA,gEAAA,EAAmE,cAAc,CAAA,CAAA,CAAG,CAAA;AACjG,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,MAAM,UAAA,GAAa,iBAAiB,UAAU,CAAA;AAC9C,EAAA,MAAM,SAAA,GAA2B,eAAA,CAAgB,EAAE,UAAA,EAAY,YAAY,CAAA;AAC3E,EAAA,MAAM,MAAA,GAAiB,IAAI,aAAA,EAAc,CAAE,kBAAkB,SAAS,CAAA;AAEtE,EAAA,OAAO,MAAA;AACT;AAQO,IAAM,kBAAkB,OAAO;AAAA,EACpC,UAAA;AAAA,EACA,UAAA;AAAA,EACA;AACF,CAAA,KAA4C;AAC1C,EAAA,IAAI,CAAC,UAAA,EAAY;AACf,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,MAAM,EAAE,KAAA,EAAO,MAAA,EAAO,GAAI,UAAA;AAE1B,EAAA,OAAO,IAAI,OAAA,CAAQ,CAAC,OAAA,EAAS,MAAA,KAAW;AACtC,IAAA,MAAM,GAAA,GAAM,IAAI,KAAA,EAAM;AAEtB,IAAA,GAAA,CAAI,SAAS,MAAM;AACjB,MAAA,IAAI;AACF,QAAA,MAAM,MAAA,GAAS,QAAA,CAAS,aAAA,CAAc,QAAQ,CAAA;AAC9C,QAAA,MAAA,CAAO,KAAA,GAAQ,KAAA;AACf,QAAA,MAAA,CAAO,MAAA,GAAS,MAAA;AAEhB,QAAA,MAAM,GAAA,GAAM,MAAA,CAAO,UAAA,CAAW,IAAI,CAAA;AAClC,QAAA,IAAI,CAAC,GAAA,EAAK;AACR,UAAA,MAAA,CAAO,IAAI,KAAA,CAAM,iCAAiC,CAAC,CAAA;AACnD,UAAA;AAAA,QACF;AAEA,QAAA,IAAI,eAAA,EAAiB;AACnB,UAAA,GAAA,CAAI,SAAA,GAAY,eAAA;AAChB,UAAA,GAAA,CAAI,QAAA,CAAS,CAAA,EAAG,CAAA,EAAG,KAAA,EAAO,MAAM,CAAA;AAAA,QAClC;AAEA,QAAA,GAAA,CAAI,SAAA,CAAU,GAAA,EAAK,CAAA,EAAG,CAAA,EAAG,OAAO,MAAM,CAAA;AACtC,QAAA,MAAM,UAAA,GAAa,MAAA,CAAO,SAAA,CAAU,WAAW,CAAA;AAC/C,QAAA,OAAA,CAAQ,UAAU,CAAA;AAAA,MACpB,SAAS,KAAA,EAAO;AACd,QAAA,MAAA,CAAO,KAAK,CAAA;AAAA,MACd;AAAA,IACF,CAAA;AAEA,IAAA,GAAA,CAAI,OAAA,GAAU,CAAC,KAAA,KAAU;AACvB,MAAA,MAAM,OAAA,GAAU,gBAAgB,KAAK,CAAA;AACrC,MAAA,MAAA,CAAO,IAAI,KAAA,CAAM,CAAA,0BAAA,EAA6B,OAAO,EAAE,CAAC,CAAA;AAAA,IAC1D,CAAA;AAEA,IAAA,GAAA,CAAI,GAAA,GAAM,UAAA;AAAA,EACZ,CAAC,CAAA;AACH","file":"web.cjs","sourcesContent":["export const getCurrentUrl = (): string => {\n if (typeof window === \"undefined\") {\n return \"\";\n }\n\n return window.location.href;\n};\n","export const getErrorMessage = (error: unknown): string => {\n if (!error) {\n return \"\";\n }\n\n if (typeof error === \"string\") {\n return error;\n }\n\n if (typeof error === \"object\" && \"message\" in error) {\n return (error as { message: string }).message;\n }\n\n return JSON.stringify(error);\n};\n","import { getErrorMessage } from \"../utils\";\n\n/**\n * Converts a Blob to a data URI string.\n */\nexport const blobToDataUri = (blob: Blob): Promise<string | null> => {\n return new Promise((resolve, reject) => {\n const reader = new FileReader();\n\n reader.onerror = () => reject(reader.error);\n reader.onloadend = () => {\n const { result } = reader;\n resolve(typeof result === \"string\" ? result : null);\n };\n\n reader.readAsDataURL(blob);\n });\n};\n\n/**\n * Fetches a resource by URL and returns its content as a data URI.\n * Content type is inferred from the response Content-Type header when possible.\n */\nexport const fetchUrlAsDataUri = async (url: string): Promise<string | null> => {\n try {\n const response = await fetch(url);\n if (!response.ok) {\n console.warn(`[fetchUrlAsDataUri] Response not ok (${response.status}). url: \"${url}\"`);\n return null;\n }\n\n const blob = await response.blob();\n return blobToDataUri(blob);\n } catch (e: unknown) {\n const message = getErrorMessage(e);\n console.error(`[fetchUrlAsDataUri] \"${message}\". url: \"${url}\"`, e);\n return null;\n }\n};\n","import { getErrorMessage, type Dimensions } from \"../utils\";\n\nexport const hasRechartsElements = (svg: SVGSVGElement): boolean => {\n return (\n svg.querySelector(\"g.recharts-layer\") !== null ||\n svg.querySelector(\"g.recharts-cartesian-axis\") !== null ||\n svg.querySelector(\"g.recharts-cartesian-grid\") !== null ||\n svg.querySelector(\"path.recharts-curve\") !== null\n );\n};\n\nexport const findRechartsSvg = (svgs: NodeListOf<SVGSVGElement> | SVGSVGElement[]): SVGSVGElement | null => {\n for (const svg of Array.from(svgs)) {\n if (hasRechartsElements(svg)) {\n return svg;\n }\n }\n\n return null;\n};\n\nexport const getElement = (id: string): HTMLElement | null => {\n const element = document?.getElementById(id);\n if (!element) {\n console.info(`[getElement] Element with id \"${id}\" not found`);\n return null;\n }\n\n return element;\n};\n\nexport interface GetRechartsSvgFromElementArgs {\n chartElement: HTMLElement;\n chartElementId: string;\n}\n\nexport const getRechartsSvgFromElement = ({\n chartElement,\n chartElementId,\n}: GetRechartsSvgFromElementArgs): SVGSVGElement | null => {\n const allSvgs = chartElement.querySelectorAll<SVGSVGElement>(\"svg\");\n if (allSvgs.length === 0) {\n console.info(`[getRechartsSvgFromElement] SVG element not found inside element with id \"${chartElementId}\"`);\n return null;\n }\n\n const rechartSvg = findRechartsSvg(allSvgs);\n if (!rechartSvg) {\n console.info(`[getRechartsSvgFromElement] No Recharts SVG element found inside element with id \"${chartElementId}\"`);\n return null;\n }\n\n return rechartSvg;\n};\n\nexport const getSvgDimensions = (svgElement: SVGSVGElement): Dimensions => {\n const width = svgElement.clientWidth || parseInt(svgElement.getAttribute(\"width\") || \"800\", 10);\n const height = svgElement.clientHeight || parseInt(svgElement.getAttribute(\"height\") || \"600\", 10);\n return { width, height };\n};\n\nexport interface PrepareSvgCloneArgs {\n svgElement: SVGSVGElement;\n dimensions: Dimensions;\n}\n\n/**\n * Clones an SVG element and ensures it has the required width and height attributes.\n *\n * This function is necessary for two main reasons:\n *\n * 1. **Defensive cloning**: Cloning prevents modifying the original SVG element in the DOM.\n * Although `XMLSerializer.serializeToString()` does not modify the element, cloning ensures\n * that no accidental modifications are made to the source element.\n *\n * 2. **Required width/height attributes**: When converting SVG → PNG via `svgToPngDataUri`,\n * the HTML Image element requires the SVG to have explicit intrinsic dimensions.\n * Without width/height attributes, the SVG may not render correctly on the canvas,\n * resulting in an incorrect or empty PNG image.\n *\n * @param svgElement - The original SVG element to clone\n * @param dimensions - The dimensions to apply to the cloned SVG if attributes are missing\n * @returns A new cloned SVG element with guaranteed width/height attributes\n */\nexport const prepareSvgClone = ({ svgElement, dimensions }: PrepareSvgCloneArgs): SVGSVGElement => {\n const clonedSvg = svgElement.cloneNode(true) as SVGSVGElement;\n\n if (!clonedSvg.hasAttribute(\"width\")) {\n clonedSvg.setAttribute(\"width\", dimensions.width.toString());\n }\n if (!clonedSvg.hasAttribute(\"height\")) {\n clonedSvg.setAttribute(\"height\", dimensions.height.toString());\n }\n\n return clonedSvg;\n};\n\nexport const convertSvgToDataUri = (svgXml: string): string => {\n const encoder = new TextEncoder();\n const data = encoder.encode(svgXml);\n let binaryString = \"\";\n for (let i = 0; i < data.length; i++) {\n binaryString += String.fromCharCode(data[i]);\n }\n const base64 = btoa(binaryString);\n return `data:image/svg+xml;base64,${base64}`;\n};\n\nexport interface ResizeSvgXmlArgs {\n svgXml: string;\n targetWidth: number;\n targetHeight: number;\n}\n\n/**\n * Modifies SVG XML to set the root <svg> width and height attributes.\n * Used to resize the SVG before converting to PNG at target dimensions (e.g. from PDF layout).\n */\nexport const resizeSvgXml = ({ svgXml, targetWidth, targetHeight }: ResizeSvgXmlArgs): string => {\n const widthAttr = `width=\"${targetWidth}\"`;\n const heightAttr = `height=\"${targetHeight}\"`;\n\n let result = svgXml.replace(/\\bwidth=[\"'][^\"']*[\"']/, widthAttr);\n if (!/\\bwidth\\s*=/.test(result)) {\n result = result.replace(/<svg/, `<svg ${widthAttr}`);\n }\n\n result = result.replace(/\\bheight=[\"'][^\"']*[\"']/, heightAttr);\n if (!/\\bheight\\s*=/.test(result)) {\n result = result.replace(/<svg/, `<svg ${heightAttr}`);\n }\n\n return result;\n};\n\nexport interface GetChartAsPngDataUriArgs {\n chartElementId: string;\n width: number;\n height: number;\n}\n\n/**\n * Gets the Recharts chart as a PNG data URI at the given dimensions (e.g. from PDF zone).\n * Resizes the SVG via resizeSvgXml before conversion; does not use the SVG's intrinsic dimensions.\n */\nexport const getChartAsPngDataUri = async ({\n chartElementId,\n width,\n height,\n}: GetChartAsPngDataUriArgs): Promise<string | null> => {\n if (!chartElementId) {\n return null;\n }\n\n const chartElement: HTMLElement | null = getElement(chartElementId);\n if (!chartElement) {\n return null;\n }\n\n const svgElement: SVGSVGElement | null = getRechartsSvgFromElement({ chartElement, chartElementId });\n if (!svgElement) {\n return null;\n }\n\n const svgXml: string = new XMLSerializer().serializeToString(svgElement);\n const resizedXml: string = resizeSvgXml({ svgXml, targetWidth: width, targetHeight: height });\n const svgDataUri: string = convertSvgToDataUri(resizedXml);\n\n return svgToPngDataUri({\n svgDataUri,\n dimensions: { width, height },\n backgroundColor: \"white\",\n });\n};\n\n/**\n * Retrieves the SVG from a Recharts chart element and converts it to SVG base64\n * @param chartElementId - The ID of the element containing the chart\n * @returns The SVG encoded in base64 with data URI prefix (data:image/svg+xml;base64,...), or null if an error occurs\n */\nexport const getSvgAsBase64DataUri = (chartElementId: string): string | null => {\n const svgXml = getRechartSvgXml(chartElementId);\n if (!svgXml) {\n return null;\n }\n\n return convertSvgToDataUri(svgXml);\n};\n\nexport const getRechartSvgXml = (chartElementId: string): string | null => {\n if (!chartElementId) {\n console.info(`[getRechartSvgXml] No chart element id provided`);\n return null;\n }\n\n const chartElement: HTMLElement | null = getElement(chartElementId);\n if (!chartElement) {\n console.info(`[getRechartSvgXml] Element with id \"${chartElementId}\" not found`);\n return null;\n }\n\n const svgElement: SVGSVGElement | null = getRechartsSvgFromElement({ chartElement, chartElementId });\n if (!svgElement) {\n console.info(`[getRechartSvgXml] No SVG element found inside element with id \"${chartElementId}\"`);\n return null;\n }\n\n const dimensions = getSvgDimensions(svgElement);\n const clonedSvg: SVGSVGElement = prepareSvgClone({ svgElement, dimensions });\n const svgXml: string = new XMLSerializer().serializeToString(clonedSvg);\n\n return svgXml;\n};\n\nexport interface SvgToPngArgs {\n svgDataUri?: string | null;\n dimensions: Dimensions;\n backgroundColor?: string;\n}\n\nexport const svgToPngDataUri = async ({\n svgDataUri,\n dimensions,\n backgroundColor,\n}: SvgToPngArgs): Promise<string | null> => {\n if (!svgDataUri) {\n return null;\n }\n\n const { width, height } = dimensions;\n\n return new Promise((resolve, reject) => {\n const img = new Image();\n\n img.onload = () => {\n try {\n const canvas = document.createElement(\"canvas\");\n canvas.width = width;\n canvas.height = height;\n\n const ctx = canvas.getContext(\"2d\");\n if (!ctx) {\n reject(new Error(\"Failed to get canvas 2D context\"));\n return;\n }\n\n if (backgroundColor) {\n ctx.fillStyle = backgroundColor;\n ctx.fillRect(0, 0, width, height);\n }\n\n ctx.drawImage(img, 0, 0, width, height);\n const pngDataUri = canvas.toDataURL(\"image/png\");\n resolve(pngDataUri);\n } catch (error) {\n reject(error);\n }\n };\n\n img.onerror = (error) => {\n const message = getErrorMessage(error);\n reject(new Error(`Failed to load SVG image: ${message}`));\n };\n\n img.src = svgDataUri;\n });\n};\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/web/browser.utils.ts","../src/utils/errors.utils.ts","../src/web/fetch.utils.ts","../src/web/image.utils.ts"],"names":[],"mappings":"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","file":"web.cjs","sourcesContent":["export const getCurrentUrl = (): string => {\n if (typeof window === \"undefined\") {\n return \"\";\n }\n\n return window.location.href;\n};\n","export const getErrorMessage = (error: unknown): string => {\n if (!error) {\n return \"\";\n }\n\n if (typeof error === \"string\") {\n return error;\n }\n\n if (typeof error === \"object\" && \"message\" in error) {\n return (error as { message: string }).message;\n }\n\n return JSON.stringify(error);\n};\n\nexport const toError = (error: unknown): Error => {\n if (error instanceof Error) {\n return error;\n }\n\n return new Error(getErrorMessage(error));\n};\n","import { getErrorMessage } from \"../utils\";\n\n/**\n * Converts a Blob to a data URI string.\n */\nexport const blobToDataUri = (blob: Blob): Promise<string | null> => {\n return new Promise((resolve, reject) => {\n const reader = new FileReader();\n\n reader.onerror = () => reject(reader.error);\n reader.onloadend = () => {\n const { result } = reader;\n resolve(typeof result === \"string\" ? result : null);\n };\n\n reader.readAsDataURL(blob);\n });\n};\n\n/**\n * Fetches a resource by URL and returns its content as a data URI.\n * Content type is inferred from the response Content-Type header when possible.\n */\nexport const fetchUrlAsDataUri = async (url: string): Promise<string | null> => {\n try {\n const response = await fetch(url);\n if (!response.ok) {\n console.warn(`[fetchUrlAsDataUri] Response not ok (${response.status}). url: \"${url}\"`);\n return null;\n }\n\n const blob = await response.blob();\n return blobToDataUri(blob);\n } catch (e: unknown) {\n const message = getErrorMessage(e);\n console.error(`[fetchUrlAsDataUri] \"${message}\". url: \"${url}\"`, e);\n return null;\n }\n};\n","import { getErrorMessage, type Dimensions } from \"../utils\";\n\nexport const hasRechartsElements = (svg: SVGSVGElement): boolean => {\n return (\n svg.querySelector(\"g.recharts-layer\") !== null ||\n svg.querySelector(\"g.recharts-cartesian-axis\") !== null ||\n svg.querySelector(\"g.recharts-cartesian-grid\") !== null ||\n svg.querySelector(\"path.recharts-curve\") !== null\n );\n};\n\nexport const findRechartsSvg = (svgs: NodeListOf<SVGSVGElement> | SVGSVGElement[]): SVGSVGElement | null => {\n for (const svg of Array.from(svgs)) {\n if (hasRechartsElements(svg)) {\n return svg;\n }\n }\n\n return null;\n};\n\nexport const getElement = (id: string): HTMLElement | null => {\n const element = document?.getElementById(id);\n if (!element) {\n console.info(`[getElement] Element with id \"${id}\" not found`);\n return null;\n }\n\n return element;\n};\n\nexport interface GetRechartsSvgFromElementArgs {\n chartElement: HTMLElement;\n chartElementId: string;\n}\n\nexport const getRechartsSvgFromElement = ({\n chartElement,\n chartElementId,\n}: GetRechartsSvgFromElementArgs): SVGSVGElement | null => {\n const allSvgs = chartElement.querySelectorAll<SVGSVGElement>(\"svg\");\n if (allSvgs.length === 0) {\n console.info(`[getRechartsSvgFromElement] SVG element not found inside element with id \"${chartElementId}\"`);\n return null;\n }\n\n const rechartSvg = findRechartsSvg(allSvgs);\n if (!rechartSvg) {\n console.info(`[getRechartsSvgFromElement] No Recharts SVG element found inside element with id \"${chartElementId}\"`);\n return null;\n }\n\n return rechartSvg;\n};\n\nexport const getSvgDimensions = (svgElement: SVGSVGElement): Dimensions => {\n const width = svgElement.clientWidth ?? parseInt(svgElement.getAttribute(\"width\") ?? \"800\", 10);\n const height = svgElement.clientHeight ?? parseInt(svgElement.getAttribute(\"height\") ?? \"600\", 10);\n return { width, height };\n};\n\nexport interface PrepareSvgCloneArgs {\n svgElement: SVGSVGElement;\n dimensions: Dimensions;\n}\n\n/**\n * Clones an SVG element and ensures it has the required width and height attributes.\n *\n * This function is necessary for two main reasons:\n *\n * 1. **Defensive cloning**: Cloning prevents modifying the original SVG element in the DOM.\n * Although `XMLSerializer.serializeToString()` does not modify the element, cloning ensures\n * that no accidental modifications are made to the source element.\n *\n * 2. **Required width/height attributes**: When converting SVG → PNG via `svgToPngDataUri`,\n * the HTML Image element requires the SVG to have explicit intrinsic dimensions.\n * Without width/height attributes, the SVG may not render correctly on the canvas,\n * resulting in an incorrect or empty PNG image.\n *\n * @param svgElement - The original SVG element to clone\n * @param dimensions - The dimensions to apply to the cloned SVG if attributes are missing\n * @returns A new cloned SVG element with guaranteed width/height attributes\n */\nexport const prepareSvgClone = ({ svgElement, dimensions }: PrepareSvgCloneArgs): SVGSVGElement => {\n const clonedSvg = svgElement.cloneNode(true) as SVGSVGElement;\n\n if (!clonedSvg.hasAttribute(\"width\")) {\n clonedSvg.setAttribute(\"width\", dimensions.width.toString());\n }\n if (!clonedSvg.hasAttribute(\"height\")) {\n clonedSvg.setAttribute(\"height\", dimensions.height.toString());\n }\n\n return clonedSvg;\n};\n\nexport const convertSvgToDataUri = (svgXml: string): string => {\n const encoder = new TextEncoder();\n const data = encoder.encode(svgXml);\n let binaryString = \"\";\n for (let i = 0; i < data.length; i++) {\n binaryString += String.fromCharCode(data[i]);\n }\n const base64 = btoa(binaryString);\n return `data:image/svg+xml;base64,${base64}`;\n};\n\nexport interface ResizeSvgXmlArgs {\n svgXml: string;\n targetWidth: number;\n targetHeight: number;\n}\n\n/**\n * Modifies SVG XML to set the root <svg> width and height attributes.\n * Used to resize the SVG before converting to PNG at target dimensions (e.g. from PDF layout).\n */\nexport const resizeSvgXml = ({ svgXml, targetWidth, targetHeight }: ResizeSvgXmlArgs): string => {\n const widthAttr = `width=\"${targetWidth}\"`;\n const heightAttr = `height=\"${targetHeight}\"`;\n\n let result = svgXml.replace(/\\bwidth=[\"'][^\"']*[\"']/, widthAttr);\n if (!/\\bwidth\\s*=/.test(result)) {\n result = result.replace(/<svg/, `<svg ${widthAttr}`);\n }\n\n result = result.replace(/\\bheight=[\"'][^\"']*[\"']/, heightAttr);\n if (!/\\bheight\\s*=/.test(result)) {\n result = result.replace(/<svg/, `<svg ${heightAttr}`);\n }\n\n return result;\n};\n\nexport interface GetChartAsPngDataUriArgs {\n chartElementId: string;\n width: number;\n height: number;\n}\n\n/**\n * Gets the Recharts chart as a PNG data URI at the given dimensions (e.g. from PDF zone).\n * Resizes the SVG via resizeSvgXml before conversion; does not use the SVG's intrinsic dimensions.\n */\nexport const getChartAsPngDataUri = async ({\n chartElementId,\n width,\n height,\n}: GetChartAsPngDataUriArgs): Promise<string | null> => {\n if (!chartElementId) {\n return null;\n }\n\n const chartElement: HTMLElement | null = getElement(chartElementId);\n if (!chartElement) {\n return null;\n }\n\n const svgElement: SVGSVGElement | null = getRechartsSvgFromElement({ chartElement, chartElementId });\n if (!svgElement) {\n return null;\n }\n\n const svgXml: string = new XMLSerializer().serializeToString(svgElement);\n const resizedXml: string = resizeSvgXml({ svgXml, targetWidth: width, targetHeight: height });\n const svgDataUri: string = convertSvgToDataUri(resizedXml);\n\n return svgToPngDataUri({\n svgDataUri,\n dimensions: { width, height },\n backgroundColor: \"white\",\n });\n};\n\n/**\n * Retrieves the SVG from a Recharts chart element and converts it to SVG base64\n * @param chartElementId - The ID of the element containing the chart\n * @returns The SVG encoded in base64 with data URI prefix (data:image/svg+xml;base64,...), or null if an error occurs\n */\nexport const getSvgAsBase64DataUri = (chartElementId: string): string | null => {\n const svgXml = getRechartSvgXml(chartElementId);\n if (!svgXml) {\n return null;\n }\n\n return convertSvgToDataUri(svgXml);\n};\n\nexport const getRechartSvgXml = (chartElementId: string): string | null => {\n if (!chartElementId) {\n console.info(`[getRechartSvgXml] No chart element id provided`);\n return null;\n }\n\n const chartElement: HTMLElement | null = getElement(chartElementId);\n if (!chartElement) {\n console.info(`[getRechartSvgXml] Element with id \"${chartElementId}\" not found`);\n return null;\n }\n\n const svgElement: SVGSVGElement | null = getRechartsSvgFromElement({ chartElement, chartElementId });\n if (!svgElement) {\n console.info(`[getRechartSvgXml] No SVG element found inside element with id \"${chartElementId}\"`);\n return null;\n }\n\n const dimensions = getSvgDimensions(svgElement);\n const clonedSvg: SVGSVGElement = prepareSvgClone({ svgElement, dimensions });\n const svgXml: string = new XMLSerializer().serializeToString(clonedSvg);\n\n return svgXml;\n};\n\nexport interface SvgToPngArgs {\n svgDataUri?: string | null;\n dimensions: Dimensions;\n backgroundColor?: string;\n}\n\nexport const svgToPngDataUri = async ({\n svgDataUri,\n dimensions,\n backgroundColor,\n}: SvgToPngArgs): Promise<string | null> => {\n if (!svgDataUri) {\n return null;\n }\n\n const { width, height } = dimensions;\n\n return new Promise((resolve, reject) => {\n const img = new Image();\n\n img.onload = () => {\n try {\n const canvas = document.createElement(\"canvas\");\n canvas.width = width;\n canvas.height = height;\n\n const ctx = canvas.getContext(\"2d\");\n if (!ctx) {\n reject(new Error(\"Failed to get canvas 2D context\"));\n return;\n }\n\n if (backgroundColor) {\n ctx.fillStyle = backgroundColor;\n ctx.fillRect(0, 0, width, height);\n }\n\n ctx.drawImage(img, 0, 0, width, height);\n const pngDataUri = canvas.toDataURL(\"image/png\");\n resolve(pngDataUri);\n } catch (error) {\n reject(error);\n }\n };\n\n img.onerror = (error) => {\n const message = getErrorMessage(error);\n reject(new Error(`Failed to load SVG image: ${message}`));\n };\n\n img.src = svgDataUri;\n });\n};\n"]}
|
package/dist/web.js
CHANGED
|
@@ -85,8 +85,8 @@ var getRechartsSvgFromElement = ({
|
|
|
85
85
|
return rechartSvg;
|
|
86
86
|
};
|
|
87
87
|
var getSvgDimensions = (svgElement) => {
|
|
88
|
-
const width = svgElement.clientWidth
|
|
89
|
-
const height = svgElement.clientHeight
|
|
88
|
+
const width = svgElement.clientWidth ?? parseInt(svgElement.getAttribute("width") ?? "800", 10);
|
|
89
|
+
const height = svgElement.clientHeight ?? parseInt(svgElement.getAttribute("height") ?? "600", 10);
|
|
90
90
|
return { width, height };
|
|
91
91
|
};
|
|
92
92
|
var prepareSvgClone = ({ svgElement, dimensions }) => {
|
package/dist/web.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/web/browser.utils.ts","../src/utils/errors.utils.ts","../src/web/fetch.utils.ts","../src/web/image.utils.ts"],"names":[],"mappings":"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","file":"web.js","sourcesContent":["export const getCurrentUrl = (): string => {\n if (typeof window === \"undefined\") {\n return \"\";\n }\n\n return window.location.href;\n};\n","export const getErrorMessage = (error: unknown): string => {\n if (!error) {\n return \"\";\n }\n\n if (typeof error === \"string\") {\n return error;\n }\n\n if (typeof error === \"object\" && \"message\" in error) {\n return (error as { message: string }).message;\n }\n\n return JSON.stringify(error);\n};\n","import { getErrorMessage } from \"../utils\";\n\n/**\n * Converts a Blob to a data URI string.\n */\nexport const blobToDataUri = (blob: Blob): Promise<string | null> => {\n return new Promise((resolve, reject) => {\n const reader = new FileReader();\n\n reader.onerror = () => reject(reader.error);\n reader.onloadend = () => {\n const { result } = reader;\n resolve(typeof result === \"string\" ? result : null);\n };\n\n reader.readAsDataURL(blob);\n });\n};\n\n/**\n * Fetches a resource by URL and returns its content as a data URI.\n * Content type is inferred from the response Content-Type header when possible.\n */\nexport const fetchUrlAsDataUri = async (url: string): Promise<string | null> => {\n try {\n const response = await fetch(url);\n if (!response.ok) {\n console.warn(`[fetchUrlAsDataUri] Response not ok (${response.status}). url: \"${url}\"`);\n return null;\n }\n\n const blob = await response.blob();\n return blobToDataUri(blob);\n } catch (e: unknown) {\n const message = getErrorMessage(e);\n console.error(`[fetchUrlAsDataUri] \"${message}\". url: \"${url}\"`, e);\n return null;\n }\n};\n","import { getErrorMessage, type Dimensions } from \"../utils\";\n\nexport const hasRechartsElements = (svg: SVGSVGElement): boolean => {\n return (\n svg.querySelector(\"g.recharts-layer\") !== null ||\n svg.querySelector(\"g.recharts-cartesian-axis\") !== null ||\n svg.querySelector(\"g.recharts-cartesian-grid\") !== null ||\n svg.querySelector(\"path.recharts-curve\") !== null\n );\n};\n\nexport const findRechartsSvg = (svgs: NodeListOf<SVGSVGElement> | SVGSVGElement[]): SVGSVGElement | null => {\n for (const svg of Array.from(svgs)) {\n if (hasRechartsElements(svg)) {\n return svg;\n }\n }\n\n return null;\n};\n\nexport const getElement = (id: string): HTMLElement | null => {\n const element = document?.getElementById(id);\n if (!element) {\n console.info(`[getElement] Element with id \"${id}\" not found`);\n return null;\n }\n\n return element;\n};\n\nexport interface GetRechartsSvgFromElementArgs {\n chartElement: HTMLElement;\n chartElementId: string;\n}\n\nexport const getRechartsSvgFromElement = ({\n chartElement,\n chartElementId,\n}: GetRechartsSvgFromElementArgs): SVGSVGElement | null => {\n const allSvgs = chartElement.querySelectorAll<SVGSVGElement>(\"svg\");\n if (allSvgs.length === 0) {\n console.info(`[getRechartsSvgFromElement] SVG element not found inside element with id \"${chartElementId}\"`);\n return null;\n }\n\n const rechartSvg = findRechartsSvg(allSvgs);\n if (!rechartSvg) {\n console.info(`[getRechartsSvgFromElement] No Recharts SVG element found inside element with id \"${chartElementId}\"`);\n return null;\n }\n\n return rechartSvg;\n};\n\nexport const getSvgDimensions = (svgElement: SVGSVGElement): Dimensions => {\n const width = svgElement.clientWidth || parseInt(svgElement.getAttribute(\"width\") || \"800\", 10);\n const height = svgElement.clientHeight || parseInt(svgElement.getAttribute(\"height\") || \"600\", 10);\n return { width, height };\n};\n\nexport interface PrepareSvgCloneArgs {\n svgElement: SVGSVGElement;\n dimensions: Dimensions;\n}\n\n/**\n * Clones an SVG element and ensures it has the required width and height attributes.\n *\n * This function is necessary for two main reasons:\n *\n * 1. **Defensive cloning**: Cloning prevents modifying the original SVG element in the DOM.\n * Although `XMLSerializer.serializeToString()` does not modify the element, cloning ensures\n * that no accidental modifications are made to the source element.\n *\n * 2. **Required width/height attributes**: When converting SVG → PNG via `svgToPngDataUri`,\n * the HTML Image element requires the SVG to have explicit intrinsic dimensions.\n * Without width/height attributes, the SVG may not render correctly on the canvas,\n * resulting in an incorrect or empty PNG image.\n *\n * @param svgElement - The original SVG element to clone\n * @param dimensions - The dimensions to apply to the cloned SVG if attributes are missing\n * @returns A new cloned SVG element with guaranteed width/height attributes\n */\nexport const prepareSvgClone = ({ svgElement, dimensions }: PrepareSvgCloneArgs): SVGSVGElement => {\n const clonedSvg = svgElement.cloneNode(true) as SVGSVGElement;\n\n if (!clonedSvg.hasAttribute(\"width\")) {\n clonedSvg.setAttribute(\"width\", dimensions.width.toString());\n }\n if (!clonedSvg.hasAttribute(\"height\")) {\n clonedSvg.setAttribute(\"height\", dimensions.height.toString());\n }\n\n return clonedSvg;\n};\n\nexport const convertSvgToDataUri = (svgXml: string): string => {\n const encoder = new TextEncoder();\n const data = encoder.encode(svgXml);\n let binaryString = \"\";\n for (let i = 0; i < data.length; i++) {\n binaryString += String.fromCharCode(data[i]);\n }\n const base64 = btoa(binaryString);\n return `data:image/svg+xml;base64,${base64}`;\n};\n\nexport interface ResizeSvgXmlArgs {\n svgXml: string;\n targetWidth: number;\n targetHeight: number;\n}\n\n/**\n * Modifies SVG XML to set the root <svg> width and height attributes.\n * Used to resize the SVG before converting to PNG at target dimensions (e.g. from PDF layout).\n */\nexport const resizeSvgXml = ({ svgXml, targetWidth, targetHeight }: ResizeSvgXmlArgs): string => {\n const widthAttr = `width=\"${targetWidth}\"`;\n const heightAttr = `height=\"${targetHeight}\"`;\n\n let result = svgXml.replace(/\\bwidth=[\"'][^\"']*[\"']/, widthAttr);\n if (!/\\bwidth\\s*=/.test(result)) {\n result = result.replace(/<svg/, `<svg ${widthAttr}`);\n }\n\n result = result.replace(/\\bheight=[\"'][^\"']*[\"']/, heightAttr);\n if (!/\\bheight\\s*=/.test(result)) {\n result = result.replace(/<svg/, `<svg ${heightAttr}`);\n }\n\n return result;\n};\n\nexport interface GetChartAsPngDataUriArgs {\n chartElementId: string;\n width: number;\n height: number;\n}\n\n/**\n * Gets the Recharts chart as a PNG data URI at the given dimensions (e.g. from PDF zone).\n * Resizes the SVG via resizeSvgXml before conversion; does not use the SVG's intrinsic dimensions.\n */\nexport const getChartAsPngDataUri = async ({\n chartElementId,\n width,\n height,\n}: GetChartAsPngDataUriArgs): Promise<string | null> => {\n if (!chartElementId) {\n return null;\n }\n\n const chartElement: HTMLElement | null = getElement(chartElementId);\n if (!chartElement) {\n return null;\n }\n\n const svgElement: SVGSVGElement | null = getRechartsSvgFromElement({ chartElement, chartElementId });\n if (!svgElement) {\n return null;\n }\n\n const svgXml: string = new XMLSerializer().serializeToString(svgElement);\n const resizedXml: string = resizeSvgXml({ svgXml, targetWidth: width, targetHeight: height });\n const svgDataUri: string = convertSvgToDataUri(resizedXml);\n\n return svgToPngDataUri({\n svgDataUri,\n dimensions: { width, height },\n backgroundColor: \"white\",\n });\n};\n\n/**\n * Retrieves the SVG from a Recharts chart element and converts it to SVG base64\n * @param chartElementId - The ID of the element containing the chart\n * @returns The SVG encoded in base64 with data URI prefix (data:image/svg+xml;base64,...), or null if an error occurs\n */\nexport const getSvgAsBase64DataUri = (chartElementId: string): string | null => {\n const svgXml = getRechartSvgXml(chartElementId);\n if (!svgXml) {\n return null;\n }\n\n return convertSvgToDataUri(svgXml);\n};\n\nexport const getRechartSvgXml = (chartElementId: string): string | null => {\n if (!chartElementId) {\n console.info(`[getRechartSvgXml] No chart element id provided`);\n return null;\n }\n\n const chartElement: HTMLElement | null = getElement(chartElementId);\n if (!chartElement) {\n console.info(`[getRechartSvgXml] Element with id \"${chartElementId}\" not found`);\n return null;\n }\n\n const svgElement: SVGSVGElement | null = getRechartsSvgFromElement({ chartElement, chartElementId });\n if (!svgElement) {\n console.info(`[getRechartSvgXml] No SVG element found inside element with id \"${chartElementId}\"`);\n return null;\n }\n\n const dimensions = getSvgDimensions(svgElement);\n const clonedSvg: SVGSVGElement = prepareSvgClone({ svgElement, dimensions });\n const svgXml: string = new XMLSerializer().serializeToString(clonedSvg);\n\n return svgXml;\n};\n\nexport interface SvgToPngArgs {\n svgDataUri?: string | null;\n dimensions: Dimensions;\n backgroundColor?: string;\n}\n\nexport const svgToPngDataUri = async ({\n svgDataUri,\n dimensions,\n backgroundColor,\n}: SvgToPngArgs): Promise<string | null> => {\n if (!svgDataUri) {\n return null;\n }\n\n const { width, height } = dimensions;\n\n return new Promise((resolve, reject) => {\n const img = new Image();\n\n img.onload = () => {\n try {\n const canvas = document.createElement(\"canvas\");\n canvas.width = width;\n canvas.height = height;\n\n const ctx = canvas.getContext(\"2d\");\n if (!ctx) {\n reject(new Error(\"Failed to get canvas 2D context\"));\n return;\n }\n\n if (backgroundColor) {\n ctx.fillStyle = backgroundColor;\n ctx.fillRect(0, 0, width, height);\n }\n\n ctx.drawImage(img, 0, 0, width, height);\n const pngDataUri = canvas.toDataURL(\"image/png\");\n resolve(pngDataUri);\n } catch (error) {\n reject(error);\n }\n };\n\n img.onerror = (error) => {\n const message = getErrorMessage(error);\n reject(new Error(`Failed to load SVG image: ${message}`));\n };\n\n img.src = svgDataUri;\n });\n};\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/web/browser.utils.ts","../src/utils/errors.utils.ts","../src/web/fetch.utils.ts","../src/web/image.utils.ts"],"names":[],"mappings":"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","file":"web.js","sourcesContent":["export const getCurrentUrl = (): string => {\n if (typeof window === \"undefined\") {\n return \"\";\n }\n\n return window.location.href;\n};\n","export const getErrorMessage = (error: unknown): string => {\n if (!error) {\n return \"\";\n }\n\n if (typeof error === \"string\") {\n return error;\n }\n\n if (typeof error === \"object\" && \"message\" in error) {\n return (error as { message: string }).message;\n }\n\n return JSON.stringify(error);\n};\n\nexport const toError = (error: unknown): Error => {\n if (error instanceof Error) {\n return error;\n }\n\n return new Error(getErrorMessage(error));\n};\n","import { getErrorMessage } from \"../utils\";\n\n/**\n * Converts a Blob to a data URI string.\n */\nexport const blobToDataUri = (blob: Blob): Promise<string | null> => {\n return new Promise((resolve, reject) => {\n const reader = new FileReader();\n\n reader.onerror = () => reject(reader.error);\n reader.onloadend = () => {\n const { result } = reader;\n resolve(typeof result === \"string\" ? result : null);\n };\n\n reader.readAsDataURL(blob);\n });\n};\n\n/**\n * Fetches a resource by URL and returns its content as a data URI.\n * Content type is inferred from the response Content-Type header when possible.\n */\nexport const fetchUrlAsDataUri = async (url: string): Promise<string | null> => {\n try {\n const response = await fetch(url);\n if (!response.ok) {\n console.warn(`[fetchUrlAsDataUri] Response not ok (${response.status}). url: \"${url}\"`);\n return null;\n }\n\n const blob = await response.blob();\n return blobToDataUri(blob);\n } catch (e: unknown) {\n const message = getErrorMessage(e);\n console.error(`[fetchUrlAsDataUri] \"${message}\". url: \"${url}\"`, e);\n return null;\n }\n};\n","import { getErrorMessage, type Dimensions } from \"../utils\";\n\nexport const hasRechartsElements = (svg: SVGSVGElement): boolean => {\n return (\n svg.querySelector(\"g.recharts-layer\") !== null ||\n svg.querySelector(\"g.recharts-cartesian-axis\") !== null ||\n svg.querySelector(\"g.recharts-cartesian-grid\") !== null ||\n svg.querySelector(\"path.recharts-curve\") !== null\n );\n};\n\nexport const findRechartsSvg = (svgs: NodeListOf<SVGSVGElement> | SVGSVGElement[]): SVGSVGElement | null => {\n for (const svg of Array.from(svgs)) {\n if (hasRechartsElements(svg)) {\n return svg;\n }\n }\n\n return null;\n};\n\nexport const getElement = (id: string): HTMLElement | null => {\n const element = document?.getElementById(id);\n if (!element) {\n console.info(`[getElement] Element with id \"${id}\" not found`);\n return null;\n }\n\n return element;\n};\n\nexport interface GetRechartsSvgFromElementArgs {\n chartElement: HTMLElement;\n chartElementId: string;\n}\n\nexport const getRechartsSvgFromElement = ({\n chartElement,\n chartElementId,\n}: GetRechartsSvgFromElementArgs): SVGSVGElement | null => {\n const allSvgs = chartElement.querySelectorAll<SVGSVGElement>(\"svg\");\n if (allSvgs.length === 0) {\n console.info(`[getRechartsSvgFromElement] SVG element not found inside element with id \"${chartElementId}\"`);\n return null;\n }\n\n const rechartSvg = findRechartsSvg(allSvgs);\n if (!rechartSvg) {\n console.info(`[getRechartsSvgFromElement] No Recharts SVG element found inside element with id \"${chartElementId}\"`);\n return null;\n }\n\n return rechartSvg;\n};\n\nexport const getSvgDimensions = (svgElement: SVGSVGElement): Dimensions => {\n const width = svgElement.clientWidth ?? parseInt(svgElement.getAttribute(\"width\") ?? \"800\", 10);\n const height = svgElement.clientHeight ?? parseInt(svgElement.getAttribute(\"height\") ?? \"600\", 10);\n return { width, height };\n};\n\nexport interface PrepareSvgCloneArgs {\n svgElement: SVGSVGElement;\n dimensions: Dimensions;\n}\n\n/**\n * Clones an SVG element and ensures it has the required width and height attributes.\n *\n * This function is necessary for two main reasons:\n *\n * 1. **Defensive cloning**: Cloning prevents modifying the original SVG element in the DOM.\n * Although `XMLSerializer.serializeToString()` does not modify the element, cloning ensures\n * that no accidental modifications are made to the source element.\n *\n * 2. **Required width/height attributes**: When converting SVG → PNG via `svgToPngDataUri`,\n * the HTML Image element requires the SVG to have explicit intrinsic dimensions.\n * Without width/height attributes, the SVG may not render correctly on the canvas,\n * resulting in an incorrect or empty PNG image.\n *\n * @param svgElement - The original SVG element to clone\n * @param dimensions - The dimensions to apply to the cloned SVG if attributes are missing\n * @returns A new cloned SVG element with guaranteed width/height attributes\n */\nexport const prepareSvgClone = ({ svgElement, dimensions }: PrepareSvgCloneArgs): SVGSVGElement => {\n const clonedSvg = svgElement.cloneNode(true) as SVGSVGElement;\n\n if (!clonedSvg.hasAttribute(\"width\")) {\n clonedSvg.setAttribute(\"width\", dimensions.width.toString());\n }\n if (!clonedSvg.hasAttribute(\"height\")) {\n clonedSvg.setAttribute(\"height\", dimensions.height.toString());\n }\n\n return clonedSvg;\n};\n\nexport const convertSvgToDataUri = (svgXml: string): string => {\n const encoder = new TextEncoder();\n const data = encoder.encode(svgXml);\n let binaryString = \"\";\n for (let i = 0; i < data.length; i++) {\n binaryString += String.fromCharCode(data[i]);\n }\n const base64 = btoa(binaryString);\n return `data:image/svg+xml;base64,${base64}`;\n};\n\nexport interface ResizeSvgXmlArgs {\n svgXml: string;\n targetWidth: number;\n targetHeight: number;\n}\n\n/**\n * Modifies SVG XML to set the root <svg> width and height attributes.\n * Used to resize the SVG before converting to PNG at target dimensions (e.g. from PDF layout).\n */\nexport const resizeSvgXml = ({ svgXml, targetWidth, targetHeight }: ResizeSvgXmlArgs): string => {\n const widthAttr = `width=\"${targetWidth}\"`;\n const heightAttr = `height=\"${targetHeight}\"`;\n\n let result = svgXml.replace(/\\bwidth=[\"'][^\"']*[\"']/, widthAttr);\n if (!/\\bwidth\\s*=/.test(result)) {\n result = result.replace(/<svg/, `<svg ${widthAttr}`);\n }\n\n result = result.replace(/\\bheight=[\"'][^\"']*[\"']/, heightAttr);\n if (!/\\bheight\\s*=/.test(result)) {\n result = result.replace(/<svg/, `<svg ${heightAttr}`);\n }\n\n return result;\n};\n\nexport interface GetChartAsPngDataUriArgs {\n chartElementId: string;\n width: number;\n height: number;\n}\n\n/**\n * Gets the Recharts chart as a PNG data URI at the given dimensions (e.g. from PDF zone).\n * Resizes the SVG via resizeSvgXml before conversion; does not use the SVG's intrinsic dimensions.\n */\nexport const getChartAsPngDataUri = async ({\n chartElementId,\n width,\n height,\n}: GetChartAsPngDataUriArgs): Promise<string | null> => {\n if (!chartElementId) {\n return null;\n }\n\n const chartElement: HTMLElement | null = getElement(chartElementId);\n if (!chartElement) {\n return null;\n }\n\n const svgElement: SVGSVGElement | null = getRechartsSvgFromElement({ chartElement, chartElementId });\n if (!svgElement) {\n return null;\n }\n\n const svgXml: string = new XMLSerializer().serializeToString(svgElement);\n const resizedXml: string = resizeSvgXml({ svgXml, targetWidth: width, targetHeight: height });\n const svgDataUri: string = convertSvgToDataUri(resizedXml);\n\n return svgToPngDataUri({\n svgDataUri,\n dimensions: { width, height },\n backgroundColor: \"white\",\n });\n};\n\n/**\n * Retrieves the SVG from a Recharts chart element and converts it to SVG base64\n * @param chartElementId - The ID of the element containing the chart\n * @returns The SVG encoded in base64 with data URI prefix (data:image/svg+xml;base64,...), or null if an error occurs\n */\nexport const getSvgAsBase64DataUri = (chartElementId: string): string | null => {\n const svgXml = getRechartSvgXml(chartElementId);\n if (!svgXml) {\n return null;\n }\n\n return convertSvgToDataUri(svgXml);\n};\n\nexport const getRechartSvgXml = (chartElementId: string): string | null => {\n if (!chartElementId) {\n console.info(`[getRechartSvgXml] No chart element id provided`);\n return null;\n }\n\n const chartElement: HTMLElement | null = getElement(chartElementId);\n if (!chartElement) {\n console.info(`[getRechartSvgXml] Element with id \"${chartElementId}\" not found`);\n return null;\n }\n\n const svgElement: SVGSVGElement | null = getRechartsSvgFromElement({ chartElement, chartElementId });\n if (!svgElement) {\n console.info(`[getRechartSvgXml] No SVG element found inside element with id \"${chartElementId}\"`);\n return null;\n }\n\n const dimensions = getSvgDimensions(svgElement);\n const clonedSvg: SVGSVGElement = prepareSvgClone({ svgElement, dimensions });\n const svgXml: string = new XMLSerializer().serializeToString(clonedSvg);\n\n return svgXml;\n};\n\nexport interface SvgToPngArgs {\n svgDataUri?: string | null;\n dimensions: Dimensions;\n backgroundColor?: string;\n}\n\nexport const svgToPngDataUri = async ({\n svgDataUri,\n dimensions,\n backgroundColor,\n}: SvgToPngArgs): Promise<string | null> => {\n if (!svgDataUri) {\n return null;\n }\n\n const { width, height } = dimensions;\n\n return new Promise((resolve, reject) => {\n const img = new Image();\n\n img.onload = () => {\n try {\n const canvas = document.createElement(\"canvas\");\n canvas.width = width;\n canvas.height = height;\n\n const ctx = canvas.getContext(\"2d\");\n if (!ctx) {\n reject(new Error(\"Failed to get canvas 2D context\"));\n return;\n }\n\n if (backgroundColor) {\n ctx.fillStyle = backgroundColor;\n ctx.fillRect(0, 0, width, height);\n }\n\n ctx.drawImage(img, 0, 0, width, height);\n const pngDataUri = canvas.toDataURL(\"image/png\");\n resolve(pngDataUri);\n } catch (error) {\n reject(error);\n }\n };\n\n img.onerror = (error) => {\n const message = getErrorMessage(error);\n reject(new Error(`Failed to load SVG image: ${message}`));\n };\n\n img.src = svgDataUri;\n });\n};\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lichens-innovation/ts-common",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.14.0",
|
|
4
4
|
"description": "Reusable generic typescript utilities, types, constants, helpers",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"typescript",
|
|
@@ -69,9 +69,12 @@
|
|
|
69
69
|
"registry": "https://registry.npmjs.org/"
|
|
70
70
|
},
|
|
71
71
|
"scripts": {
|
|
72
|
+
"prepare": "husky",
|
|
72
73
|
"clean:node": "npx rimraf node_modules yarn.lock",
|
|
73
74
|
"clean:dist": "npx rimraf dist",
|
|
74
75
|
"typecheck": "npx tsc --noEmit",
|
|
76
|
+
"lint": "eslint .",
|
|
77
|
+
"lint:fix": "eslint . --fix",
|
|
75
78
|
"build": "tsup",
|
|
76
79
|
"test": "vitest run --coverage",
|
|
77
80
|
"test:watch": "vitest",
|
|
@@ -113,7 +116,7 @@
|
|
|
113
116
|
}
|
|
114
117
|
},
|
|
115
118
|
"engines": {
|
|
116
|
-
"node": ">=20.
|
|
119
|
+
"node": ">=20.11.0"
|
|
117
120
|
},
|
|
118
121
|
"devDependencies": {
|
|
119
122
|
"@commitlint/cli": "^20.4.3",
|
|
@@ -127,6 +130,7 @@
|
|
|
127
130
|
"cross-env": "^10.1.0",
|
|
128
131
|
"eslint": "^10.0.2",
|
|
129
132
|
"exceljs": "^4.4.0",
|
|
133
|
+
"globals": "^17.4.0",
|
|
130
134
|
"husky": "^9.1.7",
|
|
131
135
|
"jspdf": "^4.2.0",
|
|
132
136
|
"jspdf-autotable": "^5.0.7",
|