utilful 2.5.2 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +207 -38
- package/dist/array.d.mts +4 -4
- package/dist/csv.d.mts +138 -148
- package/dist/csv.mjs +72 -88
- package/dist/defu.d.mts +12 -6
- package/dist/defu.mjs +3 -3
- package/dist/emitter.d.mts +5 -5
- package/dist/emitter.mjs +25 -0
- package/dist/index.d.mts +4 -4
- package/dist/index.mjs +3 -3
- package/dist/json.d.mts +6 -13
- package/dist/json.mjs +3 -19
- package/dist/module.d.mts +5 -5
- package/dist/module.mjs +2 -1
- package/dist/object.d.mts +26 -22
- package/dist/object.mjs +13 -7
- package/dist/path.d.mts +24 -20
- package/dist/path.mjs +9 -4
- package/dist/result.d.mts +16 -8
- package/dist/result.mjs +6 -5
- package/dist/string.d.mts +17 -13
- package/dist/string.mjs +8 -2
- package/dist/types.d.mts +1 -1
- package/package.json +10 -16
package/README.md
CHANGED
|
@@ -13,13 +13,12 @@ A collection of TypeScript utilities that I use across my projects.
|
|
|
13
13
|
- [JSON](#json)
|
|
14
14
|
- [Module](#module)
|
|
15
15
|
- [Object](#object)
|
|
16
|
+
- [Path](#path)
|
|
16
17
|
- [Result](#result)
|
|
17
18
|
- [String](#string)
|
|
18
19
|
|
|
19
20
|
## Installation
|
|
20
21
|
|
|
21
|
-
Run the following command to add `utilful` to your project.
|
|
22
|
-
|
|
23
22
|
```bash
|
|
24
23
|
# npm
|
|
25
24
|
npm install -D utilful
|
|
@@ -105,30 +104,34 @@ const csv = createCSV(rows)
|
|
|
105
104
|
Parses a comma-separated values (CSV) string into an array of objects.
|
|
106
105
|
|
|
107
106
|
> [!NOTE]
|
|
108
|
-
> The first row of the CSV string is used as the header row.
|
|
107
|
+
> The first row of the CSV string is used as the header row. A leading UTF-8 byte order mark is stripped.
|
|
109
108
|
|
|
110
109
|
```ts
|
|
111
110
|
type CSVRow<T extends string = string> = Record<T, string>
|
|
112
111
|
|
|
112
|
+
interface CSVParseOptions {
|
|
113
|
+
/** @default ',' */
|
|
114
|
+
delimiter?: string
|
|
115
|
+
/**
|
|
116
|
+
* Trim whitespace from unquoted headers and values.
|
|
117
|
+
* @default false
|
|
118
|
+
*/
|
|
119
|
+
trim?: boolean
|
|
120
|
+
/**
|
|
121
|
+
* Throw if a row's field count does not match the header row.
|
|
122
|
+
* @default true
|
|
123
|
+
*/
|
|
124
|
+
strict?: boolean
|
|
125
|
+
}
|
|
126
|
+
|
|
113
127
|
declare function parseCSV<Header extends string>(
|
|
114
128
|
csv?: string | null | undefined,
|
|
115
|
-
options?:
|
|
116
|
-
/** @default ',' */
|
|
117
|
-
delimiter?: string
|
|
118
|
-
/**
|
|
119
|
-
* Trim whitespace from headers and values.
|
|
120
|
-
* @default true
|
|
121
|
-
*/
|
|
122
|
-
trim?: boolean
|
|
123
|
-
/**
|
|
124
|
-
* Throw error if row has more fields than headers.
|
|
125
|
-
* @default true
|
|
126
|
-
*/
|
|
127
|
-
strict?: boolean
|
|
128
|
-
}
|
|
129
|
+
options?: CSVParseOptions
|
|
129
130
|
): CSVRow<Header>[]
|
|
130
131
|
```
|
|
131
132
|
|
|
133
|
+
The parser accepts a few lenient deviations from RFC 4180: LF, CR, and CRLF line endings are all recognized, whitespace between a closing quote and the next delimiter or line break is ignored, and quotes inside unquoted fields are kept as literal characters (a field only counts as quoted if it starts with a quote).
|
|
134
|
+
|
|
132
135
|
**Example:**
|
|
133
136
|
|
|
134
137
|
```ts
|
|
@@ -141,6 +144,88 @@ Jane,25
|
|
|
141
144
|
const data = parseCSV<'name' | 'age'>(csv) // [{ name: 'John', age: '30' }, { name: 'Jane', age: '25' }]
|
|
142
145
|
```
|
|
143
146
|
|
|
147
|
+
#### `createCSVStream`
|
|
148
|
+
|
|
149
|
+
Creates a CSV stream from an iterable or async iterable of objects. Yields complete lines (header and/or data rows) including line endings – useful for large datasets that should not be buffered in memory.
|
|
150
|
+
|
|
151
|
+
```ts
|
|
152
|
+
declare function createCSVStream<T extends Record<string, unknown>>(
|
|
153
|
+
data: AsyncIterable<T> | Iterable<T>,
|
|
154
|
+
columns: readonly (keyof T)[],
|
|
155
|
+
options?: CSVCreateOptions
|
|
156
|
+
): AsyncIterable<string>
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
**Example:**
|
|
160
|
+
|
|
161
|
+
```ts
|
|
162
|
+
for await (const chunk of createCSVStream(rows, ['name', 'age'])) {
|
|
163
|
+
process.stdout.write(chunk)
|
|
164
|
+
}
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
#### `createCSVAsync`
|
|
168
|
+
|
|
169
|
+
Convenience wrapper around `createCSVStream` that collects all chunks into a single string.
|
|
170
|
+
|
|
171
|
+
> [!NOTE]
|
|
172
|
+
> Unlike `createCSV`, the result has a trailing line ending.
|
|
173
|
+
|
|
174
|
+
```ts
|
|
175
|
+
declare function createCSVAsync<T extends Record<string, unknown>>(
|
|
176
|
+
data: AsyncIterable<T> | Iterable<T>,
|
|
177
|
+
columns: readonly (keyof T)[],
|
|
178
|
+
options?: CSVCreateOptions
|
|
179
|
+
): Promise<string>
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
#### `parseCSVStream`
|
|
183
|
+
|
|
184
|
+
Parses CSV data from an iterable or async iterable of string chunks, yielding rows as soon as they are complete. Chunks do not need to align with row boundaries – quotes and newlines are handled correctly across chunk boundaries.
|
|
185
|
+
|
|
186
|
+
```ts
|
|
187
|
+
declare function parseCSVStream<Header extends string>(
|
|
188
|
+
chunks: AsyncIterable<string> | Iterable<string>,
|
|
189
|
+
options?: CSVParseOptions
|
|
190
|
+
): AsyncIterable<CSVRow<Header>>
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
**Example:**
|
|
194
|
+
|
|
195
|
+
```ts
|
|
196
|
+
const chunks = ['name,age\nJo', 'hn,30\nJane,25']
|
|
197
|
+
|
|
198
|
+
for await (const row of parseCSVStream<'name' | 'age'>(chunks)) {
|
|
199
|
+
console.log(row) // { name: 'John', age: '30' }, then { name: 'Jane', age: '25' }
|
|
200
|
+
}
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
> [!TIP]
|
|
204
|
+
> `parseCSVStream` accepts any iterable of strings, including an array of lines.
|
|
205
|
+
|
|
206
|
+
#### `escapeCSVValue`
|
|
207
|
+
|
|
208
|
+
Escapes a single value for a CSV string. Returns an empty string for `null` and `undefined`. Values containing delimiters, quotes, or line breaks are quoted; embedded quotes are doubled.
|
|
209
|
+
|
|
210
|
+
```ts
|
|
211
|
+
declare function escapeCSVValue(
|
|
212
|
+
value: unknown,
|
|
213
|
+
options?: {
|
|
214
|
+
/** @default ',' */
|
|
215
|
+
delimiter?: string
|
|
216
|
+
/** @default false */
|
|
217
|
+
quoteAll?: boolean
|
|
218
|
+
}
|
|
219
|
+
): string
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
**Example:**
|
|
223
|
+
|
|
224
|
+
```ts
|
|
225
|
+
escapeCSVValue('hello, world') // '"hello, world"'
|
|
226
|
+
escapeCSVValue('contains "quotes"') // '"contains ""quotes"""'
|
|
227
|
+
```
|
|
228
|
+
|
|
144
229
|
### Defu
|
|
145
230
|
|
|
146
231
|
Recursively assign default properties. Simplified version based on [unjs/defu](https://github.com/unjs/defu).
|
|
@@ -154,10 +239,17 @@ The function replaces `null` and `undefined` values in the source with defaults,
|
|
|
154
239
|
```ts
|
|
155
240
|
type PlainObject = Record<PropertyKey, any>
|
|
156
241
|
|
|
157
|
-
declare function defu<
|
|
158
|
-
source:
|
|
159
|
-
...defaults:
|
|
160
|
-
):
|
|
242
|
+
declare function defu<Source extends PlainObject, Defaults extends PlainObject[]>(
|
|
243
|
+
source: Source,
|
|
244
|
+
...defaults: Defaults
|
|
245
|
+
): Defu<Source, Defaults>
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
The return type is a deep merge of the source over the defaults, so keys that only exist in the defaults are part of the result type:
|
|
249
|
+
|
|
250
|
+
```ts
|
|
251
|
+
const result = defu({ a: 1 }, { b: 2 })
|
|
252
|
+
result.b // number – no cast needed
|
|
161
253
|
```
|
|
162
254
|
|
|
163
255
|
**Example:**
|
|
@@ -262,25 +354,14 @@ emitter.off('foo', onFoo) // Unlisten
|
|
|
262
354
|
|
|
263
355
|
#### `tryParseJSON`
|
|
264
356
|
|
|
265
|
-
Type-safe wrapper around `JSON.
|
|
357
|
+
Type-safe wrapper around `JSON.parse`.
|
|
266
358
|
|
|
267
|
-
Falls back to the original value if
|
|
359
|
+
Falls back to the original value if parsing fails or the value is not a string.
|
|
268
360
|
|
|
269
361
|
```ts
|
|
270
362
|
declare function tryParseJSON<T = unknown>(value: unknown): T
|
|
271
363
|
```
|
|
272
364
|
|
|
273
|
-
#### `cloneJSON`
|
|
274
|
-
|
|
275
|
-
Clones the given JSON value.
|
|
276
|
-
|
|
277
|
-
> [!NOTE]
|
|
278
|
-
> The value must not contain circular references as JSON does not support them. It also must contain JSON serializable values.
|
|
279
|
-
|
|
280
|
-
```ts
|
|
281
|
-
declare function cloneJSON<T>(value: T): T
|
|
282
|
-
```
|
|
283
|
-
|
|
284
365
|
### Module
|
|
285
366
|
|
|
286
367
|
#### `interopDefault`
|
|
@@ -312,7 +393,7 @@ A simple general purpose memoizer utility.
|
|
|
312
393
|
- Lazily computes a value when accessed
|
|
313
394
|
- Auto-caches the result by overwriting the getter
|
|
314
395
|
|
|
315
|
-
Useful for deferring initialization or expensive operations. Unlike a simple getter, there is no runtime overhead after the first
|
|
396
|
+
Useful for deferring initialization or expensive operations. Unlike a simple getter, there is no runtime overhead after the first invocation, since the getter itself is overwritten with the memoized value.
|
|
316
397
|
|
|
317
398
|
```ts
|
|
318
399
|
declare function memoize<T>(getter: () => T): { value: T }
|
|
@@ -321,7 +402,7 @@ declare function memoize<T>(getter: () => T): { value: T }
|
|
|
321
402
|
**Example:**
|
|
322
403
|
|
|
323
404
|
```ts
|
|
324
|
-
const myValue =
|
|
405
|
+
const myValue = memoize(() => 'Hello, World!')
|
|
325
406
|
console.log(myValue.value) // Computes value, overwrites getter
|
|
326
407
|
console.log(myValue.value) // Returns cached value
|
|
327
408
|
console.log(myValue.value) // Returns cached value
|
|
@@ -332,7 +413,7 @@ console.log(myValue.value) // Returns cached value
|
|
|
332
413
|
Strictly typed `Object.keys`.
|
|
333
414
|
|
|
334
415
|
```ts
|
|
335
|
-
declare function objectKeys<T extends Record<any, any>>(obj: T): Array<`${keyof T
|
|
416
|
+
declare function objectKeys<T extends Record<any, any>>(obj: T): Array<`${Extract<keyof T, string | number>}`>
|
|
336
417
|
```
|
|
337
418
|
|
|
338
419
|
#### `objectEntries`
|
|
@@ -345,12 +426,97 @@ declare function objectEntries<T extends Record<any, any>>(obj: T): Array<[keyof
|
|
|
345
426
|
|
|
346
427
|
#### `deepApply`
|
|
347
428
|
|
|
348
|
-
Deeply applies a callback to every key-value pair in the given object, as well as nested objects and arrays.
|
|
429
|
+
Deeply applies a callback to every key-value pair in the given object, as well as nested objects and arrays (including arrays nested inside arrays).
|
|
349
430
|
|
|
350
431
|
```ts
|
|
351
432
|
declare function deepApply<T extends Record<any, any>>(data: T, callback: (item: T, key: keyof T, value: T[keyof T]) => void): void
|
|
352
433
|
```
|
|
353
434
|
|
|
435
|
+
#### `isObject`
|
|
436
|
+
|
|
437
|
+
Checks if a value is an object with the plain `[object Object]` tag. Returns `true` for object literals, class instances, and `null`-prototype objects.
|
|
438
|
+
|
|
439
|
+
```ts
|
|
440
|
+
declare function isObject(value: unknown): value is Record<any, any>
|
|
441
|
+
```
|
|
442
|
+
|
|
443
|
+
### Path
|
|
444
|
+
|
|
445
|
+
Utilities to build and normalize URL paths. All of them are also available from the `utilful/path` subpath export.
|
|
446
|
+
|
|
447
|
+
#### `withoutLeadingSlash` / `withLeadingSlash`
|
|
448
|
+
|
|
449
|
+
Removes or adds a leading slash.
|
|
450
|
+
|
|
451
|
+
```ts
|
|
452
|
+
declare function withoutLeadingSlash(path?: string): string
|
|
453
|
+
declare function withLeadingSlash(path?: string): string
|
|
454
|
+
```
|
|
455
|
+
|
|
456
|
+
#### `withoutTrailingSlash` / `withTrailingSlash`
|
|
457
|
+
|
|
458
|
+
Removes or adds a trailing slash, preserving query strings and hash fragments.
|
|
459
|
+
|
|
460
|
+
```ts
|
|
461
|
+
declare function withoutTrailingSlash(path?: string): string
|
|
462
|
+
declare function withTrailingSlash(path?: string): string
|
|
463
|
+
```
|
|
464
|
+
|
|
465
|
+
#### `joinURL`
|
|
466
|
+
|
|
467
|
+
Joins the given URL path segments, ensuring that there is only one slash between them.
|
|
468
|
+
|
|
469
|
+
```ts
|
|
470
|
+
declare function joinURL(...paths: (string | undefined)[]): string
|
|
471
|
+
```
|
|
472
|
+
|
|
473
|
+
**Example:**
|
|
474
|
+
|
|
475
|
+
```ts
|
|
476
|
+
joinURL('/api/', '/users', '42') // '/api/users/42'
|
|
477
|
+
```
|
|
478
|
+
|
|
479
|
+
#### `withBase` / `withoutBase`
|
|
480
|
+
|
|
481
|
+
Adds or removes a base path – each is a no-op if the base is already present (or absent).
|
|
482
|
+
|
|
483
|
+
```ts
|
|
484
|
+
declare function withBase(input?: string, base?: string): string
|
|
485
|
+
declare function withoutBase(input?: string, base?: string): string
|
|
486
|
+
```
|
|
487
|
+
|
|
488
|
+
**Example:**
|
|
489
|
+
|
|
490
|
+
```ts
|
|
491
|
+
withBase('/users', '/api') // '/api/users'
|
|
492
|
+
withoutBase('/api/users', '/api') // '/users'
|
|
493
|
+
```
|
|
494
|
+
|
|
495
|
+
#### `getPathname`
|
|
496
|
+
|
|
497
|
+
Returns the pathname of the given path – everything before the query string or hash. Absolute URLs (with a scheme, e.g. `https://example.com/foo`) return the URL's pathname; all other inputs are returned unchanged with the query string and hash removed.
|
|
498
|
+
|
|
499
|
+
```ts
|
|
500
|
+
declare function getPathname(path?: string): string
|
|
501
|
+
```
|
|
502
|
+
|
|
503
|
+
#### `withQuery`
|
|
504
|
+
|
|
505
|
+
Returns the URL with the given query parameters merged in. `undefined` values remove the parameter, array values append one entry per item, and object values are JSON-stringified.
|
|
506
|
+
|
|
507
|
+
```ts
|
|
508
|
+
type QueryValue = string | number | boolean | QueryValue[] | Record<string, any> | null | undefined
|
|
509
|
+
type QueryObject = Record<string, QueryValue | QueryValue[]>
|
|
510
|
+
|
|
511
|
+
declare function withQuery(input: string, query?: QueryObject): string
|
|
512
|
+
```
|
|
513
|
+
|
|
514
|
+
**Example:**
|
|
515
|
+
|
|
516
|
+
```ts
|
|
517
|
+
withQuery('/api/users', { page: 2, tags: ['a', 'b'] }) // '/api/users?page=2&tags=a&tags=b'
|
|
518
|
+
```
|
|
519
|
+
|
|
354
520
|
### Result
|
|
355
521
|
|
|
356
522
|
The `Result` type represents either success (`Ok`) or failure (`Err`). It provides a type-safe way to handle errors without relying on exceptions.
|
|
@@ -492,6 +658,9 @@ declare function toResult<T, E = unknown>(fn: () => T): Result<T, E>
|
|
|
492
658
|
declare function toResult<T, E = unknown>(promise: Promise<T>): Promise<Result<T, E>>
|
|
493
659
|
```
|
|
494
660
|
|
|
661
|
+
> [!NOTE]
|
|
662
|
+
> The function overload must be synchronous. For asynchronous work, pass the promise itself – a function returning a promise throws a `TypeError`, since its rejection could not be captured as `Err`.
|
|
663
|
+
|
|
495
664
|
**Example:**
|
|
496
665
|
|
|
497
666
|
```ts
|
package/dist/array.d.mts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
//#region src/array.d.ts
|
|
2
2
|
/**
|
|
3
|
-
* Represents a value that can be either a single value or an array of values.
|
|
4
|
-
*/
|
|
3
|
+
* Represents a value that can be either a single value or an array of values.
|
|
4
|
+
*/
|
|
5
5
|
type MaybeArray<T> = T | T[];
|
|
6
6
|
/**
|
|
7
|
-
* Converts `MaybeArray<T>` to `Array<T>`.
|
|
8
|
-
*/
|
|
7
|
+
* Converts `MaybeArray<T>` to `Array<T>`.
|
|
8
|
+
*/
|
|
9
9
|
declare function toArray<T>(array?: MaybeArray<T> | null | undefined): T[];
|
|
10
10
|
//#endregion
|
|
11
11
|
export { MaybeArray, toArray };
|
package/dist/csv.d.mts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
//#region src/csv.d.ts
|
|
2
2
|
/**
|
|
3
|
-
* Represents a row in a CSV file with column names of type T.
|
|
4
|
-
*/
|
|
3
|
+
* Represents a row in a CSV file with column names of type T.
|
|
4
|
+
*/
|
|
5
5
|
type CSVRow<T extends string = string> = Record<T, string>;
|
|
6
6
|
/**
|
|
7
|
-
* Options for the
|
|
8
|
-
*/
|
|
7
|
+
* Options for the CSV creation functions.
|
|
8
|
+
*/
|
|
9
9
|
interface CSVCreateOptions {
|
|
10
10
|
/** @default ',' */
|
|
11
11
|
delimiter?: string;
|
|
@@ -17,160 +17,150 @@ interface CSVCreateOptions {
|
|
|
17
17
|
lineEnding?: string;
|
|
18
18
|
}
|
|
19
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
|
-
* const
|
|
51
|
-
*
|
|
52
|
-
*
|
|
53
|
-
*
|
|
54
|
-
|
|
20
|
+
* Options for the CSV parsing functions.
|
|
21
|
+
*/
|
|
22
|
+
interface CSVParseOptions {
|
|
23
|
+
/** @default ',' */
|
|
24
|
+
delimiter?: string;
|
|
25
|
+
/**
|
|
26
|
+
* Trim whitespace from unquoted headers and values.
|
|
27
|
+
* @default false
|
|
28
|
+
*/
|
|
29
|
+
trim?: boolean;
|
|
30
|
+
/**
|
|
31
|
+
* Throw if a row's field count does not match the header row.
|
|
32
|
+
* @default true
|
|
33
|
+
*/
|
|
34
|
+
strict?: boolean;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Converts an array of objects to a comma-separated values (CSV) string.
|
|
38
|
+
*
|
|
39
|
+
* @remarks
|
|
40
|
+
* When `columns` is omitted, the function automatically infers columns by collecting
|
|
41
|
+
* the union of all keys across all objects in first-seen order. This means if different
|
|
42
|
+
* objects have different keys, all keys will be included in the CSV. Objects missing
|
|
43
|
+
* certain keys will have empty values for those columns.
|
|
44
|
+
*
|
|
45
|
+
* When `columns` is provided explicitly, only those columns are included in the output,
|
|
46
|
+
* allowing you to control column order and filter out unwanted properties.
|
|
47
|
+
*
|
|
48
|
+
* @example
|
|
49
|
+
* // With explicit columns
|
|
50
|
+
* const data = [
|
|
51
|
+
* { name: 'John', age: '30', city: 'New York' },
|
|
52
|
+
* { name: 'Jane', age: '25', city: 'Boston' }
|
|
53
|
+
* ]
|
|
54
|
+
*
|
|
55
|
+
* const csv = createCSV(data, ['name', 'age'])
|
|
56
|
+
* // name,age
|
|
57
|
+
* // John,30
|
|
58
|
+
* // Jane,25
|
|
59
|
+
*
|
|
60
|
+
* @example
|
|
61
|
+
* // With inferred columns (union of all keys in first-seen order)
|
|
62
|
+
* const rows = [
|
|
63
|
+
* { name: 'John', age: '30' },
|
|
64
|
+
* { name: 'Jane', city: 'Boston' },
|
|
65
|
+
* ]
|
|
66
|
+
*
|
|
67
|
+
* const csv = createCSV(rows)
|
|
68
|
+
* // name,age,city
|
|
69
|
+
* // John,30,
|
|
70
|
+
* // Jane,,Boston
|
|
71
|
+
*/
|
|
55
72
|
declare function createCSV<T extends Record<string, unknown>>(data: readonly T[], columns: readonly (keyof T)[], options?: CSVCreateOptions): string;
|
|
56
73
|
declare function createCSV<T extends Record<string, unknown>>(data: readonly T[], options?: CSVCreateOptions): string;
|
|
57
74
|
/**
|
|
58
|
-
* Creates a CSV stream from an iterable or async iterable of objects.
|
|
59
|
-
*
|
|
60
|
-
* @remarks
|
|
61
|
-
* This function yields CSV content as strings, including line endings.
|
|
62
|
-
* Each yielded chunk contains complete lines (header and/or data rows).
|
|
63
|
-
*
|
|
64
|
-
* @example
|
|
65
|
-
* const data = [
|
|
66
|
-
* { name: 'John', age: '30' },
|
|
67
|
-
* { name: 'Jane', age: '25' }
|
|
68
|
-
* ]
|
|
69
|
-
*
|
|
70
|
-
* for await (const chunk of createCSVStream(data, ['name', 'age'])) {
|
|
71
|
-
* console.log(chunk)
|
|
72
|
-
* }
|
|
73
|
-
*/
|
|
75
|
+
* Creates a CSV stream from an iterable or async iterable of objects.
|
|
76
|
+
*
|
|
77
|
+
* @remarks
|
|
78
|
+
* This function yields CSV content as strings, including line endings.
|
|
79
|
+
* Each yielded chunk contains complete lines (header and/or data rows).
|
|
80
|
+
*
|
|
81
|
+
* @example
|
|
82
|
+
* const data = [
|
|
83
|
+
* { name: 'John', age: '30' },
|
|
84
|
+
* { name: 'Jane', age: '25' }
|
|
85
|
+
* ]
|
|
86
|
+
*
|
|
87
|
+
* for await (const chunk of createCSVStream(data, ['name', 'age'])) {
|
|
88
|
+
* console.log(chunk)
|
|
89
|
+
* }
|
|
90
|
+
*/
|
|
74
91
|
declare function createCSVStream<T extends Record<string, unknown>>(data: AsyncIterable<T> | Iterable<T>, columns: readonly (keyof T)[], options?: CSVCreateOptions): AsyncIterable<string>;
|
|
75
92
|
/**
|
|
76
|
-
* Creates a CSV string from an async iterable or iterable of objects.
|
|
77
|
-
*
|
|
78
|
-
* @remarks
|
|
79
|
-
* This is a convenience wrapper around `createCSVStream` that collects
|
|
80
|
-
* all chunks into a single string. Note that the result will have a
|
|
81
|
-
* trailing line ending, unlike the synchronous `createCSV`.
|
|
82
|
-
*
|
|
83
|
-
* @example
|
|
84
|
-
* const data = [
|
|
85
|
-
* { name: 'John', age: '30' },
|
|
86
|
-
* { name: 'Jane', age: '25' }
|
|
87
|
-
* ]
|
|
88
|
-
*
|
|
89
|
-
* const csv = await createCSVAsync(data, ['name', 'age'])
|
|
90
|
-
*/
|
|
93
|
+
* Creates a CSV string from an async iterable or iterable of objects.
|
|
94
|
+
*
|
|
95
|
+
* @remarks
|
|
96
|
+
* This is a convenience wrapper around `createCSVStream` that collects
|
|
97
|
+
* all chunks into a single string. Note that the result will have a
|
|
98
|
+
* trailing line ending, unlike the synchronous `createCSV`.
|
|
99
|
+
*
|
|
100
|
+
* @example
|
|
101
|
+
* const data = [
|
|
102
|
+
* { name: 'John', age: '30' },
|
|
103
|
+
* { name: 'Jane', age: '25' }
|
|
104
|
+
* ]
|
|
105
|
+
*
|
|
106
|
+
* const csv = await createCSVAsync(data, ['name', 'age'])
|
|
107
|
+
*/
|
|
91
108
|
declare function createCSVAsync<T extends Record<string, unknown>>(data: AsyncIterable<T> | Iterable<T>, columns: readonly (keyof T)[], options?: CSVCreateOptions): Promise<string>;
|
|
92
109
|
/**
|
|
93
|
-
* Escapes a value for a CSV string.
|
|
94
|
-
*
|
|
95
|
-
* @remarks
|
|
96
|
-
* Returns an empty string if the value is `null` or `undefined`.
|
|
97
|
-
* Values containing delimiters, quotes, or line breaks are quoted.
|
|
98
|
-
* Within quoted values, double quotes are escaped by doubling them.
|
|
99
|
-
*
|
|
100
|
-
* @example
|
|
101
|
-
* escapeCSVValue('hello, world') // "hello, world"
|
|
102
|
-
* escapeCSVValue('contains "quotes"') // "contains ""quotes"""
|
|
103
|
-
*/
|
|
110
|
+
* Escapes a value for a CSV string.
|
|
111
|
+
*
|
|
112
|
+
* @remarks
|
|
113
|
+
* Returns an empty string if the value is `null` or `undefined`.
|
|
114
|
+
* Values containing delimiters, quotes, or line breaks are quoted.
|
|
115
|
+
* Within quoted values, double quotes are escaped by doubling them.
|
|
116
|
+
*
|
|
117
|
+
* @example
|
|
118
|
+
* escapeCSVValue('hello, world') // "hello, world"
|
|
119
|
+
* escapeCSVValue('contains "quotes"') // "contains ""quotes"""
|
|
120
|
+
*/
|
|
104
121
|
declare function escapeCSVValue(value: unknown, options?: {
|
|
105
|
-
/** @default ',' */
|
|
122
|
+
/** @default ',' */
|
|
123
|
+
delimiter?: string;
|
|
124
|
+
/** @default false */
|
|
106
125
|
quoteAll?: boolean;
|
|
107
126
|
}): string;
|
|
108
127
|
/**
|
|
109
|
-
* Parses a comma-separated values (CSV) string into an array of objects.
|
|
110
|
-
*
|
|
111
|
-
* @remarks
|
|
112
|
-
* The first row of the CSV string is used as the header row.
|
|
113
|
-
*
|
|
114
|
-
*
|
|
115
|
-
*
|
|
116
|
-
*
|
|
117
|
-
*
|
|
118
|
-
*
|
|
119
|
-
*
|
|
120
|
-
*
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
* Throw error if row has more fields than headers.
|
|
131
|
-
* @default true
|
|
132
|
-
*/
|
|
133
|
-
strict?: boolean;
|
|
134
|
-
}): CSVRow<Header>[];
|
|
128
|
+
* Parses a comma-separated values (CSV) string into an array of objects.
|
|
129
|
+
*
|
|
130
|
+
* @remarks
|
|
131
|
+
* The first row of the CSV string is used as the header row. A leading
|
|
132
|
+
* UTF-8 byte order mark is stripped.
|
|
133
|
+
*
|
|
134
|
+
* Parsing tolerances (lenient deviations from RFC 4180):
|
|
135
|
+
* - LF, CR, and CRLF line endings are all accepted
|
|
136
|
+
* - Whitespace between a closing quote and the next delimiter or line break is ignored
|
|
137
|
+
* - A field is only treated as quoted if it starts with a quote; quotes inside
|
|
138
|
+
* unquoted fields are kept as literal characters
|
|
139
|
+
*
|
|
140
|
+
* @example
|
|
141
|
+
* const csv = `name,age
|
|
142
|
+
* John,30
|
|
143
|
+
* Jane,25`
|
|
144
|
+
*
|
|
145
|
+
* const data = parseCSV<'name' | 'age'>(csv)
|
|
146
|
+
* // [{ name: 'John', age: '30' }, { name: 'Jane', age: '25' }]
|
|
147
|
+
*/
|
|
148
|
+
declare function parseCSV<Header extends string>(csv?: string | null | undefined, options?: CSVParseOptions): CSVRow<Header>[];
|
|
135
149
|
/**
|
|
136
|
-
* Parses CSV data from an async iterable or iterable of string chunks.
|
|
137
|
-
*
|
|
138
|
-
* @remarks
|
|
139
|
-
* This function yields CSV rows as they are parsed. Chunks do not need to
|
|
140
|
-
* align with row boundaries; the parser handles quotes and newlines correctly
|
|
141
|
-
* across chunk boundaries.
|
|
142
|
-
*
|
|
143
|
-
* @example
|
|
144
|
-
* const chunks = ['name,age\nJo', 'hn,30\nJane,25']
|
|
145
|
-
*
|
|
146
|
-
* for await (const row of parseCSVStream<'name' | 'age'>(chunks)) {
|
|
147
|
-
* console.log(row)
|
|
148
|
-
* }
|
|
149
|
-
*/
|
|
150
|
-
declare function parseCSVStream<Header extends string>(chunks: AsyncIterable<string> | Iterable<string>, options?:
|
|
151
|
-
delimiter?: string;
|
|
152
|
-
trim?: boolean;
|
|
153
|
-
strict?: boolean;
|
|
154
|
-
}): AsyncIterable<CSVRow<Header>>;
|
|
155
|
-
/**
|
|
156
|
-
* Parses CSV data from an async iterable or iterable of lines.
|
|
157
|
-
*
|
|
158
|
-
* @remarks
|
|
159
|
-
* This is a convenience wrapper around `parseCSVStream` that treats each line
|
|
160
|
-
* as a chunk. Note that lines do not necessarily correspond to CSV rows due to
|
|
161
|
-
* quoted fields containing newlines. The parser handles this correctly.
|
|
162
|
-
*
|
|
163
|
-
* @example
|
|
164
|
-
* const lines = ['name,age', 'John,30', 'Jane,25']
|
|
165
|
-
*
|
|
166
|
-
* for await (const row of parseCSVFromLines<'name' | 'age'>(lines)) {
|
|
167
|
-
* console.log(row)
|
|
168
|
-
* }
|
|
169
|
-
*/
|
|
170
|
-
declare function parseCSVFromLines<Header extends string>(lines: AsyncIterable<string> | Iterable<string>, options?: {
|
|
171
|
-
delimiter?: string;
|
|
172
|
-
trim?: boolean;
|
|
173
|
-
strict?: boolean;
|
|
174
|
-
}): AsyncIterable<CSVRow<Header>>;
|
|
150
|
+
* Parses CSV data from an async iterable or iterable of string chunks.
|
|
151
|
+
*
|
|
152
|
+
* @remarks
|
|
153
|
+
* This function yields CSV rows as they are parsed. Chunks do not need to
|
|
154
|
+
* align with row boundaries; the parser handles quotes and newlines correctly
|
|
155
|
+
* across chunk boundaries.
|
|
156
|
+
*
|
|
157
|
+
* @example
|
|
158
|
+
* const chunks = ['name,age\nJo', 'hn,30\nJane,25']
|
|
159
|
+
*
|
|
160
|
+
* for await (const row of parseCSVStream<'name' | 'age'>(chunks)) {
|
|
161
|
+
* console.log(row)
|
|
162
|
+
* }
|
|
163
|
+
*/
|
|
164
|
+
declare function parseCSVStream<Header extends string>(chunks: AsyncIterable<string> | Iterable<string>, options?: CSVParseOptions): AsyncIterable<CSVRow<Header>>;
|
|
175
165
|
//#endregion
|
|
176
|
-
export { CSVCreateOptions, CSVRow, createCSV, createCSVAsync, createCSVStream, escapeCSVValue, parseCSV,
|
|
166
|
+
export { CSVCreateOptions, CSVParseOptions, CSVRow, createCSV, createCSVAsync, createCSVStream, escapeCSVValue, parseCSV, parseCSVStream };
|