@poppinss/utils 6.0.0-0 → 6.0.0-2

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 CHANGED
@@ -2,10 +2,9 @@
2
2
 
3
3
  > A toolkit of utilities used across all the AdonisJS, Edge, and Japa packages
4
4
 
5
-
6
5
  [![gh-workflow-image]][gh-workflow-url] [![typescript-image]][typescript-url] [![npm-image]][npm-url] [![license-image]][license-url] [![synk-image]][synk-url]
7
6
 
8
- ## Why this package exists?
7
+ ## Why this package exists?
9
8
 
10
9
  Many of my open source projects (including AdonisJS) use many single-purpose utility packages from npm. Over the years, I have faced the following challenges when using these packages.
11
10
 
@@ -20,19 +19,21 @@ Many of my open source projects (including AdonisJS) use many single-purpose uti
20
19
  > **Warning**: This package is not for general use (outside the AdonisJS ecosystem). I will not add new helpers or remove any to cater to a broader audience.
21
20
 
22
21
  ## Other packages to use
22
+
23
23
  A note to self and others to consider the following packages.
24
24
 
25
- | Package | Description |
26
- |---------|-------------|
27
- | [he](https://www.npmjs.com/package/he) | For escaping HTML entities and encoding unicode symbols. Has zero dependencies |
28
- | [@sindresorhus/is](https://www.npmjs.com/package/@sindresorhus/is) | For advanced type checking. Has zero dependencies |
25
+ | Package | Description |
26
+ | ------------------------------------------------------------------ | ------------------------------------------------------------------------------ |
27
+ | [he](https://www.npmjs.com/package/he) | For escaping HTML entities and encoding unicode symbols. Has zero dependencies |
28
+ | [@sindresorhus/is](https://www.npmjs.com/package/@sindresorhus/is) | For advanced type checking. Has zero dependencies |
29
29
 
30
30
  ## Package size
31
+
31
32
  Even though I do not care much about the package size (most of work is consumed on server side), I am mindful around the utilities and ensure not end up using really big packages for smaller use-cases.
32
33
 
33
- | | |
34
- |------------------|-----------------|
35
- | Source code size | `272K` (approx) |
34
+ | | |
35
+ | ----------------- | --------------- |
36
+ | Source code size | `272K` (approx) |
36
37
  | Dependencies size | `432K` (approx) |
37
38
 
38
39
  ## Installation
@@ -83,14 +84,15 @@ console.log(string.excerpt(html, 70))
83
84
  // AdonisJS is a Node.js framework, and hence it requires Node.js to be i...
84
85
  ```
85
86
 
86
- | Argument | Type | Description |
87
- |---------|------|---------------|
88
- | `sentence` | string | The value for which to generate excerpt |
89
- | `charactersLimit` | string | The number of characters to keep |
90
- | `options.completeWords` | boolean | When set to `true`, the truncation will happen only after complete words. This option might go over the defined characters limit
91
- | `options.suffix` | string | The value to append after the truncated string. Defaults to three dots `...` |
87
+ | Argument | Type | Description |
88
+ | ----------------------- | ------- | -------------------------------------------------------------------------------------------------------------------------------- |
89
+ | `sentence` | string | The value for which to generate excerpt |
90
+ | `charactersLimit` | string | The number of characters to keep |
91
+ | `options.completeWords` | boolean | When set to `true`, the truncation will happen only after complete words. This option might go over the defined characters limit |
92
+ | `options.suffix` | string | The value to append after the truncated string. Defaults to three dots `...` |
92
93
 
93
94
  #### truncate
95
+
94
96
  Truncate a string value to a certain length. The method is the same as the `excerpt` method but does not remove any HTML tags. It is a great fit when you are truncating a non-HTML string.
95
97
 
96
98
  ```ts
@@ -100,17 +102,18 @@ console.log(string.truncate(text, 70))
100
102
  // AdonisJS is a Node.js framework, and hence it requires Node.js to be i...
101
103
  ```
102
104
 
103
- | Argument | Type | Description |
104
- |---------|------|---------------|
105
- | `sentence` | string | The value to truncate |
106
- | `charactersLimit` | string | The number of characters to keep |
107
- | `options.completeWords` | boolean | When set to `true`, the truncation will happen only after complete words. This option might go over the defined characters limit
108
- | `options.suffix` | string | The value to append after the truncated string. Defaults to three dots `...` |
105
+ | Argument | Type | Description |
106
+ | ----------------------- | ------- | -------------------------------------------------------------------------------------------------------------------------------- |
107
+ | `sentence` | string | The value to truncate |
108
+ | `charactersLimit` | string | The number of characters to keep |
109
+ | `options.completeWords` | boolean | When set to `true`, the truncation will happen only after complete words. This option might go over the defined characters limit |
110
+ | `options.suffix` | string | The value to append after the truncated string. Defaults to three dots `...` |
109
111
 
110
112
  #### slug
113
+
111
114
  Generate slug for a string value. The method is exported directly from the [slugify](https://www.npmjs.com/package/slugify) package.
112
115
 
113
- Please check the package documentation for [available options](https://www.npmjs.com/package/slugify#options).
116
+ Please check the package documentation for [available options](https://www.npmjs.com/package/slugify#options).
114
117
 
115
118
  ```ts
116
119
  console.log(string.slug('hello ♥ world'))
@@ -127,13 +130,11 @@ console.log(string.slug('unicode ♥ is ☢'))
127
130
  ```
128
131
 
129
132
  #### interpolate
133
+
130
134
  Interpolate variables inside a string. The variables must be inside double curly braces.
131
135
 
132
136
  ```ts
133
- string.interpolate(
134
- 'hello {{ user.username }}',
135
- { user: { username: 'virk' } }
136
- )
137
+ string.interpolate('hello {{ user.username }}', { user: { username: 'virk' } })
137
138
 
138
139
  // hello virk
139
140
  ```
@@ -141,10 +142,7 @@ string.interpolate(
141
142
  You can also replace array values by mentioning the array index.
142
143
 
143
144
  ```ts
144
- string.interpolate(
145
- 'hello {{ users.0 }}',
146
- { users: ['virk'] }
147
- )
145
+ string.interpolate('hello {{ users.0 }}', { users: ['virk'] })
148
146
 
149
147
  // hello virk
150
148
  ```
@@ -158,6 +156,7 @@ string.interpolate('hello \\{{ users.0 }}', {})
158
156
  ```
159
157
 
160
158
  #### plural
159
+
161
160
  Convert a word to its plural form. The method is exported directly from the [pluralize](https://www.npmjs.com/package/pluralize) package.
162
161
 
163
162
  ```ts
@@ -166,6 +165,7 @@ string.plural('test')
166
165
  ```
167
166
 
168
167
  #### singular
168
+
169
169
  Convert a word to its singular form. The method is exported directly from the [pluralize](https://www.npmjs.com/package/pluralize) package.
170
170
 
171
171
  ```ts
@@ -174,6 +174,7 @@ string.singular('tests')
174
174
  ```
175
175
 
176
176
  #### pluralize
177
+
177
178
  This method combines the `singular` and `plural` methods and uses one or the other based on the count. For example:
178
179
 
179
180
  ```ts
@@ -194,6 +195,7 @@ string.pluralize.addSingularRule(/singles$/i, 'singular')
194
195
  ```
195
196
 
196
197
  #### isPlural
198
+
197
199
  Find if a word is already in plural form. The method is exported directly from the [pluralize](https://www.npmjs.com/package/pluralize) package.
198
200
 
199
201
  ```ts
@@ -201,6 +203,7 @@ string.isPlural('tests') // true
201
203
  ```
202
204
 
203
205
  #### isSingular
206
+
204
207
  Find if a word is already in a singular form. The method is exported directly from the [pluralize](https://www.npmjs.com/package/pluralize) package.
205
208
 
206
209
  ```ts
@@ -208,6 +211,7 @@ string.isSingular('test') // true
208
211
  ```
209
212
 
210
213
  #### camelCase
214
+
211
215
  Convert a string value to camelcase.
212
216
 
213
217
  ```ts
@@ -216,17 +220,18 @@ string.camelCase('user_name') // userName
216
220
 
217
221
  Following are some of the conversion examples.
218
222
 
219
- | Input | Output |
220
- |------|---------|
221
- | 'test' | 'test' |
222
- | 'test string' | 'testString' |
223
- | 'Test String' | 'testString' |
224
- | 'TestV2' | 'testV2' |
225
- | '_foo_bar_' | 'fooBar' |
223
+ | Input | Output |
224
+ | ---------------- | ------------- |
225
+ | 'test' | 'test' |
226
+ | 'test string' | 'testString' |
227
+ | 'Test String' | 'testString' |
228
+ | 'TestV2' | 'testV2' |
229
+ | '_foo_bar_' | 'fooBar' |
226
230
  | 'version 1.2.10' | 'version1210' |
227
231
  | 'version 1.21.0' | 'version1210' |
228
232
 
229
233
  #### capitalCase
234
+
230
235
  Convert a string value to a capital case.
231
236
 
232
237
  ```ts
@@ -235,16 +240,17 @@ string.capitalCase('helloWorld') // Hello World
235
240
 
236
241
  Following are some of the conversion examples.
237
242
 
238
- | Input | Output |
239
- |------|---------|
240
- | 'test' | 'Test' |
241
- | 'test string' | 'Test String' |
242
- | 'Test String' | 'Test String' |
243
- | 'TestV2' | 'Test V 2' |
243
+ | Input | Output |
244
+ | ---------------- | ---------------- |
245
+ | 'test' | 'Test' |
246
+ | 'test string' | 'Test String' |
247
+ | 'Test String' | 'Test String' |
248
+ | 'TestV2' | 'Test V 2' |
244
249
  | 'version 1.2.10' | 'Version 1.2.10' |
245
250
  | 'version 1.21.0' | 'Version 1.21.0' |
246
251
 
247
252
  #### dashCase
253
+
248
254
  Convert a string value to a dash case.
249
255
 
250
256
  ```ts
@@ -259,17 +265,18 @@ string.dashCase('helloWorld', { capitalize: true }) // Hello-World
259
265
 
260
266
  Following are some of the conversion examples.
261
267
 
262
- | Input | Output |
263
- |--------|--------|
264
- | 'test' | 'test' |
265
- | 'test string' | 'test-string' |
266
- | 'Test String' | 'test-string' |
267
- | 'Test V2' | 'test-v2' |
268
- | 'TestV2' | 'test-v-2' |
268
+ | Input | Output |
269
+ | ---------------- | -------------- |
270
+ | 'test' | 'test' |
271
+ | 'test string' | 'test-string' |
272
+ | 'Test String' | 'test-string' |
273
+ | 'Test V2' | 'test-v2' |
274
+ | 'TestV2' | 'test-v-2' |
269
275
  | 'version 1.2.10' | 'version-1210' |
270
276
  | 'version 1.21.0' | 'version-1210' |
271
277
 
272
278
  #### dotCase
279
+
273
280
  Convert a string value to a dot case.
274
281
 
275
282
  ```ts
@@ -284,18 +291,19 @@ string.dotCase('helloWorld', { lowerCase: true }) // hello.world
284
291
 
285
292
  Following are some of the conversion examples.
286
293
 
287
- | Input | Output |
288
- |--------|--------|
289
- | 'test' | 'test' |
290
- | 'test string' | 'test.string' |
291
- | 'Test String' | 'Test.String' |
292
- | 'dot.case' | 'dot.case' |
293
- | 'path/case' | 'path.case' |
294
- | 'TestV2' | 'Test.V.2' |
294
+ | Input | Output |
295
+ | ---------------- | -------------- |
296
+ | 'test' | 'test' |
297
+ | 'test string' | 'test.string' |
298
+ | 'Test String' | 'Test.String' |
299
+ | 'dot.case' | 'dot.case' |
300
+ | 'path/case' | 'path.case' |
301
+ | 'TestV2' | 'Test.V.2' |
295
302
  | 'version 1.2.10' | 'version.1210' |
296
303
  | 'version 1.21.0' | 'version.1210' |
297
304
 
298
305
  #### noCase
306
+
299
307
  Remove all sorts of casing from a string value.
300
308
 
301
309
  ```ts
@@ -304,36 +312,37 @@ string.noCase('helloWorld') // hello world
304
312
 
305
313
  Following are some of the conversion examples.
306
314
 
307
- | Input | Output |
308
- |--------|--------|
309
- | 'test' | 'test' |
310
- | 'TEST' | 'test' |
311
- | 'testString' | 'test string' |
312
- | 'testString123' | 'test string123' |
313
- | 'testString_1_2_3' | 'test string 1 2 3' |
314
- | 'ID123String' | 'id123 string' |
315
- | 'foo bar123' | 'foo bar123' |
316
- | 'a1bStar' | 'a1b star' |
317
- | 'CONSTANT_CASE ' | 'constant case' |
318
- | 'CONST123_FOO' | 'const123 foo' |
319
- | 'FOO_bar' | 'foo bar' |
320
- | 'XMLHttpRequest' | 'xml http request' |
321
- | 'IQueryAArgs' | 'i query a args' |
322
- | 'dot.case' | 'dot case' |
323
- | 'path/case' | 'path case' |
324
- | 'snake_case' | 'snake case' |
325
- | 'snake_case123' | 'snake case123' |
326
- | 'snake_case_123' | 'snake case 123' |
327
- | '"quotes"' | 'quotes' |
328
- | 'version 0.45.0' | 'version 0 45 0' |
329
- | 'version 0..78..9' | 'version 0 78 9' |
330
- | 'version 4_99/4' | 'version 4 99 4' |
331
- | ' test ' | 'test' |
315
+ | Input | Output |
316
+ | ---------------------- | ---------------------- |
317
+ | 'test' | 'test' |
318
+ | 'TEST' | 'test' |
319
+ | 'testString' | 'test string' |
320
+ | 'testString123' | 'test string123' |
321
+ | 'testString_1_2_3' | 'test string 1 2 3' |
322
+ | 'ID123String' | 'id123 string' |
323
+ | 'foo bar123' | 'foo bar123' |
324
+ | 'a1bStar' | 'a1b star' |
325
+ | 'CONSTANT_CASE ' | 'constant case' |
326
+ | 'CONST123_FOO' | 'const123 foo' |
327
+ | 'FOO_bar' | 'foo bar' |
328
+ | 'XMLHttpRequest' | 'xml http request' |
329
+ | 'IQueryAArgs' | 'i query a args' |
330
+ | 'dot.case' | 'dot case' |
331
+ | 'path/case' | 'path case' |
332
+ | 'snake_case' | 'snake case' |
333
+ | 'snake_case123' | 'snake case123' |
334
+ | 'snake_case_123' | 'snake case 123' |
335
+ | '"quotes"' | 'quotes' |
336
+ | 'version 0.45.0' | 'version 0 45 0' |
337
+ | 'version 0..78..9' | 'version 0 78 9' |
338
+ | 'version 4_99/4' | 'version 4 99 4' |
339
+ | ' test ' | 'test' |
332
340
  | 'something_2014_other' | 'something 2014 other' |
333
- | 'amazon s3 data' | 'amazon s3 data' |
334
- | 'foo_13_bar' | 'foo 13 bar' |
341
+ | 'amazon s3 data' | 'amazon s3 data' |
342
+ | 'foo_13_bar' | 'foo 13 bar' |
335
343
 
336
344
  #### pascalCase
345
+
337
346
  Convert a string value to pascal case. Great for generating JavaScript class names.
338
347
 
339
348
  ```ts
@@ -342,16 +351,17 @@ string.pascalCase('user team') // UserTeam
342
351
 
343
352
  Following are some of the conversion examples.
344
353
 
345
- | Input | Output |
346
- |--------|--------|
347
- | 'test' | 'Test' |
348
- | 'test string' | 'TestString' |
349
- | 'Test String' | 'TestString' |
350
- | 'TestV2' | 'TestV2' |
354
+ | Input | Output |
355
+ | ---------------- | ------------- |
356
+ | 'test' | 'Test' |
357
+ | 'test string' | 'TestString' |
358
+ | 'Test String' | 'TestString' |
359
+ | 'TestV2' | 'TestV2' |
351
360
  | 'version 1.2.10' | 'Version1210' |
352
361
  | 'version 1.21.0' | 'Version1210' |
353
362
 
354
363
  #### sentenceCase
364
+
355
365
  Convert a value to a sentence.
356
366
 
357
367
  ```ts
@@ -361,16 +371,17 @@ string.sentenceCase('getting-started-with-adonisjs')
361
371
 
362
372
  Following are some of the conversion examples.
363
373
 
364
- | Input | Output |
365
- |--------|--------|
366
- | 'test' | 'Test' |
367
- | 'test string' | 'Test string' |
368
- | 'Test String' | 'Test string' |
369
- | 'TestV2' | 'Test v2' |
374
+ | Input | Output |
375
+ | ---------------- | ---------------- |
376
+ | 'test' | 'Test' |
377
+ | 'test string' | 'Test string' |
378
+ | 'Test String' | 'Test string' |
379
+ | 'TestV2' | 'Test v2' |
370
380
  | 'version 1.2.10' | 'Version 1 2 10' |
371
381
  | 'version 1.21.0' | 'Version 1 21 0' |
372
382
 
373
383
  #### snakeCase
384
+
374
385
  Convert value to snake case.
375
386
 
376
387
  ```ts
@@ -379,18 +390,19 @@ string.snakeCase('user team') // user_team
379
390
 
380
391
  Following are some of the conversion examples.
381
392
 
382
- | Input | Output |
383
- |--------|--------|
384
- | '_id' | 'id' |
385
- | 'test' | 'test' |
386
- | 'test string' | 'test_string' |
387
- | 'Test String' | 'test_string' |
388
- | 'Test V2' | 'test_v2' |
389
- | 'TestV2' | 'test_v_2' |
393
+ | Input | Output |
394
+ | ---------------- | -------------- |
395
+ | '\_id' | 'id' |
396
+ | 'test' | 'test' |
397
+ | 'test string' | 'test_string' |
398
+ | 'Test String' | 'test_string' |
399
+ | 'Test V2' | 'test_v2' |
400
+ | 'TestV2' | 'test_v_2' |
390
401
  | 'version 1.2.10' | 'version_1210' |
391
402
  | 'version 1.21.0' | 'version_1210' |
392
403
 
393
404
  #### titleCase
405
+
394
406
  Convert a string value to title case.
395
407
 
396
408
  ```ts
@@ -400,20 +412,21 @@ string.titleCase('small word ends on')
400
412
 
401
413
  Following are some of the conversion examples.
402
414
 
403
- | Input | Output |
404
- |--------|--------|
405
- | 'one. two.' | 'One. Two.' |
406
- | 'a small word starts' | 'A Small Word Starts' |
407
- | 'small word ends on' | 'Small Word Ends On' |
408
- | 'we keep NASA capitalized' | 'We Keep NASA Capitalized' |
409
- | 'pass camelCase through' | 'Pass camelCase Through' |
415
+ | Input | Output |
416
+ | ---------------------------------- | ---------------------------------- |
417
+ | 'one. two.' | 'One. Two.' |
418
+ | 'a small word starts' | 'A Small Word Starts' |
419
+ | 'small word ends on' | 'Small Word Ends On' |
420
+ | 'we keep NASA capitalized' | 'We Keep NASA Capitalized' |
421
+ | 'pass camelCase through' | 'Pass camelCase Through' |
410
422
  | 'follow step-by-step instructions' | 'Follow Step-by-Step Instructions' |
411
- | 'this vs. that' | 'This vs. That' |
412
- | 'this vs that' | 'This vs That' |
413
- | 'newcastle upon tyne' | 'Newcastle upon Tyne' |
414
- | 'newcastle \*upon\* tyne' | 'Newcastle \*upon\* Tyne' |
423
+ | 'this vs. that' | 'This vs. That' |
424
+ | 'this vs that' | 'This vs That' |
425
+ | 'newcastle upon tyne' | 'Newcastle upon Tyne' |
426
+ | 'newcastle \*upon\* tyne' | 'Newcastle \*upon\* Tyne' |
415
427
 
416
428
  #### random
429
+
417
430
  Generate a cryptographically secure random string of a given length. The output value is URL safe base64 encoded string.
418
431
 
419
432
  ```ts
@@ -422,7 +435,8 @@ string.random(32)
422
435
  ```
423
436
 
424
437
  #### toSentence
425
- Convert an array of words to a comma-separated sentence.
438
+
439
+ Convert an array of words to a comma-separated sentence.
426
440
 
427
441
  ```ts
428
442
  string.toSentence(['routes', 'controllers', 'middleware'])
@@ -433,7 +447,7 @@ You can replace the `and` with an `or` by specifying the `options.lastSeparator`
433
447
 
434
448
  ```ts
435
449
  string.toSentence(['routes', 'controllers', 'middleware'], {
436
- lastSeparator: ', or '
450
+ lastSeparator: ', or ',
437
451
  })
438
452
  ```
439
453
 
@@ -444,12 +458,13 @@ string.toSentence(['routes', 'controllers'])
444
458
  // routes and controllers
445
459
 
446
460
  string.toSentence(['routes', 'controllers'], {
447
- pairSeparator: ', and '
461
+ pairSeparator: ', and ',
448
462
  })
449
463
  // routes, and controllers
450
464
  ```
451
465
 
452
466
  #### condenseWhitespace
467
+
453
468
  Remove multiple whitespaces from a string to a single whitespace.
454
469
 
455
470
  ```ts
@@ -461,6 +476,7 @@ string.condenseWhitespace(' hello world ')
461
476
  ```
462
477
 
463
478
  #### ordinal
479
+
464
480
  Get the ordinal letter for a given number.
465
481
 
466
482
  ```ts
@@ -474,6 +490,7 @@ string.ordinal(24) // '24th'
474
490
  ```
475
491
 
476
492
  #### seconds.(parse/format)
493
+
477
494
  Parse a string-based time expression to seconds.
478
495
 
479
496
  ```ts
@@ -495,6 +512,7 @@ string.seconds.format(36000, true) // 10 hours
495
512
  ```
496
513
 
497
514
  #### milliseconds.(parse/format)
515
+
498
516
  Parse a string-based time expression to milliseconds.
499
517
 
500
518
  ```ts
@@ -516,6 +534,7 @@ string.seconds.format(3.6e6, true) // 1 hour
516
534
  ```
517
535
 
518
536
  #### bytes.(parse/format)
537
+
519
538
  Parse a string-based unit expression to bytes.
520
539
 
521
540
  ```ts
@@ -538,14 +557,17 @@ string.bytes.format(1024 * 1024 * 1000, { thousandsSeparator: ',' }) // 1,000MB
538
557
  ```
539
558
 
540
559
  ### JSON helpers
560
+
541
561
  Following are the helpers we use to `stringify` and `parse` JSON.
542
562
 
543
563
  #### safeParse
564
+
544
565
  The native implementation of `JSON.parse` opens up the possibility for [prototype poisoning](https://medium.com/intrinsic-blog/javascript-prototype-poisoning-vulnerabilities-in-the-wild-7bc15347c96). The `safeParse` method removes the `__proto__` and the `constructor.prototype` properties from the JSON string at the time of parsing it.
545
566
 
546
567
  The method is a wrapper over [secure-json-parse](https://github.com/fastify/secure-json-parse) package.
547
568
 
548
569
  #### safeStringify
570
+
549
571
  The native implementation of `JSON.stringify` cannot handle circular references or language-specific data types like `BigInt`.
550
572
 
551
573
  Therefore, we use the [safe-stable-stringify](https://github.com/BridgeAR/safe-stable-stringify) package under the hood to overcome the limitations of native implementation.
@@ -568,12 +590,13 @@ safeStringify(value)
568
590
  - The circular references are removed from the final JSON string.
569
591
  - The BigInt values are converted to a string.
570
592
 
571
- The `safeStringify` API is the same as the `JSON.stringify` method.
593
+ The `safeStringify` API is the same as the `JSON.stringify` method.
572
594
 
573
595
  - You can pass a replacer function as the second parameter.
574
596
  - And number of spaces as the third parameter.
575
597
 
576
598
  ### Lodash helpers
599
+
577
600
  Lodash is quite a big library, and we do not use all its helper methods. Therefore we create a custom build using the lodash CLI and bundle only the once we need.
578
601
 
579
602
  > **Why not use something else**: All other helpers I have used are not as accurate or well implemented as lodash.
@@ -582,7 +605,7 @@ Lodash is quite a big library, and we do not use all its helper methods. Therefo
582
605
  - omit
583
606
  - has
584
607
  - get
585
- - set
608
+ - set
586
609
  - unset
587
610
  - mergeWith
588
611
  - merge
@@ -600,6 +623,7 @@ lodash.pick(collection, keys)
600
623
  ```
601
624
 
602
625
  ### All other helpers
626
+
603
627
  The following helpers are exported from the package main module.
604
628
 
605
629
  ```ts
@@ -607,6 +631,7 @@ import { base64, compose } from '@poppinss/utils'
607
631
  ```
608
632
 
609
633
  #### base64
634
+
610
635
  Utility methods to base64 encode and decode values.
611
636
 
612
637
  ```ts
@@ -647,16 +672,11 @@ base64.decode('hello world', 'utf-8', true) // raises exception
647
672
  ```
648
673
 
649
674
  #### compose
675
+
650
676
  The `compose` helper allows you to use TypeScript class mixins with a cleaner API. Following is an example of mixins usage without the compose helper.
651
677
 
652
678
  ```ts
653
- class User extends UserWithAttributes(
654
- UserWithAge(
655
- UserWithPassword(
656
- UserWithEmail(BaseModel)
657
- )
658
- )
659
- ) {}
679
+ class User extends UserWithAttributes(UserWithAge(UserWithPassword(UserWithEmail(BaseModel)))) {}
660
680
  ```
661
681
 
662
682
  Following is an example with the `compose` helper.
@@ -677,6 +697,7 @@ class User extends compose(
677
697
  ```
678
698
 
679
699
  #### defineStaticProperty
700
+
680
701
  The `defineStaticProperty` method allows you to define static properties on a class with different reference strategies.
681
702
 
682
703
  If you use class inheritance alongside static properties, then either, you will share properties by reference, or you will define them directly on the parent class.
@@ -722,8 +743,7 @@ class UserModel extends AppModel {
722
743
  The `defineStaticProperty` method abstracts the logic to clone and also performs some interal checks to see if the value is already defined as an `ownProperty` or not.
723
744
 
724
745
  ```ts
725
- class UserModel extends AppModel {
726
- }
746
+ class UserModel extends AppModel {}
727
747
 
728
748
  defineStaticProperty(UserModel, 'columns', {
729
749
  strategy: 'inherit',
@@ -735,8 +755,8 @@ defineStaticProperty(UserModel, 'columns', {
735
755
  - The `define` strategy always re-defines the property, discarding any values on the parent class.
736
756
  - The `strategy` value can be function to perform a custom clone operations.
737
757
 
738
-
739
758
  #### Exception
759
+
740
760
  A custom exception class with support for defining the error status, error code, and help description. This class aims to standardize exceptions within your projects.
741
761
 
742
762
  ```ts
@@ -763,12 +783,11 @@ class ResourceNotFound extends Exception {
763
783
  static message = 'Unable to find resource with id {{ id }}'
764
784
  }
765
785
 
766
- throw new ResourceNotFound(
767
- interpolate(ResourceNotFound.message, { id: 1 })
768
- )
786
+ throw new ResourceNotFound(interpolate(ResourceNotFound.message, { id: 1 }))
769
787
  ```
770
788
 
771
789
  #### flatten
790
+
772
791
  Create a flat object from a nested object/array. The nested keys are combined with a dot-notation (`.`). The method is exported from the [flattie](https://www.npmjs.com/package/flattie) package.
773
792
 
774
793
  ```ts
@@ -788,10 +807,10 @@ flatten({
788
807
  f: [
789
808
  { foo: 123, bar: 123 },
790
809
  { foo: 465, bar: 456 },
791
- ]
792
- }
810
+ ],
811
+ },
793
812
  },
794
- c: 'world'
813
+ c: 'world',
795
814
  })
796
815
 
797
816
  // {
@@ -812,15 +831,13 @@ flatten({
812
831
  ```
813
832
 
814
833
  #### fsReadAll
834
+
815
835
  Get a list of all the files from a directory. The method recursively fetches files from the main and the sub-folders. The dotfiles are ignored implicitly.
816
836
 
817
837
  ```ts
818
838
  import { fsReadAll } from '@poppinss/utils'
819
839
 
820
- const files = await fsReadAll(
821
- new URL('./config', import.meta.url),
822
- { pathType: 'url' }
823
- )
840
+ const files = await fsReadAll(new URL('./config', import.meta.url), { pathType: 'url' })
824
841
  await Promise.all(files.map((file) => import(file)))
825
842
  ```
826
843
 
@@ -838,14 +855,15 @@ const options: Partial<Options> = {}
838
855
  await fsReadAll(location, options)
839
856
  ```
840
857
 
841
- | Argument | Type | Description |
842
- |---------|------|---------------|
843
- | `ignoreMissingRoot` | boolean | By default, an exception is raised when the root directory is missing. Setting `ignoreMissingRoot` to true will not result in an error and an empty array is returned back. |
844
- | `filter` | method | Define a filter to ignore certain paths. The method is called on the final list of files. |
845
- | `sort` | method | Define a custom method to sort file paths. By default, the files are sorted using natural sort. |
846
- | `pathType` | enum | Define how to return the collected paths. By default, OS-specific relative paths are returned. If you want to import the collected files, you must set the `pathType = 'url'` |
858
+ | Argument | Type | Description |
859
+ | ------------------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
860
+ | `ignoreMissingRoot` | boolean | By default, an exception is raised when the root directory is missing. Setting `ignoreMissingRoot` to true will not result in an error and an empty array is returned back. |
861
+ | `filter` | method | Define a filter to ignore certain paths. The method is called on the final list of files. |
862
+ | `sort` | method | Define a custom method to sort file paths. By default, the files are sorted using natural sort. |
863
+ | `pathType` | enum | Define how to return the collected paths. By default, OS-specific relative paths are returned. If you want to import the collected files, you must set the `pathType = 'url'` |
847
864
 
848
865
  #### fsImportAll
866
+
849
867
  The `fsImportAll` method imports all the files recursively from a given directory and set the exported value from each module on an object.
850
868
 
851
869
  ```ts
@@ -861,14 +879,15 @@ console.log(collection)
861
879
 
862
880
  The second param is the options to customize the import behavior.
863
881
 
864
- | Argument | Type | Description |
865
- |---------|------|---------------|
882
+ | Argument | Type | Description |
883
+ | ------------------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
866
884
  | `ignoreMissingRoot` | boolean | By default, an exception is raised when the root directory is missing. Setting `ignoreMissingRoot` to true will not result in an error and an empty object is returned back. |
867
- | `filter` | method | Define a filter to ignore certain paths. By default only files ending with `.js`, `.ts`, `.json`, `.cjs`, and `.mjs` are imported. |
868
- | `sort` | method | Define a custom method to sort file paths. By default, the files are sorted using natural sort. |
869
- | `transformKeys` | method | Define a callback method to transform the keys for the final object. The method receives an array of nested keys and must return an array back. |
885
+ | `filter` | method | Define a filter to ignore certain paths. By default only files ending with `.js`, `.ts`, `.json`, `.cjs`, and `.mjs` are imported. |
886
+ | `sort` | method | Define a custom method to sort file paths. By default, the files are sorted using natural sort. |
887
+ | `transformKeys` | method | Define a callback method to transform the keys for the final object. The method receives an array of nested keys and must return an array back. |
870
888
 
871
889
  #### isScriptFile
890
+
872
891
  A filter to know if the file path ends with `.js`, `.json`, `.cjs`, `.mjs` or `.ts`. In the case of `.ts` files, the `.d.ts` returns false.
873
892
 
874
893
  ```ts
@@ -893,16 +912,19 @@ const options = { pathType: 'url', filter: isScriptFile }
893
912
 
894
913
  const files = await fsReadAll(dir, options)
895
914
 
896
- await Promise.all(files.map((file) => {
897
- if (file.endsWith('.json')) {
898
- return import(file, { assert: { type: 'json' } })
899
- }
915
+ await Promise.all(
916
+ files.map((file) => {
917
+ if (file.endsWith('.json')) {
918
+ return import(file, { assert: { type: 'json' } })
919
+ }
900
920
 
901
- return import(file)
902
- }))
921
+ return import(file)
922
+ })
923
+ )
903
924
  ```
904
925
 
905
926
  #### naturalSort
927
+
906
928
  A sorting function to use natural sort for ordering an array.
907
929
 
908
930
  ```ts
@@ -916,9 +938,10 @@ const values = ['1_foo_bar', '12_foo_bar'].sort(naturalSort)
916
938
  ```
917
939
 
918
940
  #### safeEqual
941
+
919
942
  Check if two buffer or string values are the same. This method does not leak any timing information and prevents [timing attack](https://javascript.plainenglish.io/what-are-timing-attacks-and-how-to-prevent-them-using-nodejs-158cc7e2d70c).
920
943
 
921
- Under the hood, this method uses Node.js [crypto.timeSafeEqual](https://nodejs.org/api/crypto.html#cryptotimingsafeequala-b) method, with support for comparing string values. *(crypto.timeSafeEqual does not support string comparison)*
944
+ Under the hood, this method uses Node.js [crypto.timeSafeEqual](https://nodejs.org/api/crypto.html#cryptotimingsafeequala-b) method, with support for comparing string values. _(crypto.timeSafeEqual does not support string comparison)_
922
945
 
923
946
  ```ts
924
947
  import { safeEqual } from '@poppinss/utils'
@@ -941,6 +964,7 @@ if (safeEqual(trustedValue, userInput)) {
941
964
  ```
942
965
 
943
966
  #### slash
967
+
944
968
  Convert OS-specific file paths to Unix file paths. The method is exported directly from the [slash](https://npm.im/slash) package.
945
969
 
946
970
  ```ts
@@ -949,6 +973,7 @@ slash('foo\\bar') // foo/bar
949
973
  ```
950
974
 
951
975
  #### MessageBuilder
976
+
952
977
  Message builder is a convenience layer to stringify JavaScript values with an expiry date and a purpose. For example:
953
978
 
954
979
  ```ts
@@ -994,6 +1019,7 @@ const decoded = builder.verify(value, 'reset_password')
994
1019
  ```
995
1020
 
996
1021
  #### ObjectBuilder
1022
+
997
1023
  The `ObjectBuilder` is a convenience class to create an object with dynamic properties. Consider the following example, where we wrap our code inside conditionals before adding the property `b` to the `startingObject`.
998
1024
 
999
1025
  ```ts
@@ -1040,6 +1066,7 @@ builder.toObject() // get plain object
1040
1066
  ```
1041
1067
 
1042
1068
  #### dirname/filename
1069
+
1043
1070
  ES modules does not have magic variables `__filename` and `__dirname`. You can use these helpers to get the current directory and filenames as follows.
1044
1071
 
1045
1072
  ```ts
@@ -1050,16 +1077,12 @@ const filename = getFilename(import.meta.url)
1050
1077
  ```
1051
1078
 
1052
1079
  [gh-workflow-image]: https://img.shields.io/github/workflow/status/poppinss/utils/test?style=for-the-badge
1053
- [gh-workflow-url]: https://github.com/poppinss/utils/actions/workflows/test.yml "Github action"
1054
-
1080
+ [gh-workflow-url]: https://github.com/poppinss/utils/actions/workflows/test.yml 'Github action'
1055
1081
  [typescript-image]: https://img.shields.io/badge/Typescript-294E80.svg?style=for-the-badge&logo=typescript
1056
1082
  [typescript-url]: "typescript"
1057
-
1058
1083
  [npm-image]: https://img.shields.io/npm/v/@poppinss/utils.svg?style=for-the-badge&logo=npm
1059
1084
  [npm-url]: https://npmjs.org/package/@poppinss/utils 'npm'
1060
-
1061
1085
  [license-image]: https://img.shields.io/npm/l/@poppinss/utils?color=blueviolet&style=for-the-badge
1062
1086
  [license-url]: LICENSE.md 'license'
1063
-
1064
1087
  [synk-image]: https://img.shields.io/snyk/vulnerabilities/github/poppinss/utils?label=Synk%20Vulnerabilities&style=for-the-badge
1065
1088
  [synk-url]: https://snyk.io/test/github/poppinss/utils?targetFile=package.json 'synk'
@@ -11,6 +11,6 @@ export declare class Exception extends Error {
11
11
  code?: string;
12
12
  status?: number;
13
13
  });
14
- [Symbol.toStringTag](): string;
14
+ get [Symbol.toStringTag](): string;
15
15
  toString(): string;
16
16
  }
@@ -17,7 +17,7 @@ export class Exception extends Error {
17
17
  }
18
18
  Error.captureStackTrace(this, ErrorConstructor);
19
19
  }
20
- [Symbol.toStringTag]() {
20
+ get [Symbol.toStringTag]() {
21
21
  return this.constructor.name;
22
22
  }
23
23
  toString() {
@@ -16,9 +16,9 @@ async function readFiles(root, files, options, relativePath) {
16
16
  }));
17
17
  return;
18
18
  }
19
- switch (options.pathType) {
19
+ const pathType = options.pathType || 'relative';
20
+ switch (pathType) {
20
21
  case 'relative':
21
- default:
22
22
  files.push(relativePath);
23
23
  break;
24
24
  case 'absolute':
@@ -1,7 +1,7 @@
1
1
  import { safeParse } from './safe_parse.js';
2
2
  import { safeStringify } from './safe_stringify.js';
3
- declare const _default: {
3
+ declare const json: {
4
4
  safeParse: typeof safeParse;
5
5
  safeStringify: typeof safeStringify;
6
6
  };
7
- export default _default;
7
+ export default json;
@@ -1,6 +1,7 @@
1
1
  import { safeParse } from './safe_parse.js';
2
2
  import { safeStringify } from './safe_stringify.js';
3
- export default {
3
+ const json = {
4
4
  safeParse,
5
5
  safeStringify,
6
6
  };
7
+ export default json;
@@ -1,2 +1,2 @@
1
1
  import { JSONReplacer } from '../types.js';
2
- export declare function safeStringify(value: any, replacer?: JSONReplacer, space?: string | number): string;
2
+ export declare function safeStringify(value: any, replacer?: JSONReplacer, space?: string | number): string | undefined;
@@ -12,13 +12,8 @@ export class MessageBuilder {
12
12
  if (!message.expiryDate) {
13
13
  return false;
14
14
  }
15
- try {
16
- const expiryDate = new Date(message.expiryDate);
17
- return Number.isNaN(expiryDate.getTime()) || expiryDate < new Date();
18
- }
19
- catch (error) {
20
- return true;
21
- }
15
+ const expiryDate = new Date(message.expiryDate);
16
+ return Number.isNaN(expiryDate.getTime()) || expiryDate < new Date();
22
17
  }
23
18
  build(message, expiresIn, purpose) {
24
19
  const expiryDate = this.#getExpiryDate(expiresIn);
@@ -26,7 +21,7 @@ export class MessageBuilder {
26
21
  }
27
22
  verify(message, purpose) {
28
23
  const parsed = json.safeParse(message);
29
- if (parsed === message) {
24
+ if (typeof parsed !== 'object' || !parsed) {
30
25
  return null;
31
26
  }
32
27
  if (!parsed.message) {
@@ -1,9 +1,3 @@
1
- function uncurryThis(fn) {
2
- return function (...args) {
3
- return Function.call.apply(fn, args);
4
- };
5
- }
6
- const hasOwnProperty = uncurryThis(Object.prototype.hasOwnProperty);
7
1
  function parseProp(data, key) {
8
2
  const tokens = key.split('.');
9
3
  while (tokens.length) {
@@ -11,7 +5,7 @@ function parseProp(data, key) {
11
5
  return;
12
6
  }
13
7
  const token = tokens.shift();
14
- data = hasOwnProperty(data, token) ? data[token] : undefined;
8
+ data = Object.hasOwn(data, token) ? data[token] : undefined;
15
9
  }
16
10
  return data;
17
11
  }
@@ -2,12 +2,12 @@ import { random } from './random.js';
2
2
  import { excerpt } from './excerpt.js';
3
3
  import { ordinal } from './ordinal.js';
4
4
  import { truncate } from './truncate.js';
5
- import { toSentence } from './to_sentence.js';
5
+ import { sentence } from './sentence.js';
6
6
  import { interpolate } from './interpolate.js';
7
7
  import { pluralize } from './pluralize.js';
8
8
  import { noCase, dotCase, dashCase, camelCase, snakeCase, titleCase, pascalCase, capitalCase, sentenceCase } from './change_case.js';
9
9
  declare function condenseWhitespace(value: string): string;
10
- declare const _default: {
10
+ declare const string: {
11
11
  excerpt: typeof excerpt;
12
12
  truncate: typeof truncate;
13
13
  slug: typeof import("slugify").default;
@@ -27,7 +27,7 @@ declare const _default: {
27
27
  snakeCase: typeof snakeCase;
28
28
  titleCase: typeof titleCase;
29
29
  random: typeof random;
30
- toSentence: typeof toSentence;
30
+ sentence: typeof sentence;
31
31
  condenseWhitespace: typeof condenseWhitespace;
32
32
  seconds: {
33
33
  format(seconds: number, long?: boolean | undefined): string;
@@ -43,4 +43,4 @@ declare const _default: {
43
43
  };
44
44
  ordinal: typeof ordinal;
45
45
  };
46
- export default _default;
46
+ export default string;
@@ -6,14 +6,14 @@ import { excerpt } from './excerpt.js';
6
6
  import { ordinal } from './ordinal.js';
7
7
  import { truncate } from './truncate.js';
8
8
  import milliseconds from './milliseconds.js';
9
- import { toSentence } from './to_sentence.js';
9
+ import { sentence } from './sentence.js';
10
10
  import { interpolate } from './interpolate.js';
11
11
  import { plural, pluralize, singular, isPlural, isSingular } from './pluralize.js';
12
12
  import { noCase, dotCase, dashCase, camelCase, snakeCase, titleCase, pascalCase, capitalCase, sentenceCase, } from './change_case.js';
13
13
  function condenseWhitespace(value) {
14
14
  return value.trim().replace(/\s{2,}/g, ' ');
15
15
  }
16
- export default {
16
+ const string = {
17
17
  excerpt,
18
18
  truncate,
19
19
  slug,
@@ -33,10 +33,11 @@ export default {
33
33
  snakeCase,
34
34
  titleCase,
35
35
  random,
36
- toSentence,
36
+ sentence,
37
37
  condenseWhitespace,
38
38
  seconds,
39
39
  milliseconds,
40
40
  bytes,
41
41
  ordinal,
42
42
  };
43
+ export default string;
@@ -8,7 +8,7 @@ export default {
8
8
  return duration;
9
9
  }
10
10
  const milliseconds = parse(duration);
11
- if (!milliseconds) {
11
+ if (milliseconds === undefined) {
12
12
  throw new Error(`Invalid duration expression "${duration}"`);
13
13
  }
14
14
  return milliseconds;
@@ -8,7 +8,7 @@ export default {
8
8
  return duration;
9
9
  }
10
10
  const milliseconds = parse(duration);
11
- if (!milliseconds) {
11
+ if (milliseconds === undefined) {
12
12
  throw new Error(`Invalid duration expression "${duration}"`);
13
13
  }
14
14
  return Math.floor(milliseconds / 1000);
@@ -1,4 +1,4 @@
1
- export declare function toSentence(values: any[], options?: {
1
+ export declare function sentence(values: any[], options?: {
2
2
  separator?: string;
3
3
  pairSeparator?: string;
4
4
  lastSeparator?: string;
@@ -1,4 +1,4 @@
1
- export function toSentence(values, options) {
1
+ export function sentence(values, options) {
2
2
  if (values.length === 0) {
3
3
  return '';
4
4
  }
package/package.json CHANGED
@@ -1,139 +1,150 @@
1
1
  {
2
- "name": "@poppinss/utils",
3
- "version": "6.0.0-0",
4
- "description": "Handy utilities for repetitive work",
5
- "main": "build/index.js",
6
- "type": "module",
7
- "files": [
8
- "build/src",
9
- "lodash",
10
- "build/lodash",
11
- "build/index.d.ts",
12
- "build/index.js"
13
- ],
14
- "exports": {
15
- ".": "./build/index.js",
16
- "./lodash": {
17
- "types": "./lodash/lodash.types.d.ts",
18
- "node": "./build/lodash/main.cjs"
19
- },
20
- "./string": "./build/src/string/main.js",
21
- "./json": "./build/src/json/main.js",
22
- "./types": "./build/src/types.js"
23
- },
24
- "scripts": {
25
- "pretest": "npm run lint",
26
- "test": "npm run build:lodash && npm run vscode:test",
27
- "build:lodash": "lodash include=\"pick,omit,has,get,set,unset,mergeWith,merge,size,clone,cloneDeep,toPath\" --production && move-file ./lodash.custom.min.js build/lodash/main.cjs",
28
- "vscode:test": "node --loader=ts-node/esm bin/test.ts",
29
- "clean": "del-cli build",
30
- "compile": "npm run lint && npm run clean && tsc",
31
- "build": "npm run compile && npm run build:lodash",
32
- "release": "np",
33
- "version": "npm run build",
34
- "prepublishOnly": "npm run build && cd build && node bin/test.js",
35
- "lint": "eslint . --ext=.ts",
36
- "format": "prettier --write .",
37
- "sync-labels": "github-label-sync --labels .github/labels.json poppinss/utils"
38
- },
39
- "keywords": [
40
- "toolkit",
41
- "utilities"
42
- ],
43
- "author": "virk,poppinss",
44
- "license": "MIT",
45
- "devDependencies": {
46
- "@commitlint/cli": "^17.1.2",
47
- "@commitlint/config-conventional": "^17.1.0",
48
- "@japa/assert": "^1.3.6",
49
- "@japa/expect-type": "^1.0.1",
50
- "@japa/run-failed-tests": "^1.1.0",
51
- "@japa/runner": "^2.2.1",
52
- "@japa/spec-reporter": "^1.3.1",
53
- "@swc/core": "^1.3.3",
54
- "@types/fs-extra": "^9.0.13",
55
- "@types/node": "^18.7.19",
56
- "del-cli": "^5.0.0",
57
- "eslint": "^8.24.0",
58
- "eslint-config-prettier": "^8.5.0",
59
- "eslint-plugin-adonis": "^3.0.2",
60
- "eslint-plugin-prettier": "^4.2.1",
61
- "fs-extra": "^10.1.0",
62
- "github-label-sync": "^2.2.0",
63
- "husky": "^8.0.1",
64
- "lodash": "^4.17.21",
65
- "lodash-cli": "^4.17.5",
66
- "move-file-cli": "^3.0.0",
67
- "np": "^7.6.2",
68
- "prettier": "^2.7.1",
69
- "ts-node": "^10.9.1",
70
- "typescript": "^4.8.3"
71
- },
72
- "dependencies": {
73
- "@lukeed/ms": "^2.0.0",
74
- "@types/bytes": "^3.1.1",
75
- "@types/pluralize": "^0.0.29",
76
- "bytes": "^3.1.2",
77
- "case-anything": "^2.1.10",
78
- "flattie": "^1.1.0",
79
- "pluralize": "^8.0.0",
80
- "safe-stable-stringify": "^2.4.0",
81
- "secure-json-parse": "^2.5.0",
82
- "slash": "^4.0.0",
83
- "slugify": "^1.6.5",
84
- "truncatise": "^0.0.8"
85
- },
86
- "repository": {
87
- "type": "git",
88
- "url": "git+https://github.com/poppinss/utils.git"
89
- },
90
- "bugs": {
91
- "url": "https://github.com/poppinss/utils/issues"
92
- },
93
- "homepage": "https://github.com/poppinss/utils#readme",
94
- "eslintConfig": {
95
- "extends": [
96
- "plugin:adonis/typescriptPackage",
97
- "prettier"
98
- ],
99
- "plugins": [
100
- "prettier"
101
- ],
102
- "rules": {
103
- "prettier/prettier": [
104
- "error",
105
- {
106
- "endOfLine": "auto"
107
- }
108
- ]
109
- }
110
- },
111
- "eslintIgnore": [
112
- "build"
113
- ],
114
- "prettier": {
115
- "trailingComma": "es5",
116
- "semi": false,
117
- "singleQuote": true,
118
- "useTabs": false,
119
- "quoteProps": "consistent",
120
- "bracketSpacing": true,
121
- "arrowParens": "always",
122
- "printWidth": 100
123
- },
124
- "commitlint": {
125
- "extends": [
126
- "@commitlint/config-conventional"
127
- ]
128
- },
129
- "publishConfig": {
130
- "access": "public",
131
- "tag": "next"
132
- },
133
- "np": {
134
- "message": "chore(release): %s",
135
- "tag": "next",
136
- "branch": "main",
137
- "anyBranch": false
138
- }
2
+ "name": "@poppinss/utils",
3
+ "version": "6.0.0-2",
4
+ "description": "Handy utilities for repetitive work",
5
+ "main": "build/index.js",
6
+ "type": "module",
7
+ "files": [
8
+ "build/src",
9
+ "lodash",
10
+ "build/lodash",
11
+ "build/index.d.ts",
12
+ "build/index.js"
13
+ ],
14
+ "exports": {
15
+ ".": "./build/index.js",
16
+ "./lodash": {
17
+ "types": "./lodash/lodash.types.d.ts",
18
+ "node": "./build/lodash/main.cjs"
19
+ },
20
+ "./string": "./build/src/string/main.js",
21
+ "./json": "./build/src/json/main.js",
22
+ "./types": "./build/src/types.js"
23
+ },
24
+ "scripts": {
25
+ "pretest": "npm run lint",
26
+ "test": "npm run build:lodash && c8 npm run vscode:test",
27
+ "build:lodash": "lodash include=\"pick,omit,has,get,set,unset,mergeWith,merge,size,clone,cloneDeep,toPath\" --production && move-file ./lodash.custom.min.js build/lodash/main.cjs",
28
+ "vscode:test": "node --loader=ts-node/esm bin/test.ts",
29
+ "clean": "del-cli build",
30
+ "compile": "npm run lint && npm run clean && tsc",
31
+ "build": "npm run compile && npm run build:lodash",
32
+ "release": "np",
33
+ "version": "npm run build",
34
+ "prepublishOnly": "npm run build && cd build && node bin/test.js",
35
+ "lint": "eslint . --ext=.ts",
36
+ "format": "prettier --write .",
37
+ "sync-labels": "github-label-sync --labels .github/labels.json poppinss/utils"
38
+ },
39
+ "c8": {
40
+ "reporter": [
41
+ "text",
42
+ "html"
43
+ ],
44
+ "exclude": [
45
+ "**/build/lodash/**",
46
+ "tests/**"
47
+ ]
48
+ },
49
+ "keywords": [
50
+ "toolkit",
51
+ "utilities"
52
+ ],
53
+ "author": "virk,poppinss",
54
+ "license": "MIT",
55
+ "devDependencies": {
56
+ "@commitlint/cli": "^17.1.2",
57
+ "@commitlint/config-conventional": "^17.1.0",
58
+ "@japa/assert": "^1.3.6",
59
+ "@japa/expect-type": "^1.0.2",
60
+ "@japa/run-failed-tests": "^1.1.0",
61
+ "@japa/runner": "^2.2.2",
62
+ "@japa/spec-reporter": "^1.3.2",
63
+ "@swc/core": "^1.3.10",
64
+ "@types/fs-extra": "^9.0.13",
65
+ "@types/node": "^18.11.3",
66
+ "c8": "^7.12.0",
67
+ "del-cli": "^5.0.0",
68
+ "eslint": "^8.26.0",
69
+ "eslint-config-prettier": "^8.5.0",
70
+ "eslint-plugin-adonis": "^3.0.3",
71
+ "eslint-plugin-prettier": "^4.2.1",
72
+ "fs-extra": "^10.1.0",
73
+ "github-label-sync": "^2.2.0",
74
+ "husky": "^8.0.1",
75
+ "lodash": "^4.17.21",
76
+ "lodash-cli": "^4.17.5",
77
+ "move-file-cli": "^3.0.0",
78
+ "np": "^7.6.2",
79
+ "prettier": "^2.7.1",
80
+ "ts-node": "^10.9.1",
81
+ "typescript": "^4.8.3"
82
+ },
83
+ "dependencies": {
84
+ "@lukeed/ms": "^2.0.0",
85
+ "@types/bytes": "^3.1.1",
86
+ "@types/pluralize": "^0.0.29",
87
+ "bytes": "^3.1.2",
88
+ "case-anything": "^2.1.10",
89
+ "flattie": "^1.1.0",
90
+ "pluralize": "^8.0.0",
91
+ "safe-stable-stringify": "^2.4.1",
92
+ "secure-json-parse": "^2.5.0",
93
+ "slash": "^5.0.0",
94
+ "slugify": "^1.6.5",
95
+ "truncatise": "^0.0.8"
96
+ },
97
+ "repository": {
98
+ "type": "git",
99
+ "url": "git+https://github.com/poppinss/utils.git"
100
+ },
101
+ "bugs": {
102
+ "url": "https://github.com/poppinss/utils/issues"
103
+ },
104
+ "homepage": "https://github.com/poppinss/utils#readme",
105
+ "eslintConfig": {
106
+ "extends": [
107
+ "plugin:adonis/typescriptPackage",
108
+ "prettier"
109
+ ],
110
+ "plugins": [
111
+ "prettier"
112
+ ],
113
+ "rules": {
114
+ "prettier/prettier": [
115
+ "error",
116
+ {
117
+ "endOfLine": "auto"
118
+ }
119
+ ]
120
+ }
121
+ },
122
+ "eslintIgnore": [
123
+ "build"
124
+ ],
125
+ "prettier": {
126
+ "trailingComma": "es5",
127
+ "semi": false,
128
+ "singleQuote": true,
129
+ "useTabs": false,
130
+ "quoteProps": "consistent",
131
+ "bracketSpacing": true,
132
+ "arrowParens": "always",
133
+ "printWidth": 100
134
+ },
135
+ "commitlint": {
136
+ "extends": [
137
+ "@commitlint/config-conventional"
138
+ ]
139
+ },
140
+ "publishConfig": {
141
+ "access": "public",
142
+ "tag": "next"
143
+ },
144
+ "np": {
145
+ "message": "chore(release): %s",
146
+ "tag": "next",
147
+ "branch": "main",
148
+ "anyBranch": false
149
+ }
139
150
  }