import type { DataType, RelationshipType, SerializerResponseApi } from './types' const serializeRelationshipsObject = (data: DataType) => data.relationships ? serializeRelationshipsAndConfig(data) : { id: data.id, type: data.type, ...(data.meta ? { meta: data.meta } : {}), ...data.attributes, } const serializeRelationshipIds = (relationships: DataType['relationships']) => { const relationshipIds: Record = {} if (relationships) { const keys = Object.keys(relationships) keys.forEach((key) => { const dataRelationships = relationships?.[key].data if (Array.isArray(dataRelationships)) relationshipIds[`${key}Ids`] = dataRelationships.map(({ id }) => id) else relationshipIds[`${key}Id`] = dataRelationships?.id || null }) } return relationshipIds } const serializerData = (data: DataType | Record) => { const relationships = data.relationships as DataType['relationships'] const attributes = data.attributes as DataType['attributes'] const newData = data?.attributes ? { id: data.id, ...attributes, ...serializeRelationshipIds(relationships) } : { ...data, ...serializeRelationshipIds(relationships) } return newData } const serializeRelationshipsAndConfig = (data: DataType) => { const relationshipsIds: Record = {} const dataRelationships = data?.relationships if (dataRelationships) for (const [key, value] of Object.entries(dataRelationships)) { if (Array.isArray(value.data)) { //TODO Add a test relationshipsIds[`${key}Ids`] = value.data.map((x) => x.id) } else { relationshipsIds[`${key}Id`] = value.data?.id } } return { id: data.id, type: data.type, ...data.attributes, ...(data.meta ? { meta: data.meta } : {}), ...relationshipsIds, } } const serializeRelationships = (data: DataType | DataType[]) => Array.isArray(data) ? data.map((d) => serializeRelationshipsObject(d)) : serializeRelationshipsObject(data) const serializeIncluded = (includedData: DataType[]) => { const type: Record = {} const newIncluded: Record = {} includedData .map((include) => include.type) .forEach((value) => { const index = 1 if (type[value]) type[value] = index + 1 else type[value] = index }) Object.values(type).forEach((includeType, index) => { const key = Object.keys(type)[index] const includedFiltered = includedData.filter((data) => data.type === key) const includedFound = includedData.find((data) => data.type === key) if (includeType > 1) newIncluded[`${key}s`] = serializeRelationships(includedFiltered) else if (includedFound) newIncluded[`${key}s`] = serializeRelationships(includedFound) }) return newIncluded } const formatResponseApi = (response: SerializerResponseApi) => { const { data, headers, included, meta } = response if (data && typeof data !== 'string') { const newData = Array.isArray(data) ? data.map((data) => serializerData(data)) : serializerData(data) const newIncluded = included ? serializeIncluded(included) : null return { data: newData, headers, ...(meta ? { meta } : {}), ...(newIncluded ? { included: newIncluded } : {}), } } return response } export { formatResponseApi }