@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 +187 -164
- package/build/src/exception.d.ts +1 -1
- package/build/src/exception.js +1 -1
- package/build/src/fs_read_all.js +2 -2
- package/build/src/json/main.d.ts +2 -2
- package/build/src/json/main.js +2 -1
- package/build/src/json/safe_stringify.d.ts +1 -1
- package/build/src/message_builder.js +3 -8
- package/build/src/string/interpolate.js +1 -7
- package/build/src/string/main.d.ts +4 -4
- package/build/src/string/main.js +4 -3
- package/build/src/string/milliseconds.js +1 -1
- package/build/src/string/seconds.js +1 -1
- package/build/src/string/{to_sentence.d.ts → sentence.d.ts} +1 -1
- package/build/src/string/{to_sentence.js → sentence.js} +1 -1
- package/package.json +148 -137
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
|
|
26
|
-
|
|
27
|
-
| [he](https://www.npmjs.com/package/he)
|
|
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
|
|
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
|
|
87
|
-
|
|
88
|
-
| `sentence`
|
|
89
|
-
| `charactersLimit`
|
|
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`
|
|
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
|
|
104
|
-
|
|
105
|
-
| `sentence`
|
|
106
|
-
| `charactersLimit`
|
|
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`
|
|
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
|
|
220
|
-
|
|
221
|
-
| 'test'
|
|
222
|
-
| 'test string'
|
|
223
|
-
| 'Test String'
|
|
224
|
-
| 'TestV2'
|
|
225
|
-
| '_foo_bar_'
|
|
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
|
|
239
|
-
|
|
240
|
-
| 'test'
|
|
241
|
-
| 'test string'
|
|
242
|
-
| 'Test String'
|
|
243
|
-
| 'TestV2'
|
|
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
|
|
263
|
-
|
|
264
|
-
| 'test'
|
|
265
|
-
| 'test string'
|
|
266
|
-
| 'Test String'
|
|
267
|
-
| 'Test V2'
|
|
268
|
-
| 'TestV2'
|
|
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
|
|
288
|
-
|
|
289
|
-
| 'test'
|
|
290
|
-
| 'test string'
|
|
291
|
-
| 'Test String'
|
|
292
|
-
| 'dot.case'
|
|
293
|
-
| 'path/case'
|
|
294
|
-
| 'TestV2'
|
|
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
|
|
308
|
-
|
|
309
|
-
| 'test'
|
|
310
|
-
| 'TEST'
|
|
311
|
-
| 'testString'
|
|
312
|
-
| 'testString123'
|
|
313
|
-
| 'testString_1_2_3'
|
|
314
|
-
| 'ID123String'
|
|
315
|
-
| 'foo bar123'
|
|
316
|
-
| 'a1bStar'
|
|
317
|
-
| 'CONSTANT_CASE '
|
|
318
|
-
| 'CONST123_FOO'
|
|
319
|
-
| 'FOO_bar'
|
|
320
|
-
| 'XMLHttpRequest'
|
|
321
|
-
| 'IQueryAArgs'
|
|
322
|
-
| 'dot.case'
|
|
323
|
-
| 'path/case'
|
|
324
|
-
| 'snake_case'
|
|
325
|
-
| 'snake_case123'
|
|
326
|
-
| 'snake_case_123'
|
|
327
|
-
| '"quotes"'
|
|
328
|
-
| 'version 0.45.0'
|
|
329
|
-
| 'version 0..78..9'
|
|
330
|
-
| 'version 4_99/4'
|
|
331
|
-
| '
|
|
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'
|
|
334
|
-
| '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
|
|
346
|
-
|
|
347
|
-
| 'test'
|
|
348
|
-
| 'test string'
|
|
349
|
-
| 'Test String'
|
|
350
|
-
| '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
|
|
365
|
-
|
|
366
|
-
| 'test'
|
|
367
|
-
| 'test string'
|
|
368
|
-
| 'Test String'
|
|
369
|
-
| 'TestV2'
|
|
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
|
|
383
|
-
|
|
384
|
-
| '_id'
|
|
385
|
-
| 'test'
|
|
386
|
-
| 'test string'
|
|
387
|
-
| 'Test String'
|
|
388
|
-
| 'Test V2'
|
|
389
|
-
| 'TestV2'
|
|
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
|
|
404
|
-
|
|
405
|
-
| 'one. two.'
|
|
406
|
-
| 'a small word starts'
|
|
407
|
-
| 'small word ends on'
|
|
408
|
-
| 'we keep NASA capitalized'
|
|
409
|
-
| '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'
|
|
412
|
-
| 'this vs that'
|
|
413
|
-
| 'newcastle upon tyne'
|
|
414
|
-
| '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
|
-
|
|
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
|
|
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`
|
|
845
|
-
| `sort`
|
|
846
|
-
| `pathType`
|
|
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
|
|
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`
|
|
868
|
-
| `sort`
|
|
869
|
-
| `transformKeys`
|
|
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(
|
|
897
|
-
|
|
898
|
-
|
|
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
|
-
|
|
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.
|
|
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
|
|
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'
|
package/build/src/exception.d.ts
CHANGED
package/build/src/exception.js
CHANGED
package/build/src/fs_read_all.js
CHANGED
|
@@ -16,9 +16,9 @@ async function readFiles(root, files, options, relativePath) {
|
|
|
16
16
|
}));
|
|
17
17
|
return;
|
|
18
18
|
}
|
|
19
|
-
|
|
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':
|
package/build/src/json/main.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { safeParse } from './safe_parse.js';
|
|
2
2
|
import { safeStringify } from './safe_stringify.js';
|
|
3
|
-
declare const
|
|
3
|
+
declare const json: {
|
|
4
4
|
safeParse: typeof safeParse;
|
|
5
5
|
safeStringify: typeof safeStringify;
|
|
6
6
|
};
|
|
7
|
-
export default
|
|
7
|
+
export default json;
|
package/build/src/json/main.js
CHANGED
|
@@ -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
|
-
|
|
16
|
-
|
|
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
|
|
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 =
|
|
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 {
|
|
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
|
|
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
|
-
|
|
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
|
|
46
|
+
export default string;
|
package/build/src/string/main.js
CHANGED
|
@@ -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 {
|
|
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
|
-
|
|
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
|
-
|
|
36
|
+
sentence,
|
|
37
37
|
condenseWhitespace,
|
|
38
38
|
seconds,
|
|
39
39
|
milliseconds,
|
|
40
40
|
bytes,
|
|
41
41
|
ordinal,
|
|
42
42
|
};
|
|
43
|
+
export default string;
|
package/package.json
CHANGED
|
@@ -1,139 +1,150 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
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
|
}
|