@parsrun/core 0.1.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 ADDED
@@ -0,0 +1,113 @@
1
+ # @parsrun/core
2
+
3
+ > Core utilities and types for the Pars framework - Edge compatible.
4
+
5
+ ## Features
6
+
7
+ - **Logger** - Structured logging with child loggers
8
+ - **Errors** - Standardized error classes with codes
9
+ - **Runtime Detection** - Detect Node, Cloudflare, Deno, Bun
10
+ - **Environment** - Type-safe environment variable access
11
+ - **Utilities** - Common helpers (ID generation, crypto, etc.)
12
+
13
+ ## Installation
14
+
15
+ ```bash
16
+ pnpm add @parsrun/core
17
+ ```
18
+
19
+ ## Usage
20
+
21
+ ### Logger
22
+
23
+ ```typescript
24
+ import { createLogger } from "@parsrun/core/logger";
25
+
26
+ const logger = createLogger({ name: "my-service" });
27
+
28
+ logger.info("User logged in", { userId: "123" });
29
+ logger.error("Failed to process", new Error("timeout"), { requestId: "abc" });
30
+
31
+ // Child logger
32
+ const childLogger = logger.child({ module: "auth" });
33
+ childLogger.debug("Token validated");
34
+ ```
35
+
36
+ ### Errors
37
+
38
+ ```typescript
39
+ import { ParsError, createError, isRetryable } from "@parsrun/core/errors";
40
+
41
+ // Create error
42
+ throw new ParsError("User not found", "USER_NOT_FOUND", 404, {
43
+ userId: "123",
44
+ });
45
+
46
+ // Check if error is retryable
47
+ if (isRetryable(error)) {
48
+ await retry();
49
+ }
50
+ ```
51
+
52
+ ### Runtime Detection
53
+
54
+ ```typescript
55
+ import { detectRuntime, isEdgeRuntime } from "@parsrun/core/runtime";
56
+
57
+ const runtime = detectRuntime(); // "node" | "cloudflare" | "deno" | "bun"
58
+
59
+ if (isEdgeRuntime()) {
60
+ // Edge-specific code
61
+ }
62
+ ```
63
+
64
+ ### Environment
65
+
66
+ ```typescript
67
+ import { getEnv, requireEnv, EnvSchema } from "@parsrun/core/env";
68
+
69
+ // Get with fallback
70
+ const port = getEnv("PORT", "3000");
71
+
72
+ // Required (throws if missing)
73
+ const secret = requireEnv("AUTH_SECRET");
74
+
75
+ // Typed schema
76
+ const env = EnvSchema.parse({
77
+ DATABASE_URL: requireEnv("DATABASE_URL"),
78
+ REDIS_URL: getEnv("REDIS_URL"),
79
+ });
80
+ ```
81
+
82
+ ### Utilities
83
+
84
+ ```typescript
85
+ import { generateId, sleep, retry } from "@parsrun/core";
86
+
87
+ // Generate unique ID
88
+ const id = generateId(); // "abc123xyz..."
89
+
90
+ // Sleep
91
+ await sleep(1000);
92
+
93
+ // Retry with backoff
94
+ const result = await retry(
95
+ async () => fetchData(),
96
+ { attempts: 3, delay: 100 }
97
+ );
98
+ ```
99
+
100
+ ## Sub-path Imports
101
+
102
+ ```typescript
103
+ import { createLogger } from "@parsrun/core/logger";
104
+ import { ParsError } from "@parsrun/core/errors";
105
+ import { detectRuntime } from "@parsrun/core/runtime";
106
+ import { getEnv } from "@parsrun/core/env";
107
+ import { Decimal } from "@parsrun/core/decimal";
108
+ import { ERROR_CODES } from "@parsrun/core/error-codes";
109
+ ```
110
+
111
+ ## License
112
+
113
+ MIT
@@ -0,0 +1,190 @@
1
+ /**
2
+ * @parsrun/core - Decimal Utilities
3
+ * Precise decimal calculations for financial and quantity operations
4
+ * Edge-compatible - no external dependencies
5
+ */
6
+ /**
7
+ * Decimal class for precise arithmetic
8
+ * Uses string-based arithmetic to avoid floating point issues
9
+ */
10
+ declare class Decimal {
11
+ private value;
12
+ constructor(value: number | string | Decimal);
13
+ private normalizeNumber;
14
+ private normalizeString;
15
+ /**
16
+ * Add two decimals
17
+ */
18
+ add(other: number | string | Decimal): Decimal;
19
+ /**
20
+ * Subtract
21
+ */
22
+ sub(other: number | string | Decimal): Decimal;
23
+ /**
24
+ * Multiply
25
+ */
26
+ mul(other: number | string | Decimal): Decimal;
27
+ /**
28
+ * Divide
29
+ */
30
+ div(other: number | string | Decimal): Decimal;
31
+ /**
32
+ * Modulo
33
+ */
34
+ mod(other: number | string | Decimal): Decimal;
35
+ /**
36
+ * Power
37
+ */
38
+ pow(exp: number): Decimal;
39
+ /**
40
+ * Square root
41
+ */
42
+ sqrt(): Decimal;
43
+ /**
44
+ * Absolute value
45
+ */
46
+ abs(): Decimal;
47
+ /**
48
+ * Negate
49
+ */
50
+ neg(): Decimal;
51
+ /**
52
+ * Round to decimal places
53
+ */
54
+ round(decimals?: number): Decimal;
55
+ /**
56
+ * Floor to decimal places
57
+ */
58
+ floor(decimals?: number): Decimal;
59
+ /**
60
+ * Ceiling to decimal places
61
+ */
62
+ ceil(decimals?: number): Decimal;
63
+ /**
64
+ * Compare: returns -1, 0, or 1
65
+ */
66
+ cmp(other: number | string | Decimal): -1 | 0 | 1;
67
+ /**
68
+ * Equality check
69
+ */
70
+ eq(other: number | string | Decimal): boolean;
71
+ /**
72
+ * Greater than
73
+ */
74
+ gt(other: number | string | Decimal): boolean;
75
+ /**
76
+ * Greater than or equal
77
+ */
78
+ gte(other: number | string | Decimal): boolean;
79
+ /**
80
+ * Less than
81
+ */
82
+ lt(other: number | string | Decimal): boolean;
83
+ /**
84
+ * Less than or equal
85
+ */
86
+ lte(other: number | string | Decimal): boolean;
87
+ /**
88
+ * Check if zero
89
+ */
90
+ isZero(): boolean;
91
+ /**
92
+ * Check if positive
93
+ */
94
+ isPositive(): boolean;
95
+ /**
96
+ * Check if negative
97
+ */
98
+ isNegative(): boolean;
99
+ /**
100
+ * Convert to number
101
+ */
102
+ toNumber(): number;
103
+ /**
104
+ * Convert to string
105
+ */
106
+ toString(): string;
107
+ /**
108
+ * Format with fixed decimal places
109
+ */
110
+ toFixed(decimals?: number): string;
111
+ /**
112
+ * Convert to JSON (string representation)
113
+ */
114
+ toJSON(): string;
115
+ /**
116
+ * Static: Create from value
117
+ */
118
+ static from(value: number | string | Decimal): Decimal;
119
+ /**
120
+ * Static: Sum array of values
121
+ */
122
+ static sum(values: (number | string | Decimal)[]): Decimal;
123
+ /**
124
+ * Static: Average of array
125
+ */
126
+ static avg(values: (number | string | Decimal)[]): Decimal;
127
+ /**
128
+ * Static: Min of array
129
+ */
130
+ static min(...values: (number | string | Decimal)[]): Decimal;
131
+ /**
132
+ * Static: Max of array
133
+ */
134
+ static max(...values: (number | string | Decimal)[]): Decimal;
135
+ }
136
+ /**
137
+ * Decimal utilities for database operations
138
+ */
139
+ declare const DecimalUtils: {
140
+ /**
141
+ * Convert number to database decimal string
142
+ */
143
+ toDecimalString(value: number | string | null | undefined): string | null;
144
+ /**
145
+ * Convert database decimal string to number
146
+ */
147
+ fromDecimalString(value: string | null | undefined): number;
148
+ /**
149
+ * Perform precise decimal multiplication
150
+ */
151
+ multiply(a: number | string, b: number | string): string;
152
+ /**
153
+ * Perform precise decimal addition
154
+ */
155
+ add(a: number | string, b: number | string): string;
156
+ /**
157
+ * Perform precise decimal subtraction
158
+ */
159
+ subtract(a: number | string, b: number | string): string;
160
+ /**
161
+ * Perform precise decimal division
162
+ */
163
+ divide(a: number | string, b: number | string): string;
164
+ /**
165
+ * Format decimal for display
166
+ */
167
+ format(value: string | number, decimalPlaces?: number): string;
168
+ /**
169
+ * Format as currency
170
+ */
171
+ formatCurrency(value: string | number, options?: {
172
+ currency?: string;
173
+ locale?: string;
174
+ decimals?: number;
175
+ }): string;
176
+ /**
177
+ * Convert object with decimal fields for database insert/update
178
+ */
179
+ prepareForDatabase<T extends Record<string, unknown>>(data: T, decimalFields: string[]): T;
180
+ /**
181
+ * Convert object with decimal fields from database
182
+ */
183
+ parseFromDatabase<T extends Record<string, unknown>>(data: T, decimalFields: string[]): T;
184
+ };
185
+ /**
186
+ * Shorthand for creating Decimal
187
+ */
188
+ declare function decimal(value: number | string): Decimal;
189
+
190
+ export { Decimal, DecimalUtils, decimal };
@@ -0,0 +1,347 @@
1
+ // src/decimal.ts
2
+ var PRECISION = 20;
3
+ var Decimal = class _Decimal {
4
+ value;
5
+ constructor(value) {
6
+ if (value instanceof _Decimal) {
7
+ this.value = value.value;
8
+ } else if (typeof value === "number") {
9
+ this.value = this.normalizeNumber(value);
10
+ } else {
11
+ this.value = this.normalizeString(value);
12
+ }
13
+ }
14
+ normalizeNumber(n) {
15
+ if (!isFinite(n)) {
16
+ throw new Error(`Invalid number: ${n}`);
17
+ }
18
+ return n.toFixed(PRECISION).replace(/\.?0+$/, "") || "0";
19
+ }
20
+ normalizeString(s) {
21
+ const trimmed = s.trim();
22
+ if (!/^-?\d*\.?\d+$/.test(trimmed)) {
23
+ throw new Error(`Invalid decimal string: ${s}`);
24
+ }
25
+ return trimmed.replace(/^(-?)0+(?=\d)/, "$1").replace(/\.?0+$/, "") || "0";
26
+ }
27
+ /**
28
+ * Add two decimals
29
+ */
30
+ add(other) {
31
+ const a = parseFloat(this.value);
32
+ const b = parseFloat(other instanceof _Decimal ? other.value : String(other));
33
+ return new _Decimal(a + b);
34
+ }
35
+ /**
36
+ * Subtract
37
+ */
38
+ sub(other) {
39
+ const a = parseFloat(this.value);
40
+ const b = parseFloat(other instanceof _Decimal ? other.value : String(other));
41
+ return new _Decimal(a - b);
42
+ }
43
+ /**
44
+ * Multiply
45
+ */
46
+ mul(other) {
47
+ const a = parseFloat(this.value);
48
+ const b = parseFloat(other instanceof _Decimal ? other.value : String(other));
49
+ return new _Decimal(a * b);
50
+ }
51
+ /**
52
+ * Divide
53
+ */
54
+ div(other) {
55
+ const a = parseFloat(this.value);
56
+ const b = parseFloat(other instanceof _Decimal ? other.value : String(other));
57
+ if (b === 0) {
58
+ throw new Error("Division by zero");
59
+ }
60
+ return new _Decimal(a / b);
61
+ }
62
+ /**
63
+ * Modulo
64
+ */
65
+ mod(other) {
66
+ const a = parseFloat(this.value);
67
+ const b = parseFloat(other instanceof _Decimal ? other.value : String(other));
68
+ return new _Decimal(a % b);
69
+ }
70
+ /**
71
+ * Power
72
+ */
73
+ pow(exp) {
74
+ const a = parseFloat(this.value);
75
+ return new _Decimal(Math.pow(a, exp));
76
+ }
77
+ /**
78
+ * Square root
79
+ */
80
+ sqrt() {
81
+ const a = parseFloat(this.value);
82
+ if (a < 0) {
83
+ throw new Error("Square root of negative number");
84
+ }
85
+ return new _Decimal(Math.sqrt(a));
86
+ }
87
+ /**
88
+ * Absolute value
89
+ */
90
+ abs() {
91
+ const a = parseFloat(this.value);
92
+ return new _Decimal(Math.abs(a));
93
+ }
94
+ /**
95
+ * Negate
96
+ */
97
+ neg() {
98
+ const a = parseFloat(this.value);
99
+ return new _Decimal(-a);
100
+ }
101
+ /**
102
+ * Round to decimal places
103
+ */
104
+ round(decimals = 0) {
105
+ const a = parseFloat(this.value);
106
+ const factor = Math.pow(10, decimals);
107
+ return new _Decimal(Math.round(a * factor) / factor);
108
+ }
109
+ /**
110
+ * Floor to decimal places
111
+ */
112
+ floor(decimals = 0) {
113
+ const a = parseFloat(this.value);
114
+ const factor = Math.pow(10, decimals);
115
+ return new _Decimal(Math.floor(a * factor) / factor);
116
+ }
117
+ /**
118
+ * Ceiling to decimal places
119
+ */
120
+ ceil(decimals = 0) {
121
+ const a = parseFloat(this.value);
122
+ const factor = Math.pow(10, decimals);
123
+ return new _Decimal(Math.ceil(a * factor) / factor);
124
+ }
125
+ /**
126
+ * Compare: returns -1, 0, or 1
127
+ */
128
+ cmp(other) {
129
+ const a = parseFloat(this.value);
130
+ const b = parseFloat(other instanceof _Decimal ? other.value : String(other));
131
+ if (a < b) return -1;
132
+ if (a > b) return 1;
133
+ return 0;
134
+ }
135
+ /**
136
+ * Equality check
137
+ */
138
+ eq(other) {
139
+ return this.cmp(other) === 0;
140
+ }
141
+ /**
142
+ * Greater than
143
+ */
144
+ gt(other) {
145
+ return this.cmp(other) === 1;
146
+ }
147
+ /**
148
+ * Greater than or equal
149
+ */
150
+ gte(other) {
151
+ return this.cmp(other) >= 0;
152
+ }
153
+ /**
154
+ * Less than
155
+ */
156
+ lt(other) {
157
+ return this.cmp(other) === -1;
158
+ }
159
+ /**
160
+ * Less than or equal
161
+ */
162
+ lte(other) {
163
+ return this.cmp(other) <= 0;
164
+ }
165
+ /**
166
+ * Check if zero
167
+ */
168
+ isZero() {
169
+ return parseFloat(this.value) === 0;
170
+ }
171
+ /**
172
+ * Check if positive
173
+ */
174
+ isPositive() {
175
+ return parseFloat(this.value) > 0;
176
+ }
177
+ /**
178
+ * Check if negative
179
+ */
180
+ isNegative() {
181
+ return parseFloat(this.value) < 0;
182
+ }
183
+ /**
184
+ * Convert to number
185
+ */
186
+ toNumber() {
187
+ return parseFloat(this.value);
188
+ }
189
+ /**
190
+ * Convert to string
191
+ */
192
+ toString() {
193
+ return this.value;
194
+ }
195
+ /**
196
+ * Format with fixed decimal places
197
+ */
198
+ toFixed(decimals = 2) {
199
+ return parseFloat(this.value).toFixed(decimals);
200
+ }
201
+ /**
202
+ * Convert to JSON (string representation)
203
+ */
204
+ toJSON() {
205
+ return this.value;
206
+ }
207
+ /**
208
+ * Static: Create from value
209
+ */
210
+ static from(value) {
211
+ return new _Decimal(value);
212
+ }
213
+ /**
214
+ * Static: Sum array of values
215
+ */
216
+ static sum(values) {
217
+ return values.reduce(
218
+ (acc, val) => acc.add(val),
219
+ new _Decimal(0)
220
+ );
221
+ }
222
+ /**
223
+ * Static: Average of array
224
+ */
225
+ static avg(values) {
226
+ if (values.length === 0) return new _Decimal(0);
227
+ return _Decimal.sum(values).div(values.length);
228
+ }
229
+ /**
230
+ * Static: Min of array
231
+ */
232
+ static min(...values) {
233
+ if (values.length === 0) throw new Error("No values provided");
234
+ return values.reduce((min, val) => {
235
+ const d = new _Decimal(val);
236
+ return d.lt(min) ? d : min;
237
+ }, new _Decimal(values[0]));
238
+ }
239
+ /**
240
+ * Static: Max of array
241
+ */
242
+ static max(...values) {
243
+ if (values.length === 0) throw new Error("No values provided");
244
+ return values.reduce((max, val) => {
245
+ const d = new _Decimal(val);
246
+ return d.gt(max) ? d : max;
247
+ }, new _Decimal(values[0]));
248
+ }
249
+ };
250
+ var DecimalUtils = {
251
+ /**
252
+ * Convert number to database decimal string
253
+ */
254
+ toDecimalString(value) {
255
+ if (value === null || value === void 0) return null;
256
+ return new Decimal(value).toString();
257
+ },
258
+ /**
259
+ * Convert database decimal string to number
260
+ */
261
+ fromDecimalString(value) {
262
+ if (!value) return 0;
263
+ return new Decimal(value).toNumber();
264
+ },
265
+ /**
266
+ * Perform precise decimal multiplication
267
+ */
268
+ multiply(a, b) {
269
+ return new Decimal(a).mul(b).toString();
270
+ },
271
+ /**
272
+ * Perform precise decimal addition
273
+ */
274
+ add(a, b) {
275
+ return new Decimal(a).add(b).toString();
276
+ },
277
+ /**
278
+ * Perform precise decimal subtraction
279
+ */
280
+ subtract(a, b) {
281
+ return new Decimal(a).sub(b).toString();
282
+ },
283
+ /**
284
+ * Perform precise decimal division
285
+ */
286
+ divide(a, b) {
287
+ return new Decimal(a).div(b).toString();
288
+ },
289
+ /**
290
+ * Format decimal for display
291
+ */
292
+ format(value, decimalPlaces = 2) {
293
+ return new Decimal(value).toFixed(decimalPlaces);
294
+ },
295
+ /**
296
+ * Format as currency
297
+ */
298
+ formatCurrency(value, options = {}) {
299
+ const { currency = "USD", locale = "en-US", decimals = 2 } = options;
300
+ const num = new Decimal(value).toNumber();
301
+ return new Intl.NumberFormat(locale, {
302
+ style: "currency",
303
+ currency,
304
+ minimumFractionDigits: decimals,
305
+ maximumFractionDigits: decimals
306
+ }).format(num);
307
+ },
308
+ /**
309
+ * Convert object with decimal fields for database insert/update
310
+ */
311
+ prepareForDatabase(data, decimalFields) {
312
+ const result = { ...data };
313
+ for (const field of decimalFields) {
314
+ if (field in result && result[field] !== void 0 && result[field] !== null) {
315
+ const value = result[field];
316
+ if (typeof value === "number") {
317
+ result[field] = DecimalUtils.toDecimalString(value);
318
+ }
319
+ }
320
+ }
321
+ return result;
322
+ },
323
+ /**
324
+ * Convert object with decimal fields from database
325
+ */
326
+ parseFromDatabase(data, decimalFields) {
327
+ const result = { ...data };
328
+ for (const field of decimalFields) {
329
+ if (field in result && result[field] !== void 0 && result[field] !== null) {
330
+ const value = result[field];
331
+ if (typeof value === "string") {
332
+ result[field] = DecimalUtils.fromDecimalString(value);
333
+ }
334
+ }
335
+ }
336
+ return result;
337
+ }
338
+ };
339
+ function decimal(value) {
340
+ return new Decimal(value);
341
+ }
342
+ export {
343
+ Decimal,
344
+ DecimalUtils,
345
+ decimal
346
+ };
347
+ //# sourceMappingURL=decimal.js.map
@@ -0,0 +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\n/**\n * Internal precision for calculations\n */\nconst PRECISION = 20;\n\n/**\n * Decimal class for precise arithmetic\n * Uses string-based arithmetic to avoid floating point issues\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 two decimals\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\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\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\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 * Modulo\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 * Power\n */\n pow(exp: number): Decimal {\n const a = parseFloat(this.value);\n return new Decimal(Math.pow(a, exp));\n }\n\n /**\n * Square root\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 * Absolute value\n */\n abs(): Decimal {\n const a = parseFloat(this.value);\n return new Decimal(Math.abs(a));\n }\n\n /**\n * Negate\n */\n neg(): Decimal {\n const a = parseFloat(this.value);\n return new Decimal(-a);\n }\n\n /**\n * Round to decimal places\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 * Floor to decimal places\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 * Ceiling to decimal places\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: returns -1, 0, or 1\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 * Equality check\n */\n eq(other: number | string | Decimal): boolean {\n return this.cmp(other) === 0;\n }\n\n /**\n * Greater than\n */\n gt(other: number | string | Decimal): boolean {\n return this.cmp(other) === 1;\n }\n\n /**\n * Greater than or equal\n */\n gte(other: number | string | Decimal): boolean {\n return this.cmp(other) >= 0;\n }\n\n /**\n * Less than\n */\n lt(other: number | string | Decimal): boolean {\n return this.cmp(other) === -1;\n }\n\n /**\n * Less than or equal\n */\n lte(other: number | string | Decimal): boolean {\n return this.cmp(other) <= 0;\n }\n\n /**\n * Check if zero\n */\n isZero(): boolean {\n return parseFloat(this.value) === 0;\n }\n\n /**\n * Check if positive\n */\n isPositive(): boolean {\n return parseFloat(this.value) > 0;\n }\n\n /**\n * Check if negative\n */\n isNegative(): boolean {\n return parseFloat(this.value) < 0;\n }\n\n /**\n * Convert to number\n */\n toNumber(): number {\n return parseFloat(this.value);\n }\n\n /**\n * Convert to string\n */\n toString(): string {\n return this.value;\n }\n\n /**\n * Format with fixed decimal places\n */\n toFixed(decimals: number = 2): string {\n return parseFloat(this.value).toFixed(decimals);\n }\n\n /**\n * Convert to JSON (string representation)\n */\n toJSON(): string {\n return this.value;\n }\n\n /**\n * Static: Create from value\n */\n static from(value: number | string | Decimal): Decimal {\n return new Decimal(value);\n }\n\n /**\n * Static: Sum array of values\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 * Static: Average of 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 * Static: Min of array\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 * Static: Max of array\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 * Decimal utilities for database operations\n */\nexport const DecimalUtils = {\n /**\n * Convert number to database decimal string\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 database decimal string to number\n */\n fromDecimalString(value: string | null | undefined): number {\n if (!value) return 0;\n return new Decimal(value).toNumber();\n },\n\n /**\n * Perform precise decimal multiplication\n */\n multiply(a: number | string, b: number | string): string {\n return new Decimal(a).mul(b).toString();\n },\n\n /**\n * Perform precise decimal addition\n */\n add(a: number | string, b: number | string): string {\n return new Decimal(a).add(b).toString();\n },\n\n /**\n * Perform precise decimal subtraction\n */\n subtract(a: number | string, b: number | string): string {\n return new Decimal(a).sub(b).toString();\n },\n\n /**\n * Perform precise decimal division\n */\n divide(a: number | string, b: number | string): string {\n return new Decimal(a).div(b).toString();\n },\n\n /**\n * Format decimal for display\n */\n format(value: string | number, decimalPlaces: number = 2): string {\n return new Decimal(value).toFixed(decimalPlaces);\n },\n\n /**\n * Format as currency\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 * Convert object with decimal fields for database insert/update\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 * Convert object with decimal fields from database\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 for creating Decimal\n */\nexport function decimal(value: number | string): Decimal {\n return new Decimal(value);\n}\n"],"mappings":"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","names":[]}