import { inject, injectable } from "inversify"; import { IJsonApiResource } from "../../interfaces"; import Mapper from "../../mapper"; import * as TYPES from "../../types"; import { IPoi, poiType, IPoiAttributes, } from "../poi"; import PoiMapper from "../poi/mapper"; import Lodging, { lodgingType, ILodging, ILodgingResource, ILodgingAttributes, ILodgingProviderAttributes, lodgingProviderType, } from "./"; import { imageAssociationType, imageType, IImage, IImageAttributes, } from "../image"; import { IPlaceResource } from "../place"; import hotelProvider from "../../utils/hotelProvider"; import imgix from "../../utils/imgix"; import { assignContainingPlaces, assignCity, assignContinent, assignCountry, assignNeighborhood, assignRegions } from "../../utils/placeUtilities"; @injectable() class LodgingMapper extends Mapper { @inject(TYPES.Bookmark) model: ILodging; poiMapper = new PoiMapper(); toModel(resource: ILodgingResource, included: IJsonApiResource[] = []): ILodging { let providerId; const model = new Lodging(); const attrs = resource.attributes; model.id = resource.id; model.address = attrs.address; model.location = attrs.location; model.name = attrs.name; model.attributes = attrs.attributes; model.poiType = attrs.poi_type; model.price = attrs.price_string; model.priceRange = attrs.price_range; model.review = attrs.review; model.lpInternalScore = attrs.score; model.searchableName = attrs.searchable_name; model.starRating = attrs.star_rating; model.subtypes = attrs.subtypes; model.containingPlaceId = (resource.relationships["containing-place"].data).id; model.type = resource.type; if (resource.relationships.poi && resource.relationships.poi.data) { const poi = included.find((r) => r.type === poiType && r.id === (resource.relationships.poi.data).id ) as IJsonApiResource; if (poi) { model.poi = this.poiMapper.toModel(poi); } else { model.poi = resource.relationships.poi.data as IPoi; } } const place = included.find((resource) => resource.id === model.containingPlaceId); if (place) { model.containingPlaceName = (<{ [key: string]: string}>place.attributes).name; } if (place) { const ancestry = (place.relationships["ancestry"].data) || []; assignContainingPlaces(included, [place, ...ancestry], model); assignCity(included, ancestry, place, model); assignContinent(included, ancestry, place, model); assignCountry(included, ancestry, place, model); assignNeighborhood(included, ancestry, place, model); assignRegions(included, ancestry, place, model); } const providers = included.filter((resource) => resource.type === lodgingProviderType && model.id === (resource.relationships.lodging.data).id ) as IJsonApiResource[]; if (providers) { providerId = hotelProvider(providers); model.providers = providers.map(p => ({ ...p.attributes, id: p.id, provider: providerId, lodgingType: p.attributes.lodging_type, })); } const images = included.filter((resource) => resource.type === imageType && model.id === (resource.relationships.lodging.data).id ) as IJsonApiResource[]; if (images) { model.images = images.map((image: IJsonApiResource): IImage => ({ attribution: image.attributes.attribution, path: image.attributes.path, caption: image.attributes.caption, height: image.attributes.height, width: image.attributes.width, orientation: image.attributes.orientation, tags: image.attributes.tags || [], url: imgix(image.links.pixels, providerId), })); } return model; } toResource(model: ILodging): ILodgingResource { const resource = { id: model.id, type: lodgingType, attributes: { address: model.address, attributes: model.attributes, location: model.location, name: model.name, poi_type: model.poiType, price_range: model.priceRange, price_string: model.price, review: model.review, rich_hours_string: model.richHoursString, score: model.lpInternalScore, searchable_name: model.searchableName, star_rating: model.starRating, subtypes: model.subtypes, }, }; return resource; } } export default LodgingMapper;