@@ -13,33 +13,36 @@ var options = {}; // Initialize the options - this will be populated when the js
13
13
* @returns {Promise }
14
14
*/
15
15
var generateHeading = function ( data ) {
16
- return new Promise ( function ( resolve , reject ) {
17
- if ( options . KEYS ) { return resolve ( options . KEYS ) ; }
18
-
19
- var keys = _ . map ( _ . keys ( data ) , function ( key , indx ) { // for each key
20
- if ( _ . isObject ( data [ key ] ) ) {
21
- // if the data at the key is a document, then we retrieve the subHeading starting with an empty string heading and the doc
22
- return generateSubHeading ( '' , data [ key ] ) ;
23
- }
24
- return key ;
25
- } ) ;
26
-
27
- // Check for a consistent schema that does not require the same order:
28
- // if we only have one document - then there is no possiblility of multiple schemas
29
- if ( keys && keys . length <= 1 ) {
30
- return resolve ( _ . flatten ( keys ) || [ ] ) ;
16
+ if ( options . KEYS ) { return Promise . resolve ( options . KEYS ) ; }
17
+
18
+ var keys = _ . map ( data , function ( document , indx ) { // for each key
19
+ if ( _ . isObject ( document ) ) {
20
+ // if the data at the key is a document, then we retrieve the subHeading starting with an empty string heading and the doc
21
+ return generateDocumentHeading ( '' , document ) ;
22
+ }
23
+ } ) ;
24
+
25
+ // Check for a consistent schema that does not require the same order:
26
+ // if we only have one document - then there is no possibility of multiple schemas
27
+ if ( keys && keys . length <= 1 ) {
28
+ return Promise . resolve ( _ . flatten ( keys ) || [ ] ) ;
29
+ }
30
+ // else - multiple documents - ensure only one schema (regardless of field ordering)
31
+ var firstDocSchema = _ . flatten ( keys [ 0 ] ) ,
32
+ schemaDifferences = 0 ;
33
+
34
+ _ . each ( keys , function ( keyList ) {
35
+ // If there is a difference between the schemas, increment the counter of schema inconsistencies
36
+ var diff = _ . difference ( firstDocSchema , _ . flatten ( keyList ) ) ;
37
+ if ( ! _ . isEqual ( diff , [ ] ) ) {
38
+ schemaDifferences ++ ;
31
39
}
32
- // else - multiple documents - ensure only one schema (regardless of field ordering)
33
- var firstDocSchema = _ . flatten ( keys [ 0 ] ) ;
34
- _ . each ( keys , function ( keyList ) {
35
- // If there is a difference between the schemas, throw the inconsistent schema error
36
- var diff = _ . difference ( firstDocSchema , _ . flatten ( keyList ) ) ;
37
- if ( ! _ . isEqual ( diff , [ ] ) ) {
38
- return reject ( new Error ( constants . Errors . json2csv . notSameSchema ) ) ;
39
- }
40
- } ) ;
41
- return resolve ( _ . flatten ( keys [ 0 ] ) ) ;
42
40
} ) ;
41
+
42
+ // If there are schema inconsistencies, throw a schema not the same error
43
+ if ( schemaDifferences ) { return Promise . reject ( new Error ( constants . Errors . json2csv . notSameSchema ) ) ; }
44
+
45
+ return Promise . resolve ( _ . flatten ( keys [ 0 ] ) ) ;
43
46
} ;
44
47
45
48
/**
@@ -48,21 +51,22 @@ var generateHeading = function(data) {
48
51
* @param data
49
52
* @returns {Array }
50
53
*/
51
- var generateSubHeading = function ( heading , data ) {
52
- var subKeys , // retrieve the keys from the current document
53
- newKey = '' ; // temporary variable to aid in determining the heading - used to generate the 'nested' headings
54
+ var generateDocumentHeading = function ( heading , data ) {
55
+ var keyName = '' ; // temporary variable to aid in determining the heading - used to generate the 'nested' headings
54
56
55
- subKeys = _ . map ( _ . keys ( data ) , function ( subKey ) {
57
+ var documentKeys = _ . map ( _ . keys ( data ) , function ( currentKey ) {
56
58
// If the given heading is empty, then we set the heading to be the subKey, otherwise set it as a nested heading w/ a dot
57
- newKey = heading === '' ? subKey : heading + '.' + subKey ;
58
- if ( _ . isObject ( data [ subKey ] ) && ! _ . isNull ( data [ subKey ] ) && _ . isUndefined ( data [ subKey ] . length ) && _ . keys ( data [ subKey ] ) . length > 0 ) { // If we have another nested document
59
- return generateSubHeading ( newKey , data [ subKey ] ) ; // Recur on the sub-document to retrieve the full key name
60
- } else {
61
- return newKey ; // Set the key name since we don't have a sub document
59
+ keyName = heading ? heading + '.' + currentKey : currentKey ;
60
+
61
+ // If we have another nested document, recur on the sub-document to retrieve the full key name
62
+ if ( _ . isObject ( data [ currentKey ] ) && ! _ . isNull ( data [ currentKey ] ) && _ . isUndefined ( data [ currentKey ] . length ) && _ . keys ( data [ currentKey ] ) . length ) {
63
+ return generateDocumentHeading ( keyName , data [ currentKey ] ) ;
62
64
}
65
+ // Otherwise return this key name since we don't have a sub document
66
+ return keyName ;
63
67
} ) ;
64
68
65
- return subKeys ; // Return the headings joined by our field delimiter
69
+ return documentKeys ; // Return the headings joined by our field delimiter
66
70
} ;
67
71
68
72
/**
@@ -83,7 +87,7 @@ var convertData = function (data, keys) {
83
87
output . push ( convertData ( data [ pathPrefix ] , [ pathRemainder ] ) ) ;
84
88
} else if ( keys . indexOf ( key ) > - 1 ) { // If the keys contain the current key, then process the data
85
89
value = data [ key ] ; // Set the current data that we are looking at
86
- convertField ( value , output ) ;
90
+ output . push ( convertField ( value , output ) ) ;
87
91
}
88
92
} ) ;
89
93
return output ; // Return the data joined by our field delimiter
@@ -94,17 +98,15 @@ var convertData = function (data, keys) {
94
98
* @param value
95
99
* @param output
96
100
*/
97
- var convertField = function ( value , output ) {
101
+ var convertField = function ( value ) {
98
102
if ( _ . isArray ( value ) ) { // We have an array of values
99
- output . push ( options . DELIMITER . WRAP + '[' + value . join ( options . DELIMITER . ARRAY ) + ']' + options . DELIMITER . WRAP ) ;
103
+ return options . DELIMITER . WRAP + '[' + value . join ( options . DELIMITER . ARRAY ) + ']' + options . DELIMITER . WRAP ;
100
104
} else if ( _ . isDate ( value ) ) { // If we have a date
101
- output . push ( value . toString ( ) ) ;
105
+ return options . DELIMITER . WRAP + value . toString ( ) + options . DELIMITER . WRAP ;
102
106
} else if ( _ . isObject ( value ) ) { // If we have an object
103
- output . push ( convertData ( value , _ . keys ( value ) ) ) ; // Push the recursively generated CSV
104
- } else {
105
- value = value ? value . toString ( ) : '' ;
106
- output . push ( options . DELIMITER . WRAP + value + options . DELIMITER . WRAP ) ; // Otherwise push the current value
107
+ return options . DELIMITER . WRAP + convertData ( value , _ . keys ( value ) ) + options . DELIMITER . WRAP ; // Push the recursively generated CSV
107
108
}
109
+ return options . DELIMITER . WRAP + ( value ? value . toString ( ) : '' ) + options . DELIMITER . WRAP ; // Otherwise push the current value
108
110
} ;
109
111
110
112
/**
0 commit comments