@ooneex/utils 0.0.6 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +539 -203
- package/dist/index.d.ts +24 -16
- package/dist/index.js +3 -1
- package/dist/index.js.map +25 -0
- package/package.json +22 -14
- package/dist/capitalizeWord.d.ts +0 -2
- package/dist/capitalizeWord.d.ts.map +0 -1
- package/dist/dataURLtoFile.d.ts +0 -2
- package/dist/dataURLtoFile.d.ts.map +0 -1
- package/dist/formatRelativeNumber.d.ts +0 -5
- package/dist/formatRelativeNumber.d.ts.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/millisecondsToHMS.d.ts +0 -2
- package/dist/millisecondsToHMS.d.ts.map +0 -1
- package/dist/parseEnvVars.d.ts +0 -2
- package/dist/parseEnvVars.d.ts.map +0 -1
- package/dist/parseString.d.ts +0 -2
- package/dist/parseString.d.ts.map +0 -1
- package/dist/random.d.ts +0 -6
- package/dist/random.d.ts.map +0 -1
- package/dist/secondsToHMS.d.ts +0 -2
- package/dist/secondsToHMS.d.ts.map +0 -1
- package/dist/secondsToMS.d.ts +0 -2
- package/dist/secondsToMS.d.ts.map +0 -1
- package/dist/sleep.d.ts +0 -2
- package/dist/sleep.d.ts.map +0 -1
- package/dist/splitToWords.d.ts +0 -2
- package/dist/splitToWords.d.ts.map +0 -1
- package/dist/toCamelCase.d.ts +0 -2
- package/dist/toCamelCase.d.ts.map +0 -1
- package/dist/toKebabCase.d.ts +0 -2
- package/dist/toKebabCase.d.ts.map +0 -1
- package/dist/toPascalCase.d.ts +0 -2
- package/dist/toPascalCase.d.ts.map +0 -1
- package/dist/trim.d.ts +0 -2
- package/dist/trim.d.ts.map +0 -1
- package/src/capitalizeWord.ts +0 -3
- package/src/dataURLtoFile.ts +0 -12
- package/src/formatRelativeNumber.ts +0 -7
- package/src/index.ts +0 -15
- package/src/millisecondsToHMS.ts +0 -16
- package/src/parseEnvVars.ts +0 -14
- package/src/parseString.ts +0 -47
- package/src/random.ts +0 -13
- package/src/secondsToHMS.ts +0 -16
- package/src/secondsToMS.ts +0 -5
- package/src/sleep.ts +0 -3
- package/src/splitToWords.ts +0 -14
- package/src/toCamelCase.ts +0 -8
- package/src/toKebabCase.ts +0 -6
- package/src/toPascalCase.ts +0 -7
- package/src/trim.ts +0 -8
- package/tests/capitalizeWord.spec.ts +0 -163
- package/tests/dataURLtoFile.spec.ts +0 -472
- package/tests/formatRelativeNumber.spec.ts +0 -303
- package/tests/millisecondsToHMS.spec.ts +0 -209
- package/tests/parseEnvVars.spec.ts +0 -468
- package/tests/parseString.spec.ts +0 -377
- package/tests/random.spec.ts +0 -422
- package/tests/secondsToHMS.spec.ts +0 -341
- package/tests/secondsToMS.spec.ts +0 -467
- package/tests/splitToWords.spec.ts +0 -359
- package/tests/toCamelCase.spec.ts +0 -526
- package/tests/toKebabCase.spec.ts +0 -664
- package/tests/toPascalCase.spec.ts +0 -721
- package/tests/trim.spec.ts +0 -486
- package/tsconfig.build.json +0 -14
- package/tsconfig.json +0 -11
package/README.md
CHANGED
|
@@ -1,335 +1,671 @@
|
|
|
1
1
|
# @ooneex/utils
|
|
2
2
|
|
|
3
|
-
A comprehensive
|
|
3
|
+
A comprehensive TypeScript/JavaScript utility library providing essential helper functions for string manipulation, time formatting, data parsing, and more. This package offers a collection of lightweight, type-safe utilities designed to streamline common development tasks across web applications.
|
|
4
|
+
|
|
5
|
+

|
|
6
|
+

|
|
7
|
+

|
|
8
|
+

|
|
9
|
+

|
|
10
|
+

|
|
11
|
+
|
|
12
|
+
## Features
|
|
13
|
+
|
|
14
|
+
✅ **String Manipulation** - Case conversion utilities (camelCase, PascalCase, kebab-case)
|
|
15
|
+
|
|
16
|
+
✅ **Time Formatting** - Convert seconds/milliseconds to human-readable formats
|
|
17
|
+
|
|
18
|
+
✅ **Data Parsing** - Intelligent string parsing with type inference
|
|
19
|
+
|
|
20
|
+
✅ **Type-Safe** - Full TypeScript support with proper type definitions
|
|
21
|
+
|
|
22
|
+
✅ **Lightweight** - Minimal dependencies and optimized bundle size
|
|
23
|
+
|
|
24
|
+
✅ **Cross-Platform** - Works in Browser, Node.js, Bun, and Deno
|
|
25
|
+
|
|
26
|
+
✅ **Environment Variables** - Parse and transform environment variables
|
|
27
|
+
|
|
28
|
+
✅ **File Utilities** - Convert data URLs to File objects
|
|
29
|
+
|
|
30
|
+
✅ **Random Generation** - Generate random IDs and strings
|
|
31
|
+
|
|
32
|
+
✅ **Number Formatting** - Format numbers with locale-aware compact notation
|
|
33
|
+
|
|
34
|
+
✅ **Zero Dependencies** - Only one small dependency (nanoid) for random generation
|
|
4
35
|
|
|
5
36
|
## Installation
|
|
6
37
|
|
|
38
|
+
### Bun
|
|
7
39
|
```bash
|
|
8
|
-
npm install @ooneex/utils
|
|
9
|
-
# or
|
|
10
40
|
bun add @ooneex/utils
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### pnpm
|
|
44
|
+
```bash
|
|
14
45
|
pnpm add @ooneex/utils
|
|
15
46
|
```
|
|
16
47
|
|
|
48
|
+
### Yarn
|
|
49
|
+
```bash
|
|
50
|
+
yarn add @ooneex/utils
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### npm
|
|
54
|
+
```bash
|
|
55
|
+
npm install @ooneex/utils
|
|
56
|
+
```
|
|
57
|
+
|
|
17
58
|
## Usage
|
|
18
59
|
|
|
60
|
+
### String Manipulation
|
|
61
|
+
|
|
19
62
|
```typescript
|
|
20
|
-
import {
|
|
63
|
+
import {
|
|
64
|
+
capitalizeWord,
|
|
65
|
+
toCamelCase,
|
|
66
|
+
toPascalCase,
|
|
67
|
+
toKebabCase,
|
|
68
|
+
splitToWords,
|
|
69
|
+
trim
|
|
70
|
+
} from '@ooneex/utils';
|
|
71
|
+
|
|
72
|
+
// Capitalize words
|
|
73
|
+
console.log(capitalizeWord('hello')); // 'Hello'
|
|
74
|
+
console.log(capitalizeWord('WORLD')); // 'World'
|
|
75
|
+
|
|
76
|
+
// Case conversions
|
|
77
|
+
console.log(toCamelCase('hello world')); // 'helloWorld'
|
|
78
|
+
console.log(toPascalCase('hello world')); // 'HelloWorld'
|
|
79
|
+
console.log(toKebabCase('Hello World')); // 'hello-world'
|
|
80
|
+
|
|
81
|
+
// Split strings to words
|
|
82
|
+
console.log(splitToWords('HelloWorldExample')); // ['Hello', 'World', 'Example']
|
|
83
|
+
console.log(splitToWords('hello-world_example')); // ['hello', 'world', 'example']
|
|
84
|
+
|
|
85
|
+
// Advanced trimming
|
|
86
|
+
console.log(trim('...hello...', '\\.')); // 'hello'
|
|
87
|
+
console.log(trim('[test]', '\\[|\\]')); // 'test'
|
|
21
88
|
```
|
|
22
89
|
|
|
23
|
-
|
|
90
|
+
### Time Formatting
|
|
24
91
|
|
|
25
|
-
|
|
92
|
+
```typescript
|
|
93
|
+
import {
|
|
94
|
+
secondsToHMS,
|
|
95
|
+
secondsToMS,
|
|
96
|
+
millisecondsToHMS,
|
|
97
|
+
sleep
|
|
98
|
+
} from '@ooneex/utils';
|
|
99
|
+
|
|
100
|
+
// Convert seconds to time formats
|
|
101
|
+
console.log(secondsToHMS(3661)); // '1:01:01'
|
|
102
|
+
console.log(secondsToHMS(125)); // '2:05'
|
|
103
|
+
console.log(secondsToHMS(45)); // '45'
|
|
104
|
+
|
|
105
|
+
console.log(secondsToMS(125)); // '2:05'
|
|
106
|
+
console.log(secondsToMS(45)); // '0:45'
|
|
107
|
+
|
|
108
|
+
// Convert milliseconds to time format
|
|
109
|
+
console.log(millisecondsToHMS(3661000)); // '1:01:01'
|
|
110
|
+
console.log(millisecondsToHMS(125000)); // '2:05'
|
|
111
|
+
|
|
112
|
+
// Async sleep utility
|
|
113
|
+
await sleep(1000); // Wait 1 second
|
|
114
|
+
```
|
|
26
115
|
|
|
27
|
-
|
|
116
|
+
### Data Parsing
|
|
28
117
|
|
|
29
|
-
|
|
118
|
+
```typescript
|
|
119
|
+
import { parseString, parseEnvVars } from '@ooneex/utils';
|
|
120
|
+
|
|
121
|
+
// Intelligent string parsing with type inference
|
|
122
|
+
console.log(parseString('123')); // 123 (number)
|
|
123
|
+
console.log(parseString('12.34')); // 12.34 (number)
|
|
124
|
+
console.log(parseString('true')); // true (boolean)
|
|
125
|
+
console.log(parseString('false')); // false (boolean)
|
|
126
|
+
console.log(parseString('null')); // null
|
|
127
|
+
console.log(parseString('[1,2,3]')); // [1, 2, 3] (array)
|
|
128
|
+
console.log(parseString('{"name":"John"}')); // {name: "John"} (object)
|
|
129
|
+
console.log(parseString('1e5')); // 100000 (scientific notation)
|
|
130
|
+
console.log(parseString('hello')); // 'hello' (string fallback)
|
|
131
|
+
|
|
132
|
+
// Parse environment variables
|
|
133
|
+
const envs = {
|
|
134
|
+
'API_PORT': '3000',
|
|
135
|
+
'DEBUG_MODE': 'true',
|
|
136
|
+
'ALLOWED_HOSTS': '["localhost", "127.0.0.1"]'
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
const parsed = parseEnvVars(envs);
|
|
140
|
+
// Result: { apiPort: 3000, debugMode: true, allowedHosts: ['localhost', '127.0.0.1'] }
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### Number Formatting
|
|
144
|
+
|
|
145
|
+
```typescript
|
|
146
|
+
import { formatRelativeNumber } from '@ooneex/utils';
|
|
147
|
+
|
|
148
|
+
// Format numbers with compact notation
|
|
149
|
+
console.log(formatRelativeNumber(1000)); // '1K'
|
|
150
|
+
console.log(formatRelativeNumber(1500)); // '1.5K'
|
|
151
|
+
console.log(formatRelativeNumber(1000000)); // '1M'
|
|
152
|
+
console.log(formatRelativeNumber(2500000)); // '2.5M'
|
|
153
|
+
console.log(formatRelativeNumber(1000000000)); // '1B'
|
|
154
|
+
|
|
155
|
+
// Custom precision
|
|
156
|
+
console.log(formatRelativeNumber(1234, { precision: 2 })); // '1.23K'
|
|
157
|
+
console.log(formatRelativeNumber(1234, { precision: 0 })); // '1K'
|
|
158
|
+
|
|
159
|
+
// Different locales
|
|
160
|
+
console.log(formatRelativeNumber(1500, { lang: 'de-DE' })); // '1500'
|
|
161
|
+
console.log(formatRelativeNumber(1500000, { lang: 'de-DE' })); // '1,5 Mio.'
|
|
162
|
+
console.log(formatRelativeNumber(1500, { lang: 'fr-FR' })); // '1,5 k'
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
### File Utilities
|
|
30
166
|
|
|
31
|
-
**Examples:**
|
|
32
167
|
```typescript
|
|
33
168
|
import { dataURLtoFile } from '@ooneex/utils';
|
|
34
169
|
|
|
35
|
-
// Convert
|
|
170
|
+
// Convert data URL to File object
|
|
36
171
|
const dataUrl = 'data:text/plain;base64,SGVsbG8gV29ybGQ=';
|
|
37
172
|
const file = dataURLtoFile(dataUrl, 'hello.txt');
|
|
38
173
|
|
|
39
|
-
//
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
// The resulting File object can be used in FormData or uploaded
|
|
44
|
-
const formData = new FormData();
|
|
45
|
-
formData.append('file', file);
|
|
174
|
+
console.log(file.name); // 'hello.txt'
|
|
175
|
+
console.log(file.type); // 'text/plain'
|
|
176
|
+
console.log(file.size); // 11
|
|
46
177
|
```
|
|
47
178
|
|
|
48
|
-
###
|
|
179
|
+
### Random Generation
|
|
49
180
|
|
|
50
|
-
|
|
181
|
+
```typescript
|
|
182
|
+
import { random } from '@ooneex/utils';
|
|
51
183
|
|
|
52
|
-
|
|
184
|
+
// Generate random hex strings
|
|
185
|
+
console.log(random.nanoid()); // 'a1b2c3d4e5' (10 chars default)
|
|
186
|
+
console.log(random.nanoid(8)); // 'f6e5d4c3' (8 chars)
|
|
53
187
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
188
|
+
// Generate numeric strings
|
|
189
|
+
console.log(random.stringInt()); // '1234567890' (10 digits default)
|
|
190
|
+
console.log(random.stringInt(6)); // '123456' (6 digits)
|
|
57
191
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
192
|
+
// Create a factory function
|
|
193
|
+
const generateId = random.nanoidFactory(12);
|
|
194
|
+
console.log(generateId()); // 12-character hex string
|
|
195
|
+
console.log(generateId(8)); // 8-character hex string (overrides factory size)
|
|
62
196
|
```
|
|
63
197
|
|
|
64
|
-
|
|
198
|
+
## API Reference
|
|
199
|
+
|
|
200
|
+
### String Utilities
|
|
201
|
+
|
|
202
|
+
#### `capitalizeWord(word: string): string`
|
|
203
|
+
Capitalizes the first letter and lowercases the rest.
|
|
65
204
|
|
|
66
|
-
|
|
205
|
+
**Parameters:**
|
|
206
|
+
- `word` - The word to capitalize
|
|
67
207
|
|
|
68
|
-
**
|
|
208
|
+
**Returns:** Capitalized word
|
|
209
|
+
|
|
210
|
+
**Example:**
|
|
69
211
|
```typescript
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
splitToWords('PascalCaseString'); // ['Pascal', 'Case', 'String']
|
|
74
|
-
splitToWords('kebab-case-string'); // ['kebab', 'case', 'string']
|
|
75
|
-
splitToWords('snake_case_string'); // ['snake', 'case', 'string']
|
|
76
|
-
splitToWords('HTMLElement123'); // ['HTML', 'Element', '123']
|
|
77
|
-
splitToWords('URLParser'); // ['URL', 'Parser']
|
|
212
|
+
capitalizeWord('hello'); // 'Hello'
|
|
213
|
+
capitalizeWord('WORLD'); // 'World'
|
|
214
|
+
capitalizeWord(''); // ''
|
|
78
215
|
```
|
|
79
216
|
|
|
80
217
|
#### `toCamelCase(input: string): string`
|
|
218
|
+
Converts string to camelCase.
|
|
81
219
|
|
|
82
|
-
|
|
220
|
+
**Parameters:**
|
|
221
|
+
- `input` - The string to convert
|
|
83
222
|
|
|
84
|
-
**
|
|
85
|
-
```typescript
|
|
86
|
-
import { toCamelCase } from '@ooneex/utils';
|
|
223
|
+
**Returns:** camelCase string
|
|
87
224
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
toCamelCase('
|
|
91
|
-
toCamelCase('
|
|
92
|
-
toCamelCase('
|
|
225
|
+
**Example:**
|
|
226
|
+
```typescript
|
|
227
|
+
toCamelCase('hello world'); // 'helloWorld'
|
|
228
|
+
toCamelCase('Hello-World_Example'); // 'helloWorldExample'
|
|
229
|
+
toCamelCase('API_KEY'); // 'apiKey'
|
|
93
230
|
```
|
|
94
231
|
|
|
95
232
|
#### `toPascalCase(input: string): string`
|
|
233
|
+
Converts string to PascalCase.
|
|
96
234
|
|
|
97
|
-
|
|
235
|
+
**Parameters:**
|
|
236
|
+
- `input` - The string to convert
|
|
98
237
|
|
|
99
|
-
**
|
|
100
|
-
```typescript
|
|
101
|
-
import { toPascalCase } from '@ooneex/utils';
|
|
238
|
+
**Returns:** PascalCase string
|
|
102
239
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
toPascalCase('
|
|
106
|
-
toPascalCase('
|
|
107
|
-
toPascalCase('
|
|
240
|
+
**Example:**
|
|
241
|
+
```typescript
|
|
242
|
+
toPascalCase('hello world'); // 'HelloWorld'
|
|
243
|
+
toPascalCase('api-key'); // 'ApiKey'
|
|
244
|
+
toPascalCase('user_name'); // 'UserName'
|
|
108
245
|
```
|
|
109
246
|
|
|
110
247
|
#### `toKebabCase(input: string): string`
|
|
248
|
+
Converts string to kebab-case.
|
|
111
249
|
|
|
112
|
-
|
|
250
|
+
**Parameters:**
|
|
251
|
+
- `input` - The string to convert
|
|
113
252
|
|
|
114
|
-
**
|
|
253
|
+
**Returns:** kebab-case string
|
|
254
|
+
|
|
255
|
+
**Example:**
|
|
115
256
|
```typescript
|
|
116
|
-
|
|
257
|
+
toKebabCase('Hello World'); // 'hello-world'
|
|
258
|
+
toKebabCase('camelCaseString'); // 'camel-case-string'
|
|
259
|
+
toKebabCase('PascalCaseString'); // 'pascal-case-string'
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
#### `splitToWords(input: string): string[]`
|
|
263
|
+
Splits a string into individual words, handling various naming conventions.
|
|
264
|
+
|
|
265
|
+
**Parameters:**
|
|
266
|
+
- `input` - The string to split
|
|
117
267
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
268
|
+
**Returns:** Array of words
|
|
269
|
+
|
|
270
|
+
**Example:**
|
|
271
|
+
```typescript
|
|
272
|
+
splitToWords('HelloWorld'); // ['Hello', 'World']
|
|
273
|
+
splitToWords('hello-world_example'); // ['hello', 'world', 'example']
|
|
274
|
+
splitToWords('XMLHttpRequest'); // ['XML', 'Http', 'Request']
|
|
275
|
+
splitToWords('user123Name'); // ['user', '123', 'Name']
|
|
123
276
|
```
|
|
124
277
|
|
|
125
278
|
#### `trim(text: string, char?: string): string`
|
|
279
|
+
Trims specified characters from the beginning and end of a string.
|
|
126
280
|
|
|
127
|
-
|
|
281
|
+
**Parameters:**
|
|
282
|
+
- `text` - The string to trim
|
|
283
|
+
- `char` - Characters to trim (default: space). Supports regex patterns.
|
|
128
284
|
|
|
129
|
-
**
|
|
130
|
-
```typescript
|
|
131
|
-
import { trim } from '@ooneex/utils';
|
|
285
|
+
**Returns:** Trimmed string
|
|
132
286
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
trim('
|
|
136
|
-
trim('
|
|
137
|
-
trim('
|
|
287
|
+
**Example:**
|
|
288
|
+
```typescript
|
|
289
|
+
trim(' hello '); // 'hello'
|
|
290
|
+
trim('...hello...', '\\.'); // 'hello'
|
|
291
|
+
trim('[test]', '\\[|\\]'); // 'test'
|
|
292
|
+
trim('!!hello!!', '!'); // 'hello'
|
|
138
293
|
```
|
|
139
294
|
|
|
140
|
-
###
|
|
295
|
+
### Time Utilities
|
|
141
296
|
|
|
142
|
-
#### `
|
|
297
|
+
#### `secondsToHMS(seconds: number): string`
|
|
298
|
+
Converts seconds to HH:MM:SS or MM:SS or SS format.
|
|
143
299
|
|
|
144
|
-
|
|
300
|
+
**Parameters:**
|
|
301
|
+
- `seconds` - Number of seconds
|
|
145
302
|
|
|
146
|
-
**
|
|
303
|
+
**Returns:** Formatted time string
|
|
304
|
+
|
|
305
|
+
**Example:**
|
|
147
306
|
```typescript
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
parseString('true'); // true (boolean)
|
|
153
|
-
parseString('false'); // false (boolean)
|
|
154
|
-
parseString('null'); // null
|
|
155
|
-
parseString('[1, 2, 3]'); // [1, 2, 3] (array)
|
|
156
|
-
parseString('{"key": "value"}'); // { key: "value" } (object)
|
|
157
|
-
parseString('hello'); // 'hello' (string)
|
|
158
|
-
parseString('[apple, banana, 123]'); // ['apple', 'banana', 123]
|
|
307
|
+
secondsToHMS(3661); // '1:01:01' (1 hour, 1 minute, 1 second)
|
|
308
|
+
secondsToHMS(125); // '2:05' (2 minutes, 5 seconds)
|
|
309
|
+
secondsToHMS(45); // '45' (45 seconds)
|
|
310
|
+
secondsToHMS(0); // '0'
|
|
159
311
|
```
|
|
160
312
|
|
|
161
|
-
#### `
|
|
313
|
+
#### `secondsToMS(seconds: number): string`
|
|
314
|
+
Converts seconds to MM:SS format.
|
|
315
|
+
|
|
316
|
+
**Parameters:**
|
|
317
|
+
- `seconds` - Number of seconds
|
|
162
318
|
|
|
163
|
-
|
|
319
|
+
**Returns:** MM:SS formatted string
|
|
164
320
|
|
|
165
|
-
**
|
|
321
|
+
**Example:**
|
|
166
322
|
```typescript
|
|
167
|
-
|
|
323
|
+
secondsToMS(125); // '2:05'
|
|
324
|
+
secondsToMS(45); // '0:45'
|
|
325
|
+
secondsToMS(3661); // '61:01'
|
|
326
|
+
```
|
|
168
327
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
'PORT': '3000',
|
|
172
|
-
'ENABLE_LOGGING': 'true',
|
|
173
|
-
'MAX_CONNECTIONS': '100'
|
|
174
|
-
};
|
|
328
|
+
#### `millisecondsToHMS(ms: number): string`
|
|
329
|
+
Converts milliseconds to HH:MM:SS or MM:SS or SS format.
|
|
175
330
|
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
331
|
+
**Parameters:**
|
|
332
|
+
- `ms` - Number of milliseconds
|
|
333
|
+
|
|
334
|
+
**Returns:** Formatted time string
|
|
335
|
+
|
|
336
|
+
**Example:**
|
|
337
|
+
```typescript
|
|
338
|
+
millisecondsToHMS(3661000); // '1:01:01'
|
|
339
|
+
millisecondsToHMS(125000); // '2:05'
|
|
340
|
+
millisecondsToHMS(45000); // '45'
|
|
341
|
+
millisecondsToHMS(500); // '0'
|
|
183
342
|
```
|
|
184
343
|
|
|
185
|
-
|
|
344
|
+
#### `sleep(ms: number): Promise<void>`
|
|
345
|
+
Creates a promise that resolves after the specified number of milliseconds.
|
|
186
346
|
|
|
187
|
-
|
|
347
|
+
**Parameters:**
|
|
348
|
+
- `ms` - Number of milliseconds to wait
|
|
188
349
|
|
|
189
|
-
|
|
350
|
+
**Returns:** Promise that resolves after the delay
|
|
190
351
|
|
|
191
|
-
**
|
|
352
|
+
**Example:**
|
|
192
353
|
```typescript
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
354
|
+
await sleep(1000); // Wait 1 second
|
|
355
|
+
await sleep(500); // Wait 0.5 seconds
|
|
356
|
+
|
|
357
|
+
// Usage in async function
|
|
358
|
+
async function delayedLog() {
|
|
359
|
+
console.log('First');
|
|
360
|
+
await sleep(2000);
|
|
361
|
+
console.log('Second (2 seconds later)');
|
|
362
|
+
}
|
|
202
363
|
```
|
|
203
364
|
|
|
204
|
-
###
|
|
365
|
+
### Data Parsing
|
|
205
366
|
|
|
206
|
-
#### `
|
|
367
|
+
#### `parseString<T>(text: string): T`
|
|
368
|
+
Intelligently parses a string and returns the appropriate type.
|
|
369
|
+
|
|
370
|
+
**Parameters:**
|
|
371
|
+
- `text` - The string to parse
|
|
207
372
|
|
|
208
|
-
|
|
373
|
+
**Returns:** Parsed value with inferred type
|
|
209
374
|
|
|
210
|
-
**
|
|
375
|
+
**Supported Formats:**
|
|
376
|
+
- Integers: `"123"` → `123`
|
|
377
|
+
- Floats: `"12.34"` → `12.34`
|
|
378
|
+
- Scientific notation: `"1e5"` → `100000`
|
|
379
|
+
- Booleans: `"true"`, `"false"` (case insensitive)
|
|
380
|
+
- Null: `"null"` (case insensitive)
|
|
381
|
+
- Arrays: `"[1,2,3]"` → `[1, 2, 3]`
|
|
382
|
+
- Objects: `'{"key":"value"}'` → `{key: "value"}`
|
|
383
|
+
- JSON strings: `'"hello"'` → `"hello"`
|
|
384
|
+
|
|
385
|
+
**Example:**
|
|
211
386
|
```typescript
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
387
|
+
parseString('123'); // 123 (number)
|
|
388
|
+
parseString('12.34'); // 12.34 (number)
|
|
389
|
+
parseString('1e3'); // 1000 (number)
|
|
390
|
+
parseString('true'); // true (boolean)
|
|
391
|
+
parseString('null'); // null
|
|
392
|
+
parseString('[1,2,3]'); // [1, 2, 3] (array)
|
|
393
|
+
parseString('{"name":"John"}'); // {name: "John"} (object)
|
|
394
|
+
parseString('hello'); // 'hello' (string fallback)
|
|
395
|
+
|
|
396
|
+
// With type annotation
|
|
397
|
+
const num = parseString<number>('123'); // TypeScript knows it's a number
|
|
398
|
+
const arr = parseString<number[]>('[1,2,3]'); // TypeScript knows it's number[]
|
|
220
399
|
```
|
|
221
400
|
|
|
222
|
-
#### `
|
|
401
|
+
#### `parseEnvVars<T>(envs: Record<string, string>): T`
|
|
402
|
+
Parses environment variables, converting keys to camelCase and values using `parseString`.
|
|
223
403
|
|
|
224
|
-
|
|
404
|
+
**Parameters:**
|
|
405
|
+
- `envs` - Object with environment variable key-value pairs
|
|
225
406
|
|
|
226
|
-
**
|
|
407
|
+
**Returns:** Object with camelCase keys and parsed values
|
|
408
|
+
|
|
409
|
+
**Example:**
|
|
227
410
|
```typescript
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
411
|
+
const envVars = {
|
|
412
|
+
'API_PORT': '3000',
|
|
413
|
+
'DEBUG_MODE': 'true',
|
|
414
|
+
'ALLOWED_HOSTS': '["localhost", "127.0.0.1"]',
|
|
415
|
+
'MAX_CONNECTIONS': '100',
|
|
416
|
+
'ENABLE_SSL': 'false'
|
|
417
|
+
};
|
|
418
|
+
|
|
419
|
+
const config = parseEnvVars(envVars);
|
|
420
|
+
// Result:
|
|
421
|
+
// {
|
|
422
|
+
// apiPort: 3000,
|
|
423
|
+
// debugMode: true,
|
|
424
|
+
// allowedHosts: ['localhost', '127.0.0.1'],
|
|
425
|
+
// maxConnections: 100,
|
|
426
|
+
// enableSsl: false
|
|
427
|
+
// }
|
|
428
|
+
|
|
429
|
+
// With type annotation
|
|
430
|
+
interface Config {
|
|
431
|
+
apiPort: number;
|
|
432
|
+
debugMode: boolean;
|
|
433
|
+
allowedHosts: string[];
|
|
434
|
+
}
|
|
435
|
+
const typedConfig = parseEnvVars<Config>(envVars);
|
|
236
436
|
```
|
|
237
437
|
|
|
238
|
-
|
|
438
|
+
### Number Utilities
|
|
239
439
|
|
|
240
|
-
|
|
440
|
+
#### `formatRelativeNumber(num: number, config?: { precision?: number; lang?: string }): string`
|
|
441
|
+
Formats numbers using compact notation with locale support.
|
|
442
|
+
|
|
443
|
+
**Parameters:**
|
|
444
|
+
- `num` - The number to format
|
|
445
|
+
- `config.precision` - Maximum decimal places (default: 1)
|
|
446
|
+
- `config.lang` - Locale code (default: 'en-GB')
|
|
447
|
+
|
|
448
|
+
**Returns:** Formatted number string
|
|
241
449
|
|
|
242
|
-
**
|
|
450
|
+
**Example:**
|
|
243
451
|
```typescript
|
|
244
|
-
|
|
452
|
+
formatRelativeNumber(1000); // '1K'
|
|
453
|
+
formatRelativeNumber(1500); // '1.5K'
|
|
454
|
+
formatRelativeNumber(1000000); // '1M'
|
|
455
|
+
formatRelativeNumber(1000000000); // '1B'
|
|
456
|
+
|
|
457
|
+
// Custom precision
|
|
458
|
+
formatRelativeNumber(1234, { precision: 2 }); // '1.23K'
|
|
459
|
+
formatRelativeNumber(1234, { precision: 0 }); // '1K'
|
|
460
|
+
|
|
461
|
+
// Different locales
|
|
462
|
+
formatRelativeNumber(1500, { lang: 'de-DE' }); // '1500'
|
|
463
|
+
formatRelativeNumber(1500000, { lang: 'de-DE' }); // '1,5 Mio.'
|
|
464
|
+
formatRelativeNumber(1500, { lang: 'fr-FR' }); // '1,5 k'
|
|
465
|
+
formatRelativeNumber(1500, { lang: 'es-ES' }); // '1,5 mil'
|
|
466
|
+
```
|
|
467
|
+
|
|
468
|
+
### File Utilities
|
|
469
|
+
|
|
470
|
+
#### `dataURLtoFile(dataurl: string, filename: string): File`
|
|
471
|
+
Converts a data URL to a File object.
|
|
472
|
+
|
|
473
|
+
**Parameters:**
|
|
474
|
+
- `dataurl` - The data URL string
|
|
475
|
+
- `filename` - The desired filename for the File object
|
|
245
476
|
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
477
|
+
**Returns:** File object
|
|
478
|
+
|
|
479
|
+
**Example:**
|
|
480
|
+
```typescript
|
|
481
|
+
// Text file
|
|
482
|
+
const textDataUrl = 'data:text/plain;base64,SGVsbG8gV29ybGQ=';
|
|
483
|
+
const textFile = dataURLtoFile(textDataUrl, 'hello.txt');
|
|
484
|
+
console.log(textFile.name); // 'hello.txt'
|
|
485
|
+
console.log(textFile.type); // 'text/plain'
|
|
486
|
+
console.log(textFile.size); // 11
|
|
487
|
+
|
|
488
|
+
// Image file
|
|
489
|
+
const imgDataUrl = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8/5+hHgAHggJ/PchI7wAAAABJRU5ErkJggg==';
|
|
490
|
+
const imgFile = dataURLtoFile(imgDataUrl, 'pixel.png');
|
|
491
|
+
console.log(imgFile.type); // 'image/png'
|
|
492
|
+
|
|
493
|
+
// Usage with FileReader
|
|
494
|
+
const reader = new FileReader();
|
|
495
|
+
reader.onload = (e) => console.log(e.target?.result);
|
|
496
|
+
reader.readAsText(textFile);
|
|
250
497
|
```
|
|
251
498
|
|
|
252
499
|
### Random Generation
|
|
253
500
|
|
|
254
|
-
#### `random`
|
|
501
|
+
#### `random.nanoid(size?: number): string`
|
|
502
|
+
Generates a random hexadecimal string.
|
|
503
|
+
|
|
504
|
+
**Parameters:**
|
|
505
|
+
- `size` - Length of the generated string (default: 10)
|
|
255
506
|
|
|
256
|
-
|
|
507
|
+
**Returns:** Random hex string
|
|
257
508
|
|
|
258
|
-
**
|
|
509
|
+
**Example:**
|
|
259
510
|
```typescript
|
|
260
|
-
|
|
511
|
+
random.nanoid(); // 'a1b2c3d4e5' (10 characters)
|
|
512
|
+
random.nanoid(8); // 'f6e5d4c3' (8 characters)
|
|
513
|
+
random.nanoid(16); // '1a2b3c4d5e6f7890' (16 characters)
|
|
514
|
+
```
|
|
261
515
|
|
|
262
|
-
|
|
263
|
-
random.
|
|
264
|
-
random.nanoid(5); // '1a2b3'
|
|
265
|
-
random.nanoid(16); // '1234567890abcdef'
|
|
516
|
+
#### `random.stringInt(size?: number): string`
|
|
517
|
+
Generates a random numeric string.
|
|
266
518
|
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
random.stringInt(5); // '12345'
|
|
519
|
+
**Parameters:**
|
|
520
|
+
- `size` - Length of the generated string (default: 10)
|
|
270
521
|
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
522
|
+
**Returns:** Random numeric string
|
|
523
|
+
|
|
524
|
+
**Example:**
|
|
525
|
+
```typescript
|
|
526
|
+
random.stringInt(); // '1234567890' (10 digits)
|
|
527
|
+
random.stringInt(6); // '123456' (6 digits)
|
|
528
|
+
random.stringInt(4); // '9876' (4 digits)
|
|
275
529
|
```
|
|
276
530
|
|
|
277
|
-
|
|
531
|
+
#### `random.nanoidFactory(size?: number): (size?: number) => string`
|
|
532
|
+
Creates a factory function for generating random hex strings.
|
|
278
533
|
|
|
279
|
-
|
|
534
|
+
**Parameters:**
|
|
535
|
+
- `size` - Default length for the factory (default: 10)
|
|
280
536
|
|
|
281
|
-
|
|
537
|
+
**Returns:** Factory function that accepts optional size parameter
|
|
282
538
|
|
|
283
|
-
**
|
|
539
|
+
**Example:**
|
|
284
540
|
```typescript
|
|
285
|
-
|
|
541
|
+
const generateId = random.nanoidFactory(12);
|
|
542
|
+
generateId(); // 12-character hex string
|
|
543
|
+
generateId(8); // 8-character hex string (overrides factory default)
|
|
544
|
+
generateId(16); // 16-character hex string
|
|
286
545
|
|
|
287
|
-
|
|
288
|
-
|
|
546
|
+
const generateShortId = random.nanoidFactory(6);
|
|
547
|
+
generateShortId(); // 6-character hex string
|
|
548
|
+
```
|
|
289
549
|
|
|
290
|
-
|
|
291
|
-
async function delayedOperation() {
|
|
292
|
-
console.log('Starting...');
|
|
293
|
-
await sleep(2000); // Wait 2 seconds
|
|
294
|
-
console.log('Done!');
|
|
295
|
-
}
|
|
550
|
+
## Advanced Usage
|
|
296
551
|
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
552
|
+
### Environment Configuration
|
|
553
|
+
|
|
554
|
+
```typescript
|
|
555
|
+
import { parseEnvVars } from '@ooneex/utils';
|
|
556
|
+
|
|
557
|
+
// Define your configuration interface
|
|
558
|
+
interface AppConfig {
|
|
559
|
+
port: number;
|
|
560
|
+
host: string;
|
|
561
|
+
debug: boolean;
|
|
562
|
+
features: string[];
|
|
563
|
+
dbConfig: {
|
|
564
|
+
host: string;
|
|
565
|
+
port: number;
|
|
566
|
+
};
|
|
307
567
|
}
|
|
568
|
+
|
|
569
|
+
// Parse environment variables
|
|
570
|
+
const envConfig = parseEnvVars<Partial<AppConfig>>(process.env);
|
|
571
|
+
|
|
572
|
+
// Merge with defaults
|
|
573
|
+
const config: AppConfig = {
|
|
574
|
+
port: 3000,
|
|
575
|
+
host: 'localhost',
|
|
576
|
+
debug: false,
|
|
577
|
+
features: [],
|
|
578
|
+
dbConfig: { host: 'localhost', port: 5432 },
|
|
579
|
+
...envConfig
|
|
580
|
+
};
|
|
308
581
|
```
|
|
309
582
|
|
|
310
|
-
|
|
583
|
+
### String Processing Pipeline
|
|
311
584
|
|
|
312
|
-
|
|
585
|
+
```typescript
|
|
586
|
+
import { splitToWords, toCamelCase, capitalizeWord } from '@ooneex/utils';
|
|
587
|
+
|
|
588
|
+
function processUserInput(input: string): {
|
|
589
|
+
words: string[];
|
|
590
|
+
camelCase: string;
|
|
591
|
+
title: string;
|
|
592
|
+
kebabCase: string;
|
|
593
|
+
} {
|
|
594
|
+
const words = splitToWords(input);
|
|
595
|
+
|
|
596
|
+
return {
|
|
597
|
+
words,
|
|
598
|
+
camelCase: toCamelCase(input),
|
|
599
|
+
title: words.map(capitalizeWord).join(' '),
|
|
600
|
+
kebabCase: toKebabCase(input)
|
|
601
|
+
};
|
|
602
|
+
}
|
|
603
|
+
|
|
604
|
+
const result = processUserInput('user-profile_settings');
|
|
605
|
+
// {
|
|
606
|
+
// words: ['user', 'profile', 'settings'],
|
|
607
|
+
// camelCase: 'userProfileSettings',
|
|
608
|
+
// title: 'User Profile Settings',
|
|
609
|
+
// kebabCase: 'user-profile-settings'
|
|
610
|
+
// }
|
|
611
|
+
```
|
|
612
|
+
|
|
613
|
+
### Time-based Progress Tracking
|
|
313
614
|
|
|
314
615
|
```typescript
|
|
315
|
-
|
|
316
|
-
const parsedNumber = parseString<number>('123'); // Type: number
|
|
317
|
-
const parsedArray = parseString<string[]>('[a,b,c]'); // Type: string[]
|
|
616
|
+
import { millisecondsToHMS, formatRelativeNumber } from '@ooneex/utils';
|
|
318
617
|
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
618
|
+
class ProgressTracker {
|
|
619
|
+
private startTime: number;
|
|
620
|
+
private itemsProcessed: number = 0;
|
|
621
|
+
private totalItems: number;
|
|
622
|
+
|
|
623
|
+
constructor(totalItems: number) {
|
|
624
|
+
this.startTime = Date.now();
|
|
625
|
+
this.totalItems = totalItems;
|
|
626
|
+
}
|
|
627
|
+
|
|
628
|
+
update(processed: number): string {
|
|
629
|
+
this.itemsProcessed = processed;
|
|
630
|
+
const elapsed = Date.now() - this.startTime;
|
|
631
|
+
const rate = processed / (elapsed / 1000);
|
|
632
|
+
const remaining = (this.totalItems - processed) / rate * 1000;
|
|
633
|
+
|
|
634
|
+
return [
|
|
635
|
+
`Processed: ${formatRelativeNumber(processed)}/${formatRelativeNumber(this.totalItems)}`,
|
|
636
|
+
`Elapsed: ${millisecondsToHMS(elapsed)}`,
|
|
637
|
+
`ETA: ${millisecondsToHMS(remaining)}`
|
|
638
|
+
].join(' | ');
|
|
639
|
+
}
|
|
324
640
|
}
|
|
325
641
|
|
|
326
|
-
const
|
|
642
|
+
const tracker = new ProgressTracker(100000);
|
|
643
|
+
console.log(tracker.update(15000));
|
|
644
|
+
// "Processed: 15K/100K | Elapsed: 2:30 | ETA: 14:10"
|
|
327
645
|
```
|
|
328
646
|
|
|
329
647
|
## License
|
|
330
648
|
|
|
331
|
-
MIT
|
|
649
|
+
This project is licensed under the MIT License - see the [LICENSE](./LICENSE) file for details.
|
|
332
650
|
|
|
333
651
|
## Contributing
|
|
334
652
|
|
|
335
|
-
Contributions are welcome! Please feel free to submit a Pull Request.
|
|
653
|
+
Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.
|
|
654
|
+
|
|
655
|
+
### Development Setup
|
|
656
|
+
|
|
657
|
+
1. Clone the repository
|
|
658
|
+
2. Install dependencies: `bun install`
|
|
659
|
+
3. Run tests: `bun run test`
|
|
660
|
+
4. Build the project: `bun run build`
|
|
661
|
+
|
|
662
|
+
### Guidelines
|
|
663
|
+
|
|
664
|
+
- Write tests for new features
|
|
665
|
+
- Follow the existing code style
|
|
666
|
+
- Update documentation for API changes
|
|
667
|
+
- Ensure all tests pass before submitting PR
|
|
668
|
+
|
|
669
|
+
---
|
|
670
|
+
|
|
671
|
+
Made with ❤️ by the Ooneex team
|