jtcsv 2.1.1 → 2.1.5

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.
Files changed (60) hide show
  1. package/README.md +64 -327
  2. package/bin/jtcsv.js +7 -24
  3. package/csv-to-json.js +35 -26
  4. package/dist/jtcsv.cjs.js +807 -133
  5. package/dist/jtcsv.cjs.js.map +1 -1
  6. package/dist/jtcsv.esm.js +800 -134
  7. package/dist/jtcsv.esm.js.map +1 -1
  8. package/dist/jtcsv.umd.js +807 -133
  9. package/dist/jtcsv.umd.js.map +1 -1
  10. package/errors.js +20 -0
  11. package/examples/browser-vanilla.html +37 -0
  12. package/examples/cli-batch-processing.js +38 -0
  13. package/examples/simple-usage.js +12 -10
  14. package/examples/web-workers-advanced.js +28 -0
  15. package/json-save.js +2 -1
  16. package/package.json +41 -21
  17. package/plugins/README.md +50 -332
  18. package/plugins/express-middleware/README.md +32 -274
  19. package/plugins/hono/README.md +28 -0
  20. package/plugins/hono/index.d.ts +12 -0
  21. package/plugins/hono/index.js +36 -0
  22. package/plugins/hono/package.json +35 -0
  23. package/plugins/nestjs/README.md +35 -0
  24. package/plugins/nestjs/index.d.ts +25 -0
  25. package/plugins/nestjs/index.js +77 -0
  26. package/plugins/nestjs/package.json +37 -0
  27. package/plugins/nextjs-api/README.md +28 -423
  28. package/plugins/nextjs-api/index.js +1 -2
  29. package/plugins/nextjs-api/route.js +1 -2
  30. package/plugins/nuxt/README.md +24 -0
  31. package/plugins/nuxt/index.js +21 -0
  32. package/plugins/nuxt/package.json +35 -0
  33. package/plugins/nuxt/runtime/composables/useJtcsv.js +6 -0
  34. package/plugins/nuxt/runtime/plugin.js +6 -0
  35. package/plugins/remix/README.md +26 -0
  36. package/plugins/remix/index.d.ts +16 -0
  37. package/plugins/remix/index.js +62 -0
  38. package/plugins/remix/package.json +35 -0
  39. package/plugins/sveltekit/README.md +28 -0
  40. package/plugins/sveltekit/index.d.ts +17 -0
  41. package/plugins/sveltekit/index.js +54 -0
  42. package/plugins/sveltekit/package.json +33 -0
  43. package/plugins/trpc/README.md +25 -0
  44. package/plugins/trpc/index.d.ts +7 -0
  45. package/plugins/trpc/index.js +32 -0
  46. package/plugins/trpc/package.json +34 -0
  47. package/src/browser/browser-functions.js +33 -3
  48. package/src/browser/csv-to-json-browser.js +269 -11
  49. package/src/browser/errors-browser.js +19 -1
  50. package/src/browser/index.js +39 -5
  51. package/src/browser/streams.js +393 -0
  52. package/src/browser/workers/csv-parser.worker.js +20 -2
  53. package/src/browser/workers/worker-pool.js +507 -447
  54. package/src/core/plugin-system.js +4 -0
  55. package/src/engines/fast-path-engine.js +31 -23
  56. package/src/formats/ndjson-parser.js +54 -5
  57. package/src/formats/tsv-parser.js +4 -1
  58. package/stream-csv-to-json.js +11 -2
  59. package/stream-json-to-csv.js +13 -1
  60. package/cli-tui.js +0 -1498
package/README.md CHANGED
@@ -1,154 +1,48 @@
1
- # jtcsv - Complete JSON CSV Converter
1
+ # jtcsv - JSON <-> CSV toolkit for Node.js and browser
2
2
 
3
- **Version 2.0** - Now with full browser support, Web Workers, and streaming!
4
-
5
- [![npm version](https://img.shields.io/npm/v/jtcsvps://www.npmjs.com/package/jtcsv)jtcsv
3
+ [![npm version](https://img.shields.io/npm/v/jtcsv)](https://www.npmjs.com/package/jtcsv)
6
4
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
7
- [![Zero Dependencies](https://img.shields.io/badge/dependencies-zero-brightgreen.svg)](https://www.npmjs.com/package/jtcsv
8
-
9
- A lightweight, efficient, and secure library for converting between JSON and CSV formats with full browser support, Web Workers for large files, and streaming capabilities.
10
-
11
- ## ✨ Features
12
-
13
- ### 🚀 Core Features
14
- - **Bidirectional Conversion**: JSON ↔ CSV with full type preservation
15
- - **Zero Dependencies**: Pure JavaScript/TypeScript, no external dependencies
16
- - **TypeScript Support**: Full type definitions included
17
- - **Security First**: Built-in CSV injection protection
18
- - **RFC 4180 Compliant**: Proper CSV formatting and escaping
19
-
20
- ### 🌐 Browser Support
21
- - **Full Browser Compatibility**: Chrome, Firefox, Safari, Edge, Mobile
22
- - **Web Workers**: Process large files without blocking UI
23
- - **File API Integration**: Direct file upload/download support
24
- - **Streaming Processing**: Handle files of any size
25
- - **Progress Tracking**: Real-time progress updates
5
+ [![Zero-Deps Core](https://img.shields.io/badge/core-zero%20deps-brightgreen.svg)](https://www.npmjs.com/package/jtcsv)
26
6
 
27
- ### Performance
28
- - **High Speed**: Optimized parsing algorithms
29
- - **Memory Efficient**: Streaming and chunked processing
30
- - **Worker Pool**: Reusable Web Workers for parallel processing
31
- - **Caching**: Intelligent caching for repeated operations
7
+ Fast JSON <-> CSV conversion with streaming helpers, NDJSON/TSV support, and optional integrations.
32
8
 
33
- ### 🔧 Advanced Features
34
- - **Auto-detection**: Automatic delimiter detection
35
- - **Custom Headers**: Flexible header mapping and renaming
36
- - **Nested Objects**: Support for complex nested structures
37
- - **Multiple Formats**: CSV, TSV, Excel-compatible output
38
- - **Error Handling**: Comprehensive error reporting and recovery
9
+ ## Features
10
+ - JSON <-> CSV conversion with security defaults
11
+ - Streaming helpers and async iterator API
12
+ - NDJSON and TSV helpers
13
+ - Browser bundle with Web Worker helpers
14
+ - Optional plugin system and framework adapters
15
+ - CLI and optional TUI
39
16
 
40
- ## 📦 Installation
41
-
42
- ### Node.js
17
+ ## Installation
43
18
  ```bash
44
19
  npm install jtcsv
45
20
  ```
46
21
 
47
- ### Browser (CDN)
48
- ```html
49
- <!-- UMD version (global jtcsv variable) -->
50
- <script src="https://cdn.jsdelivr.net/npm/jtcsvst/jtcsv.umd.js"></script>
51
-
52
- <!-- ESM version -->
53
- <script type="module">
54
- import { jsonToCsv } from 'https://cdn.jsdelivr.net/npm/jtcsvst/jtcsv.esm.js';
55
- </script>
22
+ ### Optional add-ons
23
+ ```bash
24
+ npm install @jtcsv/tui
25
+ npm install @jtcsv/excel exceljs
26
+ npm install @jtcsv/validator
56
27
  ```
57
28
 
58
- ## 🚀 Quick Start
59
-
60
- ### Node.js Usage
29
+ ## Quick start (Node.js)
61
30
  ```javascript
62
- const { jsonToCsv, csvToJson } = require('jtcsv
31
+ const { jsonToCsv, csvToJson } = require('jtcsv');
63
32
 
64
- // JSON to CSV
65
33
  const data = [
66
34
  { id: 1, name: 'John', email: 'john@example.com' },
67
35
  { id: 2, name: 'Jane', email: 'jane@example.com' }
68
36
  ];
69
37
 
70
- const csv = jsonToCsv(data, {
71
- delimiter: ',',
72
- includeHeaders: true,
73
- preventCsvInjection: true
74
- });
38
+ const csv = jsonToCsv(data, { delimiter: ',', includeHeaders: true });
39
+ const json = csvToJson(csv, { delimiter: ',', parseNumbers: true });
75
40
 
76
41
  console.log(csv);
77
- // id,name,email
78
- // 1,John,john@example.com
79
- // 2,Jane,jane@example.com
80
-
81
- // CSV to JSON
82
- const csvString = 'id,name,email\n1,John,john@example.com\n2,Jane,jane@example.com';
83
- const json = csvToJson(csvString, {
84
- delimiter: ',',
85
- parseNumbers: true
86
- });
87
-
88
42
  console.log(json);
89
- // [
90
- // { id: 1, name: 'John', email: 'john@example.com' },
91
- // { id: 2, name: 'Jane', email: 'jane@example.com' }
92
- // ]
93
43
  ```
94
44
 
95
- ### Browser Usage
96
- ```javascript
97
- // Using global variable (UMD)
98
- const csv = window.jtcsv.jsonToCsv(data, { delimiter: ',' });
99
-
100
- // Download as file
101
- window.jtcsv.downloadAsCsv(data, 'export.csv', { delimiter: ',' });
102
-
103
- // Parse uploaded file
104
- const fileInput = document.querySelector('input[type="file"]');
105
- const json = await window.jtcsv.parseCsvFile(fileInput.files[0], {
106
- delimiter: ',',
107
- parseNumbers: true
108
- });
109
-
110
- // Use Web Workers for large files
111
- const largeFile = document.querySelector('input[type="file"]').files[0];
112
- const result = await window.jtcsv.parseCSVWithWorker(largeFile, {}, (progress) => {
113
- console.log(`Progress: ${progress.percentage.toFixed(1)}%`);
114
- });
115
- ```
116
-
117
- ## 🔧 API Reference
118
-
119
- ### Core Functions
120
-
121
- #### `jsonToCsv(data, options)`
122
- Converts an array of objects to CSV string.
123
-
124
- **Options:**
125
- - `delimiter` (string, default: ';'): CSV delimiter character
126
- - `includeHeaders` (boolean, default: true): Include header row
127
- - `renameMap` (object): Map for renaming column headers
128
- - `preventCsvInjection` (boolean, default: true): Escape formulas for security
129
- - `rfc4180Compliant` (boolean, default: true): RFC 4180 compliance
130
- - `maxRecords` (number): Maximum records to process
131
-
132
- #### `csvToJson(csv, options)`
133
- Converts CSV string to array of objects.
134
-
135
- **Options:**
136
- Fast path parsing is the default pipeline; use `fastPathMode` to control row shape.
137
- - `delimiter` (string): Delimiter (auto-detected if not specified)
138
- - `autoDetect` (boolean, default: true): Auto-detect delimiter
139
- - `hasHeaders` (boolean, default: true): CSV has header row
140
- - `parseNumbers` (boolean, default: false): Parse numeric values
141
- - `parseBooleans` (boolean, default: false): Parse boolean values
142
- - `trim` (boolean, default: true): Trim whitespace
143
- - `maxRows` (number): Maximum rows to process
144
- - `useFastPath` (boolean, default: true): Enable fast-path parser (set `false` to force quote-aware path)
145
- - `fastPathMode` (string, default: 'objects'): `'objects'` for object rows, `'compact'` for arrays (lower memory), `'stream'` to return an async iterator
146
-
147
- #### `csvToJsonIterator(csv, options)`
148
- Convert CSV to JSON rows as an async iterator for large inputs.
149
- You can also call `csvToJson(csv, { fastPathMode: 'stream' })` to get the same async iterator.
150
-
151
- **Example:**
45
+ ### Async iterator
152
46
  ```javascript
153
47
  const { csvToJsonIterator } = require('jtcsv');
154
48
 
@@ -158,222 +52,65 @@ for await (const row of csvToJsonIterator(csv, { fastPathMode: 'compact' })) {
158
52
  }
159
53
  ```
160
54
 
161
- ### Browser-Specific Functions
162
-
163
- #### `downloadAsCsv(data, filename, options)`
164
- Converts and downloads JSON as CSV file.
165
-
166
- #### `parseCsvFile(file, options)`
167
- Parses CSV File object to JSON.
168
-
169
- #### `createCsvBlob(data, options)`
170
- Creates CSV Blob without downloading.
55
+ ## Browser usage
56
+ - Bundler: `import { csvToJson, jsonToCsv } from 'jtcsv/browser';`
57
+ - CDN UMD: `https://cdn.jsdelivr.net/npm/jtcsv/dist/jtcsv.umd.js`
58
+ - CDN ESM: `https://cdn.jsdelivr.net/npm/jtcsv/dist/jtcsv.esm.js`
171
59
 
172
- #### `parseCsvBlob(blob, options)`
173
- Parses CSV Blob to JSON.
60
+ See `README-browser.md` for full browser API and worker helpers.
174
61
 
175
- ### Web Workers Functions
176
-
177
- #### `createWorkerPool(options)`
178
- Creates a pool of Web Workers for parallel processing.
62
+ ## CLI
63
+ ```bash
64
+ npx jtcsv csv-to-json input.csv output.json
65
+ npx jtcsv json-to-csv input.json output.csv
66
+ npx jtcsv stream csv-to-json big.csv output.json
67
+ npx jtcsv batch json-to-csv "data/*.json" output/
179
68
 
180
- **Options:**
181
- - `workerCount` (number, default: 4): Number of workers
182
- - `maxQueueSize` (number, default: 100): Maximum queue size
183
- - `autoScale` (boolean, default: true): Auto-scale workers
184
- - `idleTimeout` (number, default: 60000): Idle timeout in ms
69
+ # optional TUI
70
+ npx jtcsv tui
71
+ ```
185
72
 
186
- #### `parseCSVWithWorker(csvInput, options, onProgress)`
187
- Parses CSV using Web Workers with progress tracking.
73
+ See `CLI.md` for full command list and options.
188
74
 
189
- ## 💡 Examples
75
+ ## Demos
76
+ Run these from the repo root:
77
+ ```bash
78
+ # Express API demo
79
+ npm run demo
190
80
 
191
- ### React Component Example
192
- ```jsx
193
- import React, { useState } from 'react';
194
- import { parseCsvFile, downloadAsCsv } from 'jtcsv
81
+ # Web demo (Vite dev server on http://localhost:3000)
82
+ npm run demo:web
195
83
 
196
- export function CSVProcessor() {
197
- const [data, setData] = useState([]);
198
- const [loading, setLoading] = useState(false);
199
-
200
- const handleFileUpload = async (event) => {
201
- const file = event.target.files[0];
202
- if (!file) return;
203
-
204
- setLoading(true);
205
- try {
206
- const jsonData = await parseCsvFile(file, {
207
- delimiter: ',',
208
- parseNumbers: true
209
- });
210
- setData(jsonData);
211
- } catch (error) {
212
- console.error('Error:', error);
213
- } finally {
214
- setLoading(false);
215
- }
216
- };
217
-
218
- const handleExport = () => {
219
- downloadAsCsv(data, 'export.csv', { delimiter: ',' });
220
- };
221
-
222
- return (
223
- <div>
224
- <input type="file" accept=".csv" onChange={handleFileUpload} />
225
- <button onClick={handleExport} disabled={!data.length}>
226
- Export to CSV
227
- </button>
228
- {loading && <div>Processing...</div>}
229
- <pre>{JSON.stringify(data.slice(0, 5), null, 2)}</pre>
230
- </div>
231
- );
232
- }
84
+ # Preview built demo
85
+ npm run demo:serve
233
86
  ```
234
87
 
235
- ### Large File Processing with Progress
236
- ```javascript
237
- import { parseCSVWithWorker } from 'jtcsv
238
-
239
- async function processLargeFile(file) {
240
- const progressBar = document.getElementById('progress-bar');
241
- const status = document.getElementById('status');
242
-
243
- try {
244
- const result = await parseCSVWithWorker(file, {}, (progress) => {
245
- const percent = Math.round(progress.percentage);
246
- progressBar.style.width = percent + '%';
247
- progressBar.textContent = percent + '%';
248
-
249
- status.textContent =
250
- `Processing: ${progress.processed.toLocaleString()} of ${progress.total.toLocaleString()} rows ` +
251
- `(${Math.round(progress.speed)} rows/sec)`;
252
- });
253
-
254
- status.textContent = `Processed ${result.length.toLocaleString()} rows successfully`;
255
- return result;
256
- } catch (error) {
257
- status.textContent = `Error: ${error.message}`;
258
- throw error;
259
- }
260
- }
88
+ From inside `demo/` use:
89
+ ```bash
90
+ npm run dev
91
+ npm run preview
92
+ npm run serve
261
93
  ```
262
94
 
263
- ### Security: CSV Injection Protection
264
- ```javascript
265
- const dangerousData = [
266
- { formula: '=SUM(1,2)', command: '=cmd|"/c calc"!A1' }
267
- ];
95
+ ## Plugin system
96
+ The plugin-enabled API is exported from `jtcsv/plugins`.
268
97
 
269
- // With protection enabled (default)
270
- const safeCsv = jsonToCsv(dangerousData, { preventCsvInjection: true });
271
- // formula,command
272
- // "'=SUM(1,2)","'=cmd|"/c calc"!A1"
273
- // Formulas are prefixed with single quote to prevent execution
98
+ ```javascript
99
+ const { create } = require('jtcsv/plugins');
274
100
 
275
- // Without protection
276
- const unsafeCsv = jsonToCsv(dangerousData, { preventCsvInjection: false });
277
- // formula,command
278
- // =SUM(1,2),=cmd|"/c calc"!A1
279
- // WARNING: This could execute commands in Excel!
101
+ const jtcsv = create();
102
+ jtcsv.use('my-plugin', { name: 'My Plugin', version: '1.0.0' });
280
103
  ```
281
104
 
282
- ## 📊 Performance
283
-
284
- ### Benchmark Results (Node.js 22, 10K rows/records)
285
-
286
- **CSV → JSON (10K rows)**
287
-
288
- | Library | Time | Memory | Rank |
289
- |---------|------|--------|------|
290
- | **JTCSV (FastPath Compact)** | 16.79 ms | 4.47 MB | 🥇 1st |
291
- | **JTCSV (FastPath Stream)** | 18.27 ms | 6.03 MB | 🥈 2nd |
292
- | **JTCSV** | 19.76 ms | 8.96 MB | 🥉 3rd |
293
- | PapaParse | 21.57 ms | 6.97 MB | 4th |
294
- | csv-parser | 30.52 ms | 6.53 MB | 5th |
295
-
296
- **JSON → CSV (10K records)**
105
+ See `README-PLUGINS.md` and `plugins/README.md` for integrations.
297
106
 
298
- | Library | Time | Memory | Rank |
299
- |---------|------|--------|------|
300
- | **JTCSV** | 11.21 ms | 4.77 MB | 🥇 1st |
301
- | json2csv | 12.27 ms | 12.11 MB | 🥈 2nd |
302
-
303
- ### Scaling (JTCSV only)
304
-
305
- | Rows/Records | CSV→JSON Time (FastPath Compact) | JSON→CSV Time (JTCSV) | CSV→JSON Memory | JSON→CSV Memory |
306
- |--------------|----------------------------------|-----------------------|-----------------|-----------------|
307
- | 1,000 | 2.06 ms | 1.04 ms | 2.15 MB | 0.52 MB |
308
- | 10,000 | 14.68 ms | 8.23 ms | 2.11 MB | 4.14 MB |
309
- | 100,000 | 164.18 ms | 90.93 ms | 44.93 MB | 34.79 MB |
310
-
311
- See `BENCHMARK-RESULTS.md` and `docs/PERFORMANCE.md` for environment details and methodology.
312
-
313
- ## 🛠️ Development
314
-
315
- ### Building from Source
107
+ ## Development
108
+ Run from the repo root:
316
109
  ```bash
317
- # Clone repository
318
- git clone https://github.com/Linol-Hamelton/jtcsv.git
319
- cd jtcsv
320
-
321
- # Install dependencies
322
- npm install
323
-
324
- # Build browser version
325
- npm run build
326
-
327
- # Run tests
328
110
  npm test
329
-
330
- # Start demo server
331
- npm run demo
332
- ```
333
-
334
- ### Project Structure
335
- ```
336
- jtcsv/
337
- ├── src/browser/ # Browser-specific code
338
- │ ├── index.js # Browser entry point
339
- │ ├── *.js # Browser modules
340
- │ └── workers/ # Web Workers implementation
341
- ├── dist/ # Built distributions
342
- │ ├── jtcsv.umd.js # UMD bundle
343
- │ ├── jtcsv.esm.js # ESM bundle
344
- │ └── jtcsv.cjs.js # CJS bundle
345
- ├── demo/ # Demo application
346
- ├── __tests__/ # Test files
347
- ├── rollup.config.mjs # Build configuration
348
- └── package.json # Project configuration
111
+ npm run test:coverage
112
+ npm run build
349
113
  ```
350
114
 
351
- ## 🤝 Contributing
352
-
353
- Contributions are welcome! Please feel free to submit a Pull Request.
354
-
355
- 1. Fork the repository
356
- 2. Create your feature branch (`git checkout -b feature/amazing-feature`)
357
- 3. Commit your changes (`git commit -m 'Add some amazing feature'`)
358
- 4. Push to the branch (`git push origin feature/amazing-feature`)
359
- 5. Open a Pull Request
360
-
361
- ## 📄 License
362
-
363
- This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
364
-
365
- ## 🙏 Acknowledgments
366
-
367
- - Inspired by the need for secure, efficient CSV processing in browsers
368
- - Thanks to all contributors who have helped improve this library
369
- - Special thanks to the open source community for invaluable tools and libraries
370
-
371
- ## 📞 Support
372
-
373
- - **GitHub Issues**: [Report bugs or request features](https://github.com/Linol-Hamelton/jtcsv/issues)
374
- - **Documentation**: [Full API documentation](https://github.com/Linol-Hamelton/jtcsv#readme)
375
- - **Examples**: [Example code and demos](https://github.com/Linol-Hamelton/jtcsv/tree/main/demo)
376
-
377
- ---
378
-
379
- **Happy coding!** If you find this library useful, please consider giving it a star on GitHub ⭐
115
+ ## License
116
+ MIT. See `LICENSE`.
package/bin/jtcsv.js CHANGED
@@ -47,7 +47,7 @@ ${color('MAIN COMMANDS:', 'bright')}
47
47
  ${color('stream', 'yellow')} Streaming conversion for large files
48
48
  ${color('batch', 'yellow')} Batch process multiple files
49
49
  ${color('preprocess', 'magenta')} Preprocess JSON with deep unwrapping
50
- ${color('tui', 'magenta')} Launch Terminal User Interface
50
+ ${color('tui', 'magenta')} Launch Terminal User Interface (@jtcsv/tui)
51
51
  ${color('help', 'blue')} Show this help message
52
52
  ${color('version', 'blue')} Show version information
53
53
 
@@ -1038,34 +1038,17 @@ function parseOptions(args) {
1038
1038
 
1039
1039
  async function launchTUI() {
1040
1040
  try {
1041
- // Check if blessed is installed
1042
- require.resolve('blessed');
1043
-
1044
1041
  console.log(color('Launching Terminal User Interface...', 'cyan'));
1045
1042
  console.log(color('Press Ctrl+Q to exit', 'dim'));
1046
-
1047
- // Check if TUI file exists and has content
1048
- const tuiPath = path.join(__dirname, '../cli-tui.js');
1049
- const stats = await fs.promises.stat(tuiPath);
1050
-
1051
- if (stats.size < 100) {
1052
- console.log(color('⚠️ TUI interface is not fully implemented yet', 'yellow'));
1053
- console.log(color(' Basic TUI will be started...', 'dim'));
1054
-
1055
- // Start basic TUI
1056
- await startBasicTUI();
1057
- } else {
1058
- // Import and launch full TUI
1059
- const JtcsvTUI = require('../cli-tui.js');
1060
- const tui = new JtcsvTUI();
1061
- tui.start();
1062
- }
1063
-
1043
+
1044
+ const JtcsvTUI = require('@jtcsv/tui');
1045
+ const tui = new JtcsvTUI();
1046
+ tui.start();
1064
1047
  } catch (error) {
1065
1048
  if (error.code === 'MODULE_NOT_FOUND') {
1066
- console.error(color('Error: blessed is required for TUI interface', 'red'));
1049
+ console.error(color('Error: @jtcsv/tui is not installed', 'red'));
1067
1050
  console.log(color('Install it with:', 'dim'));
1068
- console.log(color(' npm install blessed blessed-contrib', 'cyan'));
1051
+ console.log(color(' npm install @jtcsv/tui', 'cyan'));
1069
1052
  console.log(color('\nOr use the CLI interface instead:', 'dim'));
1070
1053
  console.log(color(' jtcsv help', 'cyan'));
1071
1054
  } else {
package/csv-to-json.js CHANGED
@@ -114,8 +114,9 @@ function validateCsvInput(csv, options) {
114
114
  * Parses a value based on options
115
115
  * @private
116
116
  */
117
- function parseCsvValue(value, options) {
118
- const { trim = true, parseNumbers = false, parseBooleans = false } = options;
117
+ function parseCsvValue(value, options) {
118
+ /* istanbul ignore next */
119
+ const { trim = true, parseNumbers = false, parseBooleans = false } = options;
119
120
 
120
121
  let result = value;
121
122
 
@@ -131,10 +132,11 @@ function parseCsvValue(value, options) {
131
132
  // Parse numbers
132
133
  if (parseNumbers && /^-?\d+(\.\d+)?$/.test(result)) {
133
134
  const num = parseFloat(result);
134
- if (!isNaN(num)) {
135
- return num;
136
- }
137
- }
135
+ /* istanbul ignore next */
136
+ if (!isNaN(num)) {
137
+ return num;
138
+ }
139
+ }
138
140
 
139
141
  // Parse booleans
140
142
  if (parseBooleans) {
@@ -342,12 +344,13 @@ function csvToJson(csv, options = {}) {
342
344
  console.warn(`[jtcsv] Line ${totalRows}: ${fields.length - headers.length} extra fields ignored`);
343
345
  }
344
346
  });
345
- } catch (error) {
346
- if (error && error.code === 'FAST_PATH_UNCLOSED_QUOTES') {
347
- throw new ParsingError(error.message, error.lineNumber);
348
- }
349
- throw error;
350
- }
347
+ } catch (error) {
348
+ if (error && error.code === 'FAST_PATH_UNCLOSED_QUOTES') {
349
+ const lineInfo = error.lineNumber ? ` at line ${error.lineNumber}` : '';
350
+ throw new ParsingError(`Unclosed quotes in CSV${lineInfo}`, error.lineNumber);
351
+ }
352
+ throw error;
353
+ }
351
354
 
352
355
  if (!headers) {
353
356
  return [];
@@ -371,7 +374,8 @@ function csvToJson(csv, options = {}) {
371
374
  }, 'PARSE_FAILED', { function: 'csvToJson' });
372
375
  }
373
376
 
374
- async function* csvToJsonIterator(csv, options = {}) {
377
+ /* istanbul ignore next */
378
+ async function* csvToJsonIterator(csv, options = {}) {
375
379
  validateCsvInput(csv, options);
376
380
 
377
381
  const opts = options && typeof options === 'object' ? options : {};
@@ -498,7 +502,8 @@ async function* csvToJsonIterator(csv, options = {}) {
498
502
  }
499
503
  } catch (error) {
500
504
  if (error && error.code === 'FAST_PATH_UNCLOSED_QUOTES') {
501
- throw new ParsingError(error.message, error.lineNumber);
505
+ const lineInfo = error.lineNumber ? ` at line ${error.lineNumber}` : '';
506
+ throw new ParsingError(`Unclosed quotes in CSV${lineInfo}`, error.lineNumber);
502
507
  }
503
508
  throw error;
504
509
  }
@@ -638,24 +643,27 @@ function createTransformHooks() {
638
643
  * @param {number} maxSize - Maximum cache size (default: 100)
639
644
  * @returns {DelimiterCache} New DelimiterCache instance
640
645
  */
641
- function createDelimiterCache(maxSize = 100) {
642
- return new DelimiterCache(maxSize);
643
- }
646
+ /* istanbul ignore next */
647
+ function createDelimiterCache(maxSize = 100) {
648
+ return new DelimiterCache(maxSize);
649
+ }
644
650
 
645
651
  /**
646
652
  * Gets statistics from the global delimiter cache
647
653
  * @returns {Object} Cache statistics
648
654
  */
649
- function getDelimiterCacheStats() {
650
- return globalDelimiterCache.getStats();
651
- }
655
+ /* istanbul ignore next */
656
+ function getDelimiterCacheStats() {
657
+ return globalDelimiterCache.getStats();
658
+ }
652
659
 
653
660
  /**
654
661
  * Clears the global delimiter cache
655
662
  */
656
- function clearDelimiterCache() {
657
- globalDelimiterCache.clear();
658
- }
663
+ /* istanbul ignore next */
664
+ function clearDelimiterCache() {
665
+ globalDelimiterCache.clear();
666
+ }
659
667
 
660
668
  // Export the functions
661
669
  module.exports = {
@@ -674,6 +682,7 @@ module.exports = {
674
682
  };
675
683
 
676
684
  // For ES6 module compatibility
677
- if (typeof module !== 'undefined' && module.exports) {
678
- module.exports.default = csvToJson;
679
- }
685
+ /* istanbul ignore next */
686
+ if (typeof module !== 'undefined' && module.exports) {
687
+ module.exports.default = csvToJson;
688
+ }