@parsrun/core 0.1.28 → 0.1.30
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 +176 -46
- package/dist/decimal.js +123 -40
- package/dist/decimal.js.map +1 -1
- package/dist/errors.d.ts +39 -3
- package/dist/errors.js.map +1 -1
- package/dist/index.d.ts +184 -15
- package/dist/index.js +155 -40
- package/dist/index.js.map +1 -1
- package/dist/{logger-3oVznpFY.d.ts → logger-DrxxwI7C.d.ts} +136 -11
- package/dist/logger.d.ts +1 -1
- package/dist/logger.js +32 -0
- package/dist/logger.js.map +1 -1
- package/dist/transports/index.d.ts +58 -7
- package/dist/transports/index.js.map +1 -1
- package/dist/types.d.ts +176 -0
- package/dist/types.js.map +1 -1
- package/package.json +1 -1
package/dist/decimal.js
CHANGED
|
@@ -25,7 +25,9 @@ var Decimal = class _Decimal {
|
|
|
25
25
|
return trimmed.replace(/^(-?)0+(?=\d)/, "$1").replace(/\.?0+$/, "") || "0";
|
|
26
26
|
}
|
|
27
27
|
/**
|
|
28
|
-
* Add
|
|
28
|
+
* Add another value to this decimal.
|
|
29
|
+
* @param other - Value to add
|
|
30
|
+
* @returns A new Decimal with the result
|
|
29
31
|
*/
|
|
30
32
|
add(other) {
|
|
31
33
|
const a = parseFloat(this.value);
|
|
@@ -33,7 +35,9 @@ var Decimal = class _Decimal {
|
|
|
33
35
|
return new _Decimal(a + b);
|
|
34
36
|
}
|
|
35
37
|
/**
|
|
36
|
-
* Subtract
|
|
38
|
+
* Subtract a value from this decimal.
|
|
39
|
+
* @param other - Value to subtract
|
|
40
|
+
* @returns A new Decimal with the result
|
|
37
41
|
*/
|
|
38
42
|
sub(other) {
|
|
39
43
|
const a = parseFloat(this.value);
|
|
@@ -41,7 +45,9 @@ var Decimal = class _Decimal {
|
|
|
41
45
|
return new _Decimal(a - b);
|
|
42
46
|
}
|
|
43
47
|
/**
|
|
44
|
-
* Multiply
|
|
48
|
+
* Multiply this decimal by another value.
|
|
49
|
+
* @param other - Value to multiply by
|
|
50
|
+
* @returns A new Decimal with the result
|
|
45
51
|
*/
|
|
46
52
|
mul(other) {
|
|
47
53
|
const a = parseFloat(this.value);
|
|
@@ -49,7 +55,10 @@ var Decimal = class _Decimal {
|
|
|
49
55
|
return new _Decimal(a * b);
|
|
50
56
|
}
|
|
51
57
|
/**
|
|
52
|
-
* Divide
|
|
58
|
+
* Divide this decimal by another value.
|
|
59
|
+
* @param other - Value to divide by
|
|
60
|
+
* @returns A new Decimal with the result
|
|
61
|
+
* @throws Error if dividing by zero
|
|
53
62
|
*/
|
|
54
63
|
div(other) {
|
|
55
64
|
const a = parseFloat(this.value);
|
|
@@ -60,7 +69,9 @@ var Decimal = class _Decimal {
|
|
|
60
69
|
return new _Decimal(a / b);
|
|
61
70
|
}
|
|
62
71
|
/**
|
|
63
|
-
*
|
|
72
|
+
* Get the modulo (remainder) of dividing this decimal by another value.
|
|
73
|
+
* @param other - Value to divide by
|
|
74
|
+
* @returns A new Decimal with the remainder
|
|
64
75
|
*/
|
|
65
76
|
mod(other) {
|
|
66
77
|
const a = parseFloat(this.value);
|
|
@@ -68,14 +79,18 @@ var Decimal = class _Decimal {
|
|
|
68
79
|
return new _Decimal(a % b);
|
|
69
80
|
}
|
|
70
81
|
/**
|
|
71
|
-
*
|
|
82
|
+
* Raise this decimal to a power.
|
|
83
|
+
* @param exp - The exponent
|
|
84
|
+
* @returns A new Decimal with the result
|
|
72
85
|
*/
|
|
73
86
|
pow(exp) {
|
|
74
87
|
const a = parseFloat(this.value);
|
|
75
88
|
return new _Decimal(Math.pow(a, exp));
|
|
76
89
|
}
|
|
77
90
|
/**
|
|
78
|
-
*
|
|
91
|
+
* Calculate the square root of this decimal.
|
|
92
|
+
* @returns A new Decimal with the square root
|
|
93
|
+
* @throws Error if the value is negative
|
|
79
94
|
*/
|
|
80
95
|
sqrt() {
|
|
81
96
|
const a = parseFloat(this.value);
|
|
@@ -85,21 +100,25 @@ var Decimal = class _Decimal {
|
|
|
85
100
|
return new _Decimal(Math.sqrt(a));
|
|
86
101
|
}
|
|
87
102
|
/**
|
|
88
|
-
*
|
|
103
|
+
* Get the absolute value of this decimal.
|
|
104
|
+
* @returns A new Decimal with the absolute value
|
|
89
105
|
*/
|
|
90
106
|
abs() {
|
|
91
107
|
const a = parseFloat(this.value);
|
|
92
108
|
return new _Decimal(Math.abs(a));
|
|
93
109
|
}
|
|
94
110
|
/**
|
|
95
|
-
* Negate
|
|
111
|
+
* Negate this decimal (multiply by -1).
|
|
112
|
+
* @returns A new Decimal with the negated value
|
|
96
113
|
*/
|
|
97
114
|
neg() {
|
|
98
115
|
const a = parseFloat(this.value);
|
|
99
116
|
return new _Decimal(-a);
|
|
100
117
|
}
|
|
101
118
|
/**
|
|
102
|
-
* Round to decimal places
|
|
119
|
+
* Round to the specified number of decimal places using standard rounding.
|
|
120
|
+
* @param decimals - Number of decimal places (default: 0)
|
|
121
|
+
* @returns A new Decimal with the rounded value
|
|
103
122
|
*/
|
|
104
123
|
round(decimals = 0) {
|
|
105
124
|
const a = parseFloat(this.value);
|
|
@@ -107,7 +126,9 @@ var Decimal = class _Decimal {
|
|
|
107
126
|
return new _Decimal(Math.round(a * factor) / factor);
|
|
108
127
|
}
|
|
109
128
|
/**
|
|
110
|
-
*
|
|
129
|
+
* Round down to the specified number of decimal places.
|
|
130
|
+
* @param decimals - Number of decimal places (default: 0)
|
|
131
|
+
* @returns A new Decimal with the floored value
|
|
111
132
|
*/
|
|
112
133
|
floor(decimals = 0) {
|
|
113
134
|
const a = parseFloat(this.value);
|
|
@@ -115,7 +136,9 @@ var Decimal = class _Decimal {
|
|
|
115
136
|
return new _Decimal(Math.floor(a * factor) / factor);
|
|
116
137
|
}
|
|
117
138
|
/**
|
|
118
|
-
*
|
|
139
|
+
* Round up to the specified number of decimal places.
|
|
140
|
+
* @param decimals - Number of decimal places (default: 0)
|
|
141
|
+
* @returns A new Decimal with the ceiled value
|
|
119
142
|
*/
|
|
120
143
|
ceil(decimals = 0) {
|
|
121
144
|
const a = parseFloat(this.value);
|
|
@@ -123,7 +146,9 @@ var Decimal = class _Decimal {
|
|
|
123
146
|
return new _Decimal(Math.ceil(a * factor) / factor);
|
|
124
147
|
}
|
|
125
148
|
/**
|
|
126
|
-
* Compare
|
|
149
|
+
* Compare this decimal to another value.
|
|
150
|
+
* @param other - Value to compare against
|
|
151
|
+
* @returns -1 if less, 0 if equal, 1 if greater
|
|
127
152
|
*/
|
|
128
153
|
cmp(other) {
|
|
129
154
|
const a = parseFloat(this.value);
|
|
@@ -133,85 +158,107 @@ var Decimal = class _Decimal {
|
|
|
133
158
|
return 0;
|
|
134
159
|
}
|
|
135
160
|
/**
|
|
136
|
-
*
|
|
161
|
+
* Check if this decimal equals another value.
|
|
162
|
+
* @param other - Value to compare against
|
|
163
|
+
* @returns True if values are equal
|
|
137
164
|
*/
|
|
138
165
|
eq(other) {
|
|
139
166
|
return this.cmp(other) === 0;
|
|
140
167
|
}
|
|
141
168
|
/**
|
|
142
|
-
*
|
|
169
|
+
* Check if this decimal is greater than another value.
|
|
170
|
+
* @param other - Value to compare against
|
|
171
|
+
* @returns True if this is greater
|
|
143
172
|
*/
|
|
144
173
|
gt(other) {
|
|
145
174
|
return this.cmp(other) === 1;
|
|
146
175
|
}
|
|
147
176
|
/**
|
|
148
|
-
*
|
|
177
|
+
* Check if this decimal is greater than or equal to another value.
|
|
178
|
+
* @param other - Value to compare against
|
|
179
|
+
* @returns True if this is greater or equal
|
|
149
180
|
*/
|
|
150
181
|
gte(other) {
|
|
151
182
|
return this.cmp(other) >= 0;
|
|
152
183
|
}
|
|
153
184
|
/**
|
|
154
|
-
*
|
|
185
|
+
* Check if this decimal is less than another value.
|
|
186
|
+
* @param other - Value to compare against
|
|
187
|
+
* @returns True if this is less
|
|
155
188
|
*/
|
|
156
189
|
lt(other) {
|
|
157
190
|
return this.cmp(other) === -1;
|
|
158
191
|
}
|
|
159
192
|
/**
|
|
160
|
-
*
|
|
193
|
+
* Check if this decimal is less than or equal to another value.
|
|
194
|
+
* @param other - Value to compare against
|
|
195
|
+
* @returns True if this is less or equal
|
|
161
196
|
*/
|
|
162
197
|
lte(other) {
|
|
163
198
|
return this.cmp(other) <= 0;
|
|
164
199
|
}
|
|
165
200
|
/**
|
|
166
|
-
* Check if zero
|
|
201
|
+
* Check if this decimal is exactly zero.
|
|
202
|
+
* @returns True if value is zero
|
|
167
203
|
*/
|
|
168
204
|
isZero() {
|
|
169
205
|
return parseFloat(this.value) === 0;
|
|
170
206
|
}
|
|
171
207
|
/**
|
|
172
|
-
* Check if positive
|
|
208
|
+
* Check if this decimal is positive (greater than zero).
|
|
209
|
+
* @returns True if value is positive
|
|
173
210
|
*/
|
|
174
211
|
isPositive() {
|
|
175
212
|
return parseFloat(this.value) > 0;
|
|
176
213
|
}
|
|
177
214
|
/**
|
|
178
|
-
* Check if negative
|
|
215
|
+
* Check if this decimal is negative (less than zero).
|
|
216
|
+
* @returns True if value is negative
|
|
179
217
|
*/
|
|
180
218
|
isNegative() {
|
|
181
219
|
return parseFloat(this.value) < 0;
|
|
182
220
|
}
|
|
183
221
|
/**
|
|
184
|
-
* Convert to number
|
|
222
|
+
* Convert this decimal to a JavaScript number.
|
|
223
|
+
* @returns The numeric value
|
|
185
224
|
*/
|
|
186
225
|
toNumber() {
|
|
187
226
|
return parseFloat(this.value);
|
|
188
227
|
}
|
|
189
228
|
/**
|
|
190
|
-
* Convert to string
|
|
229
|
+
* Convert this decimal to its string representation.
|
|
230
|
+
* @returns The string value
|
|
191
231
|
*/
|
|
192
232
|
toString() {
|
|
193
233
|
return this.value;
|
|
194
234
|
}
|
|
195
235
|
/**
|
|
196
|
-
* Format with fixed decimal places
|
|
236
|
+
* Format this decimal with a fixed number of decimal places.
|
|
237
|
+
* @param decimals - Number of decimal places (default: 2)
|
|
238
|
+
* @returns Formatted string
|
|
197
239
|
*/
|
|
198
240
|
toFixed(decimals = 2) {
|
|
199
241
|
return parseFloat(this.value).toFixed(decimals);
|
|
200
242
|
}
|
|
201
243
|
/**
|
|
202
|
-
* Convert to JSON (string representation)
|
|
244
|
+
* Convert to JSON (returns string representation for serialization).
|
|
245
|
+
* @returns The string value for JSON serialization
|
|
203
246
|
*/
|
|
204
247
|
toJSON() {
|
|
205
248
|
return this.value;
|
|
206
249
|
}
|
|
207
250
|
/**
|
|
208
|
-
*
|
|
251
|
+
* Create a Decimal from a value (alias for constructor).
|
|
252
|
+
* @param value - The value to convert
|
|
253
|
+
* @returns A new Decimal instance
|
|
209
254
|
*/
|
|
210
255
|
static from(value) {
|
|
211
256
|
return new _Decimal(value);
|
|
212
257
|
}
|
|
213
258
|
/**
|
|
214
|
-
*
|
|
259
|
+
* Calculate the sum of an array of values.
|
|
260
|
+
* @param values - Array of values to sum
|
|
261
|
+
* @returns A new Decimal with the sum
|
|
215
262
|
*/
|
|
216
263
|
static sum(values) {
|
|
217
264
|
return values.reduce(
|
|
@@ -220,14 +267,19 @@ var Decimal = class _Decimal {
|
|
|
220
267
|
);
|
|
221
268
|
}
|
|
222
269
|
/**
|
|
223
|
-
*
|
|
270
|
+
* Calculate the average of an array of values.
|
|
271
|
+
* @param values - Array of values to average
|
|
272
|
+
* @returns A new Decimal with the average (0 if empty array)
|
|
224
273
|
*/
|
|
225
274
|
static avg(values) {
|
|
226
275
|
if (values.length === 0) return new _Decimal(0);
|
|
227
276
|
return _Decimal.sum(values).div(values.length);
|
|
228
277
|
}
|
|
229
278
|
/**
|
|
230
|
-
*
|
|
279
|
+
* Find the minimum value from the provided values.
|
|
280
|
+
* @param values - Values to compare
|
|
281
|
+
* @returns A new Decimal with the minimum value
|
|
282
|
+
* @throws Error if no values provided
|
|
231
283
|
*/
|
|
232
284
|
static min(...values) {
|
|
233
285
|
if (values.length === 0) throw new Error("No values provided");
|
|
@@ -237,7 +289,10 @@ var Decimal = class _Decimal {
|
|
|
237
289
|
}, new _Decimal(values[0]));
|
|
238
290
|
}
|
|
239
291
|
/**
|
|
240
|
-
*
|
|
292
|
+
* Find the maximum value from the provided values.
|
|
293
|
+
* @param values - Values to compare
|
|
294
|
+
* @returns A new Decimal with the maximum value
|
|
295
|
+
* @throws Error if no values provided
|
|
241
296
|
*/
|
|
242
297
|
static max(...values) {
|
|
243
298
|
if (values.length === 0) throw new Error("No values provided");
|
|
@@ -249,51 +304,73 @@ var Decimal = class _Decimal {
|
|
|
249
304
|
};
|
|
250
305
|
var DecimalUtils = {
|
|
251
306
|
/**
|
|
252
|
-
* Convert number to database decimal string
|
|
307
|
+
* Convert a number to a database-safe decimal string.
|
|
308
|
+
* @param value - The value to convert
|
|
309
|
+
* @returns The decimal string or null if value is null/undefined
|
|
253
310
|
*/
|
|
254
311
|
toDecimalString(value) {
|
|
255
312
|
if (value === null || value === void 0) return null;
|
|
256
313
|
return new Decimal(value).toString();
|
|
257
314
|
},
|
|
258
315
|
/**
|
|
259
|
-
* Convert database decimal string to number
|
|
316
|
+
* Convert a database decimal string to a JavaScript number.
|
|
317
|
+
* @param value - The decimal string from database
|
|
318
|
+
* @returns The numeric value (0 if null/undefined/empty)
|
|
260
319
|
*/
|
|
261
320
|
fromDecimalString(value) {
|
|
262
321
|
if (!value) return 0;
|
|
263
322
|
return new Decimal(value).toNumber();
|
|
264
323
|
},
|
|
265
324
|
/**
|
|
266
|
-
*
|
|
325
|
+
* Multiply two values with precise decimal arithmetic.
|
|
326
|
+
* @param a - First value
|
|
327
|
+
* @param b - Second value
|
|
328
|
+
* @returns The product as a string
|
|
267
329
|
*/
|
|
268
330
|
multiply(a, b) {
|
|
269
331
|
return new Decimal(a).mul(b).toString();
|
|
270
332
|
},
|
|
271
333
|
/**
|
|
272
|
-
*
|
|
334
|
+
* Add two values with precise decimal arithmetic.
|
|
335
|
+
* @param a - First value
|
|
336
|
+
* @param b - Second value
|
|
337
|
+
* @returns The sum as a string
|
|
273
338
|
*/
|
|
274
339
|
add(a, b) {
|
|
275
340
|
return new Decimal(a).add(b).toString();
|
|
276
341
|
},
|
|
277
342
|
/**
|
|
278
|
-
*
|
|
343
|
+
* Subtract two values with precise decimal arithmetic.
|
|
344
|
+
* @param a - Value to subtract from
|
|
345
|
+
* @param b - Value to subtract
|
|
346
|
+
* @returns The difference as a string
|
|
279
347
|
*/
|
|
280
348
|
subtract(a, b) {
|
|
281
349
|
return new Decimal(a).sub(b).toString();
|
|
282
350
|
},
|
|
283
351
|
/**
|
|
284
|
-
*
|
|
352
|
+
* Divide two values with precise decimal arithmetic.
|
|
353
|
+
* @param a - Dividend
|
|
354
|
+
* @param b - Divisor
|
|
355
|
+
* @returns The quotient as a string
|
|
285
356
|
*/
|
|
286
357
|
divide(a, b) {
|
|
287
358
|
return new Decimal(a).div(b).toString();
|
|
288
359
|
},
|
|
289
360
|
/**
|
|
290
|
-
* Format decimal for display
|
|
361
|
+
* Format a decimal value for display with fixed decimal places.
|
|
362
|
+
* @param value - The value to format
|
|
363
|
+
* @param decimalPlaces - Number of decimal places (default: 2)
|
|
364
|
+
* @returns Formatted string
|
|
291
365
|
*/
|
|
292
366
|
format(value, decimalPlaces = 2) {
|
|
293
367
|
return new Decimal(value).toFixed(decimalPlaces);
|
|
294
368
|
},
|
|
295
369
|
/**
|
|
296
|
-
* Format as currency
|
|
370
|
+
* Format a value as currency using Intl.NumberFormat.
|
|
371
|
+
* @param value - The value to format
|
|
372
|
+
* @param options - Currency formatting options
|
|
373
|
+
* @returns Formatted currency string
|
|
297
374
|
*/
|
|
298
375
|
formatCurrency(value, options = {}) {
|
|
299
376
|
const { currency = "USD", locale = "en-US", decimals = 2 } = options;
|
|
@@ -306,7 +383,10 @@ var DecimalUtils = {
|
|
|
306
383
|
}).format(num);
|
|
307
384
|
},
|
|
308
385
|
/**
|
|
309
|
-
*
|
|
386
|
+
* Prepare an object for database insert/update by converting numeric fields to decimal strings.
|
|
387
|
+
* @param data - The object to prepare
|
|
388
|
+
* @param decimalFields - Array of field names that should be converted to decimal strings
|
|
389
|
+
* @returns A new object with specified fields converted to decimal strings
|
|
310
390
|
*/
|
|
311
391
|
prepareForDatabase(data, decimalFields) {
|
|
312
392
|
const result = { ...data };
|
|
@@ -321,7 +401,10 @@ var DecimalUtils = {
|
|
|
321
401
|
return result;
|
|
322
402
|
},
|
|
323
403
|
/**
|
|
324
|
-
*
|
|
404
|
+
* Parse an object from database by converting decimal string fields to JavaScript numbers.
|
|
405
|
+
* @param data - The object from database
|
|
406
|
+
* @param decimalFields - Array of field names that should be converted from decimal strings
|
|
407
|
+
* @returns A new object with specified fields converted to numbers
|
|
325
408
|
*/
|
|
326
409
|
parseFromDatabase(data, decimalFields) {
|
|
327
410
|
const result = { ...data };
|
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\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":[]}
|
|
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":"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","names":[]}
|
package/dist/errors.d.ts
CHANGED
|
@@ -47,35 +47,63 @@ declare class UnauthorizedError extends AuthError {
|
|
|
47
47
|
declare class ForbiddenError extends AuthError {
|
|
48
48
|
constructor(message?: string, details?: Record<string, unknown>);
|
|
49
49
|
}
|
|
50
|
+
/**
|
|
51
|
+
* Credentials (username/password, API key, etc.) are invalid (HTTP 401).
|
|
52
|
+
* Thrown during authentication when credentials don't match.
|
|
53
|
+
*/
|
|
50
54
|
declare class InvalidCredentialsError extends AuthError {
|
|
51
55
|
constructor(message?: string, details?: Record<string, unknown>);
|
|
52
56
|
}
|
|
57
|
+
/**
|
|
58
|
+
* User session has expired (HTTP 401).
|
|
59
|
+
* User needs to re-authenticate to continue.
|
|
60
|
+
*/
|
|
53
61
|
declare class SessionExpiredError extends AuthError {
|
|
54
62
|
constructor(message?: string, details?: Record<string, unknown>);
|
|
55
63
|
}
|
|
64
|
+
/**
|
|
65
|
+
* Two-factor authentication is required to complete login (HTTP 403).
|
|
66
|
+
* Contains a challengeId that should be used to submit the 2FA code.
|
|
67
|
+
*/
|
|
56
68
|
declare class TwoFactorRequiredError extends AuthError {
|
|
69
|
+
/** Unique identifier for the 2FA challenge */
|
|
57
70
|
readonly challengeId: string;
|
|
58
|
-
constructor(message: string | undefined,
|
|
71
|
+
constructor(message: string | undefined,
|
|
72
|
+
/** Unique identifier for the 2FA challenge */
|
|
73
|
+
challengeId: string, details?: Record<string, unknown>);
|
|
59
74
|
}
|
|
75
|
+
/**
|
|
76
|
+
* Account has been locked due to too many failed attempts or admin action (HTTP 423).
|
|
77
|
+
* May include a lockedUntil timestamp indicating when the account will be unlocked.
|
|
78
|
+
*/
|
|
60
79
|
declare class AccountLockedError extends AuthError {
|
|
80
|
+
/** When the account will be automatically unlocked (if applicable) */
|
|
61
81
|
readonly lockedUntil?: Date | undefined;
|
|
62
|
-
constructor(message?: string,
|
|
82
|
+
constructor(message?: string,
|
|
83
|
+
/** When the account will be automatically unlocked (if applicable) */
|
|
84
|
+
lockedUntil?: Date | undefined, details?: Record<string, unknown>);
|
|
63
85
|
}
|
|
86
|
+
/** Base class for tenant-related errors */
|
|
64
87
|
declare class TenantError extends ParsError {
|
|
65
88
|
constructor(message: string, code?: string, statusCode?: number, details?: Record<string, unknown>);
|
|
66
89
|
}
|
|
90
|
+
/** Tenant does not exist or user does not have access to it (HTTP 404) */
|
|
67
91
|
declare class TenantNotFoundError extends TenantError {
|
|
68
92
|
constructor(message?: string, details?: Record<string, unknown>);
|
|
69
93
|
}
|
|
94
|
+
/** Tenant has been suspended and access is denied (HTTP 403) */
|
|
70
95
|
declare class TenantSuspendedError extends TenantError {
|
|
71
96
|
constructor(message?: string, details?: Record<string, unknown>);
|
|
72
97
|
}
|
|
98
|
+
/** Base class for membership-related errors */
|
|
73
99
|
declare class MembershipError extends TenantError {
|
|
74
100
|
constructor(message?: string, code?: string, statusCode?: number, details?: Record<string, unknown>);
|
|
75
101
|
}
|
|
102
|
+
/** User is not a member of the specified tenant (HTTP 404) */
|
|
76
103
|
declare class MembershipNotFoundError extends MembershipError {
|
|
77
104
|
constructor(message?: string, details?: Record<string, unknown>);
|
|
78
105
|
}
|
|
106
|
+
/** User's membership in the tenant has expired (HTTP 403) */
|
|
79
107
|
declare class MembershipExpiredError extends MembershipError {
|
|
80
108
|
constructor(message?: string, details?: Record<string, unknown>);
|
|
81
109
|
}
|
|
@@ -106,8 +134,16 @@ declare class NotFoundError extends ParsError {
|
|
|
106
134
|
declare class ConflictError extends ParsError {
|
|
107
135
|
constructor(message?: string, details?: Record<string, unknown>);
|
|
108
136
|
}
|
|
137
|
+
/**
|
|
138
|
+
* A duplicate resource already exists (HTTP 409).
|
|
139
|
+
* Used when attempting to create a resource that violates a uniqueness constraint.
|
|
140
|
+
*/
|
|
109
141
|
declare class DuplicateError extends ConflictError {
|
|
110
|
-
constructor(
|
|
142
|
+
constructor(
|
|
143
|
+
/** The type of resource that already exists */
|
|
144
|
+
resource?: string,
|
|
145
|
+
/** The field that caused the conflict (e.g., 'email', 'slug') */
|
|
146
|
+
field?: string, details?: Record<string, unknown>);
|
|
111
147
|
}
|
|
112
148
|
|
|
113
149
|
export { AccountLockedError, AuthError, ConflictError, DuplicateError, ForbiddenError, InvalidCredentialsError, MembershipError, MembershipExpiredError, MembershipNotFoundError, NotFoundError, ParsError, RateLimitError, SessionExpiredError, TenantError, TenantNotFoundError, TenantSuspendedError, TwoFactorRequiredError, UnauthorizedError, ValidationError, type ValidationErrorDetail };
|
package/dist/errors.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/errors.ts"],"sourcesContent":["/**\n * @module\n * Error classes for the Pars framework.\n * Provides typed errors for auth, validation, rate limiting, and more.\n *\n * @example\n * ```typescript\n * import { NotFoundError, ValidationError, UnauthorizedError } from '@parsrun/core';\n *\n * // Throw typed errors\n * throw new NotFoundError('User');\n * throw new ValidationError('Invalid input', [{ field: 'email', message: 'Invalid format' }]);\n * throw new UnauthorizedError('Token expired');\n * ```\n */\n\n/**\n * Base error class for all Pars framework errors.\n * Includes error code, HTTP status code, and optional details.\n *\n * @example\n * ```typescript\n * throw new ParsError('Something went wrong', 'CUSTOM_ERROR', 500, { extra: 'info' });\n * ```\n */\nexport class ParsError extends Error {\n public readonly code: string;\n public readonly statusCode: number;\n public readonly details: Record<string, unknown> | undefined;\n\n constructor(\n message: string,\n code: string,\n statusCode: number = 500,\n details?: Record<string, unknown>\n ) {\n super(message);\n this.name = \"ParsError\";\n this.code = code;\n this.statusCode = statusCode;\n this.details = details ?? undefined;\n Error.captureStackTrace?.(this, this.constructor);\n }\n\n toJSON() {\n return {\n name: this.name,\n message: this.message,\n code: this.code,\n statusCode: this.statusCode,\n details: this.details,\n };\n }\n}\n\n// ============================================\n// AUTH ERRORS\n// ============================================\n\n/** Base class for authentication-related errors (HTTP 401/403) */\nexport class AuthError extends ParsError {\n constructor(\n message: string,\n code: string = \"AUTH_ERROR\",\n statusCode: number = 401,\n details?: Record<string, unknown>\n ) {\n super(message, code, statusCode, details);\n this.name = \"AuthError\";\n }\n}\n\n/** User is not authenticated (HTTP 401) */\nexport class UnauthorizedError extends AuthError {\n constructor(message: string = \"Unauthorized\", details?: Record<string, unknown>) {\n super(message, \"UNAUTHORIZED\", 401, details);\n this.name = \"UnauthorizedError\";\n }\n}\n\n/** User lacks permission for the requested action (HTTP 403) */\nexport class ForbiddenError extends AuthError {\n constructor(message: string = \"Forbidden\", details?: Record<string, unknown>) {\n super(message, \"FORBIDDEN\", 403, details);\n this.name = \"ForbiddenError\";\n }\n}\n\nexport class InvalidCredentialsError extends AuthError {\n constructor(message: string = \"Invalid credentials\", details?: Record<string, unknown>) {\n super(message, \"INVALID_CREDENTIALS\", 401, details);\n this.name = \"InvalidCredentialsError\";\n }\n}\n\nexport class SessionExpiredError extends AuthError {\n constructor(message: string = \"Session expired\", details?: Record<string, unknown>) {\n super(message, \"SESSION_EXPIRED\", 401, details);\n this.name = \"SessionExpiredError\";\n }\n}\n\nexport class TwoFactorRequiredError extends AuthError {\n constructor(\n message: string = \"Two-factor authentication required\",\n public readonly challengeId: string,\n details?: Record<string, unknown>\n ) {\n super(message, \"TWO_FACTOR_REQUIRED\", 403, { ...details, challengeId });\n this.name = \"TwoFactorRequiredError\";\n }\n}\n\nexport class AccountLockedError extends AuthError {\n constructor(\n message: string = \"Account locked\",\n public readonly lockedUntil?: Date,\n details?: Record<string, unknown>\n ) {\n super(message, \"ACCOUNT_LOCKED\", 423, { ...details, lockedUntil });\n this.name = \"AccountLockedError\";\n }\n}\n\n// ============================================\n// TENANT ERRORS\n// ============================================\n\nexport class TenantError extends ParsError {\n constructor(\n message: string,\n code: string = \"TENANT_ERROR\",\n statusCode: number = 400,\n details?: Record<string, unknown>\n ) {\n super(message, code, statusCode, details);\n this.name = \"TenantError\";\n }\n}\n\nexport class TenantNotFoundError extends TenantError {\n constructor(message: string = \"Tenant not found\", details?: Record<string, unknown>) {\n super(message, \"TENANT_NOT_FOUND\", 404, details);\n this.name = \"TenantNotFoundError\";\n }\n}\n\nexport class TenantSuspendedError extends TenantError {\n constructor(message: string = \"Tenant suspended\", details?: Record<string, unknown>) {\n super(message, \"TENANT_SUSPENDED\", 403, details);\n this.name = \"TenantSuspendedError\";\n }\n}\n\nexport class MembershipError extends TenantError {\n constructor(\n message: string = \"Membership error\",\n code: string = \"MEMBERSHIP_ERROR\",\n statusCode: number = 400,\n details?: Record<string, unknown>\n ) {\n super(message, code, statusCode, details);\n this.name = \"MembershipError\";\n }\n}\n\nexport class MembershipNotFoundError extends MembershipError {\n constructor(message: string = \"Membership not found\", details?: Record<string, unknown>) {\n super(message, \"MEMBERSHIP_NOT_FOUND\", 404, details);\n this.name = \"MembershipNotFoundError\";\n }\n}\n\nexport class MembershipExpiredError extends MembershipError {\n constructor(message: string = \"Membership expired\", details?: Record<string, unknown>) {\n super(message, \"MEMBERSHIP_EXPIRED\", 403, details);\n this.name = \"MembershipExpiredError\";\n }\n}\n\n// ============================================\n// VALIDATION ERRORS\n// ============================================\n\n/** Request validation failed with one or more field errors (HTTP 400) */\nexport class ValidationError extends ParsError {\n constructor(\n message: string = \"Validation failed\",\n public readonly errors: ValidationErrorDetail[],\n details?: Record<string, unknown>\n ) {\n super(message, \"VALIDATION_ERROR\", 400, { ...details, errors });\n this.name = \"ValidationError\";\n }\n}\n\n/** Details about a single validation error */\nexport interface ValidationErrorDetail {\n /** Field path that failed validation */\n field: string;\n /** Human-readable error message */\n message: string;\n /** Optional error code for programmatic handling */\n code?: string;\n}\n\n// ============================================\n// RATE LIMIT ERRORS\n// ============================================\n\n/** Too many requests - rate limit exceeded (HTTP 429) */\nexport class RateLimitError extends ParsError {\n constructor(\n message: string = \"Rate limit exceeded\",\n public readonly retryAfter?: number,\n details?: Record<string, unknown>\n ) {\n super(message, \"RATE_LIMIT_EXCEEDED\", 429, { ...details, retryAfter });\n this.name = \"RateLimitError\";\n }\n}\n\n// ============================================\n// NOT FOUND ERRORS\n// ============================================\n\n/** Requested resource was not found (HTTP 404) */\nexport class NotFoundError extends ParsError {\n constructor(\n resource: string = \"Resource\",\n message?: string,\n details?: Record<string, unknown>\n ) {\n super(message ?? `${resource} not found`, \"NOT_FOUND\", 404, { ...details, resource });\n this.name = \"NotFoundError\";\n }\n}\n\n// ============================================\n// CONFLICT ERRORS\n// ============================================\n\n/** Resource conflict, such as duplicate entry (HTTP 409) */\nexport class ConflictError extends ParsError {\n constructor(message: string = \"Conflict\", details?: Record<string, unknown>) {\n super(message, \"CONFLICT\", 409, details);\n this.name = \"ConflictError\";\n }\n}\n\nexport class DuplicateError extends ConflictError {\n constructor(\n resource: string = \"Resource\",\n field?: string,\n details?: Record<string, unknown>\n ) {\n super(`${resource} already exists${field ? ` with this ${field}` : \"\"}`, {\n ...details,\n resource,\n field,\n });\n this.name = \"DuplicateError\";\n }\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/errors.ts"],"sourcesContent":["/**\n * @module\n * Error classes for the Pars framework.\n * Provides typed errors for auth, validation, rate limiting, and more.\n *\n * @example\n * ```typescript\n * import { NotFoundError, ValidationError, UnauthorizedError } from '@parsrun/core';\n *\n * // Throw typed errors\n * throw new NotFoundError('User');\n * throw new ValidationError('Invalid input', [{ field: 'email', message: 'Invalid format' }]);\n * throw new UnauthorizedError('Token expired');\n * ```\n */\n\n/**\n * Base error class for all Pars framework errors.\n * Includes error code, HTTP status code, and optional details.\n *\n * @example\n * ```typescript\n * throw new ParsError('Something went wrong', 'CUSTOM_ERROR', 500, { extra: 'info' });\n * ```\n */\nexport class ParsError extends Error {\n public readonly code: string;\n public readonly statusCode: number;\n public readonly details: Record<string, unknown> | undefined;\n\n constructor(\n message: string,\n code: string,\n statusCode: number = 500,\n details?: Record<string, unknown>\n ) {\n super(message);\n this.name = \"ParsError\";\n this.code = code;\n this.statusCode = statusCode;\n this.details = details ?? undefined;\n Error.captureStackTrace?.(this, this.constructor);\n }\n\n toJSON() {\n return {\n name: this.name,\n message: this.message,\n code: this.code,\n statusCode: this.statusCode,\n details: this.details,\n };\n }\n}\n\n// ============================================\n// AUTH ERRORS\n// ============================================\n\n/** Base class for authentication-related errors (HTTP 401/403) */\nexport class AuthError extends ParsError {\n constructor(\n message: string,\n code: string = \"AUTH_ERROR\",\n statusCode: number = 401,\n details?: Record<string, unknown>\n ) {\n super(message, code, statusCode, details);\n this.name = \"AuthError\";\n }\n}\n\n/** User is not authenticated (HTTP 401) */\nexport class UnauthorizedError extends AuthError {\n constructor(message: string = \"Unauthorized\", details?: Record<string, unknown>) {\n super(message, \"UNAUTHORIZED\", 401, details);\n this.name = \"UnauthorizedError\";\n }\n}\n\n/** User lacks permission for the requested action (HTTP 403) */\nexport class ForbiddenError extends AuthError {\n constructor(message: string = \"Forbidden\", details?: Record<string, unknown>) {\n super(message, \"FORBIDDEN\", 403, details);\n this.name = \"ForbiddenError\";\n }\n}\n\n/**\n * Credentials (username/password, API key, etc.) are invalid (HTTP 401).\n * Thrown during authentication when credentials don't match.\n */\nexport class InvalidCredentialsError extends AuthError {\n constructor(message: string = \"Invalid credentials\", details?: Record<string, unknown>) {\n super(message, \"INVALID_CREDENTIALS\", 401, details);\n this.name = \"InvalidCredentialsError\";\n }\n}\n\n/**\n * User session has expired (HTTP 401).\n * User needs to re-authenticate to continue.\n */\nexport class SessionExpiredError extends AuthError {\n constructor(message: string = \"Session expired\", details?: Record<string, unknown>) {\n super(message, \"SESSION_EXPIRED\", 401, details);\n this.name = \"SessionExpiredError\";\n }\n}\n\n/**\n * Two-factor authentication is required to complete login (HTTP 403).\n * Contains a challengeId that should be used to submit the 2FA code.\n */\nexport class TwoFactorRequiredError extends AuthError {\n constructor(\n message: string = \"Two-factor authentication required\",\n /** Unique identifier for the 2FA challenge */\n public readonly challengeId: string,\n details?: Record<string, unknown>\n ) {\n super(message, \"TWO_FACTOR_REQUIRED\", 403, { ...details, challengeId });\n this.name = \"TwoFactorRequiredError\";\n }\n}\n\n/**\n * Account has been locked due to too many failed attempts or admin action (HTTP 423).\n * May include a lockedUntil timestamp indicating when the account will be unlocked.\n */\nexport class AccountLockedError extends AuthError {\n constructor(\n message: string = \"Account locked\",\n /** When the account will be automatically unlocked (if applicable) */\n public readonly lockedUntil?: Date,\n details?: Record<string, unknown>\n ) {\n super(message, \"ACCOUNT_LOCKED\", 423, { ...details, lockedUntil });\n this.name = \"AccountLockedError\";\n }\n}\n\n// ============================================\n// TENANT ERRORS\n// ============================================\n\n/** Base class for tenant-related errors */\nexport class TenantError extends ParsError {\n constructor(\n message: string,\n code: string = \"TENANT_ERROR\",\n statusCode: number = 400,\n details?: Record<string, unknown>\n ) {\n super(message, code, statusCode, details);\n this.name = \"TenantError\";\n }\n}\n\n/** Tenant does not exist or user does not have access to it (HTTP 404) */\nexport class TenantNotFoundError extends TenantError {\n constructor(message: string = \"Tenant not found\", details?: Record<string, unknown>) {\n super(message, \"TENANT_NOT_FOUND\", 404, details);\n this.name = \"TenantNotFoundError\";\n }\n}\n\n/** Tenant has been suspended and access is denied (HTTP 403) */\nexport class TenantSuspendedError extends TenantError {\n constructor(message: string = \"Tenant suspended\", details?: Record<string, unknown>) {\n super(message, \"TENANT_SUSPENDED\", 403, details);\n this.name = \"TenantSuspendedError\";\n }\n}\n\n/** Base class for membership-related errors */\nexport class MembershipError extends TenantError {\n constructor(\n message: string = \"Membership error\",\n code: string = \"MEMBERSHIP_ERROR\",\n statusCode: number = 400,\n details?: Record<string, unknown>\n ) {\n super(message, code, statusCode, details);\n this.name = \"MembershipError\";\n }\n}\n\n/** User is not a member of the specified tenant (HTTP 404) */\nexport class MembershipNotFoundError extends MembershipError {\n constructor(message: string = \"Membership not found\", details?: Record<string, unknown>) {\n super(message, \"MEMBERSHIP_NOT_FOUND\", 404, details);\n this.name = \"MembershipNotFoundError\";\n }\n}\n\n/** User's membership in the tenant has expired (HTTP 403) */\nexport class MembershipExpiredError extends MembershipError {\n constructor(message: string = \"Membership expired\", details?: Record<string, unknown>) {\n super(message, \"MEMBERSHIP_EXPIRED\", 403, details);\n this.name = \"MembershipExpiredError\";\n }\n}\n\n// ============================================\n// VALIDATION ERRORS\n// ============================================\n\n/** Request validation failed with one or more field errors (HTTP 400) */\nexport class ValidationError extends ParsError {\n constructor(\n message: string = \"Validation failed\",\n public readonly errors: ValidationErrorDetail[],\n details?: Record<string, unknown>\n ) {\n super(message, \"VALIDATION_ERROR\", 400, { ...details, errors });\n this.name = \"ValidationError\";\n }\n}\n\n/** Details about a single validation error */\nexport interface ValidationErrorDetail {\n /** Field path that failed validation */\n field: string;\n /** Human-readable error message */\n message: string;\n /** Optional error code for programmatic handling */\n code?: string;\n}\n\n// ============================================\n// RATE LIMIT ERRORS\n// ============================================\n\n/** Too many requests - rate limit exceeded (HTTP 429) */\nexport class RateLimitError extends ParsError {\n constructor(\n message: string = \"Rate limit exceeded\",\n public readonly retryAfter?: number,\n details?: Record<string, unknown>\n ) {\n super(message, \"RATE_LIMIT_EXCEEDED\", 429, { ...details, retryAfter });\n this.name = \"RateLimitError\";\n }\n}\n\n// ============================================\n// NOT FOUND ERRORS\n// ============================================\n\n/** Requested resource was not found (HTTP 404) */\nexport class NotFoundError extends ParsError {\n constructor(\n resource: string = \"Resource\",\n message?: string,\n details?: Record<string, unknown>\n ) {\n super(message ?? `${resource} not found`, \"NOT_FOUND\", 404, { ...details, resource });\n this.name = \"NotFoundError\";\n }\n}\n\n// ============================================\n// CONFLICT ERRORS\n// ============================================\n\n/** Resource conflict, such as duplicate entry (HTTP 409) */\nexport class ConflictError extends ParsError {\n constructor(message: string = \"Conflict\", details?: Record<string, unknown>) {\n super(message, \"CONFLICT\", 409, details);\n this.name = \"ConflictError\";\n }\n}\n\n/**\n * A duplicate resource already exists (HTTP 409).\n * Used when attempting to create a resource that violates a uniqueness constraint.\n */\nexport class DuplicateError extends ConflictError {\n constructor(\n /** The type of resource that already exists */\n resource: string = \"Resource\",\n /** The field that caused the conflict (e.g., 'email', 'slug') */\n field?: string,\n details?: Record<string, unknown>\n ) {\n super(`${resource} already exists${field ? ` with this ${field}` : \"\"}`, {\n ...details,\n resource,\n field,\n });\n this.name = \"DuplicateError\";\n }\n}\n"],"mappings":";AAyBO,IAAM,YAAN,cAAwB,MAAM;AAAA,EACnB;AAAA,EACA;AAAA,EACA;AAAA,EAEhB,YACE,SACA,MACA,aAAqB,KACrB,SACA;AACA,UAAM,OAAO;AACb,SAAK,OAAO;AACZ,SAAK,OAAO;AACZ,SAAK,aAAa;AAClB,SAAK,UAAU,WAAW;AAC1B,UAAM,oBAAoB,MAAM,KAAK,WAAW;AAAA,EAClD;AAAA,EAEA,SAAS;AACP,WAAO;AAAA,MACL,MAAM,KAAK;AAAA,MACX,SAAS,KAAK;AAAA,MACd,MAAM,KAAK;AAAA,MACX,YAAY,KAAK;AAAA,MACjB,SAAS,KAAK;AAAA,IAChB;AAAA,EACF;AACF;AAOO,IAAM,YAAN,cAAwB,UAAU;AAAA,EACvC,YACE,SACA,OAAe,cACf,aAAqB,KACrB,SACA;AACA,UAAM,SAAS,MAAM,YAAY,OAAO;AACxC,SAAK,OAAO;AAAA,EACd;AACF;AAGO,IAAM,oBAAN,cAAgC,UAAU;AAAA,EAC/C,YAAY,UAAkB,gBAAgB,SAAmC;AAC/E,UAAM,SAAS,gBAAgB,KAAK,OAAO;AAC3C,SAAK,OAAO;AAAA,EACd;AACF;AAGO,IAAM,iBAAN,cAA6B,UAAU;AAAA,EAC5C,YAAY,UAAkB,aAAa,SAAmC;AAC5E,UAAM,SAAS,aAAa,KAAK,OAAO;AACxC,SAAK,OAAO;AAAA,EACd;AACF;AAMO,IAAM,0BAAN,cAAsC,UAAU;AAAA,EACrD,YAAY,UAAkB,uBAAuB,SAAmC;AACtF,UAAM,SAAS,uBAAuB,KAAK,OAAO;AAClD,SAAK,OAAO;AAAA,EACd;AACF;AAMO,IAAM,sBAAN,cAAkC,UAAU;AAAA,EACjD,YAAY,UAAkB,mBAAmB,SAAmC;AAClF,UAAM,SAAS,mBAAmB,KAAK,OAAO;AAC9C,SAAK,OAAO;AAAA,EACd;AACF;AAMO,IAAM,yBAAN,cAAqC,UAAU;AAAA,EACpD,YACE,UAAkB,sCAEF,aAChB,SACA;AACA,UAAM,SAAS,uBAAuB,KAAK,EAAE,GAAG,SAAS,YAAY,CAAC;AAHtD;AAIhB,SAAK,OAAO;AAAA,EACd;AACF;AAMO,IAAM,qBAAN,cAAiC,UAAU;AAAA,EAChD,YACE,UAAkB,kBAEF,aAChB,SACA;AACA,UAAM,SAAS,kBAAkB,KAAK,EAAE,GAAG,SAAS,YAAY,CAAC;AAHjD;AAIhB,SAAK,OAAO;AAAA,EACd;AACF;AAOO,IAAM,cAAN,cAA0B,UAAU;AAAA,EACzC,YACE,SACA,OAAe,gBACf,aAAqB,KACrB,SACA;AACA,UAAM,SAAS,MAAM,YAAY,OAAO;AACxC,SAAK,OAAO;AAAA,EACd;AACF;AAGO,IAAM,sBAAN,cAAkC,YAAY;AAAA,EACnD,YAAY,UAAkB,oBAAoB,SAAmC;AACnF,UAAM,SAAS,oBAAoB,KAAK,OAAO;AAC/C,SAAK,OAAO;AAAA,EACd;AACF;AAGO,IAAM,uBAAN,cAAmC,YAAY;AAAA,EACpD,YAAY,UAAkB,oBAAoB,SAAmC;AACnF,UAAM,SAAS,oBAAoB,KAAK,OAAO;AAC/C,SAAK,OAAO;AAAA,EACd;AACF;AAGO,IAAM,kBAAN,cAA8B,YAAY;AAAA,EAC/C,YACE,UAAkB,oBAClB,OAAe,oBACf,aAAqB,KACrB,SACA;AACA,UAAM,SAAS,MAAM,YAAY,OAAO;AACxC,SAAK,OAAO;AAAA,EACd;AACF;AAGO,IAAM,0BAAN,cAAsC,gBAAgB;AAAA,EAC3D,YAAY,UAAkB,wBAAwB,SAAmC;AACvF,UAAM,SAAS,wBAAwB,KAAK,OAAO;AACnD,SAAK,OAAO;AAAA,EACd;AACF;AAGO,IAAM,yBAAN,cAAqC,gBAAgB;AAAA,EAC1D,YAAY,UAAkB,sBAAsB,SAAmC;AACrF,UAAM,SAAS,sBAAsB,KAAK,OAAO;AACjD,SAAK,OAAO;AAAA,EACd;AACF;AAOO,IAAM,kBAAN,cAA8B,UAAU;AAAA,EAC7C,YACE,UAAkB,qBACF,QAChB,SACA;AACA,UAAM,SAAS,oBAAoB,KAAK,EAAE,GAAG,SAAS,OAAO,CAAC;AAH9C;AAIhB,SAAK,OAAO;AAAA,EACd;AACF;AAiBO,IAAM,iBAAN,cAA6B,UAAU;AAAA,EAC5C,YACE,UAAkB,uBACF,YAChB,SACA;AACA,UAAM,SAAS,uBAAuB,KAAK,EAAE,GAAG,SAAS,WAAW,CAAC;AAHrD;AAIhB,SAAK,OAAO;AAAA,EACd;AACF;AAOO,IAAM,gBAAN,cAA4B,UAAU;AAAA,EAC3C,YACE,WAAmB,YACnB,SACA,SACA;AACA,UAAM,WAAW,GAAG,QAAQ,cAAc,aAAa,KAAK,EAAE,GAAG,SAAS,SAAS,CAAC;AACpF,SAAK,OAAO;AAAA,EACd;AACF;AAOO,IAAM,gBAAN,cAA4B,UAAU;AAAA,EAC3C,YAAY,UAAkB,YAAY,SAAmC;AAC3E,UAAM,SAAS,YAAY,KAAK,OAAO;AACvC,SAAK,OAAO;AAAA,EACd;AACF;AAMO,IAAM,iBAAN,cAA6B,cAAc;AAAA,EAChD,YAEE,WAAmB,YAEnB,OACA,SACA;AACA,UAAM,GAAG,QAAQ,kBAAkB,QAAQ,cAAc,KAAK,KAAK,EAAE,IAAI;AAAA,MACvE,GAAG;AAAA,MACH;AAAA,MACA;AAAA,IACF,CAAC;AACD,SAAK,OAAO;AAAA,EACd;AACF;","names":[]}
|