web-csv-toolbox 0.3.1 → 0.4.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 +10 -4
- package/lib/index.d.ts +166 -24
- package/lib/index.js +85 -17
- package/lib/index.umd.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -242,6 +242,8 @@ providing an intuitive and straightforward experience for users.
|
|
|
242
242
|
|
|
243
243
|
The `input` paramater can be a `string`, a [ReadableStream](https://developer.mozilla.org/docs/Web/API/ReadableStream)
|
|
244
244
|
of `string`s or [Uint8Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array)s,
|
|
245
|
+
or a [Uint8Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) object,
|
|
246
|
+
or a [ArrayBuffer](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer) object,
|
|
245
247
|
or a [Response](https://developer.mozilla.org/docs/Web/API/Response) object.
|
|
246
248
|
|
|
247
249
|
### Middle-level APIs 🧱
|
|
@@ -249,16 +251,20 @@ or a [Response](https://developer.mozilla.org/docs/Web/API/Response) object.
|
|
|
249
251
|
These APIs are optimized for **Enhanced Performance and Control**,
|
|
250
252
|
catering to users who need more detailed and fine-tuned functionality.
|
|
251
253
|
|
|
252
|
-
- **`function
|
|
253
|
-
-
|
|
254
|
+
- **`function parseString(string[, options])`**: [📑](https://kamiazya.github.io/web-csv-toolbox/functions/parseString-1.html)
|
|
255
|
+
- Efficient parsing of CSV strings.
|
|
256
|
+
- **`function parseArrayBuffer(buffer[, options])`**: [📑](https://kamiazya.github.io/web-csv-toolbox/functions/parseArrayBuffer-1.html)
|
|
257
|
+
- Parse CSV Binary of ArrayBuffer.
|
|
258
|
+
- **`function parseUint8Array(buffer[, options])`**: [📑](https://kamiazya.github.io/web-csv-toolbox/functions/parseUint8Array-1.html)
|
|
259
|
+
- Parse CSV Binary of Uint8Array.
|
|
254
260
|
- **`function parseResponse(response[, options])`**: [📑](https://kamiazya.github.io/web-csv-toolbox/functions/parseResponse-1.html)
|
|
255
261
|
- Customized parsing directly from `Response` objects.
|
|
256
262
|
- **`function parseStream(stream[, options])`**: [📑](https://kamiazya.github.io/web-csv-toolbox/functions/parseStream-1.html)
|
|
257
263
|
- Stream-based parsing for larger or continuous data.
|
|
258
|
-
- **`function parseString(string[, options])`**: [📑](https://kamiazya.github.io/web-csv-toolbox/functions/parseString-1.html)
|
|
259
|
-
- Efficient parsing of CSV strings.
|
|
260
264
|
- **`function parseStringStream(stream[, options])`**: [📑](https://kamiazya.github.io/web-csv-toolbox/functions/parseStringStream-1.html)
|
|
261
265
|
- Combines string-based parsing with stream processing.
|
|
266
|
+
- **`function parseUint8ArrayStream(stream[, options])`**: [📑](https://kamiazya.github.io/web-csv-toolbox/functions/parseUint8ArrayStream-1.html)
|
|
267
|
+
- Parses binary streams with precise control over data types.
|
|
262
268
|
|
|
263
269
|
### Low-level APIs ⚙️
|
|
264
270
|
|
package/lib/index.d.ts
CHANGED
|
@@ -170,6 +170,28 @@ type CSVRecord<Header extends ReadonlyArray<string>> = Record<
|
|
|
170
170
|
Header[number],
|
|
171
171
|
string
|
|
172
172
|
>;
|
|
173
|
+
/**
|
|
174
|
+
* CSV String.
|
|
175
|
+
*
|
|
176
|
+
* @category Types
|
|
177
|
+
*/
|
|
178
|
+
type CSVString = string | ReadableStream<string>;
|
|
179
|
+
/**
|
|
180
|
+
* CSV Binary.
|
|
181
|
+
*
|
|
182
|
+
* @category Types
|
|
183
|
+
*/
|
|
184
|
+
type CSVBinary =
|
|
185
|
+
| ReadableStream<Uint8Array>
|
|
186
|
+
| Response
|
|
187
|
+
| ArrayBuffer
|
|
188
|
+
| Uint8Array;
|
|
189
|
+
/**
|
|
190
|
+
* CSV.
|
|
191
|
+
*
|
|
192
|
+
* @category Types
|
|
193
|
+
*/
|
|
194
|
+
type CSV = CSVString | CSVBinary;
|
|
173
195
|
|
|
174
196
|
/**
|
|
175
197
|
* A transform stream that converts a stream of tokens into a stream of rows.
|
|
@@ -311,6 +333,58 @@ declare namespace parseString {
|
|
|
311
333
|
): Promise<CSVRecord<Header>[]>;
|
|
312
334
|
}
|
|
313
335
|
|
|
336
|
+
/**
|
|
337
|
+
* Parse a binary from an {@link !Uint8Array}.
|
|
338
|
+
*
|
|
339
|
+
* @category Middle-level API
|
|
340
|
+
*
|
|
341
|
+
* @param bytes CSV bytes to parse.
|
|
342
|
+
* @param options Parsing options
|
|
343
|
+
* @returns Async iterable iterator of records.
|
|
344
|
+
*
|
|
345
|
+
* @example Parsing CSV binary
|
|
346
|
+
*
|
|
347
|
+
* ```ts
|
|
348
|
+
* import { parseUint8Array } from 'web-csv-toolbox';
|
|
349
|
+
*
|
|
350
|
+
* const csv = Uint8Array.from([
|
|
351
|
+
* // ...
|
|
352
|
+
* ]);
|
|
353
|
+
*
|
|
354
|
+
* for await (const record of parseUint8Array(csv)) {
|
|
355
|
+
* console.log(record);
|
|
356
|
+
* }
|
|
357
|
+
* ```
|
|
358
|
+
*/
|
|
359
|
+
declare function parseUint8Array<Header extends ReadonlyArray<string>>(
|
|
360
|
+
bytes: Uint8Array,
|
|
361
|
+
options?: ParseBinaryOptions<Header>,
|
|
362
|
+
): AsyncIterableIterator<CSVRecord<Header>>;
|
|
363
|
+
declare namespace parseUint8Array {
|
|
364
|
+
/**
|
|
365
|
+
* Parse a binary from an {@link !Uint8Array} to an array of records.
|
|
366
|
+
*
|
|
367
|
+
* @param bytes CSV bytes to parse.
|
|
368
|
+
* @param options Parsing options
|
|
369
|
+
* @returns Array of records
|
|
370
|
+
*
|
|
371
|
+
* @example
|
|
372
|
+
* ```ts
|
|
373
|
+
* import { parseUint8Array } from 'web-csv-toolbox';
|
|
374
|
+
*
|
|
375
|
+
* const csv = Uint8Array.from([
|
|
376
|
+
* // ...
|
|
377
|
+
* ]);
|
|
378
|
+
*
|
|
379
|
+
* const records = await parseUint8Array.toArray(csv);
|
|
380
|
+
* ```
|
|
381
|
+
*/
|
|
382
|
+
function toArray<Header extends ReadonlyArray<string>>(
|
|
383
|
+
bytes: Uint8Array,
|
|
384
|
+
options?: ParseBinaryOptions<Header>,
|
|
385
|
+
): Promise<CSVRecord<Header>[]>;
|
|
386
|
+
}
|
|
387
|
+
|
|
314
388
|
/**
|
|
315
389
|
* Parse CSV to records.
|
|
316
390
|
* This function is for parsing a binary stream.
|
|
@@ -319,15 +393,15 @@ declare namespace parseString {
|
|
|
319
393
|
* @remarks
|
|
320
394
|
* If you want to parse a string, use {@link parseStringStream}.
|
|
321
395
|
* @param stream CSV string to parse
|
|
322
|
-
* @param options Parsing options.
|
|
396
|
+
* @param options Parsing options.
|
|
323
397
|
* @returns Async iterable iterator of records.
|
|
324
398
|
*
|
|
325
|
-
* If you want array of records, use {@link
|
|
399
|
+
* If you want array of records, use {@link parseUint8ArrayStream.toArray} function.
|
|
326
400
|
*
|
|
327
401
|
* @example Parsing CSV binary
|
|
328
402
|
*
|
|
329
403
|
* ```ts
|
|
330
|
-
* import {
|
|
404
|
+
* import { parseUint8ArrayStream } from 'web-csv-toolbox';
|
|
331
405
|
*
|
|
332
406
|
* const csv = Uint8Array.from([
|
|
333
407
|
* // ...
|
|
@@ -340,16 +414,16 @@ declare namespace parseString {
|
|
|
340
414
|
* },
|
|
341
415
|
* });
|
|
342
416
|
*
|
|
343
|
-
* for await (const record of
|
|
344
|
-
*
|
|
417
|
+
* for await (const record of parseUint8ArrayStream(csv)) {
|
|
418
|
+
* console.log(record);
|
|
345
419
|
* }
|
|
346
420
|
* ```
|
|
347
421
|
*/
|
|
348
|
-
declare function
|
|
422
|
+
declare function parseUint8ArrayStream<Header extends ReadonlyArray<string>>(
|
|
349
423
|
stream: ReadableStream<Uint8Array>,
|
|
350
424
|
options?: ParseBinaryOptions<Header>,
|
|
351
425
|
): AsyncIterableIterator<CSVRecord<Header>>;
|
|
352
|
-
declare namespace
|
|
426
|
+
declare namespace parseUint8ArrayStream {
|
|
353
427
|
/**
|
|
354
428
|
* Parse CSV binary to array of records,
|
|
355
429
|
* ideal for smaller data sets.
|
|
@@ -358,7 +432,7 @@ declare namespace parseBinaryStream {
|
|
|
358
432
|
*
|
|
359
433
|
* @example Parsing CSV binary
|
|
360
434
|
* ```ts
|
|
361
|
-
* import {
|
|
435
|
+
* import { parseUint8ArrayStream } from 'web-csv-toolbox';
|
|
362
436
|
*
|
|
363
437
|
* const csv = Uint8Array.from([
|
|
364
438
|
* // ...
|
|
@@ -371,7 +445,7 @@ declare namespace parseBinaryStream {
|
|
|
371
445
|
* },
|
|
372
446
|
* });
|
|
373
447
|
*
|
|
374
|
-
* const records = await
|
|
448
|
+
* const records = await parseUint8ArrayStream.toArray(stream);
|
|
375
449
|
* console.log(records);
|
|
376
450
|
* ```
|
|
377
451
|
*/
|
|
@@ -381,6 +455,66 @@ declare namespace parseBinaryStream {
|
|
|
381
455
|
): Promise<CSVRecord<Header>[]>;
|
|
382
456
|
}
|
|
383
457
|
|
|
458
|
+
/**
|
|
459
|
+
* Parse a binary from an {@link !ArrayBuffer}.
|
|
460
|
+
*
|
|
461
|
+
* @category Middle-level API
|
|
462
|
+
|
|
463
|
+
* @param buffer CSV ArrayBuffer to parse.
|
|
464
|
+
* @param options Parsing options
|
|
465
|
+
* @returns Async iterable iterator of records.
|
|
466
|
+
*
|
|
467
|
+
* @example Parsing CSV files from ArrayBuffers
|
|
468
|
+
*
|
|
469
|
+
* ```ts
|
|
470
|
+
* import { parseArrayBuffer } from 'web-csv-toolbox';
|
|
471
|
+
*
|
|
472
|
+
* const csv = `name,age
|
|
473
|
+
* Alice,42
|
|
474
|
+
* Bob,69`;
|
|
475
|
+
*
|
|
476
|
+
* const buffer = new TextEncoder().encode(csv).buffer;
|
|
477
|
+
*
|
|
478
|
+
* for await (const record of parseArrayBuffer(buffer)) {
|
|
479
|
+
* console.log(record);
|
|
480
|
+
* }
|
|
481
|
+
* // Prints:
|
|
482
|
+
* // { name: 'Alice', age: '42' }
|
|
483
|
+
* // { name: 'Bob', age: '69' }
|
|
484
|
+
* ```
|
|
485
|
+
*/
|
|
486
|
+
declare function parseArrayBuffer<Header extends ReadonlyArray<string>>(
|
|
487
|
+
buffer: ArrayBuffer,
|
|
488
|
+
options?: ParseBinaryOptions<Header>,
|
|
489
|
+
): AsyncIterableIterator<CSVRecord<Header>>;
|
|
490
|
+
declare namespace parseArrayBuffer {
|
|
491
|
+
/**
|
|
492
|
+
* Parse a binary from an {@link !ArrayBuffer} to an array of records.
|
|
493
|
+
* @param buffer CSV ArrayBuffer to parse.
|
|
494
|
+
* @param options Parsing options
|
|
495
|
+
* @returns Array of records
|
|
496
|
+
* @example
|
|
497
|
+
* ```ts
|
|
498
|
+
* import { parseArrayBuffer } from 'web-csv-toolbox';
|
|
499
|
+
*
|
|
500
|
+
* const csv = `name,age
|
|
501
|
+
* Alice,42
|
|
502
|
+
* Bob,69`;
|
|
503
|
+
*
|
|
504
|
+
* const buffer = new TextEncoder().encode(csv).buffer;
|
|
505
|
+
*
|
|
506
|
+
* const records = await parseArrayBuffer.toArray(buffer);
|
|
507
|
+
* console.log(records);
|
|
508
|
+
* // Prints:
|
|
509
|
+
* // [ { name: 'Alice', age: '42' }, { name: 'Bob', age: '69' } ]
|
|
510
|
+
* ```
|
|
511
|
+
*/
|
|
512
|
+
function toArray<Header extends ReadonlyArray<string>>(
|
|
513
|
+
buffer: ArrayBuffer,
|
|
514
|
+
options?: ParseBinaryOptions<Header>,
|
|
515
|
+
): Promise<CSVRecord<Header>[]>;
|
|
516
|
+
}
|
|
517
|
+
|
|
384
518
|
/**
|
|
385
519
|
* Parse CSV string stream to records.
|
|
386
520
|
*
|
|
@@ -519,11 +653,11 @@ declare namespace parseResponse {
|
|
|
519
653
|
* {@link !ReadableStream} of {@link !String} and {@link !Uint8Array} are supported.
|
|
520
654
|
*
|
|
521
655
|
* @remarks
|
|
522
|
-
* {@link parseStringStream} and {@link
|
|
656
|
+
* {@link parseStringStream} and {@link parseUint8ArrayStream} are used internally.
|
|
523
657
|
* If you known the type of the stream, it performs better to use them directly.
|
|
524
658
|
*
|
|
525
659
|
* If you want to parse a string, use {@link parseStringStream}.
|
|
526
|
-
* If you want to parse a Uint8Array, use {@link
|
|
660
|
+
* If you want to parse a Uint8Array, use {@link parseUint8ArrayStream}.
|
|
527
661
|
*
|
|
528
662
|
* @category Middle-level API
|
|
529
663
|
* @param csv CSV string to parse
|
|
@@ -610,17 +744,20 @@ declare namespace parseStream {
|
|
|
610
744
|
* @category High-level API
|
|
611
745
|
*
|
|
612
746
|
* @remarks
|
|
613
|
-
* {@link parseString}, {@link
|
|
747
|
+
* {@link parseString}, {@link parseUint8ArrayStream},
|
|
748
|
+
* {@link parseArrayBuffer}, {@link parseUint8Array},
|
|
614
749
|
* {@link parseStringStream} and {@link parseResponse} are used internally.
|
|
615
750
|
*
|
|
616
751
|
* If you known the type of the CSV, it performs better to use them directly.
|
|
617
752
|
*
|
|
618
|
-
* | If you want to parse a... | Use...
|
|
619
|
-
* | ----------------------------------- |
|
|
620
|
-
* | {@link !String} | {@link parseString}
|
|
621
|
-
* | {@link !ReadableStream}<string> | {@link parseStringStream}
|
|
622
|
-
* | {@link !ReadableStream}<Uint8Array> | {@link
|
|
623
|
-
* | {@link !Response} | {@link parseResponse}
|
|
753
|
+
* | If you want to parse a... | Use... | Data are treated as... |
|
|
754
|
+
* | ----------------------------------- | ----------------------------- | ---------------------- |
|
|
755
|
+
* | {@link !String} | {@link parseString} | String |
|
|
756
|
+
* | {@link !ReadableStream}<string> | {@link parseStringStream} | String |
|
|
757
|
+
* | {@link !ReadableStream}<Uint8Array> | {@link parseUint8ArrayStream} | Binary |
|
|
758
|
+
* | {@link !Response} | {@link parseResponse} | Binary |
|
|
759
|
+
* | {@link !ArrayBuffer} | {@link parseArrayBuffer} | Binary |
|
|
760
|
+
* | {@link !Uint8Array} | {@link parseUint8Array} | Binary |
|
|
624
761
|
*
|
|
625
762
|
* @example Parsing CSV files from strings
|
|
626
763
|
*
|
|
@@ -699,7 +836,7 @@ declare namespace parseStream {
|
|
|
699
836
|
* ```
|
|
700
837
|
*/
|
|
701
838
|
declare function parse<Header extends ReadonlyArray<string>>(
|
|
702
|
-
csv:
|
|
839
|
+
csv: CSVString,
|
|
703
840
|
options?: ParseOptions<Header>,
|
|
704
841
|
): AsyncIterableIterator<CSVRecord<Header>>;
|
|
705
842
|
/**
|
|
@@ -739,7 +876,7 @@ declare function parse<Header extends ReadonlyArray<string>>(
|
|
|
739
876
|
* ```
|
|
740
877
|
*/
|
|
741
878
|
declare function parse<Header extends ReadonlyArray<string>>(
|
|
742
|
-
csv:
|
|
879
|
+
csv: CSVBinary,
|
|
743
880
|
options?: ParseBinaryOptions<Header>,
|
|
744
881
|
): AsyncIterableIterator<CSVRecord<Header>>;
|
|
745
882
|
declare namespace parse {
|
|
@@ -763,7 +900,7 @@ declare namespace parse {
|
|
|
763
900
|
* ```
|
|
764
901
|
*/
|
|
765
902
|
function toArray<Header extends ReadonlyArray<string>>(
|
|
766
|
-
csv:
|
|
903
|
+
csv: CSVString,
|
|
767
904
|
options?: ParseOptions<Header>,
|
|
768
905
|
): Promise<CSVRecord<Header>[]>;
|
|
769
906
|
/**
|
|
@@ -782,14 +919,17 @@ declare namespace parse {
|
|
|
782
919
|
* ```
|
|
783
920
|
*/
|
|
784
921
|
function toArray<Header extends ReadonlyArray<string>>(
|
|
785
|
-
csv:
|
|
786
|
-
options?:
|
|
922
|
+
csv: CSVBinary,
|
|
923
|
+
options?: ParseBinaryOptions<Header>,
|
|
787
924
|
): Promise<CSVRecord<Header>[]>;
|
|
788
925
|
}
|
|
789
926
|
|
|
790
927
|
export {
|
|
791
928
|
type BinaryOptions,
|
|
929
|
+
type CSV,
|
|
930
|
+
type CSVBinary,
|
|
792
931
|
type CSVRecord,
|
|
932
|
+
type CSVString,
|
|
793
933
|
type CommonOptions,
|
|
794
934
|
Field,
|
|
795
935
|
FieldDelimiter,
|
|
@@ -802,9 +942,11 @@ export {
|
|
|
802
942
|
type Token,
|
|
803
943
|
type TokenType,
|
|
804
944
|
parse,
|
|
805
|
-
|
|
945
|
+
parseArrayBuffer,
|
|
806
946
|
parseResponse,
|
|
807
947
|
parseStream,
|
|
808
948
|
parseString,
|
|
809
949
|
parseStringStream,
|
|
950
|
+
parseUint8Array,
|
|
951
|
+
parseUint8ArrayStream,
|
|
810
952
|
};
|
package/lib/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
const FieldDelimiter = Symbol.for("web-
|
|
2
|
-
const RecordDelimiter = Symbol.for("web-
|
|
3
|
-
const Field = Symbol.for("web-
|
|
1
|
+
const FieldDelimiter = Symbol.for("web-csv-toolbox.FieldDelimiter");
|
|
2
|
+
const RecordDelimiter = Symbol.for("web-csv-toolbox.RecordDelimiter");
|
|
3
|
+
const Field = Symbol.for("web-csv-toolbox.Field");
|
|
4
4
|
const CR = "\r";
|
|
5
5
|
const CRLF = "\r\n";
|
|
6
6
|
const LF = "\n";
|
|
@@ -122,7 +122,7 @@ class LexerTransformer extends TransformStream {
|
|
|
122
122
|
if (flush === false && this.#buffer.endsWith(this.#quotation)) {
|
|
123
123
|
return null;
|
|
124
124
|
}
|
|
125
|
-
return this.extractQuotedString();
|
|
125
|
+
return this.extractQuotedString(flush);
|
|
126
126
|
}
|
|
127
127
|
const match = this.#matcher.exec(this.#buffer);
|
|
128
128
|
if (match) {
|
|
@@ -134,7 +134,7 @@ class LexerTransformer extends TransformStream {
|
|
|
134
134
|
}
|
|
135
135
|
return null;
|
|
136
136
|
}
|
|
137
|
-
extractQuotedString() {
|
|
137
|
+
extractQuotedString(flush) {
|
|
138
138
|
let end = this.#quotationLength;
|
|
139
139
|
let value = "";
|
|
140
140
|
while (end < this.#buffer.length) {
|
|
@@ -153,6 +153,24 @@ class LexerTransformer extends TransformStream {
|
|
|
153
153
|
if (
|
|
154
154
|
this.#buffer.slice(end, end + this.#quotationLength) === this.quotation
|
|
155
155
|
) {
|
|
156
|
+
if (
|
|
157
|
+
flush === false &&
|
|
158
|
+
end + this.#quotationLength < this.#buffer.length &&
|
|
159
|
+
this.#buffer.slice(
|
|
160
|
+
end + this.#quotationLength,
|
|
161
|
+
this.#demiliterLength,
|
|
162
|
+
) !== this.demiliter &&
|
|
163
|
+
this.#buffer.slice(
|
|
164
|
+
end + this.#quotationLength,
|
|
165
|
+
end + this.#quotationLength + 2,
|
|
166
|
+
) !== CRLF &&
|
|
167
|
+
this.#buffer.slice(
|
|
168
|
+
end + this.#quotationLength,
|
|
169
|
+
end + this.#quotationLength + 1,
|
|
170
|
+
) !== LF
|
|
171
|
+
) {
|
|
172
|
+
return null;
|
|
173
|
+
}
|
|
156
174
|
this.#buffer = this.#buffer.slice(end + this.#quotationLength);
|
|
157
175
|
return { type: Field, value };
|
|
158
176
|
}
|
|
@@ -267,15 +285,23 @@ async function* parseStringStream(stream, options) {
|
|
|
267
285
|
}
|
|
268
286
|
}
|
|
269
287
|
((parseStringStream) => {
|
|
270
|
-
parseStringStream
|
|
288
|
+
Object.defineProperty(parseStringStream, "toArray", {
|
|
289
|
+
enumerable: true,
|
|
290
|
+
writable: false,
|
|
291
|
+
value: toArray,
|
|
292
|
+
});
|
|
271
293
|
})(parseStringStream || (parseStringStream = {}));
|
|
272
294
|
async function* parseString(csv, options) {
|
|
273
295
|
yield* parseStringStream(new SingleValueReadableStream(csv), options);
|
|
274
296
|
}
|
|
275
297
|
((parseString) => {
|
|
276
|
-
parseString
|
|
298
|
+
Object.defineProperty(parseString, "toArray", {
|
|
299
|
+
enumerable: true,
|
|
300
|
+
writable: false,
|
|
301
|
+
value: toArray,
|
|
302
|
+
});
|
|
277
303
|
})(parseString || (parseString = {}));
|
|
278
|
-
async function*
|
|
304
|
+
async function* parseUint8ArrayStream(stream, options) {
|
|
279
305
|
const { charset, fatal, ignoreBOM, decomposition } = options ?? {};
|
|
280
306
|
yield* parseStringStream(
|
|
281
307
|
[
|
|
@@ -285,9 +311,33 @@ async function* parseBinaryStream(stream, options) {
|
|
|
285
311
|
options,
|
|
286
312
|
);
|
|
287
313
|
}
|
|
288
|
-
((
|
|
289
|
-
|
|
290
|
-
|
|
314
|
+
((parseUint8ArrayStream) => {
|
|
315
|
+
Object.defineProperty(parseUint8ArrayStream, "toArray", {
|
|
316
|
+
enumerable: true,
|
|
317
|
+
writable: false,
|
|
318
|
+
value: toArray,
|
|
319
|
+
});
|
|
320
|
+
})(parseUint8ArrayStream || (parseUint8ArrayStream = {}));
|
|
321
|
+
function parseUint8Array(bytes, options) {
|
|
322
|
+
return parseUint8ArrayStream(new SingleValueReadableStream(bytes), options);
|
|
323
|
+
}
|
|
324
|
+
((parseUint8Array) => {
|
|
325
|
+
Object.defineProperty(parseUint8Array, "toArray", {
|
|
326
|
+
enumerable: true,
|
|
327
|
+
writable: false,
|
|
328
|
+
value: toArray,
|
|
329
|
+
});
|
|
330
|
+
})(parseUint8Array || (parseUint8Array = {}));
|
|
331
|
+
function parseArrayBuffer(buffer, options) {
|
|
332
|
+
return parseUint8Array(new Uint8Array(buffer), options);
|
|
333
|
+
}
|
|
334
|
+
((parseArrayBuffer) => {
|
|
335
|
+
Object.defineProperty(parseArrayBuffer, "toArray", {
|
|
336
|
+
enumerable: true,
|
|
337
|
+
writable: false,
|
|
338
|
+
value: toArray,
|
|
339
|
+
});
|
|
340
|
+
})(parseArrayBuffer || (parseArrayBuffer = {}));
|
|
291
341
|
function parseMime(contentType) {
|
|
292
342
|
const [type, ...parameters] = contentType.split(";");
|
|
293
343
|
const result = {
|
|
@@ -312,14 +362,18 @@ function parseResponse(response, options) {
|
|
|
312
362
|
if (response.body === null) {
|
|
313
363
|
throw new Error("Response body is null");
|
|
314
364
|
}
|
|
315
|
-
return
|
|
365
|
+
return parseUint8ArrayStream(response.body, {
|
|
316
366
|
decomposition,
|
|
317
367
|
charset,
|
|
318
368
|
...options,
|
|
319
369
|
});
|
|
320
370
|
}
|
|
321
371
|
((parseResponse) => {
|
|
322
|
-
parseResponse
|
|
372
|
+
Object.defineProperty(parseResponse, "toArray", {
|
|
373
|
+
enumerable: true,
|
|
374
|
+
writable: false,
|
|
375
|
+
value: toArray,
|
|
376
|
+
});
|
|
323
377
|
})(parseResponse || (parseResponse = {}));
|
|
324
378
|
async function* parseStream(stream, options) {
|
|
325
379
|
const [branch1, branch2] = stream.tee();
|
|
@@ -329,15 +383,23 @@ async function* parseStream(stream, options) {
|
|
|
329
383
|
if (typeof firstChunk === "string") {
|
|
330
384
|
yield* parseStringStream(branch2, options);
|
|
331
385
|
} else if (firstChunk instanceof Uint8Array) {
|
|
332
|
-
yield*
|
|
386
|
+
yield* parseUint8ArrayStream(branch2, options);
|
|
333
387
|
}
|
|
334
388
|
}
|
|
335
389
|
((parseStream) => {
|
|
336
|
-
parseStream
|
|
390
|
+
Object.defineProperty(parseStream, "toArray", {
|
|
391
|
+
enumerable: true,
|
|
392
|
+
writable: false,
|
|
393
|
+
value: toArray,
|
|
394
|
+
});
|
|
337
395
|
})(parseStream || (parseStream = {}));
|
|
338
396
|
async function* parse(csv, options) {
|
|
339
397
|
if (typeof csv === "string") {
|
|
340
398
|
yield* parseString(csv, options);
|
|
399
|
+
} else if (csv instanceof Uint8Array) {
|
|
400
|
+
yield* parseUint8Array(csv, options);
|
|
401
|
+
} else if (csv instanceof ArrayBuffer) {
|
|
402
|
+
yield* parseArrayBuffer(csv, options);
|
|
341
403
|
} else if (csv instanceof ReadableStream) {
|
|
342
404
|
yield* parseStream(csv, options);
|
|
343
405
|
} else if (csv instanceof Response) {
|
|
@@ -345,7 +407,11 @@ async function* parse(csv, options) {
|
|
|
345
407
|
}
|
|
346
408
|
}
|
|
347
409
|
((parse) => {
|
|
348
|
-
parse
|
|
410
|
+
Object.defineProperty(parse, "toArray", {
|
|
411
|
+
enumerable: true,
|
|
412
|
+
writable: false,
|
|
413
|
+
value: toArray,
|
|
414
|
+
});
|
|
349
415
|
})(parse || (parse = {}));
|
|
350
416
|
export {
|
|
351
417
|
Field,
|
|
@@ -354,9 +420,11 @@ export {
|
|
|
354
420
|
RecordAssemblerTransformar,
|
|
355
421
|
RecordDelimiter,
|
|
356
422
|
parse,
|
|
357
|
-
|
|
423
|
+
parseArrayBuffer,
|
|
358
424
|
parseResponse,
|
|
359
425
|
parseStream,
|
|
360
426
|
parseString,
|
|
361
427
|
parseStringStream,
|
|
428
|
+
parseUint8Array,
|
|
429
|
+
parseUint8ArrayStream,
|
|
362
430
|
};
|
package/lib/index.umd.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).CSV={})}(this,(function(e){"use strict";const t=Symbol.for("web-
|
|
1
|
+
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).CSV={})}(this,(function(e){"use strict";const t=Symbol.for("web-csv-toolbox.FieldDelimiter"),i=Symbol.for("web-csv-toolbox.RecordDelimiter"),r=Symbol.for("web-csv-toolbox.Field"),n="\r\n",o="\n";function s(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}class a extends TransformStream{#e;#t;#i;#r;#n;#o="";get demiliter(){return this.#e}get quotation(){return this.#i}constructor({demiliter:e=",",quotation:t='"'}={}){!function(e){if("string"==typeof e.quotation&&0===e.quotation.length)throw new Error("quotation must not be empty");if("string"==typeof e.demiliter&&0===e.demiliter.length)throw new Error("demiliter must not be empty");if(e.quotation.includes(o)||e.quotation.includes("\r"))throw new Error("quotation must not include CR or LF");if(e.demiliter.includes(o)||e.demiliter.includes("\r"))throw new Error("demiliter must not include CR or LF");if(e.demiliter.includes(e.quotation)||e.quotation.includes(e.demiliter))throw new Error("demiliter and quotation must not include each other as a substring")}({demiliter:e,quotation:t}),super({transform:(e,t)=>{if(0!==e.length){this.#o+=e;for(const e of this.#s({flush:!1}))t.enqueue(e)}},flush:e=>{for(const t of this.#s({flush:!0}))e.enqueue(t)}}),this.#e=e,this.#t=e.length,this.#i=t,this.#r=t.length;const i=s(e),r=s(t);this.#n=new RegExp(`^(?:(?!${r})(?!${i})(?![\\r\\n]))([\\S\\s\\uFEFF\\xA0]+?)(?=${r}|${i}|\\r|\\n|$)`)}*#s({flush:e}){let n=null;for(let o;o=this.#a({flush:e});)switch(o.type){case r:n?n.value+=o.value:n=o;break;case t:case i:n&&(yield n,n=null),yield o}n&&(yield n)}#a({flush:e=!1}={}){if(0===this.#o.length)return null;if(this.#o.startsWith(n))return this.#o=this.#o.slice(2),{type:i,value:n};if(this.#o.startsWith(o))return this.#o=this.#o.slice(1),{type:i,value:o};if(this.#o.startsWith(this.#e))return this.#o=this.#o.slice(this.#t),{type:t,value:this.#e};if(this.#o.startsWith(this.#i))return!1===e&&this.#o.endsWith(this.#i)?null:this.extractQuotedString(e);const s=this.#n.exec(this.#o);return s?!1===e&&s[0].length===this.#o.length?null:(this.#o=this.#o.slice(s[0].length),{type:r,value:s[0]}):null}extractQuotedString(e){let t=this.#r,i="";for(;t<this.#o.length;)if(this.#o.slice(t,t+this.#r)!==this.quotation||this.#o.slice(t+this.#r,t+2*this.#r)!==this.quotation){if(this.#o.slice(t,t+this.#r)===this.quotation)return!1===e&&t+this.#r<this.#o.length&&this.#o.slice(t+this.#r,this.#t)!==this.demiliter&&this.#o.slice(t+this.#r,t+this.#r+2)!==n&&this.#o.slice(t+this.#r,t+this.#r+1)!==o?null:(this.#o=this.#o.slice(t+this.#r),{type:r,value:i});i+=this.#o[t],t++}else i+=this.quotation,t+=2*this.#r;return null}}class u extends TransformStream{#u=0;#l=[];#h;#f=!1;constructor(e={}){super({transform:(e,n)=>{switch(e.type){case r:this.#f=!0,this.#l[this.#u]=e.value;break;case t:this.#u++;break;case i:if(void 0===this.#h)this.#c(this.#l);else if(this.#f){const e=Object.fromEntries(this.#h.filter((e=>e)).map(((e,t)=>[e,this.#l.at(t)])));n.enqueue(e)}this.#u=0,this.#l=new Array(this.#h?.length),this.#f=!1}},flush:e=>{if(0!==this.#u&&void 0!==this.#h&&this.#f){const t=Object.fromEntries(this.#h.filter((e=>e)).map(((e,t)=>[e,this.#l.at(t)])));e.enqueue(t)}}}),void 0!==e.header&&Array.isArray(e.header)&&this.#c(e.header)}#c(e){if(this.#h=e,0===this.#h.length)throw new Error("The header must not be empty.");if(new Set(this.#h).size!==this.#h.length)throw new Error("The header must not contain duplicate fields.")}}class l extends ReadableStream{constructor(e){super({start(t){t.enqueue(e),t.close()}})}}async function h(...e){const t=[];for await(const i of this(...e))t.push(i);return t}async function*f(e,t){let i;const r=new ReadableStream({start:e=>i=e});await e.pipeThrough(new a(t)).pipeThrough(new u(t)).pipeTo(new WritableStream({write:e=>i.enqueue(e),close:()=>i.close()}));const n=r.getReader();try{for(;;){const{value:e,done:t}=await n.read();if(t)break;yield e}}finally{n.releaseLock()}}async function*c(e,t){yield*f(new l(e),t)}async function*d(e,t){const{charset:i,fatal:r,ignoreBOM:n,decomposition:o}=t??{};yield*f([...o?[new DecompressionStream(o)]:[],new TextDecoderStream(i,{fatal:r,ignoreBOM:n})].reduce(((e,t)=>e.pipeThrough(t)),e),t)}function m(e,t){return d(new l(e),t)}function b(e,t){return m(new Uint8Array(e),t)}function y(e,t){const{headers:i}=e,r=i.get("content-type")??"text/csv",n=function(e){const[t,...i]=e.split(";"),r={type:t.trim(),parameters:{}};for(const e of i){const[t,i]=e.split("=");r.parameters[t.trim()]=i.trim()}return r}(r);if("text/csv"!==n.type)throw new Error(`Invalid mime type: ${r}`);const o=i.get("content-encoding")??void 0,s=n.parameters.charset??"utf-8";if(null===e.body)throw new Error("Response body is null");return d(e.body,{decomposition:o,charset:s,...t})}async function*p(e,t){const[i,r]=e.tee(),n=i.getReader(),{value:o}=await n.read();n.releaseLock(),"string"==typeof o?yield*f(r,t):o instanceof Uint8Array&&(yield*d(r,t))}async function*g(e,t){"string"==typeof e?yield*c(e,t):e instanceof Uint8Array?yield*m(e,t):e instanceof ArrayBuffer?yield*b(e,t):e instanceof ReadableStream?yield*p(e,t):e instanceof Response&&(yield*y(e,t))}!function(e){Object.defineProperty(e,"toArray",{enumerable:!0,writable:!1,value:h})}(f||(f={})),function(e){Object.defineProperty(e,"toArray",{enumerable:!0,writable:!1,value:h})}(c||(c={})),function(e){Object.defineProperty(e,"toArray",{enumerable:!0,writable:!1,value:h})}(d||(d={})),function(e){Object.defineProperty(e,"toArray",{enumerable:!0,writable:!1,value:h})}(m||(m={})),function(e){Object.defineProperty(e,"toArray",{enumerable:!0,writable:!1,value:h})}(b||(b={})),function(e){Object.defineProperty(e,"toArray",{enumerable:!0,writable:!1,value:h})}(y||(y={})),function(e){Object.defineProperty(e,"toArray",{enumerable:!0,writable:!1,value:h})}(p||(p={})),function(e){Object.defineProperty(e,"toArray",{enumerable:!0,writable:!1,value:h})}(g||(g={})),e.Field=r,e.FieldDelimiter=t,e.LexerTransformer=a,e.RecordAssemblerTransformar=u,e.RecordDelimiter=i,e.parse=g,e.parseArrayBuffer=b,e.parseResponse=y,e.parseStream=p,e.parseString=c,e.parseStringStream=f,e.parseUint8Array=m,e.parseUint8ArrayStream=d}));
|