// @ts-nocheck // TODO: Fix this file but write tests first import _ from 'lodash' import inflection from 'lodash-inflection/lib/lodash-inflection' import { keysToCamelCase } from './utils' _.mixin({ ...inflection }) // Teach some bad grammar _.singular(/^(media)$/i, '$1') _.plural(/^(media)$/i, '$1') // eslint-disable-next-line eqeqeq const transformId = id => _.thru(parseInt(id, 10), int => (int == id ? int : id)) const transformRelationships = relationships => { return Object.keys(relationships || {}).reduce((acc, key) => { const relationship = relationships[key] if (_.isArray(relationship.data)) { const ids = _.map(relationship.data, ({ id }) => transformId(id)) return { ...acc, [`${_.singularize(key)}_ids`]: ids } } else { const id = _.get(relationship, 'data.id') const type = _.get(relationship, 'data.type', null) return { ...acc, [`${key}_id`]: id ? transformId(id) : null, [`${key}_type`]: type, } } }, {}) } const addIncludedRecords = (record, included, seen, parent) => { const { relationships } = record return Object.keys(relationships || {}).reduce((acc, key) => { const relationship = relationships[key] if (_.isArray(relationship.data)) { const records = _(relationship.data) .map(elem => _.find(included, elem)) .compact() // account for orphans .value() return _.set( acc, _.pluralize(key), _.map(records, related => transformRecord(related, included, seen)) ) } else { const [id, type] = _.at(relationship, ['data.id', 'data.type']) if (id && type) { const isSelfReference = id === record.id && type === record.type const related = isSelfReference ? undefined : _.find(included, { id, type }) return _.set(acc, key, related ? transformRecord(related, included, seen) : null) } else { return acc } } }, parent) } const transformRecord = (record, included, seen) => { if (!record) return record const { id, attributes, links, relationships, type } = record if (seen.has(record)) { return seen.get(record) } else { const transformed = { id: transformId(id), type, links, ...transformRelationships(relationships), ..._.mapKeys( attributes, (v, k) => (k === 'length' ? `${type.charAt(0).toLowerCase()}${type.slice(1)}Length` : k), {} ), } seen.set(record, transformed) return addIncludedRecords(record, included, seen, transformed) } } const defaultTransformResponse = response => { if (_.isEmpty(response)) return response const { data, included, meta, links } = response const seen = new WeakMap() if (_.isArray(data)) { const result = data.map(d => transformRecord(d, included, seen)) return { data: result, meta, links, ...data } } else { return { data: { ...transformRecord(data, included, seen) }, meta, links } } } const transformResponse = _.flowRight(keysToCamelCase, defaultTransformResponse) export default transformResponse