@salespark/toolkit 2.1.7 → 2.1.9
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 +44 -5
- package/dist/index.cjs +47 -6
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +43 -2
- package/dist/index.d.ts +43 -2
- package/dist/index.js +45 -7
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -26,7 +26,7 @@ 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
31
|
- **Function utilities**: debounce, throttle, formatCurrency, parseName, currency conversions, etc.
|
|
32
32
|
- **Boolean utilities**: safe boolean conversion with common representations
|
|
@@ -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
|
|
@@ -302,6 +317,30 @@ deburr("café résumé naïve");
|
|
|
302
317
|
// Result: "cafe resume naive"
|
|
303
318
|
```
|
|
304
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
|
+
|
|
305
344
|
**`sanitize(input: unknown, maxLength?: number): string`** — Sanitizes input by removing dangerous content.
|
|
306
345
|
|
|
307
346
|
```javascript
|
|
@@ -856,5 +895,5 @@ MIT © [SalesPark](https://salespark.io)
|
|
|
856
895
|
|
|
857
896
|
---
|
|
858
897
|
|
|
859
|
-
_Document version:
|
|
860
|
-
_Last update:
|
|
898
|
+
_Document version: 11_
|
|
899
|
+
_Last update: 19-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;
|
|
@@ -211,6 +211,12 @@ function cleanObject(obj) {
|
|
|
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 "";
|
|
@@ -1702,6 +1740,8 @@ exports.areArraysDeepEqualUnordered = areArraysDeepEqualUnordered;
|
|
|
1702
1740
|
exports.areArraysEqual = areArraysEqual;
|
|
1703
1741
|
exports.assessSecurityRisks = assessSecurityRisks;
|
|
1704
1742
|
exports.basicSanitize = basicSanitize;
|
|
1743
|
+
exports.capitalizeFirst = capitalizeFirst;
|
|
1744
|
+
exports.capitalizeWords = capitalizeWords;
|
|
1705
1745
|
exports.checkMarkdownSecurity = checkMarkdownSecurity;
|
|
1706
1746
|
exports.chunk = chunk;
|
|
1707
1747
|
exports.clamp = clamp;
|
|
@@ -1769,6 +1809,7 @@ exports.safeParseInt = safeParseInt;
|
|
|
1769
1809
|
exports.safeSubtract = safeSubtract;
|
|
1770
1810
|
exports.sanitize = sanitize;
|
|
1771
1811
|
exports.sanitizeMarkdown = sanitizeMarkdown;
|
|
1812
|
+
exports.sentenceCase = sentenceCase;
|
|
1772
1813
|
exports.shuffle = shuffle;
|
|
1773
1814
|
exports.slugify = slugify;
|
|
1774
1815
|
exports.sortBy = sortBy;
|