convert-csv-to-json 3.14.0 → 3.15.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 +169 -14
- package/index.d.ts +24 -0
- package/index.js +6 -0
- package/jest.config.js +6 -2
- package/package.json +7 -3
- package/src/browserApi.js +105 -0
- package/tsconfig.json +19 -0
package/README.md
CHANGED
|
@@ -8,8 +8,11 @@
|
|
|
8
8
|
[](https://npmjs.org/package/convert-csv-to-json)
|
|
9
9
|
[](https://npmjs.org/package/convert-csv-to-json)
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
|
|
12
|
+

|
|
13
|
+

|
|
12
14
|

|
|
15
|
+

|
|
13
16
|
|
|
14
17
|
**This project is not dependent on others packages or libraries, and supports both synchronous and Promise-based asynchronous APIs.**
|
|
15
18
|
|
|
@@ -23,10 +26,9 @@ show your :heart: and support.
|
|
|
23
26
|
<!-- toc -->
|
|
24
27
|
|
|
25
28
|
- [Description](#description)
|
|
26
|
-
- [Support for JS
|
|
29
|
+
- [Support for NodeJS, Browser, JS, TS](#support-for-nodejs-browser-js-ts)
|
|
27
30
|
- [Prerequisites](#prerequisites)
|
|
28
31
|
- [Install npm *convert-csv-to-json package*](#install-npm-convert-csv-to-json-package)
|
|
29
|
-
* [Install](#install)
|
|
30
32
|
* [Sync API Usage](#sync-api-usage)
|
|
31
33
|
+ [Generate JSON file](#generate-json-file)
|
|
32
34
|
+ [Generate Array of Object in JSON format](#generate-array-of-object-in-json-format)
|
|
@@ -38,17 +40,38 @@ show your :heart: and support.
|
|
|
38
40
|
+ [Index header](#index-header)
|
|
39
41
|
+ [Empty rows](#empty-rows)
|
|
40
42
|
+ [Format property value by type](#format-property-value-by-type)
|
|
41
|
-
- [
|
|
43
|
+
- [Numbers](#numbers)
|
|
42
44
|
- [Boolean](#boolean)
|
|
45
|
+
- [Complete Example](#complete-example)
|
|
43
46
|
+ [Encoding](#encoding)
|
|
44
47
|
+ [Working with CSV strings directly](#working-with-csv-strings-directly)
|
|
45
|
-
* [
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
48
|
+
* [Sync API (TypeScript)](#sync-api-typescript)
|
|
49
|
+
- [Browser API Usage](#browser-api-usage)
|
|
50
|
+
* [Basic Browser Operations](#basic-browser-operations)
|
|
51
|
+
* [Parsing File/Blob](#parsing-fileblob)
|
|
52
|
+
* [Browser API Notes](#browser-api-notes)
|
|
53
|
+
* [Browser API (TypeScript)](#browser-api-typescript)
|
|
54
|
+
- [Async API Usage](#async-api-usage)
|
|
55
|
+
* [Async API (TypeScript)](#async-api-typescript)
|
|
56
|
+
* [Basic Async Operations](#basic-async-operations)
|
|
57
|
+
* [Working with Raw CSV Data](#working-with-raw-csv-data)
|
|
58
|
+
* [Processing Large Files](#processing-large-files)
|
|
59
|
+
* [Error Handling and Retries](#error-handling-and-retries)
|
|
60
|
+
* [Batch Processing](#batch-processing)
|
|
61
|
+
- [Chaining Pattern](#chaining-pattern)
|
|
62
|
+
* [Synchronous Chaining](#synchronous-chaining)
|
|
63
|
+
* [Asynchronous Chaining](#asynchronous-chaining)
|
|
64
|
+
- [Common Use Cases](#common-use-cases)
|
|
65
|
+
* [1. Processing CSV from HTTP Response](#1-processing-csv-from-http-response)
|
|
66
|
+
* [2. Batch Processing Multiple Files](#2-batch-processing-multiple-files)
|
|
67
|
+
* [3. Data Transformation Pipeline](#3-data-transformation-pipeline)
|
|
68
|
+
* [4. Error Recovery and Logging](#4-error-recovery-and-logging)
|
|
69
|
+
- [Troubleshooting](#troubleshooting)
|
|
70
|
+
* [Memory Issues with Large Files](#memory-issues-with-large-files)
|
|
71
|
+
* [Handling Different CSV Formats](#handling-different-csv-formats)
|
|
72
|
+
* [Common Error Solutions](#common-error-solutions)
|
|
73
|
+
* [Performance Optimization](#performance-optimization)
|
|
74
|
+
* [TypeScript Support](#typescript-support)
|
|
52
75
|
- [Development](#development)
|
|
53
76
|
- [CI CD github action](#ci-cd-github-action)
|
|
54
77
|
- [License](#license)
|
|
@@ -98,9 +121,14 @@ will generate:
|
|
|
98
121
|
}
|
|
99
122
|
]
|
|
100
123
|
```
|
|
101
|
-
## Support for JS
|
|
124
|
+
## Support for NodeJS, Browser, JS, TS
|
|
125
|
+
|
|
126
|
+
This package is compatible with:
|
|
102
127
|
|
|
103
|
-
|
|
128
|
+

|
|
129
|
+

|
|
130
|
+

|
|
131
|
+

|
|
104
132
|
|
|
105
133
|
## Prerequisites
|
|
106
134
|
**NPM** (see [Installing Npm](https://docs.npmjs.com/getting-started/installing-node)).
|
|
@@ -108,7 +136,6 @@ This package is compatible with .
|
|
110
138
|
|
|
111
|
-
### Install
|
|
112
139
|
Install package in your *package.json*
|
|
113
140
|
```bash
|
|
114
141
|
$ npm install convert-csv-to-json --save
|
|
@@ -357,10 +384,138 @@ let jsonArray = csvToJson
|
|
|
357
384
|
.csvStringToJson(csvString);
|
|
358
385
|
```
|
|
359
386
|
|
|
387
|
+
### Sync API (TypeScript)
|
|
388
|
+
|
|
389
|
+
TypeScript typings are available via the included `index.d.ts`. You can import the default converter or use named imports. Below are common patterns when using the synchronous API from TypeScript.
|
|
390
|
+
|
|
391
|
+
```ts
|
|
392
|
+
// Named import (recommended when using ES modules)
|
|
393
|
+
import converter, { /* or */ } from 'convert-csv-to-json';
|
|
394
|
+
// Access the default converter
|
|
395
|
+
const csvToJson = require('convert-csv-to-json');
|
|
396
|
+
|
|
397
|
+
// Define a type for your CSV records
|
|
398
|
+
interface Person {
|
|
399
|
+
name: string;
|
|
400
|
+
age: number;
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
// Parse CSV string synchronously and assert the returned type
|
|
404
|
+
const csv = 'name,age\nAlice,30';
|
|
405
|
+
const parsed = csvToJson.csvStringToJson(csv) as Person[];
|
|
406
|
+
|
|
407
|
+
// Chain configuration and call sync methods
|
|
408
|
+
const result = csvToJson
|
|
409
|
+
.fieldDelimiter(',')
|
|
410
|
+
.formatValueByType()
|
|
411
|
+
.csvStringToJson('name,age\nBob,25') as Person[];
|
|
412
|
+
```
|
|
413
|
+
|
|
414
|
+
## Browser API Usage
|
|
415
|
+
|
|
416
|
+
The package exposes a `browser` helper that reuses the library's parsing logic but provides browser-friendly helpers for parsing CSV strings and `File`/`Blob` objects. The API mirrors the synchronous and asynchronous Node APIs and supports method chaining for configuration.
|
|
417
|
+
|
|
418
|
+
### Basic Browser Operations
|
|
419
|
+
|
|
420
|
+
```js
|
|
421
|
+
const convert = require('convert-csv-to-json');
|
|
422
|
+
|
|
423
|
+
// Parse CSV string synchronously
|
|
424
|
+
const arr = convert.browser
|
|
425
|
+
.supportQuotedField(true)
|
|
426
|
+
.fieldDelimiter(',')
|
|
427
|
+
.csvStringToJson('name,age\nAlice,30');
|
|
428
|
+
|
|
429
|
+
// Parse CSV string asynchronously (returns Promise)
|
|
430
|
+
const arrAsync = await convert.browser.csvStringToJsonAsync('name;age\nBob;25');
|
|
431
|
+
|
|
432
|
+
// Get stringified JSON synchronously
|
|
433
|
+
const jsonString = convert.browser.csvStringToJsonStringified('name;age\nEve;40');
|
|
434
|
+
```
|
|
435
|
+
|
|
436
|
+
### Parsing File/Blob
|
|
437
|
+
|
|
438
|
+
`parseFile(file, options)` reads a `File` or `Blob` and returns a Promise that resolves with the parsed array of objects.
|
|
439
|
+
|
|
440
|
+
```js
|
|
441
|
+
// In a browser environment with an <input type="file">
|
|
442
|
+
const file = document.querySelector('input[type=file]').files[0];
|
|
443
|
+
convert.browser
|
|
444
|
+
.fieldDelimiter(',')
|
|
445
|
+
.formatValueByType()
|
|
446
|
+
.parseFile(file)
|
|
447
|
+
.then(json => console.log(json))
|
|
448
|
+
.catch(err => console.error(err));
|
|
449
|
+
```
|
|
450
|
+
|
|
451
|
+
`parseFile` accepts an optional `options` object with `encoding` (passed to `FileReader.readAsText`). If `FileReader` is not available, `parseFile` will reject.
|
|
452
|
+
|
|
453
|
+
### Browser API Notes
|
|
454
|
+
|
|
455
|
+
- The `browser` API proxies the same configuration methods as the Node API and follows the same behavior for quoted fields, sub-array parsing, trimming, and value formatting.
|
|
456
|
+
- `parseFile` depends on the browser `FileReader` API; calling it in Node.js will reject with an informative error.
|
|
457
|
+
|
|
458
|
+
### Browser API (TypeScript)
|
|
459
|
+
|
|
460
|
+
TypeScript typings are provided via the included `index.d.ts`. You can import the default converter and access the `browser` helper, or import `browser` directly. Below are common usage patterns.
|
|
461
|
+
|
|
462
|
+
```ts
|
|
463
|
+
// Named import (recommended for direct use)
|
|
464
|
+
import { browser } from 'convert-csv-to-json';
|
|
465
|
+
|
|
466
|
+
// Or default import and access the browser helper
|
|
467
|
+
import converter from 'convert-csv-to-json';
|
|
468
|
+
const browserApi = converter.browser;
|
|
469
|
+
|
|
470
|
+
// Define a type for your CSV records
|
|
471
|
+
interface Person {
|
|
472
|
+
name: string;
|
|
473
|
+
age: number;
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
// Synchronous parse (assert the returned type)
|
|
477
|
+
const csv = 'name,age\nAlice,30';
|
|
478
|
+
const parsed = browser.csvStringToJson(csv) as Person[];
|
|
479
|
+
|
|
480
|
+
// Async parse
|
|
481
|
+
const parsedAsync = await browser.csvStringToJsonAsync(csv) as Person[];
|
|
482
|
+
|
|
483
|
+
// Parse a File in the browser
|
|
484
|
+
const inputEl = document.querySelector('input[type=file]') as HTMLInputElement;
|
|
485
|
+
const file = inputEl.files![0];
|
|
486
|
+
const data = await browser.parseFile(file) as Person[];
|
|
487
|
+
```
|
|
488
|
+
|
|
489
|
+
The `BrowserApi` interface in `index.d.ts` exposes typed method signatures for IDE autocompletion and compile-time checks.
|
|
490
|
+
|
|
360
491
|
## Async API Usage
|
|
361
492
|
|
|
362
493
|
This library provides a Promise-based async API that's perfect for modern Node.js applications. For a detailed migration guide from sync to async API, see [MIGRATION.md](MIGRATION.md).
|
|
363
494
|
|
|
495
|
+
### Async API (TypeScript)
|
|
496
|
+
|
|
497
|
+
The async API also has TypeScript typings. Typical usage in TypeScript looks like this:
|
|
498
|
+
|
|
499
|
+
```ts
|
|
500
|
+
import csvToJson from 'convert-csv-to-json';
|
|
501
|
+
|
|
502
|
+
interface Person {
|
|
503
|
+
name: string;
|
|
504
|
+
age: number;
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
// Using async/await
|
|
508
|
+
async function load(): Promise<Person[]> {
|
|
509
|
+
const csv = 'name,age\nAlice,30';
|
|
510
|
+
const parsed = await csvToJson.getJsonFromCsvAsync(csv, { raw: true }) as Person[];
|
|
511
|
+
return parsed;
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
// Using the async helper that parses CSV strings
|
|
515
|
+
const parsedDirect = await csvToJson.csvStringToJsonAsync('name;age\nBob;25') as Person[];
|
|
516
|
+
```
|
|
517
|
+
|
|
518
|
+
|
|
364
519
|
### Basic Async Operations
|
|
365
520
|
|
|
366
521
|
1. Convert CSV file to JSON:
|
package/index.d.ts
CHANGED
|
@@ -116,4 +116,28 @@ declare module 'convert-csv-to-json' {
|
|
|
116
116
|
}
|
|
117
117
|
const converter: ConvertCsvToJson;
|
|
118
118
|
export default converter;
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Browser API exposes parsing helpers for browser environments
|
|
122
|
+
*/
|
|
123
|
+
export interface BrowserApi {
|
|
124
|
+
formatValueByType(active: boolean): this;
|
|
125
|
+
trimHeaderFieldWhiteSpace(active: boolean): this;
|
|
126
|
+
supportQuotedField(active: boolean): this;
|
|
127
|
+
fieldDelimiter(delimiter: string): this;
|
|
128
|
+
indexHeader(index: number): this;
|
|
129
|
+
parseSubArray(delimiter: string, separator: string): this;
|
|
130
|
+
|
|
131
|
+
csvStringToJson(csvString: string): any[];
|
|
132
|
+
csvStringToJsonStringified(csvString: string): string;
|
|
133
|
+
csvStringToJsonAsync(csvString: string): Promise<any[]>;
|
|
134
|
+
csvStringToJsonStringifiedAsync(csvString: string): Promise<string>;
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Parse a File or Blob and return a Promise that resolves to the JSON array
|
|
138
|
+
*/
|
|
139
|
+
parseFile(file: Blob | File, options?: { encoding?: string }): Promise<any[]>;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
export const browser: BrowserApi;
|
|
119
143
|
}
|
package/index.js
CHANGED
|
@@ -202,3 +202,9 @@ exports.csvStringToJsonStringified = function(csvString) {
|
|
|
202
202
|
exports.jsonToCsv = function(inputFileName, outputFileName) {
|
|
203
203
|
csvToJson.generateJsonFileFromCsv(inputFileName, outputFileName);
|
|
204
204
|
};
|
|
205
|
+
|
|
206
|
+
/**
|
|
207
|
+
* Browser API
|
|
208
|
+
* Provides parsing helpers suitable for browser environments (parsing strings and File/Blob objects)
|
|
209
|
+
*/
|
|
210
|
+
exports.browser = require('./src/browserApi');
|
package/jest.config.js
CHANGED
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
/** @type {import('jest').Config} */
|
|
2
2
|
const config = {
|
|
3
|
-
|
|
3
|
+
preset: 'ts-jest',
|
|
4
|
+
testEnvironment: 'node',
|
|
5
|
+
transform: {
|
|
6
|
+
'^.+\\.(ts|tsx)$': 'ts-jest'
|
|
7
|
+
},
|
|
8
|
+
testMatch: ['**/?(*.)+(spec|test).[tj]s?(x)'],
|
|
4
9
|
coverageReporters: ['clover', 'html' ,'json', 'lcov', ['text', {skipFull: true}]],
|
|
5
10
|
collectCoverage: true
|
|
6
|
-
|
|
7
11
|
};
|
|
8
12
|
|
|
9
13
|
module.exports = config;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "convert-csv-to-json",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.15.0",
|
|
4
4
|
"description": "Convert CSV to JSON",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"types": "index.d.ts",
|
|
@@ -35,7 +35,8 @@
|
|
|
35
35
|
"js",
|
|
36
36
|
"javascript",
|
|
37
37
|
"ts",
|
|
38
|
-
"typescript"
|
|
38
|
+
"typescript",
|
|
39
|
+
"browser"
|
|
39
40
|
],
|
|
40
41
|
"author": "iuccio",
|
|
41
42
|
"license": "MIT",
|
|
@@ -44,6 +45,9 @@
|
|
|
44
45
|
},
|
|
45
46
|
"homepage": "https://github.com/iuccio/CSVtoJSON#readme",
|
|
46
47
|
"devDependencies": {
|
|
47
|
-
"jest": "^29.7.0"
|
|
48
|
+
"jest": "^29.7.0",
|
|
49
|
+
"ts-jest": "^29.1.0",
|
|
50
|
+
"typescript": "^5.1.6",
|
|
51
|
+
"@types/jest": "^29.5.3"
|
|
48
52
|
}
|
|
49
53
|
}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
const csvToJson = require('./csvToJson');
|
|
4
|
+
|
|
5
|
+
class BrowserApi {
|
|
6
|
+
constructor() {
|
|
7
|
+
// reuse the existing csvToJson instance for parsing and configuration
|
|
8
|
+
this.csvToJson = csvToJson;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
// Configuration proxies (chainable)
|
|
12
|
+
formatValueByType(active = true) {
|
|
13
|
+
this.csvToJson.formatValueByType(active);
|
|
14
|
+
return this;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
supportQuotedField(active = false) {
|
|
18
|
+
this.csvToJson.supportQuotedField(active);
|
|
19
|
+
return this;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
fieldDelimiter(delimiter) {
|
|
23
|
+
this.csvToJson.fieldDelimiter(delimiter);
|
|
24
|
+
return this;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
trimHeaderFieldWhiteSpace(active = false) {
|
|
28
|
+
this.csvToJson.trimHeaderFieldWhiteSpace(active);
|
|
29
|
+
return this;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
indexHeader(index) {
|
|
33
|
+
this.csvToJson.indexHeader(index);
|
|
34
|
+
return this;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
parseSubArray(delimiter = '*', separator = ',') {
|
|
38
|
+
this.csvToJson.parseSubArray(delimiter, separator);
|
|
39
|
+
return this;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Synchronous parse from CSV string (browser friendly)
|
|
43
|
+
csvStringToJson(csvString) {
|
|
44
|
+
if (csvString === undefined || csvString === null) {
|
|
45
|
+
throw new Error('csvString is not defined!!!');
|
|
46
|
+
}
|
|
47
|
+
return this.csvToJson.csvToJson(csvString);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
csvStringToJsonStringified(csvString) {
|
|
51
|
+
if (csvString === undefined || csvString === null) {
|
|
52
|
+
throw new Error('csvString is not defined!!!');
|
|
53
|
+
}
|
|
54
|
+
return this.csvToJson.csvStringToJsonStringified(csvString);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// Async parse from CSV string (returns a Promise)
|
|
58
|
+
csvStringToJsonAsync(csvString) {
|
|
59
|
+
return Promise.resolve(this.csvStringToJson(csvString));
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
csvStringToJsonStringifiedAsync(csvString) {
|
|
63
|
+
return Promise.resolve(this.csvStringToJsonStringified(csvString));
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Parse a browser File or Blob object to JSON array.
|
|
68
|
+
* @param {File|Blob} file - File or Blob to read as text
|
|
69
|
+
* @param {object} options - options: { encoding?: string }
|
|
70
|
+
* @returns {Promise<any[]>}
|
|
71
|
+
*/
|
|
72
|
+
parseFile(file, options = {}) {
|
|
73
|
+
if (!file) {
|
|
74
|
+
return Promise.reject(new Error('file is not defined!!!'));
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
return new Promise((resolve, reject) => {
|
|
78
|
+
if (typeof FileReader === 'undefined') {
|
|
79
|
+
reject(new Error('FileReader is not available in this environment'));
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const reader = new FileReader();
|
|
84
|
+
reader.onerror = () => reject(reader.error || new Error('Failed to read file'));
|
|
85
|
+
reader.onload = () => {
|
|
86
|
+
try {
|
|
87
|
+
const text = reader.result;
|
|
88
|
+
const result = this.csvToJson.csvToJson(String(text));
|
|
89
|
+
resolve(result);
|
|
90
|
+
} catch (err) {
|
|
91
|
+
reject(err);
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
// If encoding is provided, pass it to readAsText
|
|
96
|
+
if (options.encoding) {
|
|
97
|
+
reader.readAsText(file, options.encoding);
|
|
98
|
+
} else {
|
|
99
|
+
reader.readAsText(file);
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
module.exports = new BrowserApi();
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2019",
|
|
4
|
+
"module": "CommonJS",
|
|
5
|
+
"strict": true,
|
|
6
|
+
"esModuleInterop": true,
|
|
7
|
+
"skipLibCheck": true,
|
|
8
|
+
"forceConsistentCasingInFileNames": true,
|
|
9
|
+
"outDir": "dist",
|
|
10
|
+
"moduleResolution": "node",
|
|
11
|
+
"resolveJsonModule": true,
|
|
12
|
+
"types": ["node", "jest"]
|
|
13
|
+
},
|
|
14
|
+
"baseUrl": ".",
|
|
15
|
+
"paths": {
|
|
16
|
+
"convert-csv-to-json": ["./index.d.ts", "./index.js"]
|
|
17
|
+
},
|
|
18
|
+
"include": ["test/**/*.ts"]
|
|
19
|
+
}
|