Created
January 6, 2022 21:35
-
-
Save chjlsch/dd0718b002976d0cac3b56d252c67b7a to your computer and use it in GitHub Desktop.
recursively encode and decode querystrings (encode = object to querystring, decode = querystring to object)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export function decode(querystring: string): object { | |
function parseValue(value: string): any { | |
if (value === 'TRUE') return true; | |
if (value === 'FALSE') return false; | |
return isNaN(Number(value)) ? value : Number(value); | |
} | |
function dec(list: any[], isArray = false): object { | |
let obj: any = isArray ? [] : {}; | |
let recs: any[] = list.filter((item) => { | |
if (item.keys.length > 1) return true; | |
obj[item.keys[0]] = parseValue(item.value); | |
}); | |
let attrs = {}; | |
recs.map((item) => { | |
item.key = item.keys.shift(); | |
attrs[item.key] = []; | |
return item; | |
}).forEach((item) => attrs[item.key].push(item)); | |
Object.keys(attrs).forEach((attr) => { | |
let nextKey = attrs[attr][0].keys[0]; | |
obj[attr] = dec(attrs[attr], typeof nextKey === 'number'); | |
}); | |
return obj; | |
} | |
return dec( | |
querystring | |
.split('&') | |
.map((item) => item.split('=').map((x) => decodeURIComponent(x))) | |
.map((item) => { | |
return { | |
keys: item[0] | |
.split(/[\[\]]/g) | |
.filter((n) => n) | |
.map((key) => (isNaN(Number(key)) ? key : Number(key))), | |
value: item[1], | |
}; | |
}) | |
); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export function encode(object: object): string { | |
function reducer(obj, parentPrefix = null) { | |
return function (prev, key) { | |
const val = obj[key]; | |
key = encodeURIComponent(key); | |
const prefix = parentPrefix ? `${parentPrefix}[${key}]` : key; | |
if (val == null || typeof val === 'function') { | |
prev.push(`${prefix}=`); | |
return prev; | |
} | |
if (typeof val === 'boolean') { | |
prev.push(`${prefix}=${val.toString().toUpperCase()}`); | |
return prev; | |
} | |
if (['number', 'string'].includes(typeof val)) { | |
prev.push(`${prefix}=${encodeURIComponent(val)}`); | |
return prev; | |
} | |
prev.push( | |
Object.keys(val).reduce(reducer(val, prefix), []).join('&') | |
); | |
return prev; | |
}; | |
} | |
return Object.keys(object).reduce(reducer(object), []).join('&'); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thanks @darkylmnx for your encode function.