Skip to content

Commit 6b67f9c

Browse files
authored
Merge pull request #248 from mrodrig/feat/add-escapeNestedDots-option
Add escapeHeaderNestedDots option
2 parents 7fda5f2 + ea84114 commit 6b67f9c

File tree

5 files changed

+51
-2
lines changed

5 files changed

+51
-2
lines changed

README.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,27 @@ Returns the CSV `string` or rejects with an `Error` if there was an issue.
6262
* Default: `\n`
6363
* `emptyFieldValue` - Any - Value that, if specified, will be substituted in for field values that are `undefined`, `null`, or an empty string.
6464
* Default: none
65+
* `escapeHeaderNestedDots` - Boolean - Should nested dots in header keys be escaped?
66+
* Default: `true`
67+
* Example:
68+
```json
69+
[
70+
{
71+
"a.a": "1"
72+
}
73+
]
74+
```
75+
* `true` will generate the following CSV:
76+
```csv
77+
a\.a
78+
1
79+
```
80+
* `false` will generate the following CSV:
81+
```csv
82+
a.a
83+
1
84+
```
85+
* Note: This may result in CSV output that does not map back exactly to the original JSON.
6586
* `excelBOM` - Boolean - Should a unicode character be prepended to allow Excel to open a UTF-8 encoded file with non-ASCII characters present.
6687
* `excludeKeys` - Array - Specify the keys that should be excluded from the output. Provided keys will also be used as a RegExp to help exclude keys under a specified prefix, such as all keys of Objects in an Array when `expandArrayObjects` is `true`.
6788
* Default: `[]`

src/constants.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ export const defaultJson2CsvOptions: DefaultJson2CsvOptions = {
2525
eol : '\n'
2626
},
2727
emptyFieldValue: undefined,
28+
escapeHeaderNestedDots: true,
2829
excelBOM: false,
2930
excludeKeys: [],
3031
expandNestedObjects: true,

src/json2csv.ts

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ export const Json2Csv = function(options: FullJson2CsvOptions) {
1515
expandNestedObjects: options.expandNestedObjects,
1616
expandArrayObjects: expandingWithoutUnwinding,
1717
ignoreEmptyArraysWhenExpanding: expandingWithoutUnwinding,
18-
escapeNestedDots: true
18+
escapeNestedDots: true,
1919
};
2020

2121
/** HEADER FIELD FUNCTIONS **/
@@ -144,7 +144,16 @@ export const Json2Csv = function(options: FullJson2CsvOptions) {
144144

145145
params.header = params.headerFields
146146
.map(function(field) {
147-
const headerKey = fieldTitleMapKeys.includes(field) ? options.fieldTitleMap[field] : field;
147+
let headerKey = field;
148+
149+
// If a custom field title was provided for this field, use that
150+
if (fieldTitleMapKeys.includes(field)) {
151+
headerKey = options.fieldTitleMap[field];
152+
} else if (!options.escapeHeaderNestedDots) {
153+
// Otherwise, if the user doesn't want nested dots in keys to be escaped, then unescape them
154+
headerKey = headerKey.replace(/\\\./g, '.');
155+
}
156+
148157
return wrapFieldValueIfNecessary(headerKey);
149158
})
150159
.join(options.delimiter.field);

src/types.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,12 @@ export interface Json2CsvOptions extends SharedConverterOptions {
9898
*/
9999
emptyFieldValue?: unknown;
100100

101+
/**
102+
* Should dots (`.`) appearing in header keys be escaped with a preceding slash (`\`)?
103+
* @default true
104+
*/
105+
escapeHeaderNestedDots?: boolean;
106+
101107
/**
102108
* Should nested objects be deep-converted to CSV
103109
* @default true

test/json2csv.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -523,6 +523,18 @@ export function runTests() {
523523
assert.equal(csv, csvTestData.excludeKeyPattern);
524524
});
525525

526+
// Test case for #245
527+
it('should not escape nested dots in keys with nested dots in them if turned on via the option', () => {
528+
const csv = json2csv(jsonTestData.nestedDotKeys, { escapeHeaderNestedDots: true }); // Default option value
529+
assert.equal(csv, csvTestData.nestedDotKeys);
530+
});
531+
532+
// Test case for #245
533+
it('should not escape nested dots in keys with nested dots in them if turned off via the option', () => {
534+
const csv = json2csv(jsonTestData.nestedDotKeys, { escapeHeaderNestedDots: false });
535+
assert.equal(csv, csvTestData.nestedDotKeys.replace(/\\\./g, '.'));
536+
});
537+
526538
it('should use a custom value parser function when provided', () => {
527539
const updatedCsv = csvTestData.trimmedFields.split('\n');
528540
const textRow = 'Parsed Value,Parsed Value,Parsed Value,Parsed Value,Parsed Value';

0 commit comments

Comments
 (0)