@salespark/toolkit 2.1.8 → 2.1.10
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 +41 -4
- package/dist/index.cjs +56 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +52 -1
- package/dist/index.d.ts +52 -1
- package/dist/index.js +53 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -26,9 +26,9 @@ npm i @salespark/toolkit
|
|
|
26
26
|
|
|
27
27
|
- **Array utilities**: chunk, uniqBy, deep equality, flatten, groupBy, etc.
|
|
28
28
|
- **Object utilities**: pick, omit, clean objects, deep merge, etc.
|
|
29
|
-
- **String utilities**: slugify, template fill, deburr, sanitize,
|
|
29
|
+
- **String utilities**: slugify, template fill, deburr, sanitize, capitalize words/sentences.
|
|
30
30
|
- **Number utilities**: clamp, round, safe arithmetic/comparisons, safe parse (locale-aware), random digits, etc.
|
|
31
|
-
- **Function utilities**: debounce, throttle, formatCurrency, parseName, currency conversions, etc.
|
|
31
|
+
- **Function utilities**: debounce, throttle, safeJSONParse, 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
|
|
34
34
|
- **Security utilities**: Markdown XSS protection, content sanitization, risk assessment
|
|
@@ -317,6 +317,30 @@ deburr("café résumé naïve");
|
|
|
317
317
|
// Result: "cafe resume naive"
|
|
318
318
|
```
|
|
319
319
|
|
|
320
|
+
**`capitalizeFirst(input: string, options?: { lowerRest?: boolean; locale?: string | string[] }): string`** — Capitalizes only the first character; optionally lowercases the rest.
|
|
321
|
+
|
|
322
|
+
```javascript
|
|
323
|
+
capitalizeFirst("hELLO world");
|
|
324
|
+
// Result: "Hello world"
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
**`capitalizeWords(input: string, options?: { lowerRest?: boolean; locale?: string | string[]; treatHyphenAsSeparator?: boolean }): string`** — Capitalizes each word; can treat hyphen as separator.
|
|
328
|
+
|
|
329
|
+
```javascript
|
|
330
|
+
capitalizeWords("e-mail marketing");
|
|
331
|
+
// Result: "E-mail Marketing"
|
|
332
|
+
|
|
333
|
+
capitalizeWords("e-mail marketing", { treatHyphenAsSeparator: true });
|
|
334
|
+
// Result: "E-Mail Marketing"
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
**`sentenceCase(input: string, options?: { lowerRest?: boolean; locale?: string | string[] }): string`** — Capitalizes the start of each sentence (. ! ?); optionally lowercases the rest.
|
|
338
|
+
|
|
339
|
+
```javascript
|
|
340
|
+
sentenceCase("hello world. this is fine!");
|
|
341
|
+
// Result: "Hello world. This is fine!"
|
|
342
|
+
```
|
|
343
|
+
|
|
320
344
|
**`sanitize(input: unknown, maxLength?: number): string`** — Sanitizes input by removing dangerous content.
|
|
321
345
|
|
|
322
346
|
```javascript
|
|
@@ -583,6 +607,19 @@ addThousandsSpace(1234567);
|
|
|
583
607
|
// Result: "1 234 567"
|
|
584
608
|
```
|
|
585
609
|
|
|
610
|
+
**`safeJSONParse<T>(input: unknown, defaultValue: T): T`** — Safely parses a JSON string or returns the object if already parsed. Falls back to default value on failure.
|
|
611
|
+
|
|
612
|
+
```javascript
|
|
613
|
+
safeJSONParse('{"key": "value"}', {});
|
|
614
|
+
// Result: { key: "value" }
|
|
615
|
+
|
|
616
|
+
safeJSONParse({ already: "object" }, {});
|
|
617
|
+
// Result: { already: "object" }
|
|
618
|
+
|
|
619
|
+
safeJSONParse("{invalid}", { fallback: true });
|
|
620
|
+
// Result: { fallback: true }
|
|
621
|
+
```
|
|
622
|
+
|
|
586
623
|
**`formatCurrency(value: number | string | null | undefined, withoutCurrencySymbol?: boolean, currency?: string, locale?: string): string`** — Formats currency values with configurable currency and locale. Uses modern Intl.NumberFormat with automatic thousands separators, proper decimal handling, and graceful fallback for errors.
|
|
587
624
|
|
|
588
625
|
```javascript
|
|
@@ -871,5 +908,5 @@ MIT © [SalesPark](https://salespark.io)
|
|
|
871
908
|
|
|
872
909
|
---
|
|
873
910
|
|
|
874
|
-
_Document version:
|
|
875
|
-
_Last update:
|
|
911
|
+
_Document version: 12_
|
|
912
|
+
_Last update: 21-12-2025_
|
package/dist/index.cjs
CHANGED
|
@@ -211,6 +211,12 @@ function cleanObject(obj, removeEmptyString = false) {
|
|
|
211
211
|
}
|
|
212
212
|
|
|
213
213
|
// src/utils/string.ts
|
|
214
|
+
function upper(value, locale) {
|
|
215
|
+
return locale ? value.toLocaleUpperCase(locale) : value.toUpperCase();
|
|
216
|
+
}
|
|
217
|
+
function lower(value, locale) {
|
|
218
|
+
return locale ? value.toLocaleLowerCase(locale) : value.toLowerCase();
|
|
219
|
+
}
|
|
214
220
|
function slugify(input) {
|
|
215
221
|
return input.normalize("NFKD").replace(/[\u0300-\u036f]/g, "").toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
|
|
216
222
|
}
|
|
@@ -224,6 +230,38 @@ function deburr(str) {
|
|
|
224
230
|
return str;
|
|
225
231
|
}
|
|
226
232
|
}
|
|
233
|
+
function capitalizeFirst(input, options) {
|
|
234
|
+
if (typeof input !== "string" || input.length === 0) return "";
|
|
235
|
+
const { lowerRest = true, locale } = options ?? {};
|
|
236
|
+
const first = upper(input[0], locale);
|
|
237
|
+
const rest = lowerRest ? lower(input.slice(1), locale) : input.slice(1);
|
|
238
|
+
return first + rest;
|
|
239
|
+
}
|
|
240
|
+
function capitalizeWords(input, options) {
|
|
241
|
+
if (typeof input !== "string" || input.length === 0) return "";
|
|
242
|
+
const {
|
|
243
|
+
lowerRest = true,
|
|
244
|
+
locale,
|
|
245
|
+
treatHyphenAsSeparator = false
|
|
246
|
+
} = options ?? {};
|
|
247
|
+
const wordPattern = treatHyphenAsSeparator ? /[\p{L}\p{N}]+(?:['’][\p{L}\p{N}]+)*/gu : /[\p{L}\p{N}]+(?:['’\-][\p{L}\p{N}]+)*/gu;
|
|
248
|
+
return input.replace(wordPattern, (word) => {
|
|
249
|
+
const first = upper(word[0], locale);
|
|
250
|
+
const rest = lowerRest ? lower(word.slice(1), locale) : word.slice(1);
|
|
251
|
+
return first + rest;
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
function sentenceCase(input, options) {
|
|
255
|
+
if (typeof input !== "string" || input.length === 0) return "";
|
|
256
|
+
const { lowerRest = true, locale } = options ?? {};
|
|
257
|
+
const base = lowerRest ? lower(input, locale) : input;
|
|
258
|
+
const sentencePattern = /(^\s*[\p{L}])|([.!?]\s*[\p{L}])/gu;
|
|
259
|
+
return base.replace(sentencePattern, (match) => {
|
|
260
|
+
const lastChar = match[match.length - 1];
|
|
261
|
+
const upperChar = upper(lastChar, locale);
|
|
262
|
+
return match.slice(0, -1) + upperChar;
|
|
263
|
+
});
|
|
264
|
+
}
|
|
227
265
|
var removeDiacritics = deburr;
|
|
228
266
|
function sanitize(input, maxLength) {
|
|
229
267
|
if (typeof input !== "string") return "";
|
|
@@ -412,6 +450,20 @@ var formatDecimalNumber = (value, decimals = 2) => {
|
|
|
412
450
|
};
|
|
413
451
|
|
|
414
452
|
// src/utils/func.ts
|
|
453
|
+
function safeJSONParse(input, defaultValue) {
|
|
454
|
+
if (typeof input === "object" && input !== null) {
|
|
455
|
+
return input;
|
|
456
|
+
}
|
|
457
|
+
if (typeof input === "string") {
|
|
458
|
+
try {
|
|
459
|
+
const parsed = JSON.parse(input);
|
|
460
|
+
return parsed;
|
|
461
|
+
} catch {
|
|
462
|
+
return defaultValue;
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
return defaultValue;
|
|
466
|
+
}
|
|
415
467
|
function debounce(fn, wait = 250) {
|
|
416
468
|
let t;
|
|
417
469
|
return function(...args) {
|
|
@@ -1702,6 +1754,8 @@ exports.areArraysDeepEqualUnordered = areArraysDeepEqualUnordered;
|
|
|
1702
1754
|
exports.areArraysEqual = areArraysEqual;
|
|
1703
1755
|
exports.assessSecurityRisks = assessSecurityRisks;
|
|
1704
1756
|
exports.basicSanitize = basicSanitize;
|
|
1757
|
+
exports.capitalizeFirst = capitalizeFirst;
|
|
1758
|
+
exports.capitalizeWords = capitalizeWords;
|
|
1705
1759
|
exports.checkMarkdownSecurity = checkMarkdownSecurity;
|
|
1706
1760
|
exports.chunk = chunk;
|
|
1707
1761
|
exports.clamp = clamp;
|
|
@@ -1763,12 +1817,14 @@ exports.removeDiacritics = removeDiacritics;
|
|
|
1763
1817
|
exports.round = round;
|
|
1764
1818
|
exports.safeAdd = safeAdd;
|
|
1765
1819
|
exports.safeDivide = safeDivide;
|
|
1820
|
+
exports.safeJSONParse = safeJSONParse;
|
|
1766
1821
|
exports.safeMultiply = safeMultiply;
|
|
1767
1822
|
exports.safeParseFloat = safeParseFloat;
|
|
1768
1823
|
exports.safeParseInt = safeParseInt;
|
|
1769
1824
|
exports.safeSubtract = safeSubtract;
|
|
1770
1825
|
exports.sanitize = sanitize;
|
|
1771
1826
|
exports.sanitizeMarkdown = sanitizeMarkdown;
|
|
1827
|
+
exports.sentenceCase = sentenceCase;
|
|
1772
1828
|
exports.shuffle = shuffle;
|
|
1773
1829
|
exports.slugify = slugify;
|
|
1774
1830
|
exports.sortBy = sortBy;
|