const nonAtomsTuples = ['replace', ':replace'] const nonAtomsObjects = ['match_actor', ':match_actor'] const objects = ['digest', 'pleroma_fe', 'masto_fe', 'poll_limits', 'styling'] const objectParents = ['mascots'] // REFACTOR export const parseTuples = (tuples, key) => { return tuples.reduce((accum, item) => { if (key === 'rate_limit') { accum[item.tuple[0]] = item.tuple[1] } else if (item.tuple[0] === ':mascots') { accum[item.tuple[0]] = item.tuple[1].reduce((acc, mascot) => { return [...acc, { [mascot.tuple[0]]: { ...mascot.tuple[1], id: `f${(~~(Math.random() * 1e8)).toString(16)}` }}] }, []) } else if (item.tuple[0] === ':groups') { accum[item.tuple[0]] = item.tuple[1].reduce((acc, group) => { return [...acc, { [group.tuple[0]]: { value: group.tuple[1], id: `f${(~~(Math.random() * 1e8)).toString(16)}` }}] }, []) } else if (item.tuple[0] === ':icons') { accum[item.tuple[0]] = item.tuple[1].map(icon => { return Object.keys(icon).map(name => { return { key: name, value: icon[name], id: `f${(~~(Math.random() * 1e8)).toString(16)}` } }) }, []) } else if (item.tuple[0] === ':proxy_url') { accum[item.tuple[0]] = parseProxyUrl(item.tuple[1]) } else if ((item.tuple[0] === ':sslopts' && item.tuple[1].length === 0) || // should be removed (item.tuple[0] === ':tlsopts' && item.tuple[1].length === 0)) { accum[item.tuple[0]] = {} } else if (Array.isArray(item.tuple[1]) && (typeof item.tuple[1][0] === 'object' && !Array.isArray(item.tuple[1][0])) && item.tuple[1][0]['tuple']) { accum[item.tuple[0]] = parseTuples(item.tuple[1], item.tuple[0]) } else if (Array.isArray(item.tuple[1])) { nonAtomsTuples.includes(item.tuple[0]) ? accum[item.tuple[0]] = parseNonAtomTuples(item.tuple[1]) : accum[item.tuple[0]] = item.tuple[1] } else if (item.tuple[0] === ':ip') { accum[item.tuple[0]] = item.tuple[1].tuple.join('.') } else if (item.tuple[1] && typeof item.tuple[1] === 'object' && 'tuple' in item.tuple[1]) { accum[item.tuple[0]] = { [item.tuple[1].tuple[0]]: item.tuple[1].tuple[1] } } else if (item.tuple[1] && typeof item.tuple[1] === 'object') { nonAtomsObjects.includes(item.tuple[0]) ? accum[item.tuple[0]] = parseNonAtomObject(item.tuple[1]) : accum[item.tuple[0]] = parseObject(item.tuple[1]) } else { accum[item.tuple[0]] = item.tuple[1] } return accum }, {}) } const parseNonAtomTuples = (tuples) => { return tuples.reduce((acc, item) => { acc[item.tuple[0]] = item.tuple[1] return acc }, {}) } const parseNonAtomObject = (object) => { return Object.keys(object).reduce((acc, item) => { acc[item] = object[item] return acc }, {}) } const parseObject = object => { return Object.keys(object).reduce((acc, item) => { acc[item] = object[item] return acc }, {}) } const parseProxyUrl = value => { if (!Array.isArray(value) && typeof value === 'object' && value.tuple.length === 3 && value.tuple[0] === ':socks5') { const [, host, port] = value.tuple return { socks5: true, host, port } } else if (typeof value === 'string') { const [host, port] = value.split(':') return { socks5: false, host, port } } return { socks5: false, host: null, port: null } } export const partialUpdate = (group, key) => { if ((group === ':pleroma' && key === ':ecto_repos') || (group === ':quack' && key === ':meta') || (group === ':mime' && key === ':types') || (group === ':auto_linker' && key === ':opts') || (group === ':swarm' && key === ':node_blacklist')) { return false } return true } export const valueHasTuples = (key, value) => { const valueIsArrayOfNonObjects = Array.isArray(value) && value.length > 0 && typeof value[0] !== 'object' return key === ':meta' || key === ':types' || key === ':compiled_template_engines' || key === ':compiled_format_encoders' || typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean' || value === null || valueIsArrayOfNonObjects } export const wrapUpdatedSettings = (group, settings) => { return Object.keys(settings).map((key) => { const value = settings[key]._value ? settings[key]._value[1] : wrapValues(settings[key]) return { group, key, value } }) } const wrapValues = settings => { return Object.keys(settings).map(setting => { const [type, value] = Array.isArray(settings[setting]) ? settings[setting] : ['', settings[setting]] if (type === 'keyword' || type.includes('keyword')) { return { 'tuple': [setting, wrapValues(value)] } } else if (type === 'atom') { return { 'tuple': [setting, `:${value}`] } } else if (type.includes('tuple') && Array.isArray(value)) { return { 'tuple': [setting, { 'tuple': value }] } } else if (type === 'map') { const objectValue = Object.keys(value).reduce((acc, key) => { acc[key] = value[key][1] return acc }, {}) return { 'tuple': [setting, objectValue] } } else if (setting === ':ip') { const ip = value.split('.').map(s => parseInt(s, 10)) return { 'tuple': [setting, { 'tuple': ip }] } } else if (setting === ':ssl_options') { return { 'tuple': [setting, wrapValues(value)] } } else { return { 'tuple': [setting, value] } } }) } const wrapNestedTuples = setting => { return Object.keys(setting).reduce((acc, settingName) => { const data = setting[settingName] if (data === null || data === '') { return acc } else if (settingName === 'ip') { const ip = data.split('.').map(s => parseInt(s, 10)) return [...acc, { 'tuple': [`:${settingName}`, { 'tuple': ip }] }] } else if (Array.isArray(data) || typeof data !== 'object') { return [...acc, { 'tuple': [`:${settingName}`, data] }] } else if (nonAtomsObjects.includes(settingName)) { return [...acc, { 'tuple': [`:${settingName}`, wrapNonAtomsObjects(data)] }] } else if (objectParents.includes(settingName)) { return [...acc, { 'tuple': [`:${settingName}`, wrapNestedObjects(data)] }] } else if (objects.includes(settingName)) { return [...acc, { 'tuple': [`:${settingName}`, wrapObjects(data)] }] } else if (nonAtomsTuples.includes(settingName)) { return [...acc, { 'tuple': [`:${settingName}`, wrapNonAtomsTuples(data)] }] } else { return [...acc, { 'tuple': [`:${settingName}`, wrapNestedTuples(data)] }] } }, []) } const wrapNonAtomsTuples = setting => { return Object.keys(setting).reduce((acc, settingName) => { return [...acc, { 'tuple': [`${settingName}`, setting[settingName]] }] }, []) } const wrapNestedObjects = setting => { return Object.keys(setting).reduce((acc, settingName) => { return [...acc, { 'tuple': [`:${settingName}`, wrapObjects(setting[settingName])] }] }, []) } const wrapNonAtomsObjects = setting => { return Object.keys(setting).reduce((acc, settingName) => { return { ...acc, [`${settingName}`]: setting[settingName] } }, {}) } const wrapObjects = setting => { return Object.keys(setting).reduce((acc, settingName) => { return { ...acc, [`:${settingName}`]: setting[settingName] } }, {}) }