@salespark/toolkit 2.1.1 → 2.1.3
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 +74 -38
- package/dist/index.cjs +32 -5
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +31 -17
- package/dist/index.d.ts +31 -17
- package/dist/index.js +31 -6
- package/dist/index.js.map +1 -1
- package/package.json +1 -12
package/README.md
CHANGED
|
@@ -311,48 +311,72 @@ sanitize("<script>alert('hack')</script>Hello World!", 20);
|
|
|
311
311
|
|
|
312
312
|
### 🔢 Number Utilities
|
|
313
313
|
|
|
314
|
-
**`clamp(n: number, min: number, max: number): number`** — Restricts a number within min and max bounds.
|
|
314
|
+
**`clamp(n: number, min: number, max: number): number`** — Restricts a number to be within the min and max bounds.
|
|
315
315
|
|
|
316
316
|
```javascript
|
|
317
|
-
clamp(
|
|
318
|
-
|
|
317
|
+
clamp(10, 0, 5); // 5
|
|
318
|
+
clamp(-5, 0, 10); // 0
|
|
319
319
|
```
|
|
320
320
|
|
|
321
|
-
**`round(n: number, decimals?: number): number`** — Rounds a number to fixed
|
|
321
|
+
**`round(n: number, decimals?: number): number`** — Rounds a number to a fixed number of decimals without floating point surprises.
|
|
322
322
|
|
|
323
323
|
```javascript
|
|
324
|
-
round(
|
|
325
|
-
//
|
|
324
|
+
round(1.2345, 2); // 1.23
|
|
325
|
+
round(1.235, 2); // 1.24
|
|
326
326
|
```
|
|
327
327
|
|
|
328
|
-
**`
|
|
328
|
+
**`safeParseInt(value: unknown, defaultValue?: number): number`** — Safely converts a value to an integer with fallback.
|
|
329
329
|
|
|
330
330
|
```javascript
|
|
331
|
-
|
|
332
|
-
//
|
|
331
|
+
safeParseInt("42"); // 42
|
|
332
|
+
safeParseInt("abc", 10); // 10
|
|
333
|
+
safeParseInt(3.9); // 3
|
|
333
334
|
```
|
|
334
335
|
|
|
335
|
-
**`
|
|
336
|
+
**`safeParseFloat(value: unknown, decimals?: number): number`** — Safely parses a value into a number with decimal precision and comma/dot normalization.
|
|
336
337
|
|
|
337
338
|
```javascript
|
|
338
|
-
|
|
339
|
-
//
|
|
339
|
+
safeParseFloat("123.45"); // 123.45
|
|
340
|
+
safeParseFloat("123,45"); // 123.45
|
|
341
|
+
safeParseFloat("1,234.56"); // 1234.56
|
|
342
|
+
safeParseFloat("abc"); // 0
|
|
340
343
|
```
|
|
341
344
|
|
|
342
|
-
**`
|
|
345
|
+
**`randomDigits(length?: number, options?: { charset?: string; noLeadingZero?: boolean }): string`** — Generates a random string of digits with secure randomness when available.
|
|
343
346
|
|
|
344
347
|
```javascript
|
|
345
|
-
|
|
346
|
-
// Result:
|
|
348
|
+
randomDigits(6);
|
|
349
|
+
// Result: "482751" (random)
|
|
347
350
|
```
|
|
348
351
|
|
|
349
352
|
**`randomDigits(length?: number, options?: { charset?: string; noLeadingZero?: boolean }): string`** — Generates a random string of digits with secure randomness when available.
|
|
350
353
|
|
|
351
354
|
```javascript
|
|
352
|
-
randomDigits(6);
|
|
353
|
-
|
|
355
|
+
randomDigits(6); // "847293"
|
|
356
|
+
randomDigits(4, { noLeadingZero: true }); // "3847" (no leading zero)
|
|
357
|
+
randomDigits(6, { charset: "ABCDEF0123456789" }); // "3F2A9D" (hex)
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
**`formatDecimalNumber(value: number | string | null | undefined, decimals?: number): string`** — Formats a number with specified decimal places, intelligently handling European (`1.234,56`) and US (`1,234.56`) number formats.
|
|
361
|
+
|
|
362
|
+
**`formatDecimalNumber(value: number | string | null | undefined, decimals?: number): string`** — Formats a number with specified decimal places, intelligently handling European (`1.234,56`) and US (`1,234.56`) number formats.
|
|
363
|
+
|
|
364
|
+
```javascript
|
|
365
|
+
formatDecimalNumber(1234.5678); // "1234.57"
|
|
366
|
+
formatDecimalNumber("1.234,56", 2); // "1234.56" (European format)
|
|
367
|
+
formatDecimalNumber("1,234.56", 2); // "1234.56" (US format)
|
|
368
|
+
formatDecimalNumber("1234,56", 3); // "1234.560"
|
|
369
|
+
formatDecimalNumber(null, 2); // "0.00"
|
|
370
|
+
formatDecimalNumber("invalid", 2); // "0.00"
|
|
354
371
|
```
|
|
355
372
|
|
|
373
|
+
#### 🗑️ Deprecated (Number Utilities)
|
|
374
|
+
|
|
375
|
+
- **`toInteger`** → Use `safeParseInt` instead
|
|
376
|
+
- **`toNumber`** → Use `safeParseFloat` instead
|
|
377
|
+
- **`parseToNumber`** → Use `safeParseFloat` instead
|
|
378
|
+
- **`otp`** → Use `randomDigits` instead
|
|
379
|
+
|
|
356
380
|
### ✅ Boolean Utilities
|
|
357
381
|
|
|
358
382
|
**`toBool(value: unknown, def?: boolean): boolean`** — Converts a value to boolean, supporting common string/number representations.
|
|
@@ -425,14 +449,20 @@ isNilText("undefined");
|
|
|
425
449
|
// Result: true
|
|
426
450
|
```
|
|
427
451
|
|
|
428
|
-
**`isNilOrEmpty(value: unknown): boolean`** — Checks if value is null/undefined or an empty string.
|
|
452
|
+
**`isNilOrEmpty(value: unknown): boolean`** — Checks if value is null/undefined or an empty string (trimmed).
|
|
429
453
|
|
|
430
454
|
```javascript
|
|
431
455
|
isNilOrEmpty("");
|
|
432
456
|
// Result: true
|
|
433
457
|
|
|
458
|
+
isNilOrEmpty(" ");
|
|
459
|
+
// Result: true
|
|
460
|
+
|
|
434
461
|
isNilOrEmpty(null);
|
|
435
462
|
// Result: true
|
|
463
|
+
|
|
464
|
+
isNilOrEmpty(undefined);
|
|
465
|
+
// Result: true
|
|
436
466
|
```
|
|
437
467
|
|
|
438
468
|
**`hasNilOrEmpty(array: unknown): boolean`** — Checks if any element in array is nil or empty.
|
|
@@ -596,15 +626,17 @@ checkMarkdownSecurity("# Hello World\n\nThis is **bold** text.");
|
|
|
596
626
|
|
|
597
627
|
// Dangerous content with script
|
|
598
628
|
checkMarkdownSecurity('<script>alert("xss")</script>');
|
|
599
|
-
// Result: {
|
|
600
|
-
// isValid: false,
|
|
601
|
-
// text: "",
|
|
602
|
-
// risks: [{ type: "scriptTags", severity: "critical", description: "..." }],
|
|
603
|
-
// sanitized: true
|
|
629
|
+
// Result: {
|
|
630
|
+
// isValid: false,
|
|
631
|
+
// text: "",
|
|
632
|
+
// risks: [{ type: "scriptTags", severity: "critical", description: "..." }],
|
|
633
|
+
// sanitized: true
|
|
604
634
|
// }
|
|
605
635
|
|
|
606
636
|
// Content with multiple threats
|
|
607
|
-
checkMarkdownSecurity(
|
|
637
|
+
checkMarkdownSecurity(
|
|
638
|
+
'<iframe src="evil.com"></iframe><div onclick="bad()">test</div>'
|
|
639
|
+
);
|
|
608
640
|
// Result: Multiple risks detected, sorted by severity
|
|
609
641
|
```
|
|
610
642
|
|
|
@@ -613,13 +645,13 @@ checkMarkdownSecurity('<iframe src="evil.com"></iframe><div onclick="bad()">test
|
|
|
613
645
|
```typescript
|
|
614
646
|
import { sanitizeMarkdown } from "@salespark/toolkit";
|
|
615
647
|
|
|
616
|
-
sanitizeMarkdown(
|
|
648
|
+
sanitizeMarkdown("<p>Hello <strong>World</strong></p>");
|
|
617
649
|
// Result: "Hello World"
|
|
618
650
|
|
|
619
651
|
sanitizeMarkdown('javascript:alert("xss")');
|
|
620
652
|
// Result: "alert(\"xss\")"
|
|
621
653
|
|
|
622
|
-
sanitizeMarkdown(
|
|
654
|
+
sanitizeMarkdown("<script>alert(1)</script>Safe text");
|
|
623
655
|
// Result: "Safe text"
|
|
624
656
|
```
|
|
625
657
|
|
|
@@ -629,7 +661,11 @@ sanitizeMarkdown('<script>alert(1)</script>Safe text');
|
|
|
629
661
|
import { assessSecurityRisks } from "@salespark/toolkit";
|
|
630
662
|
|
|
631
663
|
const risks = [
|
|
632
|
-
{
|
|
664
|
+
{
|
|
665
|
+
type: "scriptTags",
|
|
666
|
+
severity: "critical",
|
|
667
|
+
description: "Script injection detected",
|
|
668
|
+
},
|
|
633
669
|
];
|
|
634
670
|
|
|
635
671
|
assessSecurityRisks(risks);
|
|
@@ -655,10 +691,10 @@ assessSecurityRisks([]);
|
|
|
655
691
|
```typescript
|
|
656
692
|
import { isPTTaxId } from "@salespark/toolkit";
|
|
657
693
|
|
|
658
|
-
isPTTaxId("123456789");
|
|
659
|
-
isPTTaxId("123 456 789");
|
|
660
|
-
isPTTaxId("513183504");
|
|
661
|
-
isPTTaxId("423456789");
|
|
694
|
+
isPTTaxId("123456789"); // false (invalid check digit)
|
|
695
|
+
isPTTaxId("123 456 789"); // false (spaces stripped automatically)
|
|
696
|
+
isPTTaxId("513183504"); // true (valid NIF)
|
|
697
|
+
isPTTaxId("423456789"); // false (invalid prefix - 4 not allowed)
|
|
662
698
|
|
|
663
699
|
// Deprecated alias (use isPTTaxId instead)
|
|
664
700
|
// isValidPTTaxId("513183504"); // true
|
|
@@ -669,12 +705,12 @@ isPTTaxId("423456789"); // false (invalid prefix - 4 not allowed)
|
|
|
669
705
|
```typescript
|
|
670
706
|
import { isValidIBAN } from "@salespark/toolkit";
|
|
671
707
|
|
|
672
|
-
isValidIBAN("NL91ABNA0417164300");
|
|
708
|
+
isValidIBAN("NL91ABNA0417164300"); // true (valid Dutch IBAN)
|
|
673
709
|
isValidIBAN("NL91 ABNA 0417 1643 00"); // true (spaces stripped automatically)
|
|
674
710
|
isValidIBAN("GB29NWBK60161331926819"); // true (valid UK IBAN)
|
|
675
|
-
isValidIBAN("DE89370400440532013000");
|
|
676
|
-
isValidIBAN("NL91ABNA0417164301");
|
|
677
|
-
isValidIBAN("XX1234567890");
|
|
711
|
+
isValidIBAN("DE89370400440532013000"); // true (valid German IBAN)
|
|
712
|
+
isValidIBAN("NL91ABNA0417164301"); // false (invalid checksum)
|
|
713
|
+
isValidIBAN("XX1234567890"); // false (invalid country code)
|
|
678
714
|
```
|
|
679
715
|
|
|
680
716
|
### 🌐 Environment Detection
|
|
@@ -710,7 +746,7 @@ The following functions are deprecated but maintained for backward compatibility
|
|
|
710
746
|
### ⚡ Function Utilities (Deprecated)
|
|
711
747
|
|
|
712
748
|
- `isNullOrUndefined` — Use `isNil` instead.
|
|
713
|
-
- `isNullOrUndefinedTextInc` — Use `isNilText` instead.
|
|
749
|
+
- `isNullOrUndefinedTextInc` — Use `isNilText` instead.
|
|
714
750
|
- `isNullUndefinedOrEmpty` — Use `isNilOrEmpty` instead.
|
|
715
751
|
- `isNullOrUndefinedInArray` — Use `hasNilOrEmpty` instead.
|
|
716
752
|
- `isNullOrUndefinedEmptyOrZero` — Use `isNilEmptyOrZeroLen` instead.
|
|
@@ -779,5 +815,5 @@ MIT © [SalesPark](https://salespark.io)
|
|
|
779
815
|
|
|
780
816
|
---
|
|
781
817
|
|
|
782
|
-
_Document version:
|
|
783
|
-
_Last update:
|
|
818
|
+
_Document version: 6_
|
|
819
|
+
_Last update: 29-10-2025_
|
package/dist/index.cjs
CHANGED
|
@@ -253,7 +253,7 @@ function round(n, decimals = 0) {
|
|
|
253
253
|
const f = Math.pow(10, decimals);
|
|
254
254
|
return Math.round((n + Number.EPSILON) * f) / f;
|
|
255
255
|
}
|
|
256
|
-
function
|
|
256
|
+
function safeParseInt(value, defaultValue = 0) {
|
|
257
257
|
try {
|
|
258
258
|
const safeValue = parseInt(String(value), 10);
|
|
259
259
|
return isNaN(safeValue) ? defaultValue : safeValue;
|
|
@@ -261,8 +261,8 @@ function toInteger(value, defaultValue = 0) {
|
|
|
261
261
|
return defaultValue;
|
|
262
262
|
}
|
|
263
263
|
}
|
|
264
|
-
var
|
|
265
|
-
function
|
|
264
|
+
var toInteger = safeParseInt;
|
|
265
|
+
function safeParseFloat(value, decimals = 6) {
|
|
266
266
|
try {
|
|
267
267
|
if (value === void 0 || value === null || value === "") return 0;
|
|
268
268
|
let str = String(value);
|
|
@@ -278,7 +278,8 @@ function toNumber(value, decimals = 6) {
|
|
|
278
278
|
return 0;
|
|
279
279
|
}
|
|
280
280
|
}
|
|
281
|
-
var
|
|
281
|
+
var toNumber = safeParseFloat;
|
|
282
|
+
var parseToNumber = safeParseFloat;
|
|
282
283
|
function secureRandomIndex(max) {
|
|
283
284
|
if (max <= 0) return 0;
|
|
284
285
|
const g = globalThis;
|
|
@@ -310,6 +311,30 @@ function randomDigits(length = 6, options) {
|
|
|
310
311
|
return out;
|
|
311
312
|
}
|
|
312
313
|
var otp = randomDigits;
|
|
314
|
+
var formatDecimalNumber = (value, decimals = 2) => {
|
|
315
|
+
try {
|
|
316
|
+
let processedValue = value ?? 0;
|
|
317
|
+
if (typeof processedValue === "string") {
|
|
318
|
+
const trimmed = processedValue.trim();
|
|
319
|
+
if (trimmed.includes(",") && trimmed.includes(".")) {
|
|
320
|
+
const lastComma = trimmed.lastIndexOf(",");
|
|
321
|
+
const lastDot = trimmed.lastIndexOf(".");
|
|
322
|
+
processedValue = lastComma > lastDot ? trimmed.replace(/\./g, "").replace(",", ".") : trimmed.replace(/,/g, "");
|
|
323
|
+
} else if (trimmed.includes(",")) {
|
|
324
|
+
processedValue = trimmed.replace(/,/g, ".");
|
|
325
|
+
} else {
|
|
326
|
+
processedValue = trimmed;
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
const numValue = parseFloat(String(processedValue));
|
|
330
|
+
if (isNaN(numValue)) {
|
|
331
|
+
return 0 .toFixed(Math.max(0, Math.floor(decimals)));
|
|
332
|
+
}
|
|
333
|
+
return numValue.toFixed(Math.max(0, Math.floor(decimals)));
|
|
334
|
+
} catch (error) {
|
|
335
|
+
return 0 .toFixed(Math.max(0, Math.floor(decimals)));
|
|
336
|
+
}
|
|
337
|
+
};
|
|
313
338
|
|
|
314
339
|
// src/utils/func.ts
|
|
315
340
|
function debounce(fn, wait = 250) {
|
|
@@ -348,7 +373,7 @@ var isNilText = (value) => {
|
|
|
348
373
|
};
|
|
349
374
|
var isNilOrEmpty = (value) => {
|
|
350
375
|
try {
|
|
351
|
-
return isNil(value) || value === "";
|
|
376
|
+
return isNil(value) || typeof value === "string" && value?.trim() === "";
|
|
352
377
|
} catch {
|
|
353
378
|
return true;
|
|
354
379
|
}
|
|
@@ -1615,6 +1640,7 @@ exports.flattenDepthBase = flattenDepthBase;
|
|
|
1615
1640
|
exports.flattenOnce = flattenOnce;
|
|
1616
1641
|
exports.formatBytes = formatBytes;
|
|
1617
1642
|
exports.formatCurrency = formatCurrency;
|
|
1643
|
+
exports.formatDecimalNumber = formatDecimalNumber;
|
|
1618
1644
|
exports.getStringSimilarity = getStringSimilarity;
|
|
1619
1645
|
exports.groupBy = groupBy;
|
|
1620
1646
|
exports.hasNilOrEmpty = hasNilOrEmpty;
|
|
@@ -1653,6 +1679,7 @@ exports.pushAll = pushAll;
|
|
|
1653
1679
|
exports.randomDigits = randomDigits;
|
|
1654
1680
|
exports.removeDiacritics = removeDiacritics;
|
|
1655
1681
|
exports.round = round;
|
|
1682
|
+
exports.safeParseFloat = safeParseFloat;
|
|
1656
1683
|
exports.safeParseInt = safeParseInt;
|
|
1657
1684
|
exports.sanitize = sanitize;
|
|
1658
1685
|
exports.sanitizeMarkdown = sanitizeMarkdown;
|