const processChunksOutsideQuotedStrings = ( input , processChunk ) => { let insideString = false ; const inputChunks = input . split ( '"' ) ; const outputChunks = [ ] ; inputChunks . forEach ( ( chunk ) => { if ( insideString ) { outputChunks . push ( chunk ) ; if ( ! chunk . endsWith ( "\\" ) ) { insideString = false ; } } else { outputChunks . push ( processChunk ( chunk ) ) ; insideString = true ; } } ) ; return outputChunks . join ( '"' ) ; } ; param obj const recursivelyConvertApplicableObjectsToArrays = ( obj ) => { if ( obj === null || typeof obj !== "object" ) { return obj ; } let childrenHaveChanged = false ; const changedChildren = { } ; for ( const key in obj ) { if ( Object . prototype . hasOwnProperty . call ( obj , key ) ) { const newChild = recursivelyConvertApplicableObjectsToArrays ( obj [ key ] ) ; if ( newChild !== obj [ key ] ) { childrenHaveChanged = true ; changedChildren [ key ] = newChild ; } } } const resultingObject = childrenHaveChanged ? { ... obj , ... changedChildren } : obj ; const arrayValues = [ ] ; let nextExpectedKey = 0 ; for ( const key in resultingObject ) { if ( Object . prototype . hasOwnProperty . call ( resultingObject , key ) ) { if ( parseInt ( key , 10 ) !== nextExpectedKey ) { return resultingObject ; } nextExpectedKey += 1 ; arrayValues . push ( resultingObject [ key ] ) ; } } return arrayValues ; } ; /**
 * Parses Elm string representation into a corresponding JS value.
 *
 * It is recommended to use parseUsingCache() instead as it is using LRU cache.
 *
 * Examples:
 * * '' -> null
 * * '42' -> 42
 * * '"42"' -> "42" (string)
 * * '{a = 1, b = 2}' -> {a: 1, b: 2} (json)
 * * '{0 = "a", 1 = 42}' -> ["a", 42] (array)
 *
 * Array detection and conversion works recursively.
 */ export const parse = ( text ) : unknown => { if ( typeof text !== "string" ) { throw new Error ( `Expected text to be string, "${ typeof text }" given` ) ; } if ( ! text . length ) { return null ; } const processedText = processChunksOutsideQuotedStrings ( text , ( chunk ) => processChunksOutsideQuotedStrings ( chunk . replace ( /(,|{) (((?! = ).)*) = /g , '$1 "$2": ' ) , ( subChunk ) => { if ( subChunk === "True" ) { return "true" ; } else if ( subChunk === "False" ) { return "false" ; } return subChunk . replace ( /<function>/g , '"<function>"' ) . replace ( /([^$a-zA-Z_0-9])True([^$a-zA-Z_0-9])/g , "$1true$2" ) . replace ( /([^$a-zA-Z_0-9])False([^$a-zA-Z_0-9])/g , "$1false$2" ) . replace ( /(,|{) = /g , '$1 "": ' ) . replace ( /\(/g , "[" ) . replace ( /\)/g , "]" ) ; } ) ) ; try { return recursivelyConvertApplicableObjectsToArrays ( JSON . parse ( processedText ) ) ; } catch ( e ) { throw new Error ( `Could not parse "${ text . length <= 20 ? text : `${ text . substring ( 0 , 15 ) }...` }"` ) ; } } ;