convert-csv-to-json 4.46.0 → 4.47.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/index.js CHANGED
@@ -19,6 +19,24 @@ const encodingOps = {
19
19
  hex: 'hex'
20
20
  };
21
21
 
22
+ const csvToJsonAsync = require('./src/csvToJsonAsync');
23
+
24
+ /**
25
+ * Apply the same parser configuration update to every parser client.
26
+ * This keeps root-level chainable API calls in sync across sync, async, and browser clients.
27
+ * @param {function(object): void} configFn - Function that applies configuration to a client instance
28
+ * @returns {object} Module exports for chaining
29
+ * @private
30
+ */
31
+ function applyConfigToAllClients(configFn) {
32
+ configFn(csvToJson);
33
+ configFn(csvToJsonAsync);
34
+ if (exports.browser) {
35
+ configFn(exports.browser);
36
+ }
37
+ return exports;
38
+ }
39
+
22
40
  /**
23
41
  * Enable or disable automatic type formatting for values
24
42
  * Converts numeric strings to numbers, 'true'/'false' to booleans
@@ -27,8 +45,7 @@ const encodingOps = {
27
45
  * @returns {object} Module context for method chaining
28
46
  */
29
47
  exports.formatValueByType = function (active = true) {
30
- csvToJson.formatValueByType(active);
31
- return this;
48
+ return applyConfigToAllClients(client => client.formatValueByType(active));
32
49
  };
33
50
 
34
51
  /**
@@ -39,8 +56,7 @@ exports.formatValueByType = function (active = true) {
39
56
  * @returns {object} Module context for method chaining
40
57
  */
41
58
  exports.supportQuotedField = function (active = false) {
42
- csvToJson.supportQuotedField(active);
43
- return this;
59
+ return applyConfigToAllClients(client => client.supportQuotedField(active));
44
60
  };
45
61
  /**
46
62
  * Set the field delimiter character used to separate CSV fields
@@ -49,8 +65,7 @@ exports.supportQuotedField = function (active = false) {
49
65
  * @returns {object} Module context for method chaining
50
66
  */
51
67
  exports.fieldDelimiter = function (delimiter) {
52
- csvToJson.fieldDelimiter(delimiter);
53
- return this;
68
+ return applyConfigToAllClients(client => client.fieldDelimiter(delimiter));
54
69
  };
55
70
 
56
71
  /**
@@ -62,8 +77,7 @@ exports.fieldDelimiter = function (delimiter) {
62
77
  * @returns {object} Module context for method chaining
63
78
  */
64
79
  exports.trimHeaderFieldWhiteSpace = function (active = false) {
65
- csvToJson.trimHeaderFieldWhiteSpace(active);
66
- return this;
80
+ return applyConfigToAllClients(client => client.trimHeaderFieldWhiteSpace(active));
67
81
  };
68
82
 
69
83
  /**
@@ -74,8 +88,7 @@ exports.trimHeaderFieldWhiteSpace = function (active = false) {
74
88
  * @returns {object} Module context for method chaining
75
89
  */
76
90
  exports.indexHeader = function (index) {
77
- csvToJson.indexHeader(index);
78
- return this;
91
+ return applyConfigToAllClients(client => client.indexHeader(index));
79
92
  };
80
93
 
81
94
  /**
@@ -91,8 +104,7 @@ exports.indexHeader = function (index) {
91
104
  * csvToJson.parseSubArray('*', ',')
92
105
  */
93
106
  exports.parseSubArray = function (delimiter, separator) {
94
- csvToJson.parseSubArray(delimiter, separator);
95
- return this;
107
+ return applyConfigToAllClients(client => client.parseSubArray(delimiter, separator));
96
108
  };
97
109
 
98
110
  /**
@@ -111,8 +123,7 @@ exports.ignoreColumnIndexes = function (indexes) {
111
123
  if (!indexes.every(idx => Number.isInteger(idx) && idx >= 0)) {
112
124
  throw new TypeError('All elements in indexes must be valid non-negative numbers (>= 0)');
113
125
  }
114
- csvToJson.ignoreColumnIndexes(indexes);
115
- return this;
126
+ return applyConfigToAllClients(client => client.ignoreColumnIndexes(indexes));
116
127
  };
117
128
 
118
129
  /**
@@ -123,8 +134,7 @@ exports.ignoreColumnIndexes = function (indexes) {
123
134
  * @returns {object} Module context for method chaining
124
135
  */
125
136
  exports.customEncoding = function (encoding) {
126
- csvToJson.encoding = encoding;
127
- return this;
137
+ return applyConfigToAllClients(client => client.encoding(encoding));
128
138
  };
129
139
 
130
140
  /**
@@ -133,8 +143,7 @@ exports.customEncoding = function (encoding) {
133
143
  * @returns {object} Module context for method chaining
134
144
  */
135
145
  exports.utf8Encoding = function utf8Encoding() {
136
- csvToJson.encoding = encodingOps.utf8;
137
- return this;
146
+ return applyConfigToAllClients(client => client.encoding(encodingOps.utf8));
138
147
  };
139
148
 
140
149
  /**
@@ -143,8 +152,7 @@ exports.utf8Encoding = function utf8Encoding() {
143
152
  * @returns {object} Module context for method chaining
144
153
  */
145
154
  exports.ucs2Encoding = function () {
146
- csvToJson.encoding = encodingOps.ucs2;
147
- return this;
155
+ return applyConfigToAllClients(client => client.encoding(encodingOps.ucs2));
148
156
  };
149
157
 
150
158
  /**
@@ -153,8 +161,7 @@ exports.ucs2Encoding = function () {
153
161
  * @returns {object} Module context for method chaining
154
162
  */
155
163
  exports.utf16leEncoding = function () {
156
- csvToJson.encoding = encodingOps.utf16le;
157
- return this;
164
+ return applyConfigToAllClients(client => client.encoding(encodingOps.utf16le));
158
165
  };
159
166
 
160
167
  /**
@@ -163,8 +170,7 @@ exports.utf16leEncoding = function () {
163
170
  * @returns {object} Module context for method chaining
164
171
  */
165
172
  exports.latin1Encoding = function () {
166
- csvToJson.encoding = encodingOps.latin1;
167
- return this;
173
+ return applyConfigToAllClients(client => client.encoding(encodingOps.latin1));
168
174
  };
169
175
 
170
176
  /**
@@ -173,8 +179,7 @@ exports.latin1Encoding = function () {
173
179
  * @returns {object} Module context for method chaining
174
180
  */
175
181
  exports.asciiEncoding = function () {
176
- csvToJson.encoding = encodingOps.ascii;
177
- return this;
182
+ return applyConfigToAllClients(client => client.encoding(encodingOps.ascii));
178
183
  };
179
184
 
180
185
  /**
@@ -183,8 +188,7 @@ exports.asciiEncoding = function () {
183
188
  * @returns {object} Module context for method chaining
184
189
  */
185
190
  exports.base64Encoding = function () {
186
- this.csvToJson = encodingOps.base64;
187
- return this;
191
+ return applyConfigToAllClients(client => client.encoding(encodingOps.base64));
188
192
  };
189
193
 
190
194
  /**
@@ -193,8 +197,7 @@ exports.base64Encoding = function () {
193
197
  * @returns {object} Module context for method chaining
194
198
  */
195
199
  exports.hexEncoding = function () {
196
- this.csvToJson = encodingOps.hex;
197
- return this;
200
+ return applyConfigToAllClients(client => client.encoding(encodingOps.hex));
198
201
  };
199
202
 
200
203
  /**
@@ -210,8 +213,7 @@ exports.hexEncoding = function () {
210
213
  * .getJsonFromCsv('input.csv')
211
214
  */
212
215
  exports.mapRows = function (mapperFn) {
213
- csvToJson.mapRows(mapperFn);
214
- return this;
216
+ return applyConfigToAllClients(client => client.mapRows(mapperFn));
215
217
  };
216
218
 
217
219
  /**
@@ -257,8 +259,8 @@ exports.getJsonFromCsv = function(inputFileName) {
257
259
  };
258
260
 
259
261
  /**
260
- * Parse CSV file asynchronously and return parsed data as JSON array
261
- * @param {string} inputFileNameOrCsv - Path to file or CSV string
262
+ * Parse CSV file asynchronously and return parsed data as JSON array.
263
+ * @param {string} input - Path to file or CSV string
262
264
  * @param {object} options - Configuration options
263
265
  * @param {boolean} options.raw - If true, treats first param as CSV content; if false, reads from file
264
266
  * @returns {Promise<Array<object>>} Promise resolving to array of objects
@@ -271,11 +273,46 @@ exports.getJsonFromCsv = function(inputFileName) {
271
273
  * const data = await csvToJson.getJsonFromCsvAsync('resource/input.csv');
272
274
  * console.log(data);
273
275
  */
274
- const csvToJsonAsync = require('./src/csvToJsonAsync');
276
+ exports.getJsonFromCsvAsync = function(input, options) {
277
+ return csvToJsonAsync.getJsonFromCsvAsync(input, options);
278
+ };
275
279
 
276
280
  /**
277
- * Parse CSV from a Readable stream and return parsed data as JSON array
278
- * Processes data in chunks for memory-efficient handling of large files
281
+ * Parse a raw CSV string asynchronously and return parsed JSON objects.
282
+ * @param {string} input - CSV content as a string
283
+ * @param {object} [options] - Configuration options
284
+ * @param {boolean} [options.raw] - If true, treats input as CSV content
285
+ * @returns {Promise<Array<object>>} Promise resolving to array of parsed objects
286
+ * @category 1-Core API
287
+ */
288
+ exports.csvStringToJsonAsync = function(input, options) {
289
+ return csvToJsonAsync.csvStringToJsonAsync(input, options);
290
+ };
291
+
292
+ /**
293
+ * Parse a raw CSV string asynchronously and return a JSON string.
294
+ * @param {string} input - CSV content as a string
295
+ * @returns {Promise<string>} Promise resolving to JSON string
296
+ * @category 1-Core API
297
+ */
298
+ exports.csvStringToJsonStringifiedAsync = function(input) {
299
+ return csvToJsonAsync.csvStringToJsonStringifiedAsync(input);
300
+ };
301
+
302
+ /**
303
+ * Parse a CSV file asynchronously and write the parsed JSON to an output file.
304
+ * @param {string} input - Path to the input CSV file
305
+ * @param {string} output - Path to the output JSON file
306
+ * @returns {Promise<void>} Promise resolving when file is written
307
+ * @category 1-Core API
308
+ */
309
+ exports.generateJsonFileFromCsvAsync = function(input, output) {
310
+ return csvToJsonAsync.generateJsonFileFromCsv(input, output);
311
+ };
312
+
313
+ /**
314
+ * Parse CSV from a Readable stream and return parsed data as JSON array.
315
+ * Processes data in chunks for memory-efficient handling of large files.
279
316
  * @param {object} stream - Node.js Readable stream containing CSV data
280
317
  * @returns {Promise<Array<object>>} Promise resolving to array of objects representing CSV rows
281
318
  * @throws {InputValidationError} If stream is invalid
@@ -288,9 +325,12 @@ const csvToJsonAsync = require('./src/csvToJsonAsync');
288
325
  * const data = await csvToJson.getJsonFromStreamAsync(stream);
289
326
  * console.log(data);
290
327
  */
328
+ exports.getJsonFromStreamAsync = function(stream) {
329
+ return csvToJsonAsync.getJsonFromStreamAsync(stream);
330
+ };
291
331
 
292
332
  /**
293
- * Parse CSV from a file path using streaming for memory-efficient processing
333
+ * Parse CSV from a file path using streaming for memory-efficient processing.
294
334
  * @param {string} filePath - Path to the CSV file
295
335
  * @returns {Promise<Array<object>>} Promise resolving to array of objects representing CSV rows
296
336
  * @throws {InputValidationError} If filePath is invalid
@@ -302,28 +342,9 @@ const csvToJsonAsync = require('./src/csvToJsonAsync');
302
342
  * const data = await csvToJson.getJsonFromFileStreamingAsync('large.csv');
303
343
  * console.log(data);
304
344
  */
305
-
306
- // Re-export all async API methods
307
- Object.assign(exports, {
308
- getJsonFromCsvAsync: function(input, options) {
309
- return csvToJsonAsync.getJsonFromCsvAsync(input, options);
310
- },
311
- csvStringToJsonAsync: function(input, options) {
312
- return csvToJsonAsync.csvStringToJsonAsync(input, options);
313
- },
314
- csvStringToJsonStringifiedAsync: function(input) {
315
- return csvToJsonAsync.csvStringToJsonStringifiedAsync(input);
316
- },
317
- generateJsonFileFromCsvAsync: function(input, output) {
318
- return csvToJsonAsync.generateJsonFileFromCsv(input, output);
319
- },
320
- getJsonFromStreamAsync: function(stream) {
321
- return csvToJsonAsync.getJsonFromStreamAsync(stream);
322
- },
323
- getJsonFromFileStreamingAsync: function(filePath) {
324
- return csvToJsonAsync.getJsonFromFileStreamingAsync(filePath);
325
- }
326
- });
345
+ exports.getJsonFromFileStreamingAsync = function(filePath) {
346
+ return csvToJsonAsync.getJsonFromFileStreamingAsync(filePath);
347
+ };
327
348
 
328
349
  /**
329
350
  * Parse a CSV string and return as JSON array of objects (synchronous)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "convert-csv-to-json",
3
- "version": "4.46.0",
3
+ "version": "4.47.0",
4
4
  "description": "Convert CSV to JSON",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",
@@ -10,6 +10,7 @@
10
10
  "lint": "eslint .",
11
11
  "docs": "jsdoc -c jsdoc.json",
12
12
  "docs:api": "jsdoc -c jsdoc.json -d demo/api",
13
+ "demo": "npx http-server demo -p 8000",
13
14
  "prepublishOnly": "npm run docs:api",
14
15
  "version-patch": "npm version patch",
15
16
  "version-minor": "npm version minor",
@@ -55,6 +56,7 @@
55
56
  "browserify": "^17.0.1",
56
57
  "eslint": "^10.1.0",
57
58
  "eslint-plugin-jsdoc": "^63.0.0",
59
+ "http-server": "^14.1.1",
58
60
  "jest": "^30.2.0",
59
61
  "jsdoc": "^4.0.5",
60
62
  "ts-jest": "^29.4.5",
package/src/browserApi.js CHANGED
@@ -3,104 +3,52 @@
3
3
  "use strict";
4
4
 
5
5
  const csvToJson = require('./csvToJson');
6
- const { InputValidationError, BrowserApiError } = require('./util/errors');
7
- const StreamProcessor = require('./streamProcessor');
6
+ const Configurable = require('./core/configurable');
7
+ const { InputValidationError, BrowserApiError } = require('./core/errors');
8
+ const StreamProcessor = require('./core/streamProcessor');
8
9
 
9
10
  /**
10
11
  * Browser-friendly CSV to JSON API
11
12
  * Provides methods for parsing CSV strings and File/Blob objects in browser environments
12
- * Proxies configuration to sync csvToJson instance
13
+ * Uses isolated parser configuration via ParserConfig snapshots
13
14
  * @category 4-Browser
14
15
  */
15
- class BrowserApi {
16
+ class BrowserApi extends Configurable {
16
17
  /**
17
18
  * Constructor initializes proxy to sync csvToJson instance
18
19
  */
19
20
  constructor() {
20
- // reuse the existing csvToJson instance for parsing and configuration
21
+ super();
22
+ // reuse the existing csvToJson instance for parsing
21
23
  this.csvToJson = csvToJson;
22
24
  }
23
25
 
24
26
  /**
25
- * Enable or disable automatic type formatting for values
26
- * @param {boolean} active - Whether to format values by type (default: true)
27
- * @returns {this} For method chaining
28
- */
29
- formatValueByType(active = true) {
30
- this.csvToJson.formatValueByType(active);
31
- return this;
32
- }
33
-
34
- /**
35
- * Enable or disable support for RFC 4180 quoted fields
36
- * @param {boolean} active - Whether to support quoted fields (default: false)
37
- * @returns {this} For method chaining
38
- */
39
- supportQuotedField(active = false) {
40
- this.csvToJson.supportQuotedField(active);
41
- return this;
42
- }
43
-
44
- /**
45
- * Set the field delimiter character
46
- * @param {string} delimiter - Character(s) to use as field separator
47
- * @returns {this} For method chaining
48
- */
49
- fieldDelimiter(delimiter) {
50
- this.csvToJson.fieldDelimiter(delimiter);
51
- return this;
52
- }
53
-
54
- /**
55
- * Configure whitespace handling in header field names
56
- * @param {boolean} active - If true, removes all whitespace; if false, only trims edges (default: false)
57
- * @returns {this} For method chaining
58
- */
59
- trimHeaderFieldWhiteSpace(active = false) {
60
- this.csvToJson.trimHeaderFieldWhiteSpace(active);
61
- return this;
62
- }
63
-
64
- /**
65
- * Set the row index where CSV headers are located
66
- * @param {number} index - Zero-based row index containing headers
67
- * @returns {this} For method chaining
68
- */
69
- indexHeader(index) {
70
- this.csvToJson.indexHeader(index);
71
- return this;
72
- }
73
-
74
- /**
75
- * Configure columns to exclude from output
76
- * @param {Array<number>} indexes - Column indexes to ignore
77
- * @returns {this} For method chaining
78
- * @private Used internally after validation in index.js
79
- */
80
- ignoreColumnIndexes(indexes) {
81
- this.csvToJson.ignoreColumnIndexes(indexes);
82
- return this;
83
- }
84
-
85
- /**
86
- * Configure sub-array parsing for special field values
87
- * @param {string} delimiter - Bracket character (default: '*')
88
- * @param {string} separator - Item separator within brackets (default: ',')
89
- * @returns {this} For method chaining
27
+ * Validate CSV text input for browser methods.
28
+ * @param {string} csvString - CSV content as string
29
+ * @throws {InputValidationError} If the input is not a valid string
30
+ * @private
90
31
  */
91
- parseSubArray(delimiter = '*', separator = ',') {
92
- this.csvToJson.parseSubArray(delimiter, separator);
93
- return this;
32
+ _validateCsvString(csvString) {
33
+ if (csvString === undefined || csvString === null) {
34
+ throw new InputValidationError(
35
+ 'csvString',
36
+ 'string',
37
+ `${typeof csvString}`,
38
+ 'Provide valid CSV content as a string to parse.'
39
+ );
40
+ }
94
41
  }
95
42
 
96
43
  /**
97
- * Set a mapper function to transform each row after conversion
98
- * @param {function(object, number): (object|null)} mapperFn - Function receiving (row, index) that returns transformed row or null to filter
99
- * @returns {this} For method chaining
44
+ * Parse CSV text using a frozen parser configuration snapshot.
45
+ * @param {string} csvString - CSV content as string
46
+ * @returns {Array<object>} Parsed CSV rows
47
+ * @private
100
48
  */
101
- mapRows(mapperFn) {
102
- this.csvToJson.mapRows(mapperFn);
103
- return this;
49
+ _parseCsvText(csvString) {
50
+ const config = this.getParserConfig();
51
+ return this.csvToJson.csvToJsonWithConfig(String(csvString), config);
104
52
  }
105
53
 
106
54
  /**
@@ -115,15 +63,8 @@ class BrowserApi {
115
63
  * console.log(rows); // [{ name: 'Alice', age: '30' }]
116
64
  */
117
65
  csvStringToJson(csvString) {
118
- if (csvString === undefined || csvString === null) {
119
- throw new InputValidationError(
120
- 'csvString',
121
- 'string',
122
- `${typeof csvString}`,
123
- 'Provide valid CSV content as a string to parse.'
124
- );
125
- }
126
- return this.csvToJson.csvToJson(csvString);
66
+ this._validateCsvString(csvString);
67
+ return this._parseCsvText(csvString);
127
68
  }
128
69
 
129
70
  /**
@@ -138,15 +79,9 @@ class BrowserApi {
138
79
  * console.log(jsonString);
139
80
  */
140
81
  csvStringToJsonStringified(csvString) {
141
- if (csvString === undefined || csvString === null) {
142
- throw new InputValidationError(
143
- 'csvString',
144
- 'string',
145
- `${typeof csvString}`,
146
- 'Provide valid CSV content as a string to parse.'
147
- );
148
- }
149
- return this.csvToJson.csvStringToJsonStringified(csvString);
82
+ this._validateCsvString(csvString);
83
+ const rows = this._parseCsvText(csvString);
84
+ return JSON.stringify(rows, undefined, 1);
150
85
  }
151
86
 
152
87
  /**
@@ -212,9 +147,7 @@ class BrowserApi {
212
147
  ));
213
148
  reader.onload = () => {
214
149
  try {
215
- const text = reader.result;
216
- const result = this.csvToJson.csvToJson(String(text));
217
- resolve(result);
150
+ resolve(this._parseCsvText(reader.result));
218
151
  } catch (err) {
219
152
  reject(BrowserApiError.parseFileError(err));
220
153
  }
@@ -257,7 +190,8 @@ class BrowserApi {
257
190
  );
258
191
  }
259
192
 
260
- const streamProcessor = new StreamProcessor(this.csvToJson, { isBrowser: true });
193
+ const config = this.getParserConfig();
194
+ const streamProcessor = new StreamProcessor(config, { isBrowser: true });
261
195
  return streamProcessor.processStream(stream);
262
196
  }
263
197
 
@@ -302,7 +236,7 @@ class BrowserApi {
302
236
  * @param {function(Array<object>, number, number): void} options.onChunk - Callback for each chunk of processed rows
303
237
  * @param {function(Array<object>): void} [options.onComplete] - Callback when processing is complete
304
238
  * @param {function(Error): void} [options.onError] - Callback for errors
305
- * @param {number} [options.chunkSize=1000] - Number of rows per chunk
239
+ * @param {number} [options.chunkSize] - Number of rows per chunk (default: 1000)
306
240
  * @returns {Promise<void>} Promise that resolves when streaming starts
307
241
  * @throws {InputValidationError} If file or options are invalid
308
242
  * @example
@@ -343,7 +277,8 @@ class BrowserApi {
343
277
  }
344
278
 
345
279
  const chunkSize = options.chunkSize || 1000;
346
- const streamProcessor = new StreamProcessor(this.csvToJson, {
280
+ const config = this.getParserConfig();
281
+ const streamProcessor = new StreamProcessor(config, {
347
282
  isBrowser: true,
348
283
  chunkSize,
349
284
  onChunk: options.onChunk,
@@ -393,8 +328,7 @@ class BrowserApi {
393
328
 
394
329
  reader.onload = () => {
395
330
  try {
396
- const text = reader.result;
397
- const allRows = this.csvToJson.csvToJson(String(text));
331
+ const allRows = this._parseCsvText(reader.result);
398
332
 
399
333
  // Process in chunks
400
334
  let processed = 0;
@@ -0,0 +1,126 @@
1
+ 'use strict';
2
+
3
+ const { ConfigurationError } = require('./errors');
4
+ const ParserConfig = require('./parserConfig');
5
+
6
+ /**
7
+ * Shared configuration builder for CSV parser clients.
8
+ * Provides chainable methods for parser options and snapshots.
9
+ */
10
+ class Configurable {
11
+ /**
12
+ * Initialize a configurable parser instance.
13
+ * @param {object} [initialConfig] - Initial parser configuration values
14
+ */
15
+ constructor(initialConfig = {}) {
16
+ this.config = { ...initialConfig };
17
+ }
18
+
19
+ /**
20
+ * Enable or disable automatic type formatting for values.
21
+ * @param {boolean} active - Whether to format values by type
22
+ * @returns {this} For method chaining
23
+ */
24
+ formatValueByType(active = true) {
25
+ this.config.printValueFormatByType = active;
26
+ return this;
27
+ }
28
+
29
+ /**
30
+ * Enable or disable support for RFC 4180 quoted fields.
31
+ * @param {boolean} active - Whether to support quoted fields
32
+ * @returns {this} For method chaining
33
+ */
34
+ supportQuotedField(active = false) {
35
+ this.config.isSupportQuotedField = active;
36
+ return this;
37
+ }
38
+
39
+ /**
40
+ * Set the field delimiter character.
41
+ * @param {string} delimiter - Character(s) to use as field separator
42
+ * @returns {this} For method chaining
43
+ */
44
+ fieldDelimiter(delimiter) {
45
+ this.config.delimiter = delimiter;
46
+ return this;
47
+ }
48
+
49
+ /**
50
+ * Configure whitespace handling in header field names.
51
+ * @param {boolean} active - Whether to trim whitespace in header names
52
+ * @returns {this} For method chaining
53
+ */
54
+ trimHeaderFieldWhiteSpace(active = false) {
55
+ this.config.isTrimHeaderFieldWhiteSpace = active;
56
+ return this;
57
+ }
58
+
59
+ /**
60
+ * Set the row index where CSV headers are located.
61
+ * @param {number} indexHeaderValue - Zero-based row index containing headers
62
+ * @returns {this} For method chaining
63
+ */
64
+ indexHeader(indexHeaderValue) {
65
+ if (isNaN(indexHeaderValue)) {
66
+ throw ConfigurationError.invalidHeaderIndex(indexHeaderValue);
67
+ }
68
+ this.config.indexHeaderValue = indexHeaderValue;
69
+ return this;
70
+ }
71
+
72
+ /**
73
+ * Configure sub-array parsing for special field values.
74
+ * @param {string} delimiter - Bracket character
75
+ * @param {string} separator - Item separator within brackets
76
+ * @returns {this} For method chaining
77
+ */
78
+ parseSubArray(delimiter = '*', separator = ',') {
79
+ this.config.parseSubArrayDelimiter = delimiter;
80
+ this.config.parseSubArraySeparator = separator;
81
+ return this;
82
+ }
83
+
84
+ /**
85
+ * Set a mapper function for row transformation.
86
+ * @param {function(object, number): object|null} mapperFn - Function receiving (row, index)
87
+ * @returns {this} For method chaining
88
+ */
89
+ mapRows(mapperFn) {
90
+ if (typeof mapperFn !== 'function') {
91
+ throw new TypeError('mapperFn must be a function');
92
+ }
93
+ this.config.rowMapper = mapperFn;
94
+ return this;
95
+ }
96
+
97
+ /**
98
+ * Configure column indexes to exclude from output.
99
+ * @param {Array<number>} indexes - Column indexes to ignore
100
+ * @returns {this} For method chaining
101
+ */
102
+ ignoreColumnIndexes(indexes) {
103
+ this.config.indexesToIgnore = Array.isArray(indexes) ? [...indexes] : [...indexes];
104
+ return this;
105
+ }
106
+
107
+ /**
108
+ * Set the file encoding for reading CSV files.
109
+ * @param {string} encoding - Node.js supported encoding
110
+ * @returns {this} For method chaining
111
+ */
112
+ encoding(encoding) {
113
+ this.config.encoding = encoding;
114
+ return this;
115
+ }
116
+
117
+ /**
118
+ * Create an immutable parser configuration snapshot.
119
+ * @returns {ParserConfig} Frozen parser configuration
120
+ */
121
+ getParserConfig() {
122
+ return new ParserConfig(this.config);
123
+ }
124
+ }
125
+
126
+ module.exports = Configurable;