convert-csv-to-json 1.5.0 → 2.0.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/.github/workflows/nodejs.yml +1 -1
- package/.idea/codeStyles/codeStyleConfig.xml +5 -0
- package/.idea/csv-plugin.xml +51 -0
- package/README.md +25 -0
- package/index.js +7 -0
- package/package.json +2 -2
- package/src/csvToJson.js +87 -5
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<project version="4">
|
|
3
|
+
<component name="CsvFileAttributes">
|
|
4
|
+
<option name="attributeMap">
|
|
5
|
+
<map>
|
|
6
|
+
<entry key="/test/resource/input.csv">
|
|
7
|
+
<value>
|
|
8
|
+
<Attribute>
|
|
9
|
+
<option name="separator" value=";" />
|
|
10
|
+
</Attribute>
|
|
11
|
+
</value>
|
|
12
|
+
</entry>
|
|
13
|
+
<entry key="/test/resource/input_example.csv">
|
|
14
|
+
<value>
|
|
15
|
+
<Attribute>
|
|
16
|
+
<option name="separator" value=";" />
|
|
17
|
+
</Attribute>
|
|
18
|
+
</value>
|
|
19
|
+
</entry>
|
|
20
|
+
<entry key="/test/resource/input_example_sub_array.csv">
|
|
21
|
+
<value>
|
|
22
|
+
<Attribute>
|
|
23
|
+
<option name="separator" value=";" />
|
|
24
|
+
</Attribute>
|
|
25
|
+
</value>
|
|
26
|
+
</entry>
|
|
27
|
+
<entry key="/test/resource/input_quoted_fields.csv">
|
|
28
|
+
<value>
|
|
29
|
+
<Attribute>
|
|
30
|
+
<option name="separator" value="," />
|
|
31
|
+
</Attribute>
|
|
32
|
+
</value>
|
|
33
|
+
</entry>
|
|
34
|
+
<entry key="/test/resource/input_quoted_fields_with_subarray.csv">
|
|
35
|
+
<value>
|
|
36
|
+
<Attribute>
|
|
37
|
+
<option name="separator" value="," />
|
|
38
|
+
</Attribute>
|
|
39
|
+
</value>
|
|
40
|
+
</entry>
|
|
41
|
+
<entry key="/test/resource/input_tilde_delimiter.csv">
|
|
42
|
+
<value>
|
|
43
|
+
<Attribute>
|
|
44
|
+
<option name="separator" value="," />
|
|
45
|
+
</Attribute>
|
|
46
|
+
</value>
|
|
47
|
+
</entry>
|
|
48
|
+
</map>
|
|
49
|
+
</option>
|
|
50
|
+
</component>
|
|
51
|
+
</project>
|
package/README.md
CHANGED
|
@@ -23,6 +23,7 @@
|
|
|
23
23
|
+ [Generate Array of Object in JSON format](#generate-array-of-object-in-json-format)
|
|
24
24
|
+ [Generate Object with sub array](#generate-object-with-sub-array)
|
|
25
25
|
+ [Define field delimiter](#define-field-delimiter)
|
|
26
|
+
+ [Support Quoted Fields](#support-quoted-fields)
|
|
26
27
|
+ [Index header](#index-header)
|
|
27
28
|
+ [Empty rows](#empty-rows)
|
|
28
29
|
+ [Format property value by type](#format-property-value-by-type)
|
|
@@ -150,6 +151,30 @@ E.g. if your field delimiter is the comma **,** then:
|
|
|
150
151
|
csvToJson.fieldDelimiter(',').getJsonFromCsv(fileInputName);
|
|
151
152
|
```
|
|
152
153
|
|
|
154
|
+
#### Support Quoted Fields
|
|
155
|
+
To be able to parse correctly fields wrapped in quote, like the **last_name** in the first row in the following example:
|
|
156
|
+
|
|
157
|
+
|first_name| last_name |email|
|
|
158
|
+
|:----------:|:--------------------------:|:---:|
|
|
159
|
+
|Constantin| "Langsdon,Nandson,Gangson" |clangsdon0@hc360.com|
|
|
160
|
+
|
|
161
|
+
you need to activate the support quoted fields feature:
|
|
162
|
+
|
|
163
|
+
```js
|
|
164
|
+
csvToJson.supportQuotedField(true).getJsonFromCsv(fileInputName);
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
The result will be:
|
|
168
|
+
```json
|
|
169
|
+
[
|
|
170
|
+
{
|
|
171
|
+
"firstName": "Constantin",
|
|
172
|
+
"lastName": "Langsdon,Nandson,Gangson",
|
|
173
|
+
"email": "clangsdon0@hc360.com"
|
|
174
|
+
}
|
|
175
|
+
]
|
|
176
|
+
```
|
|
177
|
+
|
|
153
178
|
#### Index header
|
|
154
179
|
If the header is not on the first line you can define the header index like:
|
|
155
180
|
|
package/index.js
CHANGED
|
@@ -20,6 +20,13 @@ exports.formatValueByType = function (active = true) {
|
|
|
20
20
|
return this;
|
|
21
21
|
};
|
|
22
22
|
|
|
23
|
+
/**
|
|
24
|
+
*
|
|
25
|
+
*/
|
|
26
|
+
exports.supportQuotedField = function (active = false) {
|
|
27
|
+
csvToJson.supportQuotedField(active);
|
|
28
|
+
return this;
|
|
29
|
+
};
|
|
23
30
|
/**
|
|
24
31
|
* Defines the field delimiter which will be used to split the fields
|
|
25
32
|
*/
|
package/package.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "convert-csv-to-json",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"description": "Convert CSV to JSON",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
7
|
-
"test": "./node_modules/.bin/mocha --reporter spec",
|
|
7
|
+
"test": "./node_modules/.bin/mocha --parallel --reporter spec",
|
|
8
8
|
"test-watch": "./node_modules/.bin/mocha -w"
|
|
9
9
|
},
|
|
10
10
|
"repository": {
|
package/src/csvToJson.js
CHANGED
|
@@ -14,6 +14,11 @@ class CsvToJson {
|
|
|
14
14
|
return this;
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
+
supportQuotedField(active) {
|
|
18
|
+
this.isSupportQuotedField = active;
|
|
19
|
+
return this;
|
|
20
|
+
}
|
|
21
|
+
|
|
17
22
|
fieldDelimiter(delimiter) {
|
|
18
23
|
this.delimiter = delimiter;
|
|
19
24
|
return this;
|
|
@@ -60,6 +65,7 @@ class CsvToJson {
|
|
|
60
65
|
}
|
|
61
66
|
|
|
62
67
|
csvToJson(parsedCsv) {
|
|
68
|
+
this.validateInputConfig();
|
|
63
69
|
let lines = parsedCsv.split(newLine);
|
|
64
70
|
let fieldDelimiter = this.getFieldDelimiter();
|
|
65
71
|
let index = this.getIndexHeader();
|
|
@@ -72,11 +78,17 @@ class CsvToJson {
|
|
|
72
78
|
|
|
73
79
|
let jsonResult = [];
|
|
74
80
|
for (let i = (index + 1); i < lines.length; i++) {
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
81
|
+
let currentLine;
|
|
82
|
+
if(this.isSupportQuotedField){
|
|
83
|
+
currentLine = this.split(lines[i]);
|
|
84
|
+
}
|
|
85
|
+
else{
|
|
86
|
+
currentLine = lines[i].split(fieldDelimiter);
|
|
87
|
+
}
|
|
88
|
+
if (stringUtils.hasContent(currentLine)) {
|
|
89
|
+
jsonResult.push(this.buildJsonResult(headers, currentLine));
|
|
90
|
+
}
|
|
91
|
+
}
|
|
80
92
|
return jsonResult;
|
|
81
93
|
}
|
|
82
94
|
|
|
@@ -137,6 +149,76 @@ class CsvToJson {
|
|
|
137
149
|
return false;
|
|
138
150
|
}
|
|
139
151
|
|
|
152
|
+
validateInputConfig(){
|
|
153
|
+
if(this.isSupportQuotedField) {
|
|
154
|
+
if(this.getFieldDelimiter() === '"'){
|
|
155
|
+
throw new Error('When SupportQuotedFields is enabled you cannot defined the field delimiter as quote -> ["]');
|
|
156
|
+
}
|
|
157
|
+
if(this.parseSubArraySeparator === '"'){
|
|
158
|
+
throw new Error('When SupportQuotedFields is enabled you cannot defined the field parseSubArraySeparator as quote -> ["]');
|
|
159
|
+
}
|
|
160
|
+
if(this.parseSubArrayDelimiter === '"'){
|
|
161
|
+
throw new Error('When SupportQuotedFields is enabled you cannot defined the field parseSubArrayDelimiter as quote -> ["]');
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
hasQuotes(line) {
|
|
167
|
+
return line.includes('"');
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
split(line) {
|
|
171
|
+
if(line.length == 0){
|
|
172
|
+
return [];
|
|
173
|
+
}
|
|
174
|
+
let delim = this.getFieldDelimiter();
|
|
175
|
+
let subSplits = [''];
|
|
176
|
+
if (this.hasQuotes(line)) {
|
|
177
|
+
let chars = line.split('');
|
|
178
|
+
|
|
179
|
+
let subIndex = 0;
|
|
180
|
+
let startQuote = false;
|
|
181
|
+
let isDouble = false;
|
|
182
|
+
chars.forEach((c, i, arr) => {
|
|
183
|
+
if (isDouble) { //when run into double just pop it into current and move on
|
|
184
|
+
subSplits[subIndex] += c;
|
|
185
|
+
isDouble = false;
|
|
186
|
+
return;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
if (c != '"' && c != delim ) {
|
|
190
|
+
subSplits[subIndex] += c;
|
|
191
|
+
} else if(c == delim && startQuote){
|
|
192
|
+
subSplits[subIndex] += c;
|
|
193
|
+
} else if( c == delim ){
|
|
194
|
+
subIndex++
|
|
195
|
+
subSplits[subIndex] = '';
|
|
196
|
+
return;
|
|
197
|
+
} else {
|
|
198
|
+
if (arr[i + 1] === '"') {
|
|
199
|
+
//Double quote
|
|
200
|
+
isDouble = true;
|
|
201
|
+
//subSplits[subIndex] += c; //Skip because this is escaped quote
|
|
202
|
+
} else {
|
|
203
|
+
if (!startQuote) {
|
|
204
|
+
startQuote = true;
|
|
205
|
+
//subSplits[subIndex] += c; //Skip because we don't want quotes wrapping value
|
|
206
|
+
} else {
|
|
207
|
+
//end
|
|
208
|
+
startQuote = false;
|
|
209
|
+
//subSplits[subIndex] += c; //Skip because we don't want quotes wrapping value
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
});
|
|
214
|
+
if(startQuote){
|
|
215
|
+
throw new Error('Row contains mismatched quotes!');
|
|
216
|
+
}
|
|
217
|
+
return subSplits;
|
|
218
|
+
} else {
|
|
219
|
+
return line.split(delim);
|
|
220
|
+
}
|
|
221
|
+
}
|
|
140
222
|
}
|
|
141
223
|
|
|
142
224
|
module.exports = new CsvToJson();
|