@salespark/toolkit 2.1.6 → 2.1.8
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 +56 -5
- package/dist/index.cjs +68 -7
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +84 -13
- package/dist/index.d.ts +84 -13
- package/dist/index.js +64 -8
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -27,7 +27,7 @@ npm i @salespark/toolkit
|
|
|
27
27
|
- **Array utilities**: chunk, uniqBy, deep equality, flatten, groupBy, etc.
|
|
28
28
|
- **Object utilities**: pick, omit, clean objects, deep merge, etc.
|
|
29
29
|
- **String utilities**: slugify, template fill, deburr, sanitize, etc.
|
|
30
|
-
- **Number utilities**: clamp, round, safe parse (locale-aware), random digits, etc.
|
|
30
|
+
- **Number utilities**: clamp, round, safe arithmetic/comparisons, safe parse (locale-aware), random digits, etc.
|
|
31
31
|
- **Function utilities**: debounce, throttle, formatCurrency, parseName, currency conversions, etc.
|
|
32
32
|
- **Boolean utilities**: safe boolean conversion with common representations
|
|
33
33
|
- **Validation utilities**: IBAN validator (ISO 13616), Portuguese tax ID validator
|
|
@@ -267,16 +267,31 @@ objectToString({ name: "John", age: 30 });
|
|
|
267
267
|
// Result: "name=John_age=30"
|
|
268
268
|
```
|
|
269
269
|
|
|
270
|
-
**`cleanObject<T>(obj: T): any`** — Deep-cleans an object by removing null/undefined values.
|
|
270
|
+
**`cleanObject<T>(obj: T, removeEmptyString?: boolean): any`** — Deep-cleans an object by removing null/undefined-like values, with optional empty-string removal.
|
|
271
271
|
|
|
272
272
|
```javascript
|
|
273
|
+
// Default behaviour: keep empty strings
|
|
273
274
|
cleanObject({
|
|
274
275
|
name: "John",
|
|
275
276
|
age: null,
|
|
276
277
|
city: undefined,
|
|
278
|
+
note: "",
|
|
277
279
|
data: { valid: true, invalid: null },
|
|
278
280
|
});
|
|
279
|
-
// Result: {name: 'John', data: {valid: true}}
|
|
281
|
+
// Result: {name: 'John', note: '', data: {valid: true}}
|
|
282
|
+
|
|
283
|
+
// With removeEmptyString enabled
|
|
284
|
+
cleanObject(
|
|
285
|
+
{
|
|
286
|
+
name: "John",
|
|
287
|
+
age: null,
|
|
288
|
+
city: undefined,
|
|
289
|
+
note: "",
|
|
290
|
+
tags: ["", "ok"],
|
|
291
|
+
},
|
|
292
|
+
true
|
|
293
|
+
);
|
|
294
|
+
// Result: {name: 'John', tags: ['ok']}
|
|
280
295
|
```
|
|
281
296
|
|
|
282
297
|
### 🔤 String Utilities
|
|
@@ -325,6 +340,42 @@ round(1.2345, 2); // 1.23
|
|
|
325
340
|
round(1.235, 2); // 1.24
|
|
326
341
|
```
|
|
327
342
|
|
|
343
|
+
**`safeAdd(a: number, b: number, decimals?: number): number`** — Adds two numbers with rounding and guards against invalid operands and precision errors.
|
|
344
|
+
|
|
345
|
+
```javascript
|
|
346
|
+
safeAdd(0.1, 0.2, 2); // 0.3
|
|
347
|
+
safeAdd(Number.NaN, 5); // 0 (invalid operand)
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
**`safeMultiply(a: number, b: number, decimals?: number): number`** — Multiplies two numbers safely with rounding and operand validation.
|
|
351
|
+
|
|
352
|
+
```javascript
|
|
353
|
+
safeMultiply(0.1, 0.2, 4); // 0.02
|
|
354
|
+
safeMultiply(Infinity, 2); // 0 (invalid operand)
|
|
355
|
+
```
|
|
356
|
+
|
|
357
|
+
**`safeSubtract(a: number, b: number, decimals?: number): number`** — Subtracts numbers safely, clamping decimal precision when needed.
|
|
358
|
+
|
|
359
|
+
```javascript
|
|
360
|
+
safeSubtract(10, 3.3333, 2); // 6.67
|
|
361
|
+
safeSubtract(5, Number.NaN); // 0 (invalid operand)
|
|
362
|
+
```
|
|
363
|
+
|
|
364
|
+
**`safeDivide(a: number, b: number, decimals?: number): number`** — Divides numbers with division-by-zero protection and precision normalization.
|
|
365
|
+
|
|
366
|
+
```javascript
|
|
367
|
+
safeDivide(1, 3, 3); // 0.333
|
|
368
|
+
safeDivide(10, 0); // 0 (division by zero)
|
|
369
|
+
```
|
|
370
|
+
|
|
371
|
+
**`numbersEqual(a: number, b: number, decimals?: number): boolean`** — Safely compares two numbers using fixed decimal precision and invalid operand guards.
|
|
372
|
+
|
|
373
|
+
```javascript
|
|
374
|
+
numbersEqual(0.1 + 0.2, 0.3); // true
|
|
375
|
+
numbersEqual(1.2345, 1.2344, 4); // false
|
|
376
|
+
numbersEqual(NaN, 1); // false
|
|
377
|
+
```
|
|
378
|
+
|
|
328
379
|
**`safeParseInt(value: unknown, defaultValue?: number): number`** — Safely converts a value to an integer with fallback.
|
|
329
380
|
|
|
330
381
|
```javascript
|
|
@@ -820,5 +871,5 @@ MIT © [SalesPark](https://salespark.io)
|
|
|
820
871
|
|
|
821
872
|
---
|
|
822
873
|
|
|
823
|
-
_Document version:
|
|
824
|
-
_Last update:
|
|
874
|
+
_Document version: 10_
|
|
875
|
+
_Last update: 11-12-2025_
|
package/dist/index.cjs
CHANGED
|
@@ -187,18 +187,18 @@ function objectToString(obj) {
|
|
|
187
187
|
}
|
|
188
188
|
}
|
|
189
189
|
}
|
|
190
|
-
var isRemovable = (v) => v === null || v === void 0 || v === "null" || v === "undefined";
|
|
191
|
-
function cleanObject(obj) {
|
|
190
|
+
var isRemovable = (v, removeEmptyString) => v === null || v === void 0 || v === "null" || v === "undefined" || removeEmptyString && v === "";
|
|
191
|
+
function cleanObject(obj, removeEmptyString = false) {
|
|
192
192
|
if (Array.isArray(obj)) {
|
|
193
|
-
const cleanedArray = obj.map((item) => cleanObject(item)).filter((item) => !isRemovable(item));
|
|
193
|
+
const cleanedArray = obj.map((item) => cleanObject(item, removeEmptyString)).filter((item) => !isRemovable(item, removeEmptyString));
|
|
194
194
|
return cleanedArray;
|
|
195
195
|
}
|
|
196
196
|
if (obj !== null && typeof obj === "object") {
|
|
197
197
|
const cleaned = {};
|
|
198
198
|
for (const [key, value] of Object.entries(obj)) {
|
|
199
|
-
if (isRemovable(value)) continue;
|
|
200
|
-
const nested = cleanObject(value);
|
|
201
|
-
if (isRemovable(nested)) continue;
|
|
199
|
+
if (isRemovable(value, removeEmptyString)) continue;
|
|
200
|
+
const nested = cleanObject(value, removeEmptyString);
|
|
201
|
+
if (isRemovable(nested, removeEmptyString)) continue;
|
|
202
202
|
const isObj = typeof nested === "object" && nested !== null;
|
|
203
203
|
const isEmptyObj = isObj && !Array.isArray(nested) && Object.keys(nested).length === 0;
|
|
204
204
|
const isEmptyArr = Array.isArray(nested) && nested.length === 0;
|
|
@@ -261,6 +261,61 @@ function safeParseInt(value, defaultValue = 0) {
|
|
|
261
261
|
return defaultValue;
|
|
262
262
|
}
|
|
263
263
|
}
|
|
264
|
+
function normalizeDecimals(decimals) {
|
|
265
|
+
if (!Number.isFinite(decimals)) return 0;
|
|
266
|
+
const int = Math.floor(decimals);
|
|
267
|
+
if (int < 0) return 0;
|
|
268
|
+
if (int > 100) return 100;
|
|
269
|
+
return int;
|
|
270
|
+
}
|
|
271
|
+
function sanitizeOperands(...values) {
|
|
272
|
+
return values.every((value) => Number.isFinite(value));
|
|
273
|
+
}
|
|
274
|
+
function safeAdd(a, b, decimals = 2) {
|
|
275
|
+
try {
|
|
276
|
+
if (!sanitizeOperands(a, b)) return 0;
|
|
277
|
+
const precision = normalizeDecimals(decimals);
|
|
278
|
+
return Number((a + b).toFixed(precision));
|
|
279
|
+
} catch {
|
|
280
|
+
return 0;
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
function safeMultiply(a, b, decimals = 2) {
|
|
284
|
+
try {
|
|
285
|
+
if (!sanitizeOperands(a, b)) return 0;
|
|
286
|
+
const precision = normalizeDecimals(decimals);
|
|
287
|
+
return Number((a * b).toFixed(precision));
|
|
288
|
+
} catch {
|
|
289
|
+
return 0;
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
function safeSubtract(a, b, decimals = 2) {
|
|
293
|
+
try {
|
|
294
|
+
if (!sanitizeOperands(a, b)) return 0;
|
|
295
|
+
const precision = normalizeDecimals(decimals);
|
|
296
|
+
return Number((a - b).toFixed(precision));
|
|
297
|
+
} catch {
|
|
298
|
+
return 0;
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
function safeDivide(a, b, decimals = 2) {
|
|
302
|
+
try {
|
|
303
|
+
if (!sanitizeOperands(a, b) || b === 0) return 0;
|
|
304
|
+
const precision = normalizeDecimals(decimals);
|
|
305
|
+
return Number((a / b).toFixed(precision));
|
|
306
|
+
} catch {
|
|
307
|
+
return 0;
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
function numbersEqual(a, b, decimals = 2) {
|
|
311
|
+
try {
|
|
312
|
+
if (!sanitizeOperands(a, b)) return false;
|
|
313
|
+
const precision = normalizeDecimals(decimals);
|
|
314
|
+
return a.toFixed(precision) === b.toFixed(precision);
|
|
315
|
+
} catch {
|
|
316
|
+
return false;
|
|
317
|
+
}
|
|
318
|
+
}
|
|
264
319
|
var toInteger = safeParseInt;
|
|
265
320
|
function safeParseFloat(value, decimals = 6) {
|
|
266
321
|
try {
|
|
@@ -292,7 +347,8 @@ function safeParseFloat(value, decimals = 6) {
|
|
|
292
347
|
}
|
|
293
348
|
const num = parseFloat(normalized);
|
|
294
349
|
if (!isFinite(num)) return 0;
|
|
295
|
-
|
|
350
|
+
const precision = normalizeDecimals(decimals);
|
|
351
|
+
return Number(num.toFixed(precision));
|
|
296
352
|
} catch {
|
|
297
353
|
return 0;
|
|
298
354
|
}
|
|
@@ -1692,6 +1748,7 @@ exports.isNullUndefinedOrZero = isNullUndefinedOrZero;
|
|
|
1692
1748
|
exports.isPTTaxId = isPTTaxId;
|
|
1693
1749
|
exports.isValidIBAN = isValidIBAN;
|
|
1694
1750
|
exports.isValidPTTaxId = isValidPTTaxId;
|
|
1751
|
+
exports.numbersEqual = numbersEqual;
|
|
1695
1752
|
exports.objectToString = objectToString;
|
|
1696
1753
|
exports.omit = omit;
|
|
1697
1754
|
exports.otp = otp;
|
|
@@ -1704,8 +1761,12 @@ exports.pushAll = pushAll;
|
|
|
1704
1761
|
exports.randomDigits = randomDigits;
|
|
1705
1762
|
exports.removeDiacritics = removeDiacritics;
|
|
1706
1763
|
exports.round = round;
|
|
1764
|
+
exports.safeAdd = safeAdd;
|
|
1765
|
+
exports.safeDivide = safeDivide;
|
|
1766
|
+
exports.safeMultiply = safeMultiply;
|
|
1707
1767
|
exports.safeParseFloat = safeParseFloat;
|
|
1708
1768
|
exports.safeParseInt = safeParseInt;
|
|
1769
|
+
exports.safeSubtract = safeSubtract;
|
|
1709
1770
|
exports.sanitize = sanitize;
|
|
1710
1771
|
exports.sanitizeMarkdown = sanitizeMarkdown;
|
|
1711
1772
|
exports.shuffle = shuffle;
|