Fixed #906: Implemented turning Python objects containing `True`, `False` and `None` into valid JSON using repair

This commit is contained in:
jos 2020-02-15 20:21:38 +01:00
parent 21aa049588
commit dcc66d5d81
3 changed files with 49 additions and 20 deletions

View File

@ -3,6 +3,12 @@
https://github.com/josdejong/jsoneditor
## not yet published, version 8.6.0
- Fixed #906: Implemented turning Python objects containing `True`, `False`
and `None` into valid JSON using repair.
## 2020-02-06, version 8.5.3
- Fix #892: the undo/redo buttons in mode `code` being broken when custom

View File

@ -67,6 +67,12 @@ export function repair (jsString) {
const graveAccent = '\u0060'
const acuteAccent = '\u00B4'
const pythonConstants = {
None: 'null',
True: 'true',
False: 'false'
}
// helper functions to get the current/prev/next character
function curr () { return jsString.charAt(i) }
function next () { return jsString.charAt(i + 1) }
@ -180,29 +186,29 @@ export function repair (jsString) {
}
}
function parseMongoDataType () {
function parseValue () {
let c = curr()
let value
let dataType = ''
while (/[a-zA-Z_$]/.test(c)) {
dataType += c
let value = ''
while (/\w/.test(c)) {
value += c
i++
c = curr()
}
if (dataType.length > 0 && c === '(') {
// This is an MongoDB data type like {"_id": ObjectId("123")}
if (value.length > 0 && c === '(') {
// This is an MongoDB data type like in {"_id": ObjectId("123")}
let innerValue
i++
c = curr()
if (c === '"') {
// a data type containing a string, like ISODate("2012-12-19T06:01:17.171Z")
value = parseString(c)
innerValue = parseString(c)
c = curr()
} else {
// a data type containing a value, like 'NumberLong(2)'
value = ''
innerValue = ''
while (c !== ')' && c !== '') {
value += c
innerValue += c
i++
c = curr()
}
@ -213,14 +219,17 @@ export function repair (jsString) {
i++
// return the value (strip the data type object)
return value
return innerValue
} else {
// huh? that's unexpected. don't touch it
return dataType + '(' + value + c
return value + '(' + innerValue + c
}
} else if (typeof pythonConstants[value] === 'string') {
// it's a python constant like None
return pythonConstants[value]
} else {
// hm, no Mongo data type after all
return dataType
// just leave as is
return value
}
}
@ -260,15 +269,13 @@ export function repair (jsString) {
} else if (/[a-zA-Z_$]/.test(c) && ['{', ','].indexOf(lastNonWhitespace()) !== -1) {
// an unquoted object key (like a in '{a:2}')
chars.push(parseKey())
} else {
if (/[a-zA-Z_$]/.test(c)) {
chars.push(parseMongoDataType())
} else if (/\w/.test(c)) {
chars.push(parseValue())
} else {
chars.push(c)
i++
}
}
}
return chars.join('')
}

View File

@ -135,6 +135,22 @@ describe('util', () => {
assert.strictEqual(repair(mongoDocument), expectedJson)
})
it('should replace Python constants None, True, False', () => {
const pythonDocument = '{\n' +
' "null": None,\n' +
' "true": True,\n' +
' "false": False\n' +
'}'
const expectedJson = '{\n' +
' "null": null,\n' +
' "true": true,\n' +
' "false": false\n' +
'}'
assert.strictEqual(repair(pythonDocument), expectedJson)
})
})
describe('jsonPath', () => {