Skip to content

Commit

Permalink
fix: escape keys
Browse files Browse the repository at this point in the history
Fixes #96
  • Loading branch information
kenany committed Aug 31, 2021
1 parent 4d37327 commit faddd7e
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 2 deletions.
45 changes: 43 additions & 2 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,29 +5,65 @@ var isPlainObject = require('lodash.isplainobject');
var keys = require('lodash.keys');
var strftime = require('strftime');

/**
* @param {unknown} obj
* @returns {string}
*/
function format(obj) {
return isDate(obj)
? strftime('%FT%TZ', obj)
: JSON.stringify(obj);
}

/**
* @param {readonly unknown[][]} simplePairs
* @returns {boolean}
*/
function isArrayOfTables(simplePairs) {
return simplePairs.some(function(array) {
var value = array[1];
return Array.isArray(value) && isPlainObject(value[0]);
});
}

/**
* @param {readonly unknown[]} obj
* @returns {boolean}
*/
function isObjectArrayOfTables(obj) {
return Array.isArray(obj) && obj.length === 2 && isPlainObject(obj[1][0]);
}

/**
* @param {readonly unknown[][]} simplePairs
* @returns {boolean}
*/
function isLastObjectArrayOfTables(simplePairs) {
var array = simplePairs[simplePairs.length - 1];
return isObjectArrayOfTables(array);
}

/**
* @param {string} key
* @returns {string}
*/
function escapeKey(key) {
return /^[a-zA-Z0-9-_]*$/.test(key)
? key
: `"${key}"`;
}

/**
* @param {object} hash
* @param {object} options
* @returns {string}
*/
module.exports = function(hash, options = {}) {
/**
* @param {object} hash
* @param {string} prefix
* @returns {void}
*/
function visit(hash, prefix) {
var nestedPairs = [];
var simplePairs = [];
Expand Down Expand Up @@ -67,7 +103,7 @@ module.exports = function(hash, options = {}) {
});
}
else {
toml += indentStr + key + ' = ' + format(value) + '\n';
toml += indentStr + escapeKey(key) + ' = ' + format(value) + '\n';
}
});

Expand All @@ -80,7 +116,12 @@ module.exports = function(hash, options = {}) {
var key = array[0];
var value = array[1];

visit(value, isEmpty(prefix) ? key.toString() : [prefix, key].join('.'));
visit(
value,
isEmpty(prefix)
? escapeKey(key.toString())
: `${prefix}.${escapeKey(key.toString())}`
);
});
}

Expand Down
44 changes: 44 additions & 0 deletions test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -99,3 +99,47 @@ test('pretty', function(t) {
toml
);
});

test('key > escapes', (t) => {
t.plan(6);

t.equal(
json2toml({ '\n': 'newline' }),
'"\n" = "newline"\n'
);
t.equal(
json2toml({ '"': 'just a quote' }),
'""" = "just a quote"\n'
);
t.equal(
json2toml({ '"quoted"': { quote: true } }),
`[""quoted""]
quote = true
`
);
t.equal(
json2toml({ 'a.b': { À: { c: 'c' } } }),
`["a.b"."\u00c0"]
c = "c"
`
);
t.equal(
json2toml({ 'backsp\u0008\u0008': { c: 'c' } }),
`["backsp\b\b"]
c = "c"
`
);
t.equal(
json2toml({ À: 'latin capital letter A with grave' }),
'"À" = "latin capital letter A with grave"\n'
);
});

test('key > space', (t) => {
t.plan(1);

t.equal(
json2toml({ 'a b': 1 }),
'"a b" = 1\n'
);
});

0 comments on commit faddd7e

Please sign in to comment.