import { inject, injectable } from "inversify"; import Association, { IAssociation, associationType, IAssociationResource } from "./"; import { associationEntryType, IAssociationEntryResource } from "../associationEntry"; import { IJsonApiResource, IResourceMapper } from "../../interfaces"; import PoiMapper from "../poi/mapper"; import PartnerActivityMapper from "../partnerActivity/mapper"; import LodgingMapper from "../lodging/mapper"; import AssociationEntryMapper from "../associationEntry/mapper"; import Mapper from "../../mapper"; const mappers = { poi: new PoiMapper(), lodging: new LodgingMapper(), partner_activity: new PartnerActivityMapper(), }; @injectable() export class AssociationMapper extends Mapper { associationEntryMapper = new AssociationEntryMapper(); toModel(resource: IAssociationResource, included: IJsonApiResource[] = []): IAssociation { const model = new Association(); const attrs = resource.attributes; model.id = resource.id; model.associationType = attrs.association_type; model.createdAt = attrs.created_at; model.status = attrs.status; model.targetTypes = attrs.target_types; model.updatedAt = attrs.updated_at; model.entries = included.filter((i) => i.type === associationEntryType) .filter((i) => { const isArray = Array.isArray(resource.relationships.entries.data); const entries = ((isArray ? resource.relationships.entries.data : resource.relationships.entries.data && [resource.relationships.entries.data])); if (entries) { return entries.some(e => e.id === i.id); } return false; }) .map((b: IAssociationEntryResource) => { return this.associationEntryMapper.toModel(b, included); }); if (resource.relationships.source) { const sourceResource = resource.relationships.source.data; model.source = this.mapIncluded(sourceResource, included); } if (resource.relationships.suggestions && resource.relationships.suggestions.data) { model.suggestions = (resource.relationships.suggestions.data as any).map((item) => this.mapIncluded(item as IJsonApiResource, included)); } return model; } toResource(model: IAssociation): IAssociationResource { const resource: IAssociationResource = { id: model.id, type: associationType, attributes: { association_type: model.associationType, created_at: model.createdAt, status: model.status, target_types: model.targetTypes, updated_at: model.updatedAt }, }; resource.relationships = {}; if (model.source) { resource.relationships.source = { data: { type: model.source.type, id: model.source.id } } } if (model.suggestions) { resource.relationships.suggestions = { data: model.suggestions.map((s) => ({ type: s.type, id: s.id, })), } } Object.keys(resource.attributes).forEach((key) => { if (typeof resource.attributes[key] === "undefined") { delete resource.attributes[key]; } }); if (Object.keys(resource.relationships).length === 0) { delete resource.relationships; } return resource; } private mapIncluded(resourceIdentifier: IJsonApiResource, included: any[]) { const resource = included.find((i) => i.type === resourceIdentifier.type && i.id === resourceIdentifier.id); if (!resource) { return resourceIdentifier; } const mapper: IResourceMapper = mappers[resource.type]; return mapper.toModel(resource, included); } } export default AssociationMapper;