@parsrun/core 0.2.5 → 0.2.9
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/dist/decimal.d.ts +79 -9
- package/dist/decimal.js +158 -76
- package/dist/decimal.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +158 -76
- package/dist/index.js.map +1 -1
- package/package.json +4 -1
package/dist/decimal.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/decimal.ts"],"sourcesContent":["/**\n * @parsrun/core - Decimal Utilities\n * Precise decimal calculations for financial and quantity operations.\n * Edge-compatible - no external dependencies.\n *\n * @example\n * ```typescript\n * import { Decimal, decimal } from '@parsrun/core';\n *\n * // Create decimals\n * const price = new Decimal('19.99');\n * const quantity = decimal(3);\n *\n * // Arithmetic operations (chainable)\n * const total = price.mul(quantity).round(2);\n * console.log(total.toString()); // '59.97'\n *\n * // Static helpers\n * const sum = Decimal.sum(['10.50', '20.25', '15.75']);\n * const avg = Decimal.avg([100, 200, 300]);\n * ```\n */\n\n/**\n * Internal precision for calculations (number of decimal places)\n */\nconst PRECISION = 20;\n\n/**\n * Decimal class for precise arithmetic operations.\n * Uses string-based representation internally to avoid floating point issues.\n *\n * @example\n * ```typescript\n * const a = new Decimal('0.1');\n * const b = new Decimal('0.2');\n * const c = a.add(b);\n * console.log(c.toString()); // '0.3' (not 0.30000000000000004)\n * ```\n */\nexport class Decimal {\n private value: string;\n\n constructor(value: number | string | Decimal) {\n if (value instanceof Decimal) {\n this.value = value.value;\n } else if (typeof value === \"number\") {\n this.value = this.normalizeNumber(value);\n } else {\n this.value = this.normalizeString(value);\n }\n }\n\n private normalizeNumber(n: number): string {\n if (!isFinite(n)) {\n throw new Error(`Invalid number: ${n}`);\n }\n return n.toFixed(PRECISION).replace(/\\.?0+$/, \"\") || \"0\";\n }\n\n private normalizeString(s: string): string {\n const trimmed = s.trim();\n if (!/^-?\\d*\\.?\\d+$/.test(trimmed)) {\n throw new Error(`Invalid decimal string: ${s}`);\n }\n return trimmed.replace(/^(-?)0+(?=\\d)/, \"$1\").replace(/\\.?0+$/, \"\") || \"0\";\n }\n\n /**\n * Add another value to this decimal.\n * @param other - Value to add\n * @returns A new Decimal with the result\n */\n add(other: number | string | Decimal): Decimal {\n const a = parseFloat(this.value);\n const b = parseFloat(other instanceof Decimal ? other.value : String(other));\n return new Decimal(a + b);\n }\n\n /**\n * Subtract a value from this decimal.\n * @param other - Value to subtract\n * @returns A new Decimal with the result\n */\n sub(other: number | string | Decimal): Decimal {\n const a = parseFloat(this.value);\n const b = parseFloat(other instanceof Decimal ? other.value : String(other));\n return new Decimal(a - b);\n }\n\n /**\n * Multiply this decimal by another value.\n * @param other - Value to multiply by\n * @returns A new Decimal with the result\n */\n mul(other: number | string | Decimal): Decimal {\n const a = parseFloat(this.value);\n const b = parseFloat(other instanceof Decimal ? other.value : String(other));\n return new Decimal(a * b);\n }\n\n /**\n * Divide this decimal by another value.\n * @param other - Value to divide by\n * @returns A new Decimal with the result\n * @throws Error if dividing by zero\n */\n div(other: number | string | Decimal): Decimal {\n const a = parseFloat(this.value);\n const b = parseFloat(other instanceof Decimal ? other.value : String(other));\n if (b === 0) {\n throw new Error(\"Division by zero\");\n }\n return new Decimal(a / b);\n }\n\n /**\n * Get the modulo (remainder) of dividing this decimal by another value.\n * @param other - Value to divide by\n * @returns A new Decimal with the remainder\n */\n mod(other: number | string | Decimal): Decimal {\n const a = parseFloat(this.value);\n const b = parseFloat(other instanceof Decimal ? other.value : String(other));\n return new Decimal(a % b);\n }\n\n /**\n * Raise this decimal to a power.\n * @param exp - The exponent\n * @returns A new Decimal with the result\n */\n pow(exp: number): Decimal {\n const a = parseFloat(this.value);\n return new Decimal(Math.pow(a, exp));\n }\n\n /**\n * Calculate the square root of this decimal.\n * @returns A new Decimal with the square root\n * @throws Error if the value is negative\n */\n sqrt(): Decimal {\n const a = parseFloat(this.value);\n if (a < 0) {\n throw new Error(\"Square root of negative number\");\n }\n return new Decimal(Math.sqrt(a));\n }\n\n /**\n * Get the absolute value of this decimal.\n * @returns A new Decimal with the absolute value\n */\n abs(): Decimal {\n const a = parseFloat(this.value);\n return new Decimal(Math.abs(a));\n }\n\n /**\n * Negate this decimal (multiply by -1).\n * @returns A new Decimal with the negated value\n */\n neg(): Decimal {\n const a = parseFloat(this.value);\n return new Decimal(-a);\n }\n\n /**\n * Round to the specified number of decimal places using standard rounding.\n * @param decimals - Number of decimal places (default: 0)\n * @returns A new Decimal with the rounded value\n */\n round(decimals: number = 0): Decimal {\n const a = parseFloat(this.value);\n const factor = Math.pow(10, decimals);\n return new Decimal(Math.round(a * factor) / factor);\n }\n\n /**\n * Round down to the specified number of decimal places.\n * @param decimals - Number of decimal places (default: 0)\n * @returns A new Decimal with the floored value\n */\n floor(decimals: number = 0): Decimal {\n const a = parseFloat(this.value);\n const factor = Math.pow(10, decimals);\n return new Decimal(Math.floor(a * factor) / factor);\n }\n\n /**\n * Round up to the specified number of decimal places.\n * @param decimals - Number of decimal places (default: 0)\n * @returns A new Decimal with the ceiled value\n */\n ceil(decimals: number = 0): Decimal {\n const a = parseFloat(this.value);\n const factor = Math.pow(10, decimals);\n return new Decimal(Math.ceil(a * factor) / factor);\n }\n\n /**\n * Compare this decimal to another value.\n * @param other - Value to compare against\n * @returns -1 if less, 0 if equal, 1 if greater\n */\n cmp(other: number | string | Decimal): -1 | 0 | 1 {\n const a = parseFloat(this.value);\n const b = parseFloat(other instanceof Decimal ? other.value : String(other));\n if (a < b) return -1;\n if (a > b) return 1;\n return 0;\n }\n\n /**\n * Check if this decimal equals another value.\n * @param other - Value to compare against\n * @returns True if values are equal\n */\n eq(other: number | string | Decimal): boolean {\n return this.cmp(other) === 0;\n }\n\n /**\n * Check if this decimal is greater than another value.\n * @param other - Value to compare against\n * @returns True if this is greater\n */\n gt(other: number | string | Decimal): boolean {\n return this.cmp(other) === 1;\n }\n\n /**\n * Check if this decimal is greater than or equal to another value.\n * @param other - Value to compare against\n * @returns True if this is greater or equal\n */\n gte(other: number | string | Decimal): boolean {\n return this.cmp(other) >= 0;\n }\n\n /**\n * Check if this decimal is less than another value.\n * @param other - Value to compare against\n * @returns True if this is less\n */\n lt(other: number | string | Decimal): boolean {\n return this.cmp(other) === -1;\n }\n\n /**\n * Check if this decimal is less than or equal to another value.\n * @param other - Value to compare against\n * @returns True if this is less or equal\n */\n lte(other: number | string | Decimal): boolean {\n return this.cmp(other) <= 0;\n }\n\n /**\n * Check if this decimal is exactly zero.\n * @returns True if value is zero\n */\n isZero(): boolean {\n return parseFloat(this.value) === 0;\n }\n\n /**\n * Check if this decimal is positive (greater than zero).\n * @returns True if value is positive\n */\n isPositive(): boolean {\n return parseFloat(this.value) > 0;\n }\n\n /**\n * Check if this decimal is negative (less than zero).\n * @returns True if value is negative\n */\n isNegative(): boolean {\n return parseFloat(this.value) < 0;\n }\n\n /**\n * Convert this decimal to a JavaScript number.\n * @returns The numeric value\n */\n toNumber(): number {\n return parseFloat(this.value);\n }\n\n /**\n * Convert this decimal to its string representation.\n * @returns The string value\n */\n toString(): string {\n return this.value;\n }\n\n /**\n * Format this decimal with a fixed number of decimal places.\n * @param decimals - Number of decimal places (default: 2)\n * @returns Formatted string\n */\n toFixed(decimals: number = 2): string {\n return parseFloat(this.value).toFixed(decimals);\n }\n\n /**\n * Convert to JSON (returns string representation for serialization).\n * @returns The string value for JSON serialization\n */\n toJSON(): string {\n return this.value;\n }\n\n /**\n * Create a Decimal from a value (alias for constructor).\n * @param value - The value to convert\n * @returns A new Decimal instance\n */\n static from(value: number | string | Decimal): Decimal {\n return new Decimal(value);\n }\n\n /**\n * Calculate the sum of an array of values.\n * @param values - Array of values to sum\n * @returns A new Decimal with the sum\n */\n static sum(values: (number | string | Decimal)[]): Decimal {\n return values.reduce<Decimal>(\n (acc, val) => acc.add(val),\n new Decimal(0)\n );\n }\n\n /**\n * Calculate the average of an array of values.\n * @param values - Array of values to average\n * @returns A new Decimal with the average (0 if empty array)\n */\n static avg(values: (number | string | Decimal)[]): Decimal {\n if (values.length === 0) return new Decimal(0);\n return Decimal.sum(values).div(values.length);\n }\n\n /**\n * Find the minimum value from the provided values.\n * @param values - Values to compare\n * @returns A new Decimal with the minimum value\n * @throws Error if no values provided\n */\n static min(...values: (number | string | Decimal)[]): Decimal {\n if (values.length === 0) throw new Error(\"No values provided\");\n return values.reduce<Decimal>((min, val) => {\n const d = new Decimal(val);\n return d.lt(min) ? d : min;\n }, new Decimal(values[0]!));\n }\n\n /**\n * Find the maximum value from the provided values.\n * @param values - Values to compare\n * @returns A new Decimal with the maximum value\n * @throws Error if no values provided\n */\n static max(...values: (number | string | Decimal)[]): Decimal {\n if (values.length === 0) throw new Error(\"No values provided\");\n return values.reduce<Decimal>((max, val) => {\n const d = new Decimal(val);\n return d.gt(max) ? d : max;\n }, new Decimal(values[0]!));\n }\n}\n\n/**\n * Utility functions for working with decimals in database operations.\n * Provides helpers for converting between JavaScript numbers and database decimal strings.\n *\n * @example\n * ```typescript\n * // Convert numeric fields before database insert\n * const data = DecimalUtils.prepareForDatabase(\n * { price: 19.99, quantity: 5 },\n * ['price']\n * );\n *\n * // Format for display\n * DecimalUtils.formatCurrency('19.99', { currency: 'USD' }); // '$19.99'\n * ```\n */\nexport const DecimalUtils = {\n /**\n * Convert a number to a database-safe decimal string.\n * @param value - The value to convert\n * @returns The decimal string or null if value is null/undefined\n */\n toDecimalString(value: number | string | null | undefined): string | null {\n if (value === null || value === undefined) return null;\n return new Decimal(value).toString();\n },\n\n /**\n * Convert a database decimal string to a JavaScript number.\n * @param value - The decimal string from database\n * @returns The numeric value (0 if null/undefined/empty)\n */\n fromDecimalString(value: string | null | undefined): number {\n if (!value) return 0;\n return new Decimal(value).toNumber();\n },\n\n /**\n * Multiply two values with precise decimal arithmetic.\n * @param a - First value\n * @param b - Second value\n * @returns The product as a string\n */\n multiply(a: number | string, b: number | string): string {\n return new Decimal(a).mul(b).toString();\n },\n\n /**\n * Add two values with precise decimal arithmetic.\n * @param a - First value\n * @param b - Second value\n * @returns The sum as a string\n */\n add(a: number | string, b: number | string): string {\n return new Decimal(a).add(b).toString();\n },\n\n /**\n * Subtract two values with precise decimal arithmetic.\n * @param a - Value to subtract from\n * @param b - Value to subtract\n * @returns The difference as a string\n */\n subtract(a: number | string, b: number | string): string {\n return new Decimal(a).sub(b).toString();\n },\n\n /**\n * Divide two values with precise decimal arithmetic.\n * @param a - Dividend\n * @param b - Divisor\n * @returns The quotient as a string\n */\n divide(a: number | string, b: number | string): string {\n return new Decimal(a).div(b).toString();\n },\n\n /**\n * Format a decimal value for display with fixed decimal places.\n * @param value - The value to format\n * @param decimalPlaces - Number of decimal places (default: 2)\n * @returns Formatted string\n */\n format(value: string | number, decimalPlaces: number = 2): string {\n return new Decimal(value).toFixed(decimalPlaces);\n },\n\n /**\n * Format a value as currency using Intl.NumberFormat.\n * @param value - The value to format\n * @param options - Currency formatting options\n * @returns Formatted currency string\n */\n formatCurrency(\n value: string | number,\n options: {\n currency?: string;\n locale?: string;\n decimals?: number;\n } = {}\n ): string {\n const { currency = \"USD\", locale = \"en-US\", decimals = 2 } = options;\n const num = new Decimal(value).toNumber();\n return new Intl.NumberFormat(locale, {\n style: \"currency\",\n currency,\n minimumFractionDigits: decimals,\n maximumFractionDigits: decimals,\n }).format(num);\n },\n\n /**\n * Prepare an object for database insert/update by converting numeric fields to decimal strings.\n * @param data - The object to prepare\n * @param decimalFields - Array of field names that should be converted to decimal strings\n * @returns A new object with specified fields converted to decimal strings\n */\n prepareForDatabase<T extends Record<string, unknown>>(\n data: T,\n decimalFields: string[]\n ): T {\n const result = { ...data };\n for (const field of decimalFields) {\n if (field in result && result[field] !== undefined && result[field] !== null) {\n const value = result[field];\n if (typeof value === \"number\") {\n (result as Record<string, unknown>)[field] = DecimalUtils.toDecimalString(value);\n }\n }\n }\n return result;\n },\n\n /**\n * Parse an object from database by converting decimal string fields to JavaScript numbers.\n * @param data - The object from database\n * @param decimalFields - Array of field names that should be converted from decimal strings\n * @returns A new object with specified fields converted to numbers\n */\n parseFromDatabase<T extends Record<string, unknown>>(\n data: T,\n decimalFields: string[]\n ): T {\n const result = { ...data };\n for (const field of decimalFields) {\n if (field in result && result[field] !== undefined && result[field] !== null) {\n const value = result[field];\n if (typeof value === \"string\") {\n (result as Record<string, unknown>)[field] = DecimalUtils.fromDecimalString(value);\n }\n }\n }\n return result;\n },\n};\n\n/**\n * Shorthand function for creating a Decimal instance.\n *\n * @param value - The value to convert to a Decimal\n * @returns A new Decimal instance\n *\n * @example\n * ```typescript\n * const price = decimal('19.99');\n * const total = decimal(100).mul(price);\n * ```\n */\nexport function decimal(value: number | string): Decimal {\n return new Decimal(value);\n}\n"],"mappings":";AA0BA,IAAM,YAAY;AAcX,IAAM,UAAN,MAAM,SAAQ;AAAA,EACX;AAAA,EAER,YAAY,OAAkC;AAC5C,QAAI,iBAAiB,UAAS;AAC5B,WAAK,QAAQ,MAAM;AAAA,IACrB,WAAW,OAAO,UAAU,UAAU;AACpC,WAAK,QAAQ,KAAK,gBAAgB,KAAK;AAAA,IACzC,OAAO;AACL,WAAK,QAAQ,KAAK,gBAAgB,KAAK;AAAA,IACzC;AAAA,EACF;AAAA,EAEQ,gBAAgB,GAAmB;AACzC,QAAI,CAAC,SAAS,CAAC,GAAG;AAChB,YAAM,IAAI,MAAM,mBAAmB,CAAC,EAAE;AAAA,IACxC;AACA,WAAO,EAAE,QAAQ,SAAS,EAAE,QAAQ,UAAU,EAAE,KAAK;AAAA,EACvD;AAAA,EAEQ,gBAAgB,GAAmB;AACzC,UAAM,UAAU,EAAE,KAAK;AACvB,QAAI,CAAC,gBAAgB,KAAK,OAAO,GAAG;AAClC,YAAM,IAAI,MAAM,2BAA2B,CAAC,EAAE;AAAA,IAChD;AACA,WAAO,QAAQ,QAAQ,iBAAiB,IAAI,EAAE,QAAQ,UAAU,EAAE,KAAK;AAAA,EACzE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,IAAI,OAA2C;AAC7C,UAAM,IAAI,WAAW,KAAK,KAAK;AAC/B,UAAM,IAAI,WAAW,iBAAiB,WAAU,MAAM,QAAQ,OAAO,KAAK,CAAC;AAC3E,WAAO,IAAI,SAAQ,IAAI,CAAC;AAAA,EAC1B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,IAAI,OAA2C;AAC7C,UAAM,IAAI,WAAW,KAAK,KAAK;AAC/B,UAAM,IAAI,WAAW,iBAAiB,WAAU,MAAM,QAAQ,OAAO,KAAK,CAAC;AAC3E,WAAO,IAAI,SAAQ,IAAI,CAAC;AAAA,EAC1B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,IAAI,OAA2C;AAC7C,UAAM,IAAI,WAAW,KAAK,KAAK;AAC/B,UAAM,IAAI,WAAW,iBAAiB,WAAU,MAAM,QAAQ,OAAO,KAAK,CAAC;AAC3E,WAAO,IAAI,SAAQ,IAAI,CAAC;AAAA,EAC1B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,IAAI,OAA2C;AAC7C,UAAM,IAAI,WAAW,KAAK,KAAK;AAC/B,UAAM,IAAI,WAAW,iBAAiB,WAAU,MAAM,QAAQ,OAAO,KAAK,CAAC;AAC3E,QAAI,MAAM,GAAG;AACX,YAAM,IAAI,MAAM,kBAAkB;AAAA,IACpC;AACA,WAAO,IAAI,SAAQ,IAAI,CAAC;AAAA,EAC1B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,IAAI,OAA2C;AAC7C,UAAM,IAAI,WAAW,KAAK,KAAK;AAC/B,UAAM,IAAI,WAAW,iBAAiB,WAAU,MAAM,QAAQ,OAAO,KAAK,CAAC;AAC3E,WAAO,IAAI,SAAQ,IAAI,CAAC;AAAA,EAC1B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,IAAI,KAAsB;AACxB,UAAM,IAAI,WAAW,KAAK,KAAK;AAC/B,WAAO,IAAI,SAAQ,KAAK,IAAI,GAAG,GAAG,CAAC;AAAA,EACrC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,OAAgB;AACd,UAAM,IAAI,WAAW,KAAK,KAAK;AAC/B,QAAI,IAAI,GAAG;AACT,YAAM,IAAI,MAAM,gCAAgC;AAAA,IAClD;AACA,WAAO,IAAI,SAAQ,KAAK,KAAK,CAAC,CAAC;AAAA,EACjC;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAe;AACb,UAAM,IAAI,WAAW,KAAK,KAAK;AAC/B,WAAO,IAAI,SAAQ,KAAK,IAAI,CAAC,CAAC;AAAA,EAChC;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAe;AACb,UAAM,IAAI,WAAW,KAAK,KAAK;AAC/B,WAAO,IAAI,SAAQ,CAAC,CAAC;AAAA,EACvB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,WAAmB,GAAY;AACnC,UAAM,IAAI,WAAW,KAAK,KAAK;AAC/B,UAAM,SAAS,KAAK,IAAI,IAAI,QAAQ;AACpC,WAAO,IAAI,SAAQ,KAAK,MAAM,IAAI,MAAM,IAAI,MAAM;AAAA,EACpD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,WAAmB,GAAY;AACnC,UAAM,IAAI,WAAW,KAAK,KAAK;AAC/B,UAAM,SAAS,KAAK,IAAI,IAAI,QAAQ;AACpC,WAAO,IAAI,SAAQ,KAAK,MAAM,IAAI,MAAM,IAAI,MAAM;AAAA,EACpD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,KAAK,WAAmB,GAAY;AAClC,UAAM,IAAI,WAAW,KAAK,KAAK;AAC/B,UAAM,SAAS,KAAK,IAAI,IAAI,QAAQ;AACpC,WAAO,IAAI,SAAQ,KAAK,KAAK,IAAI,MAAM,IAAI,MAAM;AAAA,EACnD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,IAAI,OAA8C;AAChD,UAAM,IAAI,WAAW,KAAK,KAAK;AAC/B,UAAM,IAAI,WAAW,iBAAiB,WAAU,MAAM,QAAQ,OAAO,KAAK,CAAC;AAC3E,QAAI,IAAI,EAAG,QAAO;AAClB,QAAI,IAAI,EAAG,QAAO;AAClB,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,GAAG,OAA2C;AAC5C,WAAO,KAAK,IAAI,KAAK,MAAM;AAAA,EAC7B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,GAAG,OAA2C;AAC5C,WAAO,KAAK,IAAI,KAAK,MAAM;AAAA,EAC7B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,IAAI,OAA2C;AAC7C,WAAO,KAAK,IAAI,KAAK,KAAK;AAAA,EAC5B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,GAAG,OAA2C;AAC5C,WAAO,KAAK,IAAI,KAAK,MAAM;AAAA,EAC7B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,IAAI,OAA2C;AAC7C,WAAO,KAAK,IAAI,KAAK,KAAK;AAAA,EAC5B;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,SAAkB;AAChB,WAAO,WAAW,KAAK,KAAK,MAAM;AAAA,EACpC;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,aAAsB;AACpB,WAAO,WAAW,KAAK,KAAK,IAAI;AAAA,EAClC;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,aAAsB;AACpB,WAAO,WAAW,KAAK,KAAK,IAAI;AAAA,EAClC;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,WAAmB;AACjB,WAAO,WAAW,KAAK,KAAK;AAAA,EAC9B;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,WAAmB;AACjB,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,QAAQ,WAAmB,GAAW;AACpC,WAAO,WAAW,KAAK,KAAK,EAAE,QAAQ,QAAQ;AAAA,EAChD;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,SAAiB;AACf,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,OAAO,KAAK,OAA2C;AACrD,WAAO,IAAI,SAAQ,KAAK;AAAA,EAC1B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,OAAO,IAAI,QAAgD;AACzD,WAAO,OAAO;AAAA,MACZ,CAAC,KAAK,QAAQ,IAAI,IAAI,GAAG;AAAA,MACzB,IAAI,SAAQ,CAAC;AAAA,IACf;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,OAAO,IAAI,QAAgD;AACzD,QAAI,OAAO,WAAW,EAAG,QAAO,IAAI,SAAQ,CAAC;AAC7C,WAAO,SAAQ,IAAI,MAAM,EAAE,IAAI,OAAO,MAAM;AAAA,EAC9C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,OAAO,OAAO,QAAgD;AAC5D,QAAI,OAAO,WAAW,EAAG,OAAM,IAAI,MAAM,oBAAoB;AAC7D,WAAO,OAAO,OAAgB,CAAC,KAAK,QAAQ;AAC1C,YAAM,IAAI,IAAI,SAAQ,GAAG;AACzB,aAAO,EAAE,GAAG,GAAG,IAAI,IAAI;AAAA,IACzB,GAAG,IAAI,SAAQ,OAAO,CAAC,CAAE,CAAC;AAAA,EAC5B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,OAAO,OAAO,QAAgD;AAC5D,QAAI,OAAO,WAAW,EAAG,OAAM,IAAI,MAAM,oBAAoB;AAC7D,WAAO,OAAO,OAAgB,CAAC,KAAK,QAAQ;AAC1C,YAAM,IAAI,IAAI,SAAQ,GAAG;AACzB,aAAO,EAAE,GAAG,GAAG,IAAI,IAAI;AAAA,IACzB,GAAG,IAAI,SAAQ,OAAO,CAAC,CAAE,CAAC;AAAA,EAC5B;AACF;AAkBO,IAAM,eAAe;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAM1B,gBAAgB,OAA0D;AACxE,QAAI,UAAU,QAAQ,UAAU,OAAW,QAAO;AAClD,WAAO,IAAI,QAAQ,KAAK,EAAE,SAAS;AAAA,EACrC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,kBAAkB,OAA0C;AAC1D,QAAI,CAAC,MAAO,QAAO;AACnB,WAAO,IAAI,QAAQ,KAAK,EAAE,SAAS;AAAA,EACrC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,SAAS,GAAoB,GAA4B;AACvD,WAAO,IAAI,QAAQ,CAAC,EAAE,IAAI,CAAC,EAAE,SAAS;AAAA,EACxC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,IAAI,GAAoB,GAA4B;AAClD,WAAO,IAAI,QAAQ,CAAC,EAAE,IAAI,CAAC,EAAE,SAAS;AAAA,EACxC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,SAAS,GAAoB,GAA4B;AACvD,WAAO,IAAI,QAAQ,CAAC,EAAE,IAAI,CAAC,EAAE,SAAS;AAAA,EACxC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,OAAO,GAAoB,GAA4B;AACrD,WAAO,IAAI,QAAQ,CAAC,EAAE,IAAI,CAAC,EAAE,SAAS;AAAA,EACxC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,OAAO,OAAwB,gBAAwB,GAAW;AAChE,WAAO,IAAI,QAAQ,KAAK,EAAE,QAAQ,aAAa;AAAA,EACjD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,eACE,OACA,UAII,CAAC,GACG;AACR,UAAM,EAAE,WAAW,OAAO,SAAS,SAAS,WAAW,EAAE,IAAI;AAC7D,UAAM,MAAM,IAAI,QAAQ,KAAK,EAAE,SAAS;AACxC,WAAO,IAAI,KAAK,aAAa,QAAQ;AAAA,MACnC,OAAO;AAAA,MACP;AAAA,MACA,uBAAuB;AAAA,MACvB,uBAAuB;AAAA,IACzB,CAAC,EAAE,OAAO,GAAG;AAAA,EACf;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,mBACE,MACA,eACG;AACH,UAAM,SAAS,EAAE,GAAG,KAAK;AACzB,eAAW,SAAS,eAAe;AACjC,UAAI,SAAS,UAAU,OAAO,KAAK,MAAM,UAAa,OAAO,KAAK,MAAM,MAAM;AAC5E,cAAM,QAAQ,OAAO,KAAK;AAC1B,YAAI,OAAO,UAAU,UAAU;AAC7B,UAAC,OAAmC,KAAK,IAAI,aAAa,gBAAgB,KAAK;AAAA,QACjF;AAAA,MACF;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,kBACE,MACA,eACG;AACH,UAAM,SAAS,EAAE,GAAG,KAAK;AACzB,eAAW,SAAS,eAAe;AACjC,UAAI,SAAS,UAAU,OAAO,KAAK,MAAM,UAAa,OAAO,KAAK,MAAM,MAAM;AAC5E,cAAM,QAAQ,OAAO,KAAK;AAC1B,YAAI,OAAO,UAAU,UAAU;AAC7B,UAAC,OAAmC,KAAK,IAAI,aAAa,kBAAkB,KAAK;AAAA,QACnF;AAAA,MACF;AAAA,IACF;AACA,WAAO;AAAA,EACT;AACF;AAcO,SAAS,QAAQ,OAAiC;AACvD,SAAO,IAAI,QAAQ,KAAK;AAC1B;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/decimal.ts"],"sourcesContent":["/**\n * @parsrun/core - Decimal Utilities\n * Precise decimal calculations for financial and quantity operations.\n * Edge-compatible - wraps decimal.js for arbitrary precision arithmetic.\n *\n * @example\n * ```typescript\n * import { Decimal, decimal } from '@parsrun/core';\n *\n * // Create decimals\n * const price = new Decimal('19.99');\n * const quantity = decimal(3);\n *\n * // Arithmetic operations (chainable)\n * const total = price.mul(quantity).round(2);\n * console.log(total.toString()); // '59.97'\n *\n * // Precision info\n * const d = new Decimal('123.45');\n * d.precision(); // 5 (total significant digits)\n * d.decimalPlaces(); // 2 (digits after decimal point)\n *\n * // Static helpers\n * const sum = Decimal.sum(['10.50', '20.25', '15.75']);\n * const avg = Decimal.avg([100, 200, 300]);\n * ```\n */\n\nimport DecimalJS from 'decimal.js';\n\n// Configure decimal.js for financial precision\nDecimalJS.set({\n precision: 40,\n rounding: DecimalJS.ROUND_HALF_UP,\n toExpNeg: -9,\n toExpPos: 21,\n});\n\n/**\n * Decimal class for precise arithmetic operations.\n * Wraps decimal.js to provide arbitrary precision decimal arithmetic.\n *\n * @example\n * ```typescript\n * const a = new Decimal('0.1');\n * const b = new Decimal('0.2');\n * const c = a.add(b);\n * console.log(c.toString()); // '0.3' (not 0.30000000000000004)\n * ```\n */\nexport class Decimal {\n private readonly _value: DecimalJS;\n\n constructor(value: number | string | Decimal | DecimalJS) {\n if (value instanceof Decimal) {\n this._value = value._value;\n } else if (value instanceof DecimalJS) {\n this._value = value;\n } else {\n this._value = new DecimalJS(value);\n }\n }\n\n /**\n * Add another value to this decimal.\n * @param other - Value to add\n * @returns A new Decimal with the result\n */\n add(other: number | string | Decimal): Decimal {\n const otherValue = other instanceof Decimal ? other._value : other;\n return new Decimal(this._value.plus(otherValue));\n }\n\n /**\n * Subtract a value from this decimal.\n * @param other - Value to subtract\n * @returns A new Decimal with the result\n */\n sub(other: number | string | Decimal): Decimal {\n const otherValue = other instanceof Decimal ? other._value : other;\n return new Decimal(this._value.minus(otherValue));\n }\n\n /**\n * Multiply this decimal by another value.\n * @param other - Value to multiply by\n * @returns A new Decimal with the result\n */\n mul(other: number | string | Decimal): Decimal {\n const otherValue = other instanceof Decimal ? other._value : other;\n return new Decimal(this._value.times(otherValue));\n }\n\n /**\n * Divide this decimal by another value.\n * @param other - Value to divide by\n * @returns A new Decimal with the result\n * @throws Error if dividing by zero\n */\n div(other: number | string | Decimal): Decimal {\n const otherValue = other instanceof Decimal ? other._value : other;\n const divisor = new DecimalJS(otherValue);\n if (divisor.isZero()) {\n throw new Error('Division by zero');\n }\n return new Decimal(this._value.dividedBy(divisor));\n }\n\n /**\n * Get the modulo (remainder) of dividing this decimal by another value.\n * @param other - Value to divide by\n * @returns A new Decimal with the remainder\n */\n mod(other: number | string | Decimal): Decimal {\n const otherValue = other instanceof Decimal ? other._value : other;\n return new Decimal(this._value.modulo(otherValue));\n }\n\n /**\n * Raise this decimal to a power.\n * @param exp - The exponent\n * @returns A new Decimal with the result\n */\n pow(exp: number): Decimal {\n return new Decimal(this._value.pow(exp));\n }\n\n /**\n * Calculate the square root of this decimal.\n * @returns A new Decimal with the square root\n * @throws Error if the value is negative\n */\n sqrt(): Decimal {\n if (this._value.isNegative()) {\n throw new Error('Square root of negative number');\n }\n return new Decimal(this._value.sqrt());\n }\n\n /**\n * Get the absolute value of this decimal.\n * @returns A new Decimal with the absolute value\n */\n abs(): Decimal {\n return new Decimal(this._value.abs());\n }\n\n /**\n * Negate this decimal (multiply by -1).\n * @returns A new Decimal with the negated value\n */\n neg(): Decimal {\n return new Decimal(this._value.negated());\n }\n\n /**\n * Round to the specified number of decimal places using standard rounding.\n * @param decimals - Number of decimal places (default: 0)\n * @returns A new Decimal with the rounded value\n */\n round(decimals: number = 0): Decimal {\n return new Decimal(this._value.toDecimalPlaces(decimals, DecimalJS.ROUND_HALF_UP));\n }\n\n /**\n * Round down to the specified number of decimal places.\n * @param decimals - Number of decimal places (default: 0)\n * @returns A new Decimal with the floored value\n */\n floor(decimals: number = 0): Decimal {\n return new Decimal(this._value.toDecimalPlaces(decimals, DecimalJS.ROUND_FLOOR));\n }\n\n /**\n * Round up to the specified number of decimal places.\n * @param decimals - Number of decimal places (default: 0)\n * @returns A new Decimal with the ceiled value\n */\n ceil(decimals: number = 0): Decimal {\n return new Decimal(this._value.toDecimalPlaces(decimals, DecimalJS.ROUND_CEIL));\n }\n\n /**\n * Compare this decimal to another value.\n * @param other - Value to compare against\n * @returns -1 if less, 0 if equal, 1 if greater\n */\n cmp(other: number | string | Decimal): -1 | 0 | 1 {\n const otherValue = other instanceof Decimal ? other._value : other;\n return this._value.comparedTo(otherValue) as -1 | 0 | 1;\n }\n\n /**\n * Check if this decimal equals another value.\n * @param other - Value to compare against\n * @returns True if values are equal\n */\n eq(other: number | string | Decimal): boolean {\n const otherValue = other instanceof Decimal ? other._value : other;\n return this._value.equals(otherValue);\n }\n\n /**\n * Check if this decimal is greater than another value.\n * @param other - Value to compare against\n * @returns True if this is greater\n */\n gt(other: number | string | Decimal): boolean {\n const otherValue = other instanceof Decimal ? other._value : other;\n return this._value.greaterThan(otherValue);\n }\n\n /**\n * Check if this decimal is greater than or equal to another value.\n * @param other - Value to compare against\n * @returns True if this is greater or equal\n */\n gte(other: number | string | Decimal): boolean {\n const otherValue = other instanceof Decimal ? other._value : other;\n return this._value.greaterThanOrEqualTo(otherValue);\n }\n\n /**\n * Check if this decimal is less than another value.\n * @param other - Value to compare against\n * @returns True if this is less\n */\n lt(other: number | string | Decimal): boolean {\n const otherValue = other instanceof Decimal ? other._value : other;\n return this._value.lessThan(otherValue);\n }\n\n /**\n * Check if this decimal is less than or equal to another value.\n * @param other - Value to compare against\n * @returns True if this is less or equal\n */\n lte(other: number | string | Decimal): boolean {\n const otherValue = other instanceof Decimal ? other._value : other;\n return this._value.lessThanOrEqualTo(otherValue);\n }\n\n /**\n * Check if this decimal is exactly zero.\n * @returns True if value is zero\n */\n isZero(): boolean {\n return this._value.isZero();\n }\n\n /**\n * Check if this decimal is positive (greater than zero).\n * @returns True if value is positive\n */\n isPositive(): boolean {\n return this._value.isPositive() && !this._value.isZero();\n }\n\n /**\n * Check if this decimal is negative (less than zero).\n * @returns True if value is negative\n */\n isNegative(): boolean {\n return this._value.isNegative();\n }\n\n /**\n * Check if this decimal is an integer (no decimal places).\n * @returns True if value is an integer\n */\n isInteger(): boolean {\n return this._value.isInteger();\n }\n\n /**\n * Get the number of decimal places (digits after the decimal point).\n * @returns Number of decimal places\n *\n * @example\n * ```typescript\n * new Decimal('123.45').decimalPlaces(); // 2\n * new Decimal('100').decimalPlaces(); // 0\n * new Decimal('1.500').decimalPlaces(); // 1 (trailing zeros removed)\n * ```\n */\n decimalPlaces(): number {\n return this._value.decimalPlaces();\n }\n\n /**\n * Get the precision (total number of significant digits).\n * @param includeZeros - If true, include trailing zeros in the count\n * @returns The precision\n *\n * @example\n * ```typescript\n * new Decimal('123.45').precision(); // 5\n * new Decimal('100').precision(); // 1\n * new Decimal('100').precision(true); // 3\n * ```\n */\n precision(includeZeros: boolean = false): number {\n return this._value.precision(includeZeros);\n }\n\n /**\n * Convert this decimal to a JavaScript number.\n * Warning: May lose precision for very large or very precise numbers.\n * @returns The numeric value\n */\n toNumber(): number {\n return this._value.toNumber();\n }\n\n /**\n * Convert this decimal to its string representation.\n * @returns The string value\n */\n toString(): string {\n return this._value.toString();\n }\n\n /**\n * Format this decimal with a fixed number of decimal places.\n * @param decimals - Number of decimal places (default: 2)\n * @returns Formatted string\n */\n toFixed(decimals: number = 2): string {\n return this._value.toFixed(decimals);\n }\n\n /**\n * Convert to JSON (returns string representation for serialization).\n * @returns The string value for JSON serialization\n */\n toJSON(): string {\n return this._value.toString();\n }\n\n /**\n * Get the underlying decimal.js instance.\n * Useful for advanced operations not covered by this wrapper.\n * @returns The underlying DecimalJS instance\n */\n toDecimalJS(): DecimalJS {\n return this._value;\n }\n\n /**\n * Create a Decimal from a value (alias for constructor).\n * @param value - The value to convert\n * @returns A new Decimal instance\n */\n static from(value: number | string | Decimal): Decimal {\n return new Decimal(value);\n }\n\n /**\n * Calculate the sum of an array of values.\n * @param values - Array of values to sum\n * @returns A new Decimal with the sum\n */\n static sum(values: (number | string | Decimal)[]): Decimal {\n return values.reduce<Decimal>(\n (acc, val) => acc.add(val),\n new Decimal(0)\n );\n }\n\n /**\n * Calculate the average of an array of values.\n * @param values - Array of values to average\n * @returns A new Decimal with the average (0 if empty array)\n */\n static avg(values: (number | string | Decimal)[]): Decimal {\n if (values.length === 0) return new Decimal(0);\n return Decimal.sum(values).div(values.length);\n }\n\n /**\n * Find the minimum value from the provided values.\n * @param values - Values to compare\n * @returns A new Decimal with the minimum value\n * @throws Error if no values provided\n */\n static min(...values: (number | string | Decimal)[]): Decimal {\n if (values.length === 0) throw new Error('No values provided');\n return values.reduce<Decimal>((min, val) => {\n const d = new Decimal(val);\n return d.lt(min) ? d : min;\n }, new Decimal(values[0]!));\n }\n\n /**\n * Find the maximum value from the provided values.\n * @param values - Values to compare\n * @returns A new Decimal with the maximum value\n * @throws Error if no values provided\n */\n static max(...values: (number | string | Decimal)[]): Decimal {\n if (values.length === 0) throw new Error('No values provided');\n return values.reduce<Decimal>((max, val) => {\n const d = new Decimal(val);\n return d.gt(max) ? d : max;\n }, new Decimal(values[0]!));\n }\n\n /**\n * Check if a value is a valid decimal representation.\n * @param value - The value to check\n * @returns True if the value can be converted to a Decimal\n */\n static isValid(value: unknown): boolean {\n if (value === null || value === undefined) return false;\n if (value instanceof Decimal) return true;\n try {\n new DecimalJS(value as string | number);\n return true;\n } catch {\n return false;\n }\n }\n\n /**\n * Create a Decimal or return null if the value is invalid.\n * @param value - The value to convert\n * @returns A Decimal or null\n */\n static tryParse(value: unknown): Decimal | null {\n if (!Decimal.isValid(value)) return null;\n return new Decimal(value as number | string | Decimal);\n }\n}\n\n/**\n * Utility functions for working with decimals in database operations.\n * Provides helpers for converting between JavaScript numbers and database decimal strings.\n *\n * @example\n * ```typescript\n * // Convert numeric fields before database insert\n * const data = DecimalUtils.prepareForDatabase(\n * { price: 19.99, quantity: 5 },\n * ['price']\n * );\n *\n * // Format for display\n * DecimalUtils.formatCurrency('19.99', { currency: 'USD' }); // '$19.99'\n * ```\n */\nexport const DecimalUtils = {\n /**\n * Convert a number to a database-safe decimal string.\n * @param value - The value to convert\n * @returns The decimal string or null if value is null/undefined\n */\n toDecimalString(value: number | string | null | undefined): string | null {\n if (value === null || value === undefined) return null;\n return new Decimal(value).toString();\n },\n\n /**\n * Convert a database decimal string to a JavaScript number.\n * @param value - The decimal string from database\n * @returns The numeric value (0 if null/undefined/empty)\n */\n fromDecimalString(value: string | null | undefined): number {\n if (!value) return 0;\n return new Decimal(value).toNumber();\n },\n\n /**\n * Multiply two values with precise decimal arithmetic.\n * @param a - First value\n * @param b - Second value\n * @returns The product as a string\n */\n multiply(a: number | string, b: number | string): string {\n return new Decimal(a).mul(b).toString();\n },\n\n /**\n * Add two values with precise decimal arithmetic.\n * @param a - First value\n * @param b - Second value\n * @returns The sum as a string\n */\n add(a: number | string, b: number | string): string {\n return new Decimal(a).add(b).toString();\n },\n\n /**\n * Subtract two values with precise decimal arithmetic.\n * @param a - Value to subtract from\n * @param b - Value to subtract\n * @returns The difference as a string\n */\n subtract(a: number | string, b: number | string): string {\n return new Decimal(a).sub(b).toString();\n },\n\n /**\n * Divide two values with precise decimal arithmetic.\n * @param a - Dividend\n * @param b - Divisor\n * @returns The quotient as a string\n */\n divide(a: number | string, b: number | string): string {\n return new Decimal(a).div(b).toString();\n },\n\n /**\n * Format a decimal value for display with fixed decimal places.\n * @param value - The value to format\n * @param decimalPlaces - Number of decimal places (default: 2)\n * @returns Formatted string\n */\n format(value: string | number, decimalPlaces: number = 2): string {\n return new Decimal(value).toFixed(decimalPlaces);\n },\n\n /**\n * Format a value as currency using Intl.NumberFormat.\n * @param value - The value to format\n * @param options - Currency formatting options\n * @returns Formatted currency string\n */\n formatCurrency(\n value: string | number,\n options: {\n currency?: string;\n locale?: string;\n decimals?: number;\n } = {}\n ): string {\n const { currency = 'USD', locale = 'en-US', decimals = 2 } = options;\n const num = new Decimal(value).toNumber();\n return new Intl.NumberFormat(locale, {\n style: 'currency',\n currency,\n minimumFractionDigits: decimals,\n maximumFractionDigits: decimals,\n }).format(num);\n },\n\n /**\n * Prepare an object for database insert/update by converting numeric fields to decimal strings.\n * @param data - The object to prepare\n * @param decimalFields - Array of field names that should be converted to decimal strings\n * @returns A new object with specified fields converted to decimal strings\n */\n prepareForDatabase<T extends Record<string, unknown>>(\n data: T,\n decimalFields: string[]\n ): T {\n const result = { ...data };\n for (const field of decimalFields) {\n if (field in result && result[field] !== undefined && result[field] !== null) {\n const value = result[field];\n if (typeof value === 'number' || typeof value === 'string') {\n (result as Record<string, unknown>)[field] = DecimalUtils.toDecimalString(value);\n } else if (value instanceof Decimal) {\n (result as Record<string, unknown>)[field] = value.toString();\n }\n }\n }\n return result;\n },\n\n /**\n * Parse an object from database by converting decimal string fields to Decimal instances.\n * @param data - The object from database\n * @param decimalFields - Array of field names that should be converted to Decimal\n * @returns A new object with specified fields converted to Decimal instances\n */\n parseFromDatabase<T extends Record<string, unknown>>(\n data: T,\n decimalFields: string[]\n ): T {\n const result = { ...data };\n for (const field of decimalFields) {\n if (field in result && result[field] !== undefined && result[field] !== null) {\n const value = result[field];\n if (typeof value === 'string' || typeof value === 'number') {\n (result as Record<string, unknown>)[field] = new Decimal(value);\n }\n }\n }\n return result;\n },\n\n /**\n * Validate that a value matches the specified precision and scale.\n * @param value - The value to validate\n * @param precision - Total number of digits (integer + decimal)\n * @param scale - Number of decimal places\n * @returns An error message if invalid, or null if valid\n *\n * @example\n * ```typescript\n * DecimalUtils.validate('123.45', 5, 2); // null (valid)\n * DecimalUtils.validate('123.456', 5, 2); // \"max 2 decimal places allowed\"\n * DecimalUtils.validate('1234.56', 5, 2); // \"max 3 integer digits allowed\"\n * ```\n */\n validate(\n value: number | string | Decimal,\n precision: number,\n scale: number\n ): string | null {\n const d = value instanceof Decimal ? value : new Decimal(value);\n const maxIntDigits = precision - scale;\n\n // Check scale (decimal places)\n if (d.decimalPlaces() > scale) {\n return `max ${scale} decimal places allowed`;\n }\n\n // Check integer digits\n const absValue = d.abs();\n if (!absValue.isZero()) {\n // Count integer digits: precision(true) - decimalPlaces\n // But for numbers like 100, precision(true) gives 3, which is correct\n // For 100.00, we need the integer part's digit count\n const integerPart = absValue.floor(0);\n const intDigits = integerPart.isZero() ? 0 : integerPart.precision(true);\n\n if (intDigits > maxIntDigits) {\n return `max ${maxIntDigits} integer digits allowed`;\n }\n }\n\n return null;\n },\n};\n\n/**\n * Shorthand function for creating a Decimal instance.\n *\n * @param value - The value to convert to a Decimal\n * @returns A new Decimal instance\n *\n * @example\n * ```typescript\n * const price = decimal('19.99');\n * const total = decimal(100).mul(price);\n * ```\n */\nexport function decimal(value: number | string): Decimal {\n return new Decimal(value);\n}\n"],"mappings":"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","names":[]}
|
package/dist/index.d.ts
CHANGED
|
@@ -6,6 +6,7 @@ export { AccessLevel, AuthContext, DeepPartial, IpRestrictions, MembershipPermis
|
|
|
6
6
|
export { AccountLockedError, AuthError, ConflictError, DuplicateError, ForbiddenError, InvalidCredentialsError, MembershipError, MembershipExpiredError, MembershipNotFoundError, NotFoundError, ParsError, RateLimitError, SessionExpiredError, TenantError, TenantNotFoundError, TenantSuspendedError, TwoFactorRequiredError, UnauthorizedError, ValidationError, ValidationErrorDetail } from './errors.js';
|
|
7
7
|
export { ErrorCategory, ErrorCode, ErrorCodeDefinition, ErrorCodes, getErrorCode, getErrorCodesByCategory, getStatusForCode, isRetryableError } from './error-codes.js';
|
|
8
8
|
export { AxiomTransport, AxiomTransportOptions, LogtapeLogger, LogtapeTransport, LogtapeTransportOptions, SentryClient, SentryEvent, SentryTransport, SentryTransportOptions, createAxiomTransport, createLogtapeTransport, createSentryTransport } from './transports/index.js';
|
|
9
|
+
import 'decimal.js';
|
|
9
10
|
|
|
10
11
|
/**
|
|
11
12
|
* @module
|
package/dist/index.js
CHANGED
|
@@ -481,40 +481,32 @@ function createRequestLogger(baseLogger, request) {
|
|
|
481
481
|
}
|
|
482
482
|
|
|
483
483
|
// src/decimal.ts
|
|
484
|
-
|
|
484
|
+
import DecimalJS from "decimal.js";
|
|
485
|
+
DecimalJS.set({
|
|
486
|
+
precision: 40,
|
|
487
|
+
rounding: DecimalJS.ROUND_HALF_UP,
|
|
488
|
+
toExpNeg: -9,
|
|
489
|
+
toExpPos: 21
|
|
490
|
+
});
|
|
485
491
|
var Decimal = class _Decimal {
|
|
486
|
-
|
|
492
|
+
_value;
|
|
487
493
|
constructor(value) {
|
|
488
494
|
if (value instanceof _Decimal) {
|
|
489
|
-
this.
|
|
490
|
-
} else if (
|
|
491
|
-
this.
|
|
495
|
+
this._value = value._value;
|
|
496
|
+
} else if (value instanceof DecimalJS) {
|
|
497
|
+
this._value = value;
|
|
492
498
|
} else {
|
|
493
|
-
this.
|
|
499
|
+
this._value = new DecimalJS(value);
|
|
494
500
|
}
|
|
495
501
|
}
|
|
496
|
-
normalizeNumber(n) {
|
|
497
|
-
if (!isFinite(n)) {
|
|
498
|
-
throw new Error(`Invalid number: ${n}`);
|
|
499
|
-
}
|
|
500
|
-
return n.toFixed(PRECISION).replace(/\.?0+$/, "") || "0";
|
|
501
|
-
}
|
|
502
|
-
normalizeString(s) {
|
|
503
|
-
const trimmed = s.trim();
|
|
504
|
-
if (!/^-?\d*\.?\d+$/.test(trimmed)) {
|
|
505
|
-
throw new Error(`Invalid decimal string: ${s}`);
|
|
506
|
-
}
|
|
507
|
-
return trimmed.replace(/^(-?)0+(?=\d)/, "$1").replace(/\.?0+$/, "") || "0";
|
|
508
|
-
}
|
|
509
502
|
/**
|
|
510
503
|
* Add another value to this decimal.
|
|
511
504
|
* @param other - Value to add
|
|
512
505
|
* @returns A new Decimal with the result
|
|
513
506
|
*/
|
|
514
507
|
add(other) {
|
|
515
|
-
const
|
|
516
|
-
|
|
517
|
-
return new _Decimal(a + b);
|
|
508
|
+
const otherValue = other instanceof _Decimal ? other._value : other;
|
|
509
|
+
return new _Decimal(this._value.plus(otherValue));
|
|
518
510
|
}
|
|
519
511
|
/**
|
|
520
512
|
* Subtract a value from this decimal.
|
|
@@ -522,9 +514,8 @@ var Decimal = class _Decimal {
|
|
|
522
514
|
* @returns A new Decimal with the result
|
|
523
515
|
*/
|
|
524
516
|
sub(other) {
|
|
525
|
-
const
|
|
526
|
-
|
|
527
|
-
return new _Decimal(a - b);
|
|
517
|
+
const otherValue = other instanceof _Decimal ? other._value : other;
|
|
518
|
+
return new _Decimal(this._value.minus(otherValue));
|
|
528
519
|
}
|
|
529
520
|
/**
|
|
530
521
|
* Multiply this decimal by another value.
|
|
@@ -532,9 +523,8 @@ var Decimal = class _Decimal {
|
|
|
532
523
|
* @returns A new Decimal with the result
|
|
533
524
|
*/
|
|
534
525
|
mul(other) {
|
|
535
|
-
const
|
|
536
|
-
|
|
537
|
-
return new _Decimal(a * b);
|
|
526
|
+
const otherValue = other instanceof _Decimal ? other._value : other;
|
|
527
|
+
return new _Decimal(this._value.times(otherValue));
|
|
538
528
|
}
|
|
539
529
|
/**
|
|
540
530
|
* Divide this decimal by another value.
|
|
@@ -543,12 +533,12 @@ var Decimal = class _Decimal {
|
|
|
543
533
|
* @throws Error if dividing by zero
|
|
544
534
|
*/
|
|
545
535
|
div(other) {
|
|
546
|
-
const
|
|
547
|
-
const
|
|
548
|
-
if (
|
|
536
|
+
const otherValue = other instanceof _Decimal ? other._value : other;
|
|
537
|
+
const divisor = new DecimalJS(otherValue);
|
|
538
|
+
if (divisor.isZero()) {
|
|
549
539
|
throw new Error("Division by zero");
|
|
550
540
|
}
|
|
551
|
-
return new _Decimal(
|
|
541
|
+
return new _Decimal(this._value.dividedBy(divisor));
|
|
552
542
|
}
|
|
553
543
|
/**
|
|
554
544
|
* Get the modulo (remainder) of dividing this decimal by another value.
|
|
@@ -556,9 +546,8 @@ var Decimal = class _Decimal {
|
|
|
556
546
|
* @returns A new Decimal with the remainder
|
|
557
547
|
*/
|
|
558
548
|
mod(other) {
|
|
559
|
-
const
|
|
560
|
-
|
|
561
|
-
return new _Decimal(a % b);
|
|
549
|
+
const otherValue = other instanceof _Decimal ? other._value : other;
|
|
550
|
+
return new _Decimal(this._value.modulo(otherValue));
|
|
562
551
|
}
|
|
563
552
|
/**
|
|
564
553
|
* Raise this decimal to a power.
|
|
@@ -566,8 +555,7 @@ var Decimal = class _Decimal {
|
|
|
566
555
|
* @returns A new Decimal with the result
|
|
567
556
|
*/
|
|
568
557
|
pow(exp) {
|
|
569
|
-
|
|
570
|
-
return new _Decimal(Math.pow(a, exp));
|
|
558
|
+
return new _Decimal(this._value.pow(exp));
|
|
571
559
|
}
|
|
572
560
|
/**
|
|
573
561
|
* Calculate the square root of this decimal.
|
|
@@ -575,27 +563,24 @@ var Decimal = class _Decimal {
|
|
|
575
563
|
* @throws Error if the value is negative
|
|
576
564
|
*/
|
|
577
565
|
sqrt() {
|
|
578
|
-
|
|
579
|
-
if (a < 0) {
|
|
566
|
+
if (this._value.isNegative()) {
|
|
580
567
|
throw new Error("Square root of negative number");
|
|
581
568
|
}
|
|
582
|
-
return new _Decimal(
|
|
569
|
+
return new _Decimal(this._value.sqrt());
|
|
583
570
|
}
|
|
584
571
|
/**
|
|
585
572
|
* Get the absolute value of this decimal.
|
|
586
573
|
* @returns A new Decimal with the absolute value
|
|
587
574
|
*/
|
|
588
575
|
abs() {
|
|
589
|
-
|
|
590
|
-
return new _Decimal(Math.abs(a));
|
|
576
|
+
return new _Decimal(this._value.abs());
|
|
591
577
|
}
|
|
592
578
|
/**
|
|
593
579
|
* Negate this decimal (multiply by -1).
|
|
594
580
|
* @returns A new Decimal with the negated value
|
|
595
581
|
*/
|
|
596
582
|
neg() {
|
|
597
|
-
|
|
598
|
-
return new _Decimal(-a);
|
|
583
|
+
return new _Decimal(this._value.negated());
|
|
599
584
|
}
|
|
600
585
|
/**
|
|
601
586
|
* Round to the specified number of decimal places using standard rounding.
|
|
@@ -603,9 +588,7 @@ var Decimal = class _Decimal {
|
|
|
603
588
|
* @returns A new Decimal with the rounded value
|
|
604
589
|
*/
|
|
605
590
|
round(decimals = 0) {
|
|
606
|
-
|
|
607
|
-
const factor = Math.pow(10, decimals);
|
|
608
|
-
return new _Decimal(Math.round(a * factor) / factor);
|
|
591
|
+
return new _Decimal(this._value.toDecimalPlaces(decimals, DecimalJS.ROUND_HALF_UP));
|
|
609
592
|
}
|
|
610
593
|
/**
|
|
611
594
|
* Round down to the specified number of decimal places.
|
|
@@ -613,9 +596,7 @@ var Decimal = class _Decimal {
|
|
|
613
596
|
* @returns A new Decimal with the floored value
|
|
614
597
|
*/
|
|
615
598
|
floor(decimals = 0) {
|
|
616
|
-
|
|
617
|
-
const factor = Math.pow(10, decimals);
|
|
618
|
-
return new _Decimal(Math.floor(a * factor) / factor);
|
|
599
|
+
return new _Decimal(this._value.toDecimalPlaces(decimals, DecimalJS.ROUND_FLOOR));
|
|
619
600
|
}
|
|
620
601
|
/**
|
|
621
602
|
* Round up to the specified number of decimal places.
|
|
@@ -623,9 +604,7 @@ var Decimal = class _Decimal {
|
|
|
623
604
|
* @returns A new Decimal with the ceiled value
|
|
624
605
|
*/
|
|
625
606
|
ceil(decimals = 0) {
|
|
626
|
-
|
|
627
|
-
const factor = Math.pow(10, decimals);
|
|
628
|
-
return new _Decimal(Math.ceil(a * factor) / factor);
|
|
607
|
+
return new _Decimal(this._value.toDecimalPlaces(decimals, DecimalJS.ROUND_CEIL));
|
|
629
608
|
}
|
|
630
609
|
/**
|
|
631
610
|
* Compare this decimal to another value.
|
|
@@ -633,11 +612,8 @@ var Decimal = class _Decimal {
|
|
|
633
612
|
* @returns -1 if less, 0 if equal, 1 if greater
|
|
634
613
|
*/
|
|
635
614
|
cmp(other) {
|
|
636
|
-
const
|
|
637
|
-
|
|
638
|
-
if (a < b) return -1;
|
|
639
|
-
if (a > b) return 1;
|
|
640
|
-
return 0;
|
|
615
|
+
const otherValue = other instanceof _Decimal ? other._value : other;
|
|
616
|
+
return this._value.comparedTo(otherValue);
|
|
641
617
|
}
|
|
642
618
|
/**
|
|
643
619
|
* Check if this decimal equals another value.
|
|
@@ -645,7 +621,8 @@ var Decimal = class _Decimal {
|
|
|
645
621
|
* @returns True if values are equal
|
|
646
622
|
*/
|
|
647
623
|
eq(other) {
|
|
648
|
-
|
|
624
|
+
const otherValue = other instanceof _Decimal ? other._value : other;
|
|
625
|
+
return this._value.equals(otherValue);
|
|
649
626
|
}
|
|
650
627
|
/**
|
|
651
628
|
* Check if this decimal is greater than another value.
|
|
@@ -653,7 +630,8 @@ var Decimal = class _Decimal {
|
|
|
653
630
|
* @returns True if this is greater
|
|
654
631
|
*/
|
|
655
632
|
gt(other) {
|
|
656
|
-
|
|
633
|
+
const otherValue = other instanceof _Decimal ? other._value : other;
|
|
634
|
+
return this._value.greaterThan(otherValue);
|
|
657
635
|
}
|
|
658
636
|
/**
|
|
659
637
|
* Check if this decimal is greater than or equal to another value.
|
|
@@ -661,7 +639,8 @@ var Decimal = class _Decimal {
|
|
|
661
639
|
* @returns True if this is greater or equal
|
|
662
640
|
*/
|
|
663
641
|
gte(other) {
|
|
664
|
-
|
|
642
|
+
const otherValue = other instanceof _Decimal ? other._value : other;
|
|
643
|
+
return this._value.greaterThanOrEqualTo(otherValue);
|
|
665
644
|
}
|
|
666
645
|
/**
|
|
667
646
|
* Check if this decimal is less than another value.
|
|
@@ -669,7 +648,8 @@ var Decimal = class _Decimal {
|
|
|
669
648
|
* @returns True if this is less
|
|
670
649
|
*/
|
|
671
650
|
lt(other) {
|
|
672
|
-
|
|
651
|
+
const otherValue = other instanceof _Decimal ? other._value : other;
|
|
652
|
+
return this._value.lessThan(otherValue);
|
|
673
653
|
}
|
|
674
654
|
/**
|
|
675
655
|
* Check if this decimal is less than or equal to another value.
|
|
@@ -677,42 +657,80 @@ var Decimal = class _Decimal {
|
|
|
677
657
|
* @returns True if this is less or equal
|
|
678
658
|
*/
|
|
679
659
|
lte(other) {
|
|
680
|
-
|
|
660
|
+
const otherValue = other instanceof _Decimal ? other._value : other;
|
|
661
|
+
return this._value.lessThanOrEqualTo(otherValue);
|
|
681
662
|
}
|
|
682
663
|
/**
|
|
683
664
|
* Check if this decimal is exactly zero.
|
|
684
665
|
* @returns True if value is zero
|
|
685
666
|
*/
|
|
686
667
|
isZero() {
|
|
687
|
-
return
|
|
668
|
+
return this._value.isZero();
|
|
688
669
|
}
|
|
689
670
|
/**
|
|
690
671
|
* Check if this decimal is positive (greater than zero).
|
|
691
672
|
* @returns True if value is positive
|
|
692
673
|
*/
|
|
693
674
|
isPositive() {
|
|
694
|
-
return
|
|
675
|
+
return this._value.isPositive() && !this._value.isZero();
|
|
695
676
|
}
|
|
696
677
|
/**
|
|
697
678
|
* Check if this decimal is negative (less than zero).
|
|
698
679
|
* @returns True if value is negative
|
|
699
680
|
*/
|
|
700
681
|
isNegative() {
|
|
701
|
-
return
|
|
682
|
+
return this._value.isNegative();
|
|
683
|
+
}
|
|
684
|
+
/**
|
|
685
|
+
* Check if this decimal is an integer (no decimal places).
|
|
686
|
+
* @returns True if value is an integer
|
|
687
|
+
*/
|
|
688
|
+
isInteger() {
|
|
689
|
+
return this._value.isInteger();
|
|
690
|
+
}
|
|
691
|
+
/**
|
|
692
|
+
* Get the number of decimal places (digits after the decimal point).
|
|
693
|
+
* @returns Number of decimal places
|
|
694
|
+
*
|
|
695
|
+
* @example
|
|
696
|
+
* ```typescript
|
|
697
|
+
* new Decimal('123.45').decimalPlaces(); // 2
|
|
698
|
+
* new Decimal('100').decimalPlaces(); // 0
|
|
699
|
+
* new Decimal('1.500').decimalPlaces(); // 1 (trailing zeros removed)
|
|
700
|
+
* ```
|
|
701
|
+
*/
|
|
702
|
+
decimalPlaces() {
|
|
703
|
+
return this._value.decimalPlaces();
|
|
704
|
+
}
|
|
705
|
+
/**
|
|
706
|
+
* Get the precision (total number of significant digits).
|
|
707
|
+
* @param includeZeros - If true, include trailing zeros in the count
|
|
708
|
+
* @returns The precision
|
|
709
|
+
*
|
|
710
|
+
* @example
|
|
711
|
+
* ```typescript
|
|
712
|
+
* new Decimal('123.45').precision(); // 5
|
|
713
|
+
* new Decimal('100').precision(); // 1
|
|
714
|
+
* new Decimal('100').precision(true); // 3
|
|
715
|
+
* ```
|
|
716
|
+
*/
|
|
717
|
+
precision(includeZeros = false) {
|
|
718
|
+
return this._value.precision(includeZeros);
|
|
702
719
|
}
|
|
703
720
|
/**
|
|
704
721
|
* Convert this decimal to a JavaScript number.
|
|
722
|
+
* Warning: May lose precision for very large or very precise numbers.
|
|
705
723
|
* @returns The numeric value
|
|
706
724
|
*/
|
|
707
725
|
toNumber() {
|
|
708
|
-
return
|
|
726
|
+
return this._value.toNumber();
|
|
709
727
|
}
|
|
710
728
|
/**
|
|
711
729
|
* Convert this decimal to its string representation.
|
|
712
730
|
* @returns The string value
|
|
713
731
|
*/
|
|
714
732
|
toString() {
|
|
715
|
-
return this.
|
|
733
|
+
return this._value.toString();
|
|
716
734
|
}
|
|
717
735
|
/**
|
|
718
736
|
* Format this decimal with a fixed number of decimal places.
|
|
@@ -720,14 +738,22 @@ var Decimal = class _Decimal {
|
|
|
720
738
|
* @returns Formatted string
|
|
721
739
|
*/
|
|
722
740
|
toFixed(decimals = 2) {
|
|
723
|
-
return
|
|
741
|
+
return this._value.toFixed(decimals);
|
|
724
742
|
}
|
|
725
743
|
/**
|
|
726
744
|
* Convert to JSON (returns string representation for serialization).
|
|
727
745
|
* @returns The string value for JSON serialization
|
|
728
746
|
*/
|
|
729
747
|
toJSON() {
|
|
730
|
-
return this.
|
|
748
|
+
return this._value.toString();
|
|
749
|
+
}
|
|
750
|
+
/**
|
|
751
|
+
* Get the underlying decimal.js instance.
|
|
752
|
+
* Useful for advanced operations not covered by this wrapper.
|
|
753
|
+
* @returns The underlying DecimalJS instance
|
|
754
|
+
*/
|
|
755
|
+
toDecimalJS() {
|
|
756
|
+
return this._value;
|
|
731
757
|
}
|
|
732
758
|
/**
|
|
733
759
|
* Create a Decimal from a value (alias for constructor).
|
|
@@ -783,6 +809,30 @@ var Decimal = class _Decimal {
|
|
|
783
809
|
return d.gt(max) ? d : max;
|
|
784
810
|
}, new _Decimal(values[0]));
|
|
785
811
|
}
|
|
812
|
+
/**
|
|
813
|
+
* Check if a value is a valid decimal representation.
|
|
814
|
+
* @param value - The value to check
|
|
815
|
+
* @returns True if the value can be converted to a Decimal
|
|
816
|
+
*/
|
|
817
|
+
static isValid(value) {
|
|
818
|
+
if (value === null || value === void 0) return false;
|
|
819
|
+
if (value instanceof _Decimal) return true;
|
|
820
|
+
try {
|
|
821
|
+
new DecimalJS(value);
|
|
822
|
+
return true;
|
|
823
|
+
} catch {
|
|
824
|
+
return false;
|
|
825
|
+
}
|
|
826
|
+
}
|
|
827
|
+
/**
|
|
828
|
+
* Create a Decimal or return null if the value is invalid.
|
|
829
|
+
* @param value - The value to convert
|
|
830
|
+
* @returns A Decimal or null
|
|
831
|
+
*/
|
|
832
|
+
static tryParse(value) {
|
|
833
|
+
if (!_Decimal.isValid(value)) return null;
|
|
834
|
+
return new _Decimal(value);
|
|
835
|
+
}
|
|
786
836
|
};
|
|
787
837
|
var DecimalUtils = {
|
|
788
838
|
/**
|
|
@@ -875,30 +925,62 @@ var DecimalUtils = {
|
|
|
875
925
|
for (const field of decimalFields) {
|
|
876
926
|
if (field in result && result[field] !== void 0 && result[field] !== null) {
|
|
877
927
|
const value = result[field];
|
|
878
|
-
if (typeof value === "number") {
|
|
928
|
+
if (typeof value === "number" || typeof value === "string") {
|
|
879
929
|
result[field] = DecimalUtils.toDecimalString(value);
|
|
930
|
+
} else if (value instanceof Decimal) {
|
|
931
|
+
result[field] = value.toString();
|
|
880
932
|
}
|
|
881
933
|
}
|
|
882
934
|
}
|
|
883
935
|
return result;
|
|
884
936
|
},
|
|
885
937
|
/**
|
|
886
|
-
* Parse an object from database by converting decimal string fields to
|
|
938
|
+
* Parse an object from database by converting decimal string fields to Decimal instances.
|
|
887
939
|
* @param data - The object from database
|
|
888
|
-
* @param decimalFields - Array of field names that should be converted
|
|
889
|
-
* @returns A new object with specified fields converted to
|
|
940
|
+
* @param decimalFields - Array of field names that should be converted to Decimal
|
|
941
|
+
* @returns A new object with specified fields converted to Decimal instances
|
|
890
942
|
*/
|
|
891
943
|
parseFromDatabase(data, decimalFields) {
|
|
892
944
|
const result = { ...data };
|
|
893
945
|
for (const field of decimalFields) {
|
|
894
946
|
if (field in result && result[field] !== void 0 && result[field] !== null) {
|
|
895
947
|
const value = result[field];
|
|
896
|
-
if (typeof value === "string") {
|
|
897
|
-
result[field] =
|
|
948
|
+
if (typeof value === "string" || typeof value === "number") {
|
|
949
|
+
result[field] = new Decimal(value);
|
|
898
950
|
}
|
|
899
951
|
}
|
|
900
952
|
}
|
|
901
953
|
return result;
|
|
954
|
+
},
|
|
955
|
+
/**
|
|
956
|
+
* Validate that a value matches the specified precision and scale.
|
|
957
|
+
* @param value - The value to validate
|
|
958
|
+
* @param precision - Total number of digits (integer + decimal)
|
|
959
|
+
* @param scale - Number of decimal places
|
|
960
|
+
* @returns An error message if invalid, or null if valid
|
|
961
|
+
*
|
|
962
|
+
* @example
|
|
963
|
+
* ```typescript
|
|
964
|
+
* DecimalUtils.validate('123.45', 5, 2); // null (valid)
|
|
965
|
+
* DecimalUtils.validate('123.456', 5, 2); // "max 2 decimal places allowed"
|
|
966
|
+
* DecimalUtils.validate('1234.56', 5, 2); // "max 3 integer digits allowed"
|
|
967
|
+
* ```
|
|
968
|
+
*/
|
|
969
|
+
validate(value, precision, scale) {
|
|
970
|
+
const d = value instanceof Decimal ? value : new Decimal(value);
|
|
971
|
+
const maxIntDigits = precision - scale;
|
|
972
|
+
if (d.decimalPlaces() > scale) {
|
|
973
|
+
return `max ${scale} decimal places allowed`;
|
|
974
|
+
}
|
|
975
|
+
const absValue = d.abs();
|
|
976
|
+
if (!absValue.isZero()) {
|
|
977
|
+
const integerPart = absValue.floor(0);
|
|
978
|
+
const intDigits = integerPart.isZero() ? 0 : integerPart.precision(true);
|
|
979
|
+
if (intDigits > maxIntDigits) {
|
|
980
|
+
return `max ${maxIntDigits} integer digits allowed`;
|
|
981
|
+
}
|
|
982
|
+
}
|
|
983
|
+
return null;
|
|
902
984
|
}
|
|
903
985
|
};
|
|
904
986
|
function decimal(value) {
|