convert-csv-to-json 3.12.1 → 3.13.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 +46 -26
- package/package.json +1 -1
- package/src/util/stringUtils.js +90 -21
package/README.md
CHANGED
|
@@ -221,13 +221,49 @@ If the header is not on the first line you can define the header index like:
|
|
|
221
221
|
Empty rows are ignored and not parsed.
|
|
222
222
|
|
|
223
223
|
#### Format property value by type
|
|
224
|
-
|
|
224
|
+
The `formatValueByType()` function intelligently converts string values to their appropriate types while preserving data integrity. To enable automatic type conversion:
|
|
225
|
+
|
|
225
226
|
```js
|
|
226
|
-
|
|
227
|
-
|
|
227
|
+
csvToJson.formatValueByType()
|
|
228
|
+
.getJsonFromCsv(fileInputName);
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
This conversion follows these rules:
|
|
232
|
+
|
|
233
|
+
##### Numbers
|
|
234
|
+
- Regular integers and decimals are converted to Number type
|
|
235
|
+
- Numbers with leading zeros are preserved as strings (e.g., "0012" stays "0012")
|
|
236
|
+
- Large integers outside JavaScript's safe range are preserved as strings
|
|
237
|
+
- Valid decimal numbers are converted to Number type
|
|
238
|
+
|
|
239
|
+
For example:
|
|
240
|
+
```json
|
|
241
|
+
{
|
|
242
|
+
"normalInteger": 42, // Converted to number
|
|
243
|
+
"decimal": 3.14, // Converted to number
|
|
244
|
+
"leadingZeros": "0012345", // Kept as string to preserve leading zeros
|
|
245
|
+
"largeNumber": "9007199254740992" // Kept as string to preserve precision
|
|
246
|
+
}
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
##### Boolean
|
|
250
|
+
Case-insensitive "true" or "false" strings are converted to boolean values:
|
|
251
|
+
```json
|
|
252
|
+
{
|
|
253
|
+
"registered": true, // From "true" or "TRUE" or "True"
|
|
254
|
+
"active": false // From "false" or "FALSE" or "False"
|
|
255
|
+
}
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
##### Complete Example
|
|
259
|
+
Input CSV:
|
|
260
|
+
```csv
|
|
261
|
+
first_name;last_name;email;gender;age;id;zip;registered
|
|
262
|
+
Constantin;Langsdon;clangsdon0@hc360.com;Male;96;00123;123;true
|
|
263
|
+
Norah;Raison;nraison1@wired.com;Female;32;987;00456;FALSE
|
|
228
264
|
```
|
|
229
|
-
For example:
|
|
230
265
|
|
|
266
|
+
Output JSON:
|
|
231
267
|
```json
|
|
232
268
|
[
|
|
233
269
|
{
|
|
@@ -236,8 +272,9 @@ For example:
|
|
|
236
272
|
"email": "clangsdon0@hc360.com",
|
|
237
273
|
"gender": "Male",
|
|
238
274
|
"age": 96,
|
|
239
|
-
"
|
|
240
|
-
"
|
|
275
|
+
"id": "00123", // Preserved leading zeros
|
|
276
|
+
"zip": 123, // Converted to number
|
|
277
|
+
"registered": true // Converted to boolean
|
|
241
278
|
},
|
|
242
279
|
{
|
|
243
280
|
"first_name": "Norah",
|
|
@@ -245,29 +282,12 @@ For example:
|
|
|
245
282
|
"email": "nraison1@wired.com",
|
|
246
283
|
"gender": "Female",
|
|
247
284
|
"age": 32,
|
|
248
|
-
"
|
|
249
|
-
"
|
|
285
|
+
"id": "987",
|
|
286
|
+
"zip": "00456", // Preserved leading zeros
|
|
287
|
+
"registered": false // Case-insensitive boolean conversion
|
|
250
288
|
}
|
|
251
289
|
]
|
|
252
290
|
```
|
|
253
|
-
##### Number
|
|
254
|
-
The property **age** is printed as
|
|
255
|
-
```json
|
|
256
|
-
"age": 32
|
|
257
|
-
```
|
|
258
|
-
instead of
|
|
259
|
-
```json
|
|
260
|
-
"age": "32"
|
|
261
|
-
```
|
|
262
|
-
##### Boolean
|
|
263
|
-
The property **registered** is printed as
|
|
264
|
-
```json
|
|
265
|
-
"registered": true
|
|
266
|
-
```
|
|
267
|
-
instead of
|
|
268
|
-
```json
|
|
269
|
-
"registered": "true"
|
|
270
|
-
```
|
|
271
291
|
|
|
272
292
|
#### Encoding
|
|
273
293
|
You can read and decode files with the following encoding:
|
package/package.json
CHANGED
package/src/util/stringUtils.js
CHANGED
|
@@ -1,40 +1,109 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
class StringUtils {
|
|
4
|
+
// Regular expressions as constants for better maintainability
|
|
5
|
+
static PATTERNS = {
|
|
6
|
+
INTEGER: /^-?\d+$/,
|
|
7
|
+
FLOAT: /^-?\d*\.\d+$/,
|
|
8
|
+
WHITESPACE: /\s/g
|
|
9
|
+
};
|
|
4
10
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
11
|
+
static BOOLEAN_VALUES = {
|
|
12
|
+
TRUE: 'true',
|
|
13
|
+
FALSE: 'false'
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Removes whitespace from property names based on configuration
|
|
18
|
+
* @param {boolean} shouldTrimAll - If true, removes all whitespace, otherwise only trims edges
|
|
19
|
+
* @param {string} propertyName - The property name to process
|
|
20
|
+
* @returns {string} The processed property name
|
|
21
|
+
*/
|
|
22
|
+
trimPropertyName(shouldTrimAll, propertyName) {
|
|
23
|
+
if (!propertyName) {
|
|
24
|
+
return '';
|
|
8
25
|
}
|
|
9
|
-
return
|
|
10
|
-
|
|
26
|
+
return shouldTrimAll ?
|
|
27
|
+
propertyName.replace(StringUtils.PATTERNS.WHITESPACE, '') :
|
|
28
|
+
propertyName.trim();
|
|
11
29
|
}
|
|
12
30
|
|
|
31
|
+
/**
|
|
32
|
+
* Converts a string value to its appropriate type while preserving data integrity
|
|
33
|
+
* @param {string} value - The input value to convert
|
|
34
|
+
* @returns {string|number|boolean} The converted value
|
|
35
|
+
*/
|
|
13
36
|
getValueFormatByType(value) {
|
|
14
|
-
if(value
|
|
37
|
+
if (this.isEmpty(value)) {
|
|
15
38
|
return String();
|
|
16
39
|
}
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
40
|
+
|
|
41
|
+
if (this.isBoolean(value)) {
|
|
42
|
+
return this.convertToBoolean(value);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
if (this.isInteger(value)) {
|
|
46
|
+
return this.convertInteger(value);
|
|
21
47
|
}
|
|
22
|
-
|
|
23
|
-
if(value
|
|
24
|
-
return
|
|
48
|
+
|
|
49
|
+
if (this.isFloat(value)) {
|
|
50
|
+
return this.convertFloat(value);
|
|
25
51
|
}
|
|
52
|
+
|
|
26
53
|
return String(value);
|
|
27
54
|
}
|
|
28
55
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
56
|
+
/**
|
|
57
|
+
* Checks if a value array contains any non-empty values
|
|
58
|
+
* @param {Array} values - Array to check for content
|
|
59
|
+
* @returns {boolean} True if array has any non-empty values
|
|
60
|
+
*/
|
|
61
|
+
hasContent(values = []) {
|
|
62
|
+
return Array.isArray(values) &&
|
|
63
|
+
values.some(value => Boolean(value));
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// Private helper methods for type checking and conversion
|
|
67
|
+
isEmpty(value) {
|
|
68
|
+
return value === undefined || value === '';
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
isBoolean(value) {
|
|
72
|
+
const normalizedValue = value.toLowerCase();
|
|
73
|
+
return normalizedValue === StringUtils.BOOLEAN_VALUES.TRUE ||
|
|
74
|
+
normalizedValue === StringUtils.BOOLEAN_VALUES.FALSE;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
isInteger(value) {
|
|
78
|
+
return StringUtils.PATTERNS.INTEGER.test(value);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
isFloat(value) {
|
|
82
|
+
return StringUtils.PATTERNS.FLOAT.test(value);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
hasLeadingZero(value) {
|
|
86
|
+
const isPositiveWithLeadingZero = value.length > 1 && value[0] === '0';
|
|
87
|
+
const isNegativeWithLeadingZero = value.length > 2 && value[0] === '-' && value[1] === '0';
|
|
88
|
+
return isPositiveWithLeadingZero || isNegativeWithLeadingZero;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
convertToBoolean(value) {
|
|
92
|
+
return JSON.parse(value.toLowerCase());
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
convertInteger(value) {
|
|
96
|
+
if (this.hasLeadingZero(value)) {
|
|
97
|
+
return String(value);
|
|
36
98
|
}
|
|
37
|
-
|
|
99
|
+
|
|
100
|
+
const num = Number(value);
|
|
101
|
+
return Number.isSafeInteger(num) ? num : String(value);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
convertFloat(value) {
|
|
105
|
+
const num = Number(value);
|
|
106
|
+
return Number.isFinite(num) ? num : String(value);
|
|
38
107
|
}
|
|
39
108
|
}
|
|
40
109
|
|