@ix-xs/node-comfort 1.2.0 → 2.0.0

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.
Files changed (75) hide show
  1. package/CHANGELOG.md +190 -0
  2. package/README.md +136 -549
  3. package/index.js +80 -35
  4. package/package.json +160 -33
  5. package/src/Arr.js +887 -419
  6. package/src/Async.js +585 -0
  7. package/src/Cache.js +329 -0
  8. package/src/Checker.js +971 -539
  9. package/src/Cli.js +1034 -0
  10. package/src/Color.js +415 -0
  11. package/src/Crypto.js +707 -0
  12. package/src/Emitter.js +289 -0
  13. package/src/Env.js +555 -0
  14. package/src/FS.js +1483 -894
  15. package/src/Func.js +670 -353
  16. package/src/Http.js +538 -0
  17. package/src/Id.js +384 -201
  18. package/src/Logger.js +739 -378
  19. package/src/Num.js +844 -361
  20. package/src/Obj.js +855 -372
  21. package/src/SQLite.js +1308 -1005
  22. package/src/Schema.js +1586 -0
  23. package/src/Str.js +983 -436
  24. package/src/Sys.js +511 -0
  25. package/src/Time.js +1260 -422
  26. package/src/Utils.js +321 -325
  27. package/src/errors.js +292 -0
  28. package/types/index.d.ts +693 -526
  29. package/types/src/Arr.d.ts +455 -145
  30. package/types/src/Arr.d.ts.map +1 -1
  31. package/types/src/Async.d.ts +321 -0
  32. package/types/src/Async.d.ts.map +1 -0
  33. package/types/src/Cache.d.ts +195 -0
  34. package/types/src/Cache.d.ts.map +1 -0
  35. package/types/src/Checker.d.ts +501 -235
  36. package/types/src/Checker.d.ts.map +1 -1
  37. package/types/src/Cli.d.ts +582 -0
  38. package/types/src/Cli.d.ts.map +1 -0
  39. package/types/src/Color.d.ts +294 -0
  40. package/types/src/Color.d.ts.map +1 -0
  41. package/types/src/Crypto.d.ts +534 -0
  42. package/types/src/Crypto.d.ts.map +1 -0
  43. package/types/src/Emitter.d.ts +170 -0
  44. package/types/src/Emitter.d.ts.map +1 -0
  45. package/types/src/Env.d.ts +382 -0
  46. package/types/src/Env.d.ts.map +1 -0
  47. package/types/src/FS.d.ts +686 -238
  48. package/types/src/FS.d.ts.map +1 -1
  49. package/types/src/Func.d.ts +380 -135
  50. package/types/src/Func.d.ts.map +1 -1
  51. package/types/src/Http.d.ts +374 -0
  52. package/types/src/Http.d.ts.map +1 -0
  53. package/types/src/Id.d.ts +149 -68
  54. package/types/src/Id.d.ts.map +1 -1
  55. package/types/src/Logger.d.ts +363 -46
  56. package/types/src/Logger.d.ts.map +1 -1
  57. package/types/src/Num.d.ts +473 -137
  58. package/types/src/Num.d.ts.map +1 -1
  59. package/types/src/Obj.d.ts +390 -104
  60. package/types/src/Obj.d.ts.map +1 -1
  61. package/types/src/SQLite.d.ts +646 -309
  62. package/types/src/SQLite.d.ts.map +1 -1
  63. package/types/src/Schema.d.ts +940 -0
  64. package/types/src/Schema.d.ts.map +1 -0
  65. package/types/src/Str.d.ts +569 -166
  66. package/types/src/Str.d.ts.map +1 -1
  67. package/types/src/Sys.d.ts +269 -0
  68. package/types/src/Sys.d.ts.map +1 -0
  69. package/types/src/Time.d.ts +663 -204
  70. package/types/src/Time.d.ts.map +1 -1
  71. package/types/src/Utils.d.ts +154 -102
  72. package/types/src/Utils.d.ts.map +1 -1
  73. package/types/src/errors.d.ts +292 -0
  74. package/types/src/errors.d.ts.map +1 -0
  75. package/types/index.d.ts.map +0 -1
@@ -1,293 +1,696 @@
1
1
  /**
2
- * Capitalizes the first character of a string and lowercases the rest.
2
+ * Options for `slugify()`.
3
+ */
4
+ export type SlugifyOptions = {
5
+ /**
6
+ * Placed between words. Defaults to `"-"`.
7
+ */
8
+ separator?: string | undefined;
9
+ /**
10
+ * Lowercase the result. Defaults to `true`.
11
+ */
12
+ lower?: boolean | undefined;
13
+ /**
14
+ * Maximum length, cut on a word boundary when possible.
15
+ */
16
+ maxLength?: number | undefined;
17
+ };
18
+ /**
19
+ * Options for `truncate()`.
20
+ */
21
+ export type TruncateOptions = {
22
+ /**
23
+ * Added where the text is cut, and counted in the length. Defaults to `"…"`.
24
+ */
25
+ omission?: string | undefined;
26
+ /**
27
+ * Cut at the previous space rather than inside a word.
28
+ */
29
+ words?: boolean | undefined;
30
+ };
31
+ /**
32
+ * Options for `template()`.
33
+ */
34
+ export type TemplateOptions = {
35
+ /**
36
+ * Opening delimiter. Defaults to `"{"`.
37
+ */
38
+ open?: string | undefined;
39
+ /**
40
+ * Closing delimiter. Defaults to `"}"`.
41
+ */
42
+ close?: string | undefined;
43
+ /**
44
+ * Used for missing values. Without it, their placeholders stay as they are.
45
+ */
46
+ fallback?: string | undefined;
47
+ };
48
+ /**
49
+ * Options for `wrap()`.
50
+ */
51
+ export type WrapOptions = {
52
+ /**
53
+ * Maximum visible characters per line. Defaults to `80`.
54
+ */
55
+ width?: number | undefined;
56
+ /**
57
+ * Added at the start of every line.
58
+ */
59
+ indent?: string | undefined;
60
+ /**
61
+ * Break words longer than `width` instead of letting them overflow.
62
+ */
63
+ cut?: boolean | undefined;
64
+ /**
65
+ * Line separator. Defaults to `"\n"`.
66
+ */
67
+ newline?: string | undefined;
68
+ };
69
+ /**
70
+ * Options for `mask()`.
71
+ */
72
+ export type MaskOptions = {
73
+ /**
74
+ * Characters left visible at the start. Defaults to `0`.
75
+ */
76
+ start?: number | undefined;
77
+ /**
78
+ * Characters left visible at the end. Defaults to `4`.
79
+ */
80
+ end?: number | undefined;
81
+ /**
82
+ * Mask character. Defaults to `"*"`.
83
+ */
84
+ char?: string | undefined;
85
+ /**
86
+ * Leave spaces and dashes visible, nice for card numbers.
87
+ */
88
+ keepSpaces?: boolean | undefined;
89
+ };
90
+ /**
91
+ * The word forms for `plural()`. Only `other` is required; add the others
92
+ * when your language needs them.
93
+ */
94
+ export type PluralForms = {
95
+ /**
96
+ * The general plural, like `"files"`.
97
+ */
98
+ other: string;
99
+ /**
100
+ * Used for `0` in any language, like `"no files"`.
101
+ */
102
+ zero?: string | undefined;
103
+ /**
104
+ * The singular, like `"file"`. French also uses it for 0.
105
+ */
106
+ one?: string | undefined;
107
+ /**
108
+ * Dual form (Arabic, Hebrew, Slovenian...).
109
+ */
110
+ two?: string | undefined;
111
+ /**
112
+ * "Few" form (Polish, Czech, Russian...).
113
+ */
114
+ few?: string | undefined;
115
+ /**
116
+ * "Many" form (Polish, Russian, Arabic...).
117
+ */
118
+ many?: string | undefined;
119
+ };
120
+ /**
121
+ * Options for `plural()`.
122
+ */
123
+ export type PluralOptions = {
124
+ /**
125
+ * Language whose plural rules apply. Defaults to `"en"`.
126
+ */
127
+ locale?: string | undefined;
128
+ /**
129
+ * Put the formatted count before the word. Defaults to `true`.
130
+ */
131
+ includeCount?: boolean | undefined;
132
+ /**
133
+ * Use ordinal rules (1st, 2nd, 3rd).
134
+ */
135
+ ordinal?: boolean | undefined;
136
+ };
137
+ /**
138
+ * Options for `compare()`.
139
+ */
140
+ export type CompareOptions = {
141
+ /**
142
+ * Language used for alphabetical order. Defaults to the system's.
143
+ */
144
+ locale?: string | undefined;
145
+ /**
146
+ * Sort numbers naturally, `"file2"` before `"file10"`. Defaults to `true`.
147
+ */
148
+ numeric?: boolean | undefined;
149
+ /**
150
+ * Which differences count. `"base"` ignores accents and case. Defaults to `"variant"`.
151
+ */
152
+ sensitivity?: "base" | "accent" | "case" | "variant" | undefined;
153
+ };
154
+ /**
155
+ * Options for `closest()`.
156
+ */
157
+ export type ClosestOptions = {
158
+ /**
159
+ * Minimum similarity (0 to 1) to accept a match. Defaults to `0.4`.
160
+ */
161
+ threshold?: number | undefined;
162
+ /**
163
+ * Take case into account.
164
+ */
165
+ caseSensitive?: boolean | undefined;
166
+ };
167
+ /**
168
+ * Options for `random()`.
169
+ */
170
+ export type RandomStringOptions = {
171
+ /**
172
+ * Characters to pick from. Defaults to letters and digits.
173
+ */
174
+ charset?: string | undefined;
175
+ };
176
+ /**
177
+ * Uppercases the first character and lowercases the rest.
178
+ *
179
+ * @example
180
+ * str.capitalize("hELLO wORLD"); // "Hello world"
181
+ *
182
+ * @param {unknown} input
183
+ * @returns {string}
184
+ */
185
+ export function capitalize(input: unknown): string;
186
+ /**
187
+ * Uppercases the first letter of each word and leaves the rest alone.
188
+ *
189
+ * @example
190
+ * str.titleCase("the quick brown fox"); // "The Quick Brown Fox"
191
+ * str.titleCase("élodie o'neil"); // "Élodie O'neil"
192
+ *
193
+ * @param {unknown} input
194
+ * @returns {string}
195
+ */
196
+ export function titleCase(input: unknown): string;
197
+ /**
198
+ * Lowercases everything, then capitalizes the start of each sentence.
199
+ *
200
+ * @example
201
+ * str.sentenceCase("hELLO WORLD. how ARE you?"); // "Hello world. How are you?"
202
+ *
203
+ * @param {unknown} input
204
+ * @returns {string}
205
+ */
206
+ export function sentenceCase(input: unknown): string;
207
+ /**
208
+ * Converts to `camelCase`.
209
+ *
210
+ * @example
211
+ * str.camelCase("user_first-name"); // "userFirstName"
212
+ * str.camelCase("XMLHttpRequest"); // "xmlHttpRequest"
213
+ *
214
+ * @param {unknown} input
215
+ * @returns {string}
216
+ */
217
+ export function camelCase(input: unknown): string;
218
+ /**
219
+ * Converts to `PascalCase`.
220
+ *
221
+ * @example
222
+ * str.pascalCase("hello world"); // "HelloWorld"
223
+ *
224
+ * @param {unknown} input
225
+ * @returns {string}
226
+ */
227
+ export function pascalCase(input: unknown): string;
228
+ /**
229
+ * Converts to `snake_case`.
230
+ *
231
+ * @example
232
+ * str.snakeCase("helloWorld"); // "hello_world"
233
+ *
234
+ * @param {unknown} input
235
+ * @returns {string}
236
+ */
237
+ export function snakeCase(input: unknown): string;
238
+ /**
239
+ * Converts to `kebab-case`.
240
+ *
241
+ * @example
242
+ * str.kebabCase("helloWorld"); // "hello-world"
243
+ *
244
+ * @param {unknown} input
245
+ * @returns {string}
246
+ */
247
+ export function kebabCase(input: unknown): string;
248
+ /**
249
+ * Converts to `CONSTANT_CASE`.
3
250
  *
4
251
  * @example
5
- * nodeComfort.str.capitalize("hELLO"); // "Hello"
252
+ * str.constantCase("helloWorld"); // "HELLO_WORLD"
6
253
  *
7
- * @param {string} str - Input string.
8
- * @returns {string} The capitalized string.
254
+ * @param {unknown} input
255
+ * @returns {string}
9
256
  */
10
- export function capitalize(str: string): string;
257
+ export function constantCase(input: unknown): string;
11
258
  /**
12
- * Uppercases the first character of each word (Title Case), leaving the rest untouched.
259
+ * Converts to `dot.case`.
13
260
  *
14
261
  * @example
15
- * nodeComfort.str.titleCase("the quick brown fox"); // "The Quick Brown Fox"
262
+ * str.dotCase("userFirstName"); // "user.first.name"
16
263
  *
17
- * @param {string} str - Input string.
18
- * @returns {string} The title-cased string.
264
+ * @param {unknown} input
265
+ * @returns {string}
19
266
  */
20
- export function titleCase(str: string): string;
267
+ export function dotCase(input: unknown): string;
21
268
  /**
22
- * Converts a string to `camelCase`.
269
+ * Splits text into words. Understands camelCase, snake_case, kebab-case,
270
+ * dots, spaces and punctuation.
23
271
  *
24
272
  * @example
25
- * nodeComfort.str.camelCase("hello world"); // "helloWorld"
26
- * nodeComfort.str.camelCase("foo-bar_baz"); // "fooBarBaz"
273
+ * str.words("helloWorld-foo_bar"); // ["hello", "World", "foo", "bar"]
27
274
  *
28
- * @param {string} str - Input string.
29
- * @returns {string} The camelCased string.
275
+ * @param {unknown} input
276
+ * @returns {string[]}
30
277
  */
31
- export function camelCase(str: string): string;
278
+ export function words(input: unknown): string[];
32
279
  /**
33
- * Converts a string to `PascalCase`.
280
+ * Removes accents (`é` becomes `e`) and spells out special Latin letters
281
+ * (`ß` becomes `ss`, `æ` becomes `ae`).
34
282
  *
35
283
  * @example
36
- * nodeComfort.str.pascalCase("hello world"); // "HelloWorld"
284
+ * str.deburr("Crème brûlée"); // "Creme brulee"
285
+ * str.deburr("Straße"); // "Strasse"
37
286
  *
38
- * @param {string} str - Input string.
39
- * @returns {string} The PascalCased string.
287
+ * @param {unknown} input
288
+ * @returns {string}
40
289
  */
41
- export function pascalCase(str: string): string;
290
+ export function deburr(input: unknown): string;
42
291
  /**
43
- * Converts a string to `snake_case`.
292
+ * Turns text into a URL slug: no accents, lowercase, words joined by dashes.
44
293
  *
45
294
  * @example
46
- * nodeComfort.str.snakeCase("helloWorld"); // "hello_world"
295
+ * str.slugify("Héllo, World!"); // "hello-world"
296
+ * str.slugify("Crème Brûlée", { separator: "_" }); // "creme_brulee"
297
+ * str.slugify("A very long title", { maxLength: 8 }); // "a-very"
47
298
  *
48
- * @param {string} str - Input string.
49
- * @returns {string} The snake_cased string.
299
+ * @param {unknown} input
300
+ * @param {SlugifyOptions} [options]
301
+ * @returns {string} The slug, possibly empty.
50
302
  */
51
- export function snakeCase(str: string): string;
303
+ export function slugify(input: unknown, options?: SlugifyOptions): string;
52
304
  /**
53
- * Converts a string to `kebab-case`.
305
+ * Collapses runs of whitespace into single spaces and trims the ends.
54
306
  *
55
307
  * @example
56
- * nodeComfort.str.kebabCase("helloWorld"); // "hello-world"
308
+ * str.squish(" hello \n\t world "); // "hello world"
57
309
  *
58
- * @param {string} str - Input string.
59
- * @returns {string} The kebab-cased string.
310
+ * @param {unknown} input
311
+ * @returns {string}
60
312
  */
61
- export function kebabCase(str: string): string;
313
+ export function squish(input: unknown): string;
62
314
  /**
63
- * Converts a string to `CONSTANT_CASE`.
315
+ * Removes HTML tags and keeps the text. This is not a sanitizer: to show
316
+ * untrusted text in HTML, use `escapeHTML()`.
64
317
  *
65
318
  * @example
66
- * nodeComfort.str.constantCase("helloWorld"); // "HELLO_WORLD"
319
+ * str.stripTags("<p>Hello <b>world</b></p>"); // "Hello world"
67
320
  *
68
- * @param {string} str - Input string.
69
- * @returns {string} The CONSTANT_CASED string.
321
+ * @param {unknown} input
322
+ * @returns {string}
70
323
  */
71
- export function constantCase(str: string): string;
324
+ export function stripTags(input: unknown): string;
72
325
  /**
73
- * Converts a string into a URL-friendly slug.
326
+ * Escapes `& < > " '` so the text is safe inside HTML content and attributes.
74
327
  *
75
- * Accents/diacritics are stripped, non-alphanumeric runs become the separator.
328
+ * @example
329
+ * str.escapeHTML('<a href="x">Tom & Jerry</a>');
330
+ * // "&lt;a href=&quot;x&quot;&gt;Tom &amp; Jerry&lt;/a&gt;"
331
+ *
332
+ * @param {unknown} input
333
+ * @returns {string}
334
+ */
335
+ export function escapeHTML(input: unknown): string;
336
+ /**
337
+ * Decodes HTML entities: named ones like `&amp;` and `&nbsp;`, and numeric
338
+ * ones like `&#233;`.
76
339
  *
77
340
  * @example
78
- * nodeComfort.str.slugify("Héllo, World!"); // "hello-world"
79
- * nodeComfort.str.slugify("A B C", { separator: "_" }); // "a_b_c"
341
+ * str.unescapeHTML("Tom &amp; Jerry &#x1F600;"); // "Tom & Jerry 😀"
80
342
  *
81
- * @param {string} str - Input string.
82
- * @param {{ separator?: string, lower?: boolean }} [options] - Slug options.
83
- * @returns {string} The slug.
343
+ * @param {unknown} input
344
+ * @returns {string}
84
345
  */
85
- export function slugify(str: string, options?: {
86
- separator?: string;
87
- lower?: boolean;
88
- }): string;
346
+ export function unescapeHTML(input: unknown): string;
89
347
  /**
90
- * Truncates a string to a maximum length, appending an ellipsis if cut.
348
+ * Escapes regex special characters so the text matches literally.
91
349
  *
92
350
  * @example
93
- * nodeComfort.str.truncate("Hello world", 8); // "Hello…"
94
- * nodeComfort.str.truncate("Hello world", 8, { omission: "..." }); // "Hello..."
351
+ * new RegExp(str.escapeRegExp("1+1=2?")).test("1+1=2?"); // true
95
352
  *
96
- * @param {string} str - Input string.
97
- * @param {number} length - Maximum length of the result (including the omission).
98
- * @param {{ omission?: string, words?: boolean }} [options] - Truncation options.
99
- * @returns {string} The truncated string.
353
+ * @param {unknown} input
354
+ * @returns {string}
100
355
  */
101
- export function truncate(str: string, length: number, options?: {
102
- omission?: string;
103
- words?: boolean;
104
- }): string;
356
+ export function escapeRegExp(input: unknown): string;
105
357
  /**
106
- * Pads a string on the left (start) to a target length.
358
+ * Counts visible characters. Unlike `.length`, an emoji or an accented
359
+ * letter counts as one.
107
360
  *
108
- * @param {string} str - Input string.
109
- * @param {number} length - Target total length.
110
- * @param {string} [char=" "] - Padding character(s).
111
- * @returns {string} The padded string.
361
+ * @example
362
+ * "👨‍👩‍👧".length; // 8
363
+ * str.length("👨‍👩‍👧"); // 1
364
+ *
365
+ * @param {unknown} input
366
+ * @returns {number}
112
367
  */
113
- export function padStart(str: string, length: number, char?: string): string;
368
+ export function length(input: unknown): number;
114
369
  /**
115
- * Pads a string on the right (end) to a target length.
370
+ * Size of the text in bytes once encoded, UTF-8 by default. Useful when a
371
+ * limit is in bytes, like a database column or an HTTP header.
372
+ *
373
+ * @example
374
+ * str.byteLength("é"); // 2
375
+ * str.byteLength("😀"); // 4
116
376
  *
117
- * @param {string} str - Input string.
118
- * @param {number} length - Target total length.
119
- * @param {string} [char=" "] - Padding character(s).
120
- * @returns {string} The padded string.
377
+ * @param {unknown} input
378
+ * @param {BufferEncoding} [encoding="utf8"]
379
+ * @returns {number}
121
380
  */
122
- export function padEnd(str: string, length: number, char?: string): string;
381
+ export function byteLength(input: unknown, encoding?: BufferEncoding): number;
123
382
  /**
124
- * Centers a string within a target length by padding both sides.
383
+ * Counts how many times `search` appears, without overlaps.
125
384
  *
126
385
  * @example
127
- * nodeComfort.str.center("hi", 6); // " hi "
128
- * nodeComfort.str.center("hi", 6, "*"); // "**hi**"
386
+ * str.count("banana", "a"); // 3
387
+ * str.count("aaaa", "aa"); // 2
129
388
  *
130
- * @param {string} str - Input string.
131
- * @param {number} length - Target total length.
132
- * @param {string} [char=" "] - Padding character.
133
- * @returns {string} The centered string.
389
+ * @param {unknown} input
390
+ * @param {string} search An empty string gives `0`.
391
+ * @returns {number}
134
392
  */
135
- export function center(str: string, length: number, char?: string): string;
393
+ export function count(input: unknown, search: string): number;
136
394
  /**
137
- * Reverses a string (Unicode code-point aware, so emojis stay intact).
395
+ * Shortens text to `length` visible characters, ending with `…` when cut.
138
396
  *
139
397
  * @example
140
- * nodeComfort.str.reverse("abc"); // "cba"
398
+ * str.truncate("Hello world", 8); // "Hello w…"
399
+ * str.truncate("Hello world", 8, { omission: "..." }); // "Hello..."
400
+ * str.truncate("Hello big world", 12, { words: true }); // "Hello big…"
401
+ *
402
+ * @param {unknown} input
403
+ * @param {number} length Maximum length, omission included.
404
+ * @param {TruncateOptions} [options]
405
+ * @returns {string}
406
+ */
407
+ export function truncate(input: unknown, length: number, options?: TruncateOptions): string;
408
+ /**
409
+ * Returns the text between `start` and the next `end`, or `undefined` if a
410
+ * marker is missing.
141
411
  *
142
- * @param {string} str - Input string.
143
- * @returns {string} The reversed string.
412
+ * @example
413
+ * str.between("Hello [world]!", "[", "]"); // "world"
414
+ *
415
+ * @param {unknown} input
416
+ * @param {string} start
417
+ * @param {string} end
418
+ * @returns {string | undefined}
144
419
  */
145
- export function reverse(str: string): string;
420
+ export function between(input: unknown, start: string, end: string): string | undefined;
146
421
  /**
147
- * Collapses all runs of whitespace into single spaces and trims the ends.
422
+ * Splits at the first occurrence of `separator` only.
148
423
  *
149
424
  * @example
150
- * nodeComfort.str.squish(" hello world \n"); // "hello world"
425
+ * str.splitOnce("key=value=more", "="); // ["key", "value=more"]
426
+ * str.splitOnce("novalue", "="); // ["novalue", undefined]
151
427
  *
152
- * @param {string} str - Input string.
153
- * @returns {string} The normalized string.
428
+ * @param {unknown} input
429
+ * @param {string} separator
430
+ * @returns {[string, string | undefined]}
154
431
  */
155
- export function squish(str: string): string;
432
+ export function splitOnce(input: unknown, separator: string): [string, string | undefined];
156
433
  /**
157
- * Removes all HTML tags from a string.
434
+ * Splits text into lines, whatever the line endings.
158
435
  *
159
436
  * @example
160
- * nodeComfort.str.stripTags("<b>Hi</b> there"); // "Hi there"
437
+ * str.lines("a\r\nb\nc"); // ["a", "b", "c"]
161
438
  *
162
- * @param {string} str - Input string.
163
- * @returns {string} The string with tags removed.
439
+ * @param {unknown} input
440
+ * @returns {string[]}
164
441
  */
165
- export function stripTags(str: string): string;
442
+ export function lines(input: unknown): string[];
166
443
  /**
167
- * Escapes HTML-sensitive characters (`& < > " '`).
444
+ * Pads the start until the text is `length` characters long.
168
445
  *
169
446
  * @example
170
- * nodeComfort.str.escapeHTML('<a href="x">'); // "&lt;a href=&quot;x&quot;&gt;"
447
+ * str.padStart("7", 3, "0"); // "007"
171
448
  *
172
- * @param {string} str - Input string.
173
- * @returns {string} The escaped string.
449
+ * @param {unknown} input
450
+ * @param {number} length
451
+ * @param {string} [char=" "]
452
+ * @returns {string}
174
453
  */
175
- export function escapeHTML(str: string): string;
454
+ export function padStart(input: unknown, length: number, char?: string): string;
176
455
  /**
177
- * Reverses {@link escapeHTML}: turns HTML entities back into characters.
456
+ * Pads the end until the text is `length` characters long.
457
+ *
458
+ * @example
459
+ * str.padEnd("ab", 5, "."); // "ab..."
178
460
  *
179
- * @param {string} str - Input string.
180
- * @returns {string} The unescaped string.
461
+ * @param {unknown} input
462
+ * @param {number} length
463
+ * @param {string} [char=" "]
464
+ * @returns {string}
181
465
  */
182
- export function unescapeHTML(str: string): string;
466
+ export function padEnd(input: unknown, length: number, char?: string): string;
183
467
  /**
184
- * Escapes a string for safe use inside a `RegExp`.
468
+ * Centers text within `length` characters. An odd leftover goes to the right.
185
469
  *
186
470
  * @example
187
- * new RegExp(nodeComfort.str.escapeRegExp("a.b")); // matches literal "a.b"
471
+ * str.center("hi", 7, "*"); // "**hi***"
188
472
  *
189
- * @param {string} str - Input string.
190
- * @returns {string} The escaped string.
473
+ * @param {unknown} input
474
+ * @param {number} length
475
+ * @param {string} [char=" "]
476
+ * @returns {string}
191
477
  */
192
- export function escapeRegExp(str: string): string;
478
+ export function center(input: unknown, length: number, char?: string): string;
193
479
  /**
194
- * Counts the number of non-overlapping occurrences of a substring.
480
+ * Indents every non-empty line.
195
481
  *
196
482
  * @example
197
- * nodeComfort.str.count("banana", "a"); // 3
483
+ * str.indent("a\nb", 2); // " a\n b"
484
+ * str.indent("a\nb", "> "); // "> a\n> b"
198
485
  *
199
- * @param {string} str - Input string.
200
- * @param {string} sub - Substring to count.
201
- * @returns {number} Number of occurrences.
486
+ * @param {unknown} input
487
+ * @param {number | string} [prefix=2] A number of spaces, or the prefix itself.
488
+ * @returns {string}
202
489
  */
203
- export function count(str: string, sub: string): number;
490
+ export function indent(input: unknown, prefix?: number | string): string;
204
491
  /**
205
- * Ensures a string starts with a given prefix (adds it only if missing).
492
+ * Removes the indentation shared by all lines, and blank first and last
493
+ * lines. Works as a template tag, so multi-line strings can follow your
494
+ * code's indentation.
206
495
  *
207
496
  * @example
208
- * nodeComfort.str.ensurePrefix("example.com", "https://"); // "https://example.com"
497
+ * const sql = str.dedent`
498
+ * SELECT *
499
+ * FROM users
500
+ * WHERE id = ${id}
501
+ * `;
502
+ * // "SELECT *\n FROM users\n WHERE id = 42"
503
+ *
504
+ * @param {unknown} input
505
+ * @param {...unknown} values
506
+ * @returns {string}
507
+ */
508
+ export function dedent(input: unknown, ...values: unknown[]): string;
509
+ /**
510
+ * Wraps text so no line is longer than `width` visible characters. Existing
511
+ * line breaks are kept.
512
+ *
513
+ * @example
514
+ * str.wrap("The quick brown fox jumps over the lazy dog", 16);
515
+ * // "The quick brown\nfox jumps over\nthe lazy dog"
209
516
  *
210
- * @param {string} str - Input string.
211
- * @param {string} prefix - Prefix to ensure.
212
- * @returns {string} The string with the prefix guaranteed.
517
+ * @param {unknown} input
518
+ * @param {WrapOptions | number} [options] Options, or just the width.
519
+ * @returns {string}
213
520
  */
214
- export function ensurePrefix(str: string, prefix: string): string;
521
+ export function wrap(input: unknown, options?: WrapOptions | number): string;
215
522
  /**
216
- * Ensures a string ends with a given suffix (adds it only if missing).
523
+ * Reverses text without breaking emoji or accents.
217
524
  *
218
525
  * @example
219
- * nodeComfort.str.ensureSuffix("path", "/"); // "path/"
526
+ * str.reverse("añ👍🏽"); // "👍🏽ña"
220
527
  *
221
- * @param {string} str - Input string.
222
- * @param {string} suffix - Suffix to ensure.
223
- * @returns {string} The string with the suffix guaranteed.
528
+ * @param {unknown} input
529
+ * @returns {string}
224
530
  */
225
- export function ensureSuffix(str: string, suffix: string): string;
531
+ export function reverse(input: unknown): string;
226
532
  /**
227
- * Removes a prefix from a string if present.
533
+ * Hides part of a string, like a card number or a token.
228
534
  *
229
- * @param {string} str - Input string.
230
- * @param {string} prefix - Prefix to remove.
231
- * @returns {string} The string without the prefix.
535
+ * @example
536
+ * str.mask("4242424242424242"); // "************4242"
537
+ * str.mask("4242 4242 4242 4242", { keepSpaces: true }); // "**** **** **** 4242"
538
+ * str.mask("secret-token", { start: 2, end: 2, char: "•" }); // "se••••••••en"
539
+ *
540
+ * @param {unknown} input
541
+ * @param {MaskOptions} [options]
542
+ * @returns {string}
232
543
  */
233
- export function removePrefix(str: string, prefix: string): string;
544
+ export function mask(input: unknown, options?: MaskOptions): string;
234
545
  /**
235
- * Removes a suffix from a string if present.
546
+ * The initials of a name, in uppercase.
547
+ *
548
+ * @example
549
+ * str.initials("Ada Lovelace"); // "AL"
550
+ * str.initials("jean-luc picard", 3); // "JLP"
236
551
  *
237
- * @param {string} str - Input string.
238
- * @param {string} suffix - Suffix to remove.
239
- * @returns {string} The string without the suffix.
552
+ * @param {unknown} input
553
+ * @param {number} [max=2] Maximum number of letters.
554
+ * @returns {string}
240
555
  */
241
- export function removeSuffix(str: string, suffix: string): string;
556
+ export function initials(input: unknown, max?: number): string;
242
557
  /**
243
- * Renders a template, replacing `{key}` placeholders with values from `data`.
558
+ * Picks the right plural for a count, following the rules of the language,
559
+ * and puts the formatted count in front.
244
560
  *
245
- * Missing keys are left as-is by default. Nested paths (`{user.name}`) are supported.
561
+ * @example
562
+ * str.plural(1, { one: "file", other: "files" }); // "1 file"
563
+ * str.plural(1234, { one: "item", other: "items" }); // "1,234 items"
564
+ * str.plural(0, { zero: "no files", one: "file", other: "files" }); // "no files"
565
+ * str.plural(0, { one: "fichier", other: "fichiers" }, { locale: "fr" }); // "0 fichier"
566
+ *
567
+ * @param {number} value
568
+ * @param {PluralForms} forms
569
+ * @param {PluralOptions} [options]
570
+ * @returns {string}
571
+ */
572
+ export function plural(value: number, forms: PluralForms, options?: PluralOptions): string;
573
+ /**
574
+ * Fills `{placeholders}` with values. Dotted paths like `{user.name}` work,
575
+ * and missing values are left alone unless you give a `fallback`.
246
576
  *
247
577
  * @example
248
- * nodeComfort.str.template("Hi {name}, you have {count} msgs", { name: "Jo", count: 3 });
249
- * // "Hi Jo, you have 3 msgs"
578
+ * str.template("Hi {name}, you have {count} messages", { name: "Jo", count: 3 });
579
+ * // "Hi Jo, you have 3 messages"
580
+ * str.template("Hello {{ user.name }}", { user: { name: "Ada" } }, { open: "{{", close: "}}" });
581
+ * // "Hello Ada"
582
+ *
583
+ * @param {unknown} input
584
+ * @param {Record<string, any>} data
585
+ * @param {TemplateOptions} [options]
586
+ * @returns {string}
587
+ */
588
+ export function template(input: unknown, data: Record<string, any>, options?: TemplateOptions): string;
589
+ /**
590
+ * Adds `prefix` unless the text already starts with it.
250
591
  *
251
- * @param {string} str - Template string.
252
- * @param {Record<string, any>} data - Replacement values.
253
- * @param {{ open?: string, close?: string, fallback?: string }} [options] - Delimiters / fallback.
254
- * @returns {string} The rendered string.
592
+ * @example
593
+ * str.ensurePrefix("example.com", "https://"); // "https://example.com"
594
+ *
595
+ * @param {unknown} input
596
+ * @param {string} prefix
597
+ * @returns {string}
598
+ */
599
+ export function ensurePrefix(input: unknown, prefix: string): string;
600
+ /**
601
+ * Adds `suffix` unless the text already ends with it.
602
+ *
603
+ * @example
604
+ * str.ensureSuffix("path/to", "/"); // "path/to/"
605
+ *
606
+ * @param {unknown} input
607
+ * @param {string} suffix
608
+ * @returns {string}
609
+ */
610
+ export function ensureSuffix(input: unknown, suffix: string): string;
611
+ /**
612
+ * Removes `prefix` if the text starts with it.
613
+ *
614
+ * @example
615
+ * str.removePrefix("https://example.com", "https://"); // "example.com"
616
+ *
617
+ * @param {unknown} input
618
+ * @param {string} prefix
619
+ * @returns {string}
255
620
  */
256
- export function template(str: string, data: Record<string, any>, options?: {
257
- open?: string;
258
- close?: string;
259
- fallback?: string;
260
- }): string;
621
+ export function removePrefix(input: unknown, prefix: string): string;
261
622
  /**
262
- * Splits a string into an array of "words" (camelCase / snake / kebab aware).
623
+ * Removes `suffix` if the text ends with it.
263
624
  *
264
625
  * @example
265
- * nodeComfort.str.words("helloWorld-foo_bar"); // ["hello", "World", "foo", "bar"]
626
+ * str.removeSuffix("report.pdf", ".pdf"); // "report"
266
627
  *
267
- * @param {string} str - Input string.
268
- * @returns {string[]} The words.
628
+ * @param {unknown} input
629
+ * @param {string} suffix
630
+ * @returns {string}
269
631
  */
270
- export function words(str: string): string[];
632
+ export function removeSuffix(input: unknown, suffix: string): string;
271
633
  /**
272
- * Returns the visible length of a string in code points (emoji-safe).
634
+ * Compares two strings the way people sort them: numbers in natural order
635
+ * and accents in the right place. Pass it straight to `sort()`.
273
636
  *
274
637
  * @example
275
- * "😀".length; // 2
276
- * nodeComfort.str.length("😀"); // 1
638
+ * ["file10", "file2", "File1"].sort(str.compare); // ["File1", "file2", "file10"]
639
+ * str.compare("a", "A", { sensitivity: "base" }); // 0
277
640
  *
278
- * @param {string} str - Input string.
279
- * @returns {number} The number of code points.
641
+ * @param {unknown} a
642
+ * @param {unknown} b
643
+ * @param {CompareOptions} [options]
644
+ * @returns {number} Negative if `a` comes first, positive if `b` does, `0` if equal.
280
645
  */
281
- export function length(str: string): number;
646
+ export function compare(a: unknown, b: unknown, options?: CompareOptions): number;
282
647
  /**
283
- * Generates a random alphanumeric string of a given length.
648
+ * The number of single-character edits needed to turn `a` into `b`.
284
649
  *
285
- * Note: uses `Math.random` and is **not** cryptographically secure.
286
- * For tokens/IDs use `nodeComfort.id.token()` instead.
650
+ * @example
651
+ * str.levenshtein("kitten", "sitting"); // 3
652
+ *
653
+ * @param {unknown} a
654
+ * @param {unknown} b
655
+ * @returns {number}
656
+ */
657
+ export function levenshtein(a: unknown, b: unknown): number;
658
+ /**
659
+ * How alike two strings are, from `0` (nothing in common) to `1` (identical).
660
+ *
661
+ * @example
662
+ * str.similarity("hello", "hallo"); // 0.8
663
+ *
664
+ * @param {unknown} a
665
+ * @param {unknown} b
666
+ * @returns {number}
667
+ */
668
+ export function similarity(a: unknown, b: unknown): number;
669
+ /**
670
+ * Finds the candidate closest to `input`. Made for "Did you mean...?"
671
+ * suggestions.
672
+ *
673
+ * @example
674
+ * str.closest("instal", ["install", "uninstall", "list"]); // "install"
675
+ * str.closest("xyz", ["install", "list"]); // undefined
676
+ *
677
+ * @param {unknown} input
678
+ * @param {Iterable<string>} candidates
679
+ * @param {ClosestOptions} [options]
680
+ * @returns {string | undefined} `undefined` when nothing is close enough.
681
+ */
682
+ export function closest(input: unknown, candidates: Iterable<string>, options?: ClosestOptions): string | undefined;
683
+ /**
684
+ * A random string. It relies on `Math.random`, so don't use it for secrets:
685
+ * `nc.id.token()` and `nc.id.nano()` are made for that.
686
+ *
687
+ * @example
688
+ * str.random(); // "aZ3kP9qL0xYb7TcW"
689
+ * str.random(6, { charset: "0123456789" }); // "402917"
287
690
  *
288
- * @param {number} [length=16] - Desired length.
289
- * @param {string} [charset] - Characters to pick from.
290
- * @returns {string} The random string.
691
+ * @param {number} [size=16]
692
+ * @param {RandomStringOptions | string} [options] Options, or the charset itself.
693
+ * @returns {string}
291
694
  */
292
- export function random(length?: number, charset?: string): string;
695
+ export function random(size?: number, options?: RandomStringOptions | string): string;
293
696
  //# sourceMappingURL=Str.d.ts.map