jtcsv 2.1.3 → 2.2.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/LICENSE +1 -1
- package/README.md +60 -341
- package/bin/jtcsv.js +2462 -1372
- package/csv-to-json.js +35 -26
- package/dist/jtcsv.cjs.js +807 -133
- package/dist/jtcsv.cjs.js.map +1 -1
- package/dist/jtcsv.esm.js +800 -134
- package/dist/jtcsv.esm.js.map +1 -1
- package/dist/jtcsv.umd.js +807 -133
- package/dist/jtcsv.umd.js.map +1 -1
- package/errors.js +20 -0
- package/examples/browser-vanilla.html +37 -0
- package/examples/cli-batch-processing.js +38 -0
- package/examples/error-handling.js +324 -0
- package/examples/ndjson-processing.js +434 -0
- package/examples/react-integration.jsx +637 -0
- package/examples/schema-validation.js +640 -0
- package/examples/simple-usage.js +10 -7
- package/examples/typescript-example.ts +486 -0
- package/examples/web-workers-advanced.js +28 -0
- package/index.d.ts +2 -0
- package/json-save.js +2 -1
- package/json-to-csv.js +171 -131
- package/package.json +20 -4
- package/plugins/README.md +41 -467
- package/plugins/express-middleware/README.md +32 -274
- package/plugins/hono/README.md +16 -13
- package/plugins/nestjs/README.md +13 -11
- package/plugins/nextjs-api/README.md +28 -423
- package/plugins/nextjs-api/index.js +1 -2
- package/plugins/nextjs-api/route.js +1 -2
- package/plugins/nuxt/README.md +6 -7
- package/plugins/remix/README.md +9 -9
- package/plugins/sveltekit/README.md +8 -8
- package/plugins/trpc/README.md +8 -5
- package/src/browser/browser-functions.js +33 -3
- package/src/browser/csv-to-json-browser.js +269 -11
- package/src/browser/errors-browser.js +19 -1
- package/src/browser/index.js +39 -5
- package/src/browser/streams.js +393 -0
- package/src/browser/workers/csv-parser.worker.js +20 -2
- package/src/browser/workers/worker-pool.js +507 -447
- package/src/core/plugin-system.js +4 -0
- package/src/engines/fast-path-engine.js +31 -23
- package/src/errors.js +26 -0
- package/src/formats/ndjson-parser.js +54 -5
- package/src/formats/tsv-parser.js +4 -1
- package/src/utils/schema-validator.js +594 -0
- package/src/utils/transform-loader.js +205 -0
- package/src/web-server/index.js +683 -0
- package/stream-csv-to-json.js +16 -87
- package/stream-json-to-csv.js +18 -86
|
@@ -10,15 +10,10 @@ import {
|
|
|
10
10
|
} from './errors-browser.js';
|
|
11
11
|
|
|
12
12
|
/**
|
|
13
|
-
* Валидация
|
|
13
|
+
* Валидация опций парсинга
|
|
14
14
|
* @private
|
|
15
15
|
*/
|
|
16
|
-
function
|
|
17
|
-
// Validate CSV input
|
|
18
|
-
if (typeof csv !== 'string') {
|
|
19
|
-
throw new ValidationError('Input must be a CSV string');
|
|
20
|
-
}
|
|
21
|
-
|
|
16
|
+
function validateCsvOptions(options) {
|
|
22
17
|
// Validate options
|
|
23
18
|
if (options && typeof options !== 'object') {
|
|
24
19
|
throw new ConfigurationError('Options must be an object');
|
|
@@ -47,10 +42,27 @@ function validateCsvInput(csv, options) {
|
|
|
47
42
|
if (options?.maxRows !== undefined && (typeof options.maxRows !== 'number' || options.maxRows <= 0)) {
|
|
48
43
|
throw new ConfigurationError('maxRows must be a positive number');
|
|
49
44
|
}
|
|
45
|
+
|
|
46
|
+
if (options?.warnExtraFields !== undefined && typeof options.warnExtraFields !== 'boolean') {
|
|
47
|
+
throw new ConfigurationError('warnExtraFields must be a boolean');
|
|
48
|
+
}
|
|
50
49
|
|
|
51
50
|
return true;
|
|
52
51
|
}
|
|
53
52
|
|
|
53
|
+
/**
|
|
54
|
+
* Валидация CSV ввода и опций
|
|
55
|
+
* @private
|
|
56
|
+
*/
|
|
57
|
+
function validateCsvInput(csv, options) {
|
|
58
|
+
// Validate CSV input
|
|
59
|
+
if (typeof csv !== 'string') {
|
|
60
|
+
throw new ValidationError('Input must be a CSV string');
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
return validateCsvOptions(options);
|
|
64
|
+
}
|
|
65
|
+
|
|
54
66
|
/**
|
|
55
67
|
* Парсинг одной строки CSV с правильным экранированием
|
|
56
68
|
* @private
|
|
@@ -205,6 +217,95 @@ function parseCsvValue(value, options) {
|
|
|
205
217
|
return result;
|
|
206
218
|
}
|
|
207
219
|
|
|
220
|
+
function isSimpleCsv(csv) {
|
|
221
|
+
return csv.indexOf('"') === -1 && csv.indexOf('\\') === -1;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
function parseSimpleCsv(csv, delimiter, options) {
|
|
225
|
+
const {
|
|
226
|
+
hasHeaders = true,
|
|
227
|
+
renameMap = {},
|
|
228
|
+
trim = true,
|
|
229
|
+
parseNumbers = false,
|
|
230
|
+
parseBooleans = false,
|
|
231
|
+
maxRows
|
|
232
|
+
} = options;
|
|
233
|
+
|
|
234
|
+
const result = [];
|
|
235
|
+
let headers = null;
|
|
236
|
+
let fieldStart = 0;
|
|
237
|
+
let currentRow = [];
|
|
238
|
+
let rowHasData = false;
|
|
239
|
+
let rowCount = 0;
|
|
240
|
+
|
|
241
|
+
const finalizeRow = (fields) => {
|
|
242
|
+
if (fields.length === 1 && fields[0].trim() === '') {
|
|
243
|
+
return;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
if (!headers) {
|
|
247
|
+
if (hasHeaders) {
|
|
248
|
+
headers = fields.map(header => {
|
|
249
|
+
const trimmed = trim ? header.trim() : header;
|
|
250
|
+
return renameMap[trimmed] || trimmed;
|
|
251
|
+
});
|
|
252
|
+
return;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
headers = fields.map((_, index) => `column${index + 1}`);
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
rowCount++;
|
|
259
|
+
if (maxRows && rowCount > maxRows) {
|
|
260
|
+
throw new LimitError(
|
|
261
|
+
`CSV size exceeds maximum limit of ${maxRows} rows`,
|
|
262
|
+
maxRows,
|
|
263
|
+
rowCount
|
|
264
|
+
);
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
const row = {};
|
|
268
|
+
const fieldCount = Math.min(fields.length, headers.length);
|
|
269
|
+
for (let i = 0; i < fieldCount; i++) {
|
|
270
|
+
row[headers[i]] = parseCsvValue(fields[i], { trim, parseNumbers, parseBooleans });
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
result.push(row);
|
|
274
|
+
};
|
|
275
|
+
|
|
276
|
+
let i = 0;
|
|
277
|
+
while (i <= csv.length) {
|
|
278
|
+
const char = i < csv.length ? csv[i] : '\n';
|
|
279
|
+
|
|
280
|
+
if (char !== '\r' && char !== '\n' && char !== ' ' && char !== '\t') {
|
|
281
|
+
rowHasData = true;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
if (char === delimiter || char === '\n' || char === '\r' || i === csv.length) {
|
|
285
|
+
const field = csv.slice(fieldStart, i);
|
|
286
|
+
currentRow.push(field);
|
|
287
|
+
|
|
288
|
+
if (char === '\n' || char === '\r' || i === csv.length) {
|
|
289
|
+
if (rowHasData || currentRow.length > 1) {
|
|
290
|
+
finalizeRow(currentRow);
|
|
291
|
+
}
|
|
292
|
+
currentRow = [];
|
|
293
|
+
rowHasData = false;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
if (char === '\r' && csv[i + 1] === '\n') {
|
|
297
|
+
i++;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
fieldStart = i + 1;
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
i++;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
return result;
|
|
307
|
+
}
|
|
308
|
+
|
|
208
309
|
/**
|
|
209
310
|
* Автоматическое определение разделителя CSV
|
|
210
311
|
*
|
|
@@ -285,7 +386,8 @@ export function csvToJson(csv, options = {}) {
|
|
|
285
386
|
trim = true,
|
|
286
387
|
parseNumbers = false,
|
|
287
388
|
parseBooleans = false,
|
|
288
|
-
maxRows
|
|
389
|
+
maxRows,
|
|
390
|
+
warnExtraFields = true
|
|
289
391
|
} = opts;
|
|
290
392
|
|
|
291
393
|
// Определение разделителя
|
|
@@ -300,6 +402,17 @@ export function csvToJson(csv, options = {}) {
|
|
|
300
402
|
return [];
|
|
301
403
|
}
|
|
302
404
|
|
|
405
|
+
if (isSimpleCsv(csv)) {
|
|
406
|
+
return parseSimpleCsv(csv, finalDelimiter, {
|
|
407
|
+
hasHeaders,
|
|
408
|
+
renameMap,
|
|
409
|
+
trim,
|
|
410
|
+
parseNumbers,
|
|
411
|
+
parseBooleans,
|
|
412
|
+
maxRows
|
|
413
|
+
});
|
|
414
|
+
}
|
|
415
|
+
|
|
303
416
|
// Парсинг CSV с обработкой кавычек и переносов строк
|
|
304
417
|
const lines = [];
|
|
305
418
|
let currentLine = '';
|
|
@@ -416,7 +529,8 @@ export function csvToJson(csv, options = {}) {
|
|
|
416
529
|
}
|
|
417
530
|
|
|
418
531
|
// Предупреждение о лишних полях
|
|
419
|
-
|
|
532
|
+
const isDev = typeof process !== 'undefined' && process.env && process.env.NODE_ENV === 'development';
|
|
533
|
+
if (fields.length > headers.length && warnExtraFields && isDev) {
|
|
420
534
|
console.warn(`[jtcsv] Line ${i + 1}: ${fields.length - headers.length} extra fields ignored`);
|
|
421
535
|
}
|
|
422
536
|
|
|
@@ -433,10 +547,154 @@ export function csvToJson(csv, options = {}) {
|
|
|
433
547
|
}, 'PARSE_FAILED', { function: 'csvToJson' });
|
|
434
548
|
}
|
|
435
549
|
|
|
550
|
+
export async function* csvToJsonIterator(input, options = {}) {
|
|
551
|
+
const opts = options && typeof options === 'object' ? options : {};
|
|
552
|
+
validateCsvOptions(opts);
|
|
553
|
+
|
|
554
|
+
if (typeof input === 'string') {
|
|
555
|
+
const rows = csvToJson(input, options);
|
|
556
|
+
for (const row of rows) {
|
|
557
|
+
yield row;
|
|
558
|
+
}
|
|
559
|
+
return;
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
const {
|
|
563
|
+
delimiter,
|
|
564
|
+
autoDetect = true,
|
|
565
|
+
candidates = [';', ',', '\t', '|'],
|
|
566
|
+
hasHeaders = true,
|
|
567
|
+
renameMap = {},
|
|
568
|
+
trim = true,
|
|
569
|
+
parseNumbers = false,
|
|
570
|
+
parseBooleans = false,
|
|
571
|
+
maxRows
|
|
572
|
+
} = opts;
|
|
573
|
+
|
|
574
|
+
const stream = (input instanceof Blob && input.stream) ? input.stream() : input;
|
|
575
|
+
if (!stream || typeof stream.getReader !== 'function') {
|
|
576
|
+
throw new ValidationError('Input must be a CSV string, Blob/File, or ReadableStream');
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
const reader = stream.getReader();
|
|
580
|
+
const decoder = new TextDecoder('utf-8');
|
|
581
|
+
let buffer = '';
|
|
582
|
+
let insideQuotes = false;
|
|
583
|
+
let headers = null;
|
|
584
|
+
let rowCount = 0;
|
|
585
|
+
let lineNumber = 0;
|
|
586
|
+
let finalDelimiter = delimiter;
|
|
587
|
+
let delimiterResolved = Boolean(finalDelimiter);
|
|
588
|
+
|
|
589
|
+
const processFields = (fields) => {
|
|
590
|
+
if (fields.length === 1 && fields[0].trim() === '') {
|
|
591
|
+
return null;
|
|
592
|
+
}
|
|
593
|
+
|
|
594
|
+
rowCount++;
|
|
595
|
+
if (maxRows && rowCount > maxRows) {
|
|
596
|
+
throw new LimitError(
|
|
597
|
+
`CSV size exceeds maximum limit of ${maxRows} rows`,
|
|
598
|
+
maxRows,
|
|
599
|
+
rowCount
|
|
600
|
+
);
|
|
601
|
+
}
|
|
602
|
+
|
|
603
|
+
const row = {};
|
|
604
|
+
const fieldCount = Math.min(fields.length, headers.length);
|
|
605
|
+
for (let j = 0; j < fieldCount; j++) {
|
|
606
|
+
row[headers[j]] = parseCsvValue(fields[j], { trim, parseNumbers, parseBooleans });
|
|
607
|
+
}
|
|
608
|
+
return row;
|
|
609
|
+
};
|
|
610
|
+
|
|
611
|
+
const processLine = (line) => {
|
|
612
|
+
lineNumber++;
|
|
613
|
+
let cleanLine = line;
|
|
614
|
+
if (cleanLine.endsWith('\r')) {
|
|
615
|
+
cleanLine = cleanLine.slice(0, -1);
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
if (!delimiterResolved) {
|
|
619
|
+
if (!finalDelimiter && autoDetect) {
|
|
620
|
+
finalDelimiter = autoDetectDelimiter(cleanLine, candidates);
|
|
621
|
+
}
|
|
622
|
+
finalDelimiter = finalDelimiter || ';';
|
|
623
|
+
delimiterResolved = true;
|
|
624
|
+
}
|
|
625
|
+
|
|
626
|
+
if (cleanLine.trim() === '') {
|
|
627
|
+
return null;
|
|
628
|
+
}
|
|
629
|
+
|
|
630
|
+
if (!headers) {
|
|
631
|
+
if (hasHeaders) {
|
|
632
|
+
headers = parseCsvLine(cleanLine, lineNumber, finalDelimiter).map(header => {
|
|
633
|
+
const trimmed = trim ? header.trim() : header;
|
|
634
|
+
return renameMap[trimmed] || trimmed;
|
|
635
|
+
});
|
|
636
|
+
return null;
|
|
637
|
+
}
|
|
638
|
+
|
|
639
|
+
const fields = parseCsvLine(cleanLine, lineNumber, finalDelimiter);
|
|
640
|
+
headers = fields.map((_, index) => `column${index + 1}`);
|
|
641
|
+
return processFields(fields);
|
|
642
|
+
}
|
|
643
|
+
|
|
644
|
+
const fields = parseCsvLine(cleanLine, lineNumber, finalDelimiter);
|
|
645
|
+
return processFields(fields);
|
|
646
|
+
};
|
|
647
|
+
|
|
648
|
+
while (true) {
|
|
649
|
+
const { value, done } = await reader.read();
|
|
650
|
+
if (done) {
|
|
651
|
+
break;
|
|
652
|
+
}
|
|
653
|
+
|
|
654
|
+
buffer += decoder.decode(value, { stream: true });
|
|
655
|
+
|
|
656
|
+
let start = 0;
|
|
657
|
+
for (let i = 0; i < buffer.length; i++) {
|
|
658
|
+
const char = buffer[i];
|
|
659
|
+
if (char === '"') {
|
|
660
|
+
if (insideQuotes && buffer[i + 1] === '"') {
|
|
661
|
+
i++;
|
|
662
|
+
continue;
|
|
663
|
+
}
|
|
664
|
+
insideQuotes = !insideQuotes;
|
|
665
|
+
continue;
|
|
666
|
+
}
|
|
667
|
+
|
|
668
|
+
if (char === '\n' && !insideQuotes) {
|
|
669
|
+
const line = buffer.slice(start, i);
|
|
670
|
+
start = i + 1;
|
|
671
|
+
const row = processLine(line);
|
|
672
|
+
if (row) {
|
|
673
|
+
yield row;
|
|
674
|
+
}
|
|
675
|
+
}
|
|
676
|
+
}
|
|
677
|
+
|
|
678
|
+
buffer = buffer.slice(start);
|
|
679
|
+
}
|
|
680
|
+
|
|
681
|
+
if (buffer.length > 0) {
|
|
682
|
+
const row = processLine(buffer);
|
|
683
|
+
if (row) {
|
|
684
|
+
yield row;
|
|
685
|
+
}
|
|
686
|
+
}
|
|
687
|
+
|
|
688
|
+
if (insideQuotes) {
|
|
689
|
+
throw new ParsingError('Unclosed quotes in CSV', lineNumber);
|
|
690
|
+
}
|
|
691
|
+
}
|
|
692
|
+
|
|
436
693
|
// Экспорт для Node.js совместимости
|
|
437
694
|
if (typeof module !== 'undefined' && module.exports) {
|
|
438
695
|
module.exports = {
|
|
439
696
|
csvToJson,
|
|
440
|
-
autoDetectDelimiter
|
|
697
|
+
autoDetectDelimiter,
|
|
698
|
+
csvToJsonIterator
|
|
441
699
|
};
|
|
442
|
-
}
|
|
700
|
+
}
|
|
@@ -85,6 +85,23 @@ export class ConfigurationError extends JTCSVError {
|
|
|
85
85
|
}
|
|
86
86
|
}
|
|
87
87
|
|
|
88
|
+
export const ERROR_CODES = {
|
|
89
|
+
JTCSV_ERROR: 'JTCSV_ERROR',
|
|
90
|
+
VALIDATION_ERROR: 'VALIDATION_ERROR',
|
|
91
|
+
SECURITY_ERROR: 'SECURITY_ERROR',
|
|
92
|
+
FILE_SYSTEM_ERROR: 'FILE_SYSTEM_ERROR',
|
|
93
|
+
PARSING_ERROR: 'PARSING_ERROR',
|
|
94
|
+
LIMIT_ERROR: 'LIMIT_ERROR',
|
|
95
|
+
CONFIGURATION_ERROR: 'CONFIGURATION_ERROR',
|
|
96
|
+
INVALID_INPUT: 'INVALID_INPUT',
|
|
97
|
+
SECURITY_VIOLATION: 'SECURITY_VIOLATION',
|
|
98
|
+
FILE_NOT_FOUND: 'FILE_NOT_FOUND',
|
|
99
|
+
PARSE_FAILED: 'PARSE_FAILED',
|
|
100
|
+
SIZE_LIMIT: 'SIZE_LIMIT',
|
|
101
|
+
INVALID_CONFIG: 'INVALID_CONFIG',
|
|
102
|
+
UNKNOWN_ERROR: 'UNKNOWN_ERROR'
|
|
103
|
+
};
|
|
104
|
+
|
|
88
105
|
/**
|
|
89
106
|
* Безопасное выполнение функции с обработкой ошибок
|
|
90
107
|
*
|
|
@@ -188,7 +205,8 @@ if (typeof module !== 'undefined' && module.exports) {
|
|
|
188
205
|
ParsingError,
|
|
189
206
|
LimitError,
|
|
190
207
|
ConfigurationError,
|
|
208
|
+
ERROR_CODES,
|
|
191
209
|
safeExecute,
|
|
192
210
|
safeExecuteAsync
|
|
193
211
|
};
|
|
194
|
-
}
|
|
212
|
+
}
|
package/src/browser/index.js
CHANGED
|
@@ -2,8 +2,15 @@
|
|
|
2
2
|
// Экспортирует все функции с поддержкой браузера
|
|
3
3
|
|
|
4
4
|
import { jsonToCsv, preprocessData, deepUnwrap } from './json-to-csv-browser.js';
|
|
5
|
-
import { csvToJson, autoDetectDelimiter } from './csv-to-json-browser.js';
|
|
6
|
-
import {
|
|
5
|
+
import { csvToJson, csvToJsonIterator, autoDetectDelimiter } from './csv-to-json-browser.js';
|
|
6
|
+
import {
|
|
7
|
+
downloadAsCsv,
|
|
8
|
+
parseCsvFile,
|
|
9
|
+
parseCsvFileStream,
|
|
10
|
+
jsonToCsvStream,
|
|
11
|
+
jsonToNdjsonStream,
|
|
12
|
+
csvToJsonStream
|
|
13
|
+
} from './browser-functions.js';
|
|
7
14
|
import { createWorkerPool, parseCSVWithWorker } from './workers/worker-pool.js';
|
|
8
15
|
import {
|
|
9
16
|
ValidationError,
|
|
@@ -11,9 +18,20 @@ import {
|
|
|
11
18
|
FileSystemError,
|
|
12
19
|
ParsingError,
|
|
13
20
|
LimitError,
|
|
14
|
-
ConfigurationError
|
|
21
|
+
ConfigurationError,
|
|
22
|
+
ERROR_CODES
|
|
15
23
|
} from './errors-browser.js';
|
|
16
24
|
|
|
25
|
+
async function createWorkerPoolLazy(options = {}) {
|
|
26
|
+
const mod = await import('./workers/worker-pool.js');
|
|
27
|
+
return mod.createWorkerPool(options);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
async function parseCSVWithWorkerLazy(csvInput, options = {}, onProgress = null) {
|
|
31
|
+
const mod = await import('./workers/worker-pool.js');
|
|
32
|
+
return mod.parseCSVWithWorker(csvInput, options, onProgress);
|
|
33
|
+
}
|
|
34
|
+
|
|
17
35
|
// Основной экспорт
|
|
18
36
|
const jtcsv = {
|
|
19
37
|
// JSON to CSV функции
|
|
@@ -24,12 +42,19 @@ const jtcsv = {
|
|
|
24
42
|
|
|
25
43
|
// CSV to JSON функции
|
|
26
44
|
csvToJson,
|
|
45
|
+
csvToJsonIterator,
|
|
27
46
|
parseCsvFile,
|
|
47
|
+
parseCsvFileStream,
|
|
48
|
+
jsonToCsvStream,
|
|
49
|
+
jsonToNdjsonStream,
|
|
50
|
+
csvToJsonStream,
|
|
28
51
|
autoDetectDelimiter,
|
|
29
52
|
|
|
30
53
|
// Web Workers функции
|
|
31
54
|
createWorkerPool,
|
|
32
55
|
parseCSVWithWorker,
|
|
56
|
+
createWorkerPoolLazy,
|
|
57
|
+
parseCSVWithWorkerLazy,
|
|
33
58
|
|
|
34
59
|
// Error classes
|
|
35
60
|
ValidationError,
|
|
@@ -38,6 +63,7 @@ const jtcsv = {
|
|
|
38
63
|
ParsingError,
|
|
39
64
|
LimitError,
|
|
40
65
|
ConfigurationError,
|
|
66
|
+
ERROR_CODES,
|
|
41
67
|
|
|
42
68
|
// Удобные алиасы
|
|
43
69
|
parse: csvToJson,
|
|
@@ -66,14 +92,22 @@ export {
|
|
|
66
92
|
downloadAsCsv,
|
|
67
93
|
deepUnwrap,
|
|
68
94
|
csvToJson,
|
|
95
|
+
csvToJsonIterator,
|
|
69
96
|
parseCsvFile,
|
|
97
|
+
parseCsvFileStream,
|
|
98
|
+
jsonToCsvStream,
|
|
99
|
+
jsonToNdjsonStream,
|
|
100
|
+
csvToJsonStream,
|
|
70
101
|
autoDetectDelimiter,
|
|
71
102
|
createWorkerPool,
|
|
72
103
|
parseCSVWithWorker,
|
|
104
|
+
createWorkerPoolLazy,
|
|
105
|
+
parseCSVWithWorkerLazy,
|
|
73
106
|
ValidationError,
|
|
74
107
|
SecurityError,
|
|
75
108
|
FileSystemError,
|
|
76
109
|
ParsingError,
|
|
77
110
|
LimitError,
|
|
78
|
-
ConfigurationError
|
|
79
|
-
|
|
111
|
+
ConfigurationError,
|
|
112
|
+
ERROR_CODES
|
|
113
|
+
};
|