convert-csv-to-json 3.28.0 → 4.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +41 -1
- package/README.md +173 -833
- package/docs/ASYNC.md +485 -0
- package/docs/BROWSER.md +425 -0
- package/docs/ERROR_HANDLING.md +367 -0
- package/docs/MAPROWS.md +196 -0
- package/docs/SYNC.md +239 -0
- package/index.d.ts +10 -8
- package/index.js +13 -10
- package/migration/RFC4180_MIGRATION_GUIDE.md +737 -0
- package/package.json +1 -1
- package/release-notes/RELEASE_NOTES_v4.0.0.md +320 -0
- package/src/browserApi.js +29 -6
- package/src/csvToJson.js +233 -82
- package/src/csvToJsonAsync.js +15 -1
- package/src/util/errors.js +227 -0
- package/src/util/fileUtils.js +18 -7
- package/src/util/jsonUtils.js +3 -1
- /package/{MIGRATION.md → migration/MIGRATION_TO_ASYNC.md} +0 -0
package/docs/BROWSER.md
ADDED
|
@@ -0,0 +1,425 @@
|
|
|
1
|
+
# Browser API Documentation
|
|
2
|
+
|
|
3
|
+
Client-side CSV parsing for web browsers. Supports parsing CSV strings and file/blob objects with both synchronous and asynchronous methods.
|
|
4
|
+
|
|
5
|
+
## Table of Contents
|
|
6
|
+
- [Basic Usage](#basic-usage)
|
|
7
|
+
- [Parsing CSV Strings](#parsing-csv-strings)
|
|
8
|
+
- [Parsing Files and Blobs](#parsing-files-and-blobs)
|
|
9
|
+
- [Configuration Options](#configuration-options)
|
|
10
|
+
- [File Upload Examples](#file-upload-examples)
|
|
11
|
+
- [TypeScript Support](#typescript-support)
|
|
12
|
+
|
|
13
|
+
## Basic Usage
|
|
14
|
+
|
|
15
|
+
The browser API is accessed through the `browser` property:
|
|
16
|
+
|
|
17
|
+
```js
|
|
18
|
+
const convert = require('convert-csv-to-json');
|
|
19
|
+
|
|
20
|
+
// Synchronous parse
|
|
21
|
+
const data = convert.browser.csvStringToJson('name,age\nAlice,30');
|
|
22
|
+
|
|
23
|
+
// Asynchronous parse (recommended)
|
|
24
|
+
const dataAsync = await convert.browser.csvStringToJsonAsync('name,age\nAlice,30');
|
|
25
|
+
|
|
26
|
+
// Parse file
|
|
27
|
+
const file = document.querySelector('input[type=file]').files[0];
|
|
28
|
+
const fileData = await convert.browser.parseFile(file);
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Parsing CSV Strings
|
|
32
|
+
|
|
33
|
+
### Synchronous String Parsing
|
|
34
|
+
|
|
35
|
+
```js
|
|
36
|
+
const convert = require('convert-csv-to-json');
|
|
37
|
+
|
|
38
|
+
const csv = `name,email,age
|
|
39
|
+
John,john@example.com,30
|
|
40
|
+
Jane,jane@example.com,25`;
|
|
41
|
+
|
|
42
|
+
const json = convert.browser.csvStringToJson(csv);
|
|
43
|
+
// Output: [
|
|
44
|
+
// { name: 'John', email: 'john@example.com', age: '30' },
|
|
45
|
+
// { name: 'Jane', email: 'jane@example.com', age: '25' }
|
|
46
|
+
// ]
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### Asynchronous String Parsing
|
|
50
|
+
|
|
51
|
+
```js
|
|
52
|
+
async function parseCSV(csv) {
|
|
53
|
+
try {
|
|
54
|
+
const json = await convert.browser.csvStringToJsonAsync(csv);
|
|
55
|
+
console.log(json);
|
|
56
|
+
} catch (error) {
|
|
57
|
+
console.error('Parse error:', error);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
parseCSV('name,age\nAlice,30\nBob,25');
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### Get JSON String
|
|
65
|
+
|
|
66
|
+
```js
|
|
67
|
+
const convert = require('convert-csv-to-json');
|
|
68
|
+
|
|
69
|
+
const csv = 'name,age\nAlice,30';
|
|
70
|
+
const jsonString = convert.browser.csvStringToJsonStringified(csv);
|
|
71
|
+
// Output: "[\n {\n \"name\": \"Alice\",\n \"age\": \"30\"\n }\n]"
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## Parsing Files and Blobs
|
|
75
|
+
|
|
76
|
+
### Parse File Upload
|
|
77
|
+
|
|
78
|
+
```js
|
|
79
|
+
const convert = require('convert-csv-to-json');
|
|
80
|
+
|
|
81
|
+
async function handleFileUpload(event) {
|
|
82
|
+
const file = event.target.files[0];
|
|
83
|
+
|
|
84
|
+
try {
|
|
85
|
+
const json = await convert.browser.parseFile(file);
|
|
86
|
+
console.log('Parsed records:', json.length);
|
|
87
|
+
displayData(json);
|
|
88
|
+
} catch (error) {
|
|
89
|
+
console.error('Error parsing file:', error);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// HTML: <input type="file" id="csvFile" accept=".csv">
|
|
94
|
+
document.getElementById('csvFile').addEventListener('change', handleFileUpload);
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### Parse Blob Data
|
|
98
|
+
|
|
99
|
+
```js
|
|
100
|
+
async function parseBlobData(blob) {
|
|
101
|
+
const json = await convert.browser.parseFile(blob);
|
|
102
|
+
return json;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// Example: from fetch response
|
|
106
|
+
const response = await fetch('data.csv');
|
|
107
|
+
const blob = await response.blob();
|
|
108
|
+
const data = await parseBlobData(blob);
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### Parse with Custom Encoding
|
|
112
|
+
|
|
113
|
+
```js
|
|
114
|
+
const convert = require('convert-csv-to-json');
|
|
115
|
+
|
|
116
|
+
async function parseWithEncoding(file) {
|
|
117
|
+
const options = { encoding: 'utf-8' };
|
|
118
|
+
const json = await convert.browser
|
|
119
|
+
.parseFile(file, options);
|
|
120
|
+
|
|
121
|
+
return json;
|
|
122
|
+
}
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
## Configuration Options
|
|
126
|
+
|
|
127
|
+
All configuration methods from the [Sync API](SYNC.md) are available:
|
|
128
|
+
|
|
129
|
+
### Field Delimiter
|
|
130
|
+
|
|
131
|
+
```js
|
|
132
|
+
const convert = require('convert-csv-to-json');
|
|
133
|
+
|
|
134
|
+
const csv = 'name;age\nAlice;30\nBob;25';
|
|
135
|
+
const json = convert.browser
|
|
136
|
+
.fieldDelimiter(';')
|
|
137
|
+
.csvStringToJson(csv);
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
### Quoted Fields Support
|
|
141
|
+
|
|
142
|
+
```js
|
|
143
|
+
const csv = `name,description
|
|
144
|
+
"Smith, John","He said ""Hello"""`;
|
|
145
|
+
|
|
146
|
+
const json = convert.browser
|
|
147
|
+
.supportQuotedField(true)
|
|
148
|
+
.csvStringToJson(csv);
|
|
149
|
+
// Output: { name: 'Smith, John', description: 'He said "Hello"' }
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
### Format Values by Type
|
|
153
|
+
|
|
154
|
+
```js
|
|
155
|
+
const csv = 'name,age,active\nAlice,30,true\nBob,25,false';
|
|
156
|
+
const json = convert.browser
|
|
157
|
+
.formatValueByType()
|
|
158
|
+
.csvStringToJson(csv);
|
|
159
|
+
|
|
160
|
+
// Output:
|
|
161
|
+
// [
|
|
162
|
+
// { name: 'Alice', age: 30, active: true },
|
|
163
|
+
// { name: 'Bob', age: 25, active: false }
|
|
164
|
+
// ]
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
### Trim Header Fields
|
|
168
|
+
|
|
169
|
+
```js
|
|
170
|
+
const csv = ' Name , Age \nAlice,30';
|
|
171
|
+
const json = convert.browser
|
|
172
|
+
.trimHeaderFieldWhiteSpace(true)
|
|
173
|
+
.csvStringToJson(csv);
|
|
174
|
+
|
|
175
|
+
// Output: { Name: 'Alice', Age: '30' } (spaces removed from header)
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
### Method Chaining
|
|
179
|
+
|
|
180
|
+
```js
|
|
181
|
+
const json = convert.browser
|
|
182
|
+
.fieldDelimiter(';')
|
|
183
|
+
.formatValueByType()
|
|
184
|
+
.supportQuotedField(true)
|
|
185
|
+
.trimHeaderFieldWhiteSpace(true)
|
|
186
|
+
.csvStringToJson(csvContent);
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
## File Upload Examples
|
|
190
|
+
|
|
191
|
+
### HTML File Input
|
|
192
|
+
|
|
193
|
+
```html
|
|
194
|
+
<input type="file" id="csvInput" accept=".csv" />
|
|
195
|
+
<button onclick="handleUpload()">Parse CSV</button>
|
|
196
|
+
<div id="results"></div>
|
|
197
|
+
|
|
198
|
+
<script>
|
|
199
|
+
const convert = require('convert-csv-to-json');
|
|
200
|
+
|
|
201
|
+
async function handleUpload() {
|
|
202
|
+
const file = document.getElementById('csvInput').files[0];
|
|
203
|
+
|
|
204
|
+
if (!file) {
|
|
205
|
+
alert('Please select a file');
|
|
206
|
+
return;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
try {
|
|
210
|
+
const json = await convert.browser
|
|
211
|
+
.formatValueByType()
|
|
212
|
+
.parseFile(file);
|
|
213
|
+
|
|
214
|
+
displayResults(json);
|
|
215
|
+
} catch (error) {
|
|
216
|
+
document.getElementById('results').innerHTML =
|
|
217
|
+
`<p style="color: red;">Error: ${error.message}</p>`;
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
function displayResults(data) {
|
|
222
|
+
const html = `
|
|
223
|
+
<h3>Parsed ${data.length} records:</h3>
|
|
224
|
+
<pre>${JSON.stringify(data, null, 2)}</pre>
|
|
225
|
+
`;
|
|
226
|
+
document.getElementById('results').innerHTML = html;
|
|
227
|
+
}
|
|
228
|
+
</script>
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
### Drag and Drop Upload
|
|
232
|
+
|
|
233
|
+
```html
|
|
234
|
+
<div id="dropZone" style="border: 2px dashed #ccc; padding: 20px;">
|
|
235
|
+
Drag CSV file here or <input type="file" id="csvFile" accept=".csv" />
|
|
236
|
+
</div>
|
|
237
|
+
|
|
238
|
+
<script>
|
|
239
|
+
const convert = require('convert-csv-to-json');
|
|
240
|
+
const dropZone = document.getElementById('dropZone');
|
|
241
|
+
const fileInput = document.getElementById('csvFile');
|
|
242
|
+
|
|
243
|
+
// Handle file selection
|
|
244
|
+
fileInput.addEventListener('change', (e) => handleFiles(e.target.files));
|
|
245
|
+
|
|
246
|
+
// Handle drag and drop
|
|
247
|
+
dropZone.addEventListener('dragover', (e) => {
|
|
248
|
+
e.preventDefault();
|
|
249
|
+
dropZone.style.backgroundColor = '#f0f0f0';
|
|
250
|
+
});
|
|
251
|
+
|
|
252
|
+
dropZone.addEventListener('dragleave', () => {
|
|
253
|
+
dropZone.style.backgroundColor = 'transparent';
|
|
254
|
+
});
|
|
255
|
+
|
|
256
|
+
dropZone.addEventListener('drop', (e) => {
|
|
257
|
+
e.preventDefault();
|
|
258
|
+
dropZone.style.backgroundColor = 'transparent';
|
|
259
|
+
handleFiles(e.dataTransfer.files);
|
|
260
|
+
});
|
|
261
|
+
|
|
262
|
+
async function handleFiles(files) {
|
|
263
|
+
const file = files[0];
|
|
264
|
+
if (!file || !file.type.includes('csv')) {
|
|
265
|
+
alert('Please select a CSV file');
|
|
266
|
+
return;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
try {
|
|
270
|
+
const json = await convert.browser.parseFile(file);
|
|
271
|
+
console.log('Parsed data:', json);
|
|
272
|
+
} catch (error) {
|
|
273
|
+
console.error('Parse error:', error);
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
</script>
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
### Multiple File Upload
|
|
280
|
+
|
|
281
|
+
```js
|
|
282
|
+
const convert = require('convert-csv-to-json');
|
|
283
|
+
|
|
284
|
+
async function handleMultipleFiles(files) {
|
|
285
|
+
const results = [];
|
|
286
|
+
|
|
287
|
+
for (const file of files) {
|
|
288
|
+
try {
|
|
289
|
+
const json = await convert.browser
|
|
290
|
+
.formatValueByType()
|
|
291
|
+
.parseFile(file);
|
|
292
|
+
|
|
293
|
+
results.push({
|
|
294
|
+
fileName: file.name,
|
|
295
|
+
records: json,
|
|
296
|
+
success: true
|
|
297
|
+
});
|
|
298
|
+
} catch (error) {
|
|
299
|
+
results.push({
|
|
300
|
+
fileName: file.name,
|
|
301
|
+
error: error.message,
|
|
302
|
+
success: false
|
|
303
|
+
});
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
return results;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
// Usage with file input
|
|
311
|
+
document.getElementById('csvFiles').addEventListener('change', async (e) => {
|
|
312
|
+
const results = await handleMultipleFiles(e.target.files);
|
|
313
|
+
console.log(results);
|
|
314
|
+
});
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
## TypeScript Support
|
|
318
|
+
|
|
319
|
+
```ts
|
|
320
|
+
import { browser } from 'convert-csv-to-json';
|
|
321
|
+
|
|
322
|
+
interface User {
|
|
323
|
+
name: string;
|
|
324
|
+
email: string;
|
|
325
|
+
age: number;
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
// Parse CSV string
|
|
329
|
+
function parseUsers(csv: string): User[] {
|
|
330
|
+
return browser.csvStringToJson(csv) as User[];
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
// Parse file
|
|
334
|
+
async function parseUserFile(file: File): Promise<User[]> {
|
|
335
|
+
return browser
|
|
336
|
+
.formatValueByType()
|
|
337
|
+
.parseFile(file) as Promise<User[]>;
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
// Async string parsing
|
|
341
|
+
async function parseUsersAsync(csv: string): Promise<User[]> {
|
|
342
|
+
return browser.csvStringToJsonAsync(csv) as Promise<User[]>;
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
// Handle file upload with type safety
|
|
346
|
+
async function handleUpload(event: Event): Promise<void> {
|
|
347
|
+
const input = event.target as HTMLInputElement;
|
|
348
|
+
const file = input.files?.[0];
|
|
349
|
+
|
|
350
|
+
if (!file) return;
|
|
351
|
+
|
|
352
|
+
try {
|
|
353
|
+
const users = await parseUserFile(file);
|
|
354
|
+
console.log(`Loaded ${users.length} users`);
|
|
355
|
+
} catch (error) {
|
|
356
|
+
console.error('Failed to parse file:', error);
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
## Browser Compatibility
|
|
362
|
+
|
|
363
|
+
The browser API requires:
|
|
364
|
+
- `FileReader` API for file parsing
|
|
365
|
+
- Modern JavaScript (ES2015+) for async/await support
|
|
366
|
+
|
|
367
|
+
**Supported Browsers:**
|
|
368
|
+
- Chrome 42+ (FileReader)
|
|
369
|
+
- Firefox 38+ (FileReader)
|
|
370
|
+
- Safari 10+ (FileReader)
|
|
371
|
+
- Edge 12+ (FileReader)
|
|
372
|
+
|
|
373
|
+
## Common Issues
|
|
374
|
+
|
|
375
|
+
### FileReader Not Available
|
|
376
|
+
|
|
377
|
+
```js
|
|
378
|
+
if (typeof FileReader === 'undefined') {
|
|
379
|
+
console.error('FileReader API is not available in this environment');
|
|
380
|
+
}
|
|
381
|
+
```
|
|
382
|
+
|
|
383
|
+
### File Reading Errors
|
|
384
|
+
|
|
385
|
+
```js
|
|
386
|
+
async function safeParseFile(file) {
|
|
387
|
+
try {
|
|
388
|
+
return await convert.browser.parseFile(file);
|
|
389
|
+
} catch (error) {
|
|
390
|
+
if (error.message.includes('FileReader')) {
|
|
391
|
+
console.error('File reading not supported');
|
|
392
|
+
} else {
|
|
393
|
+
console.error('Parse error:', error);
|
|
394
|
+
}
|
|
395
|
+
return null;
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
```
|
|
399
|
+
|
|
400
|
+
### Large File Handling
|
|
401
|
+
|
|
402
|
+
For large files, consider:
|
|
403
|
+
1. Processing in chunks
|
|
404
|
+
2. Using Web Workers for non-blocking parsing
|
|
405
|
+
3. Showing progress feedback to users
|
|
406
|
+
|
|
407
|
+
```js
|
|
408
|
+
async function parseWithProgress(file) {
|
|
409
|
+
const fileSize = file.size;
|
|
410
|
+
console.log(`Parsing file: ${file.name} (${fileSize} bytes)`);
|
|
411
|
+
|
|
412
|
+
const start = Date.now();
|
|
413
|
+
const json = await convert.browser.parseFile(file);
|
|
414
|
+
const duration = Date.now() - start;
|
|
415
|
+
|
|
416
|
+
console.log(`Completed in ${duration}ms: ${json.length} records`);
|
|
417
|
+
return json;
|
|
418
|
+
}
|
|
419
|
+
```
|
|
420
|
+
|
|
421
|
+
## See Also
|
|
422
|
+
|
|
423
|
+
- [Main README](../README.md) - Overview and installation
|
|
424
|
+
- [Sync API](SYNC.md) - Synchronous operations
|
|
425
|
+
- [Async API](ASYNC.md) - Asynchronous operations with Promises/async-await
|