import { injectable } from "inversify"; import Video, { IVideo, videoType, IVideoResource } from "./"; import {IJsonApiRelationshipResource, IJsonApiResource, IResourceMapper} from "../../interfaces"; import Mapper from "../../mapper"; import { videoSourceType } from "../videoSource"; import VideoSourceMapper from "../videoSource/mapper"; import PlaceMapper from "../place/mapper"; import PoiMapper from "../poi/mapper"; import {placeType} from "../place/index"; import {poiType} from "../poi/index"; @injectable() export class VideoMapper extends Mapper { private mappers = { [placeType]: new PlaceMapper(), [poiType]: new PoiMapper(), [videoSourceType]: new VideoSourceMapper(), }; toModel(resource: IVideoResource, included: IJsonApiResource[] = []): IVideo { const model = new Video(); const { relationships, attributes: attrs } = resource; model.id = resource.id; model.url = attrs.url; model.tags = attrs.tags || []; model.iframeEmbed = attrs.iframe_embed; model.html5Embed = attrs.html5_embed; model.updatedAt = attrs.modify_date; model.createdAt = attrs.create_date; model.name = attrs.name; model.slug = attrs.slug; model.live = attrs.live; model.referenceId = attrs.reference_id; model.shortDescription = attrs.short_description; model.longDescription = attrs.description; model.duration = attrs.duration; model.isSpherical = attrs.is_360; model.episode = attrs.episode; model.season = attrs.season; model.format = attrs.format; model.host = attrs.host; model.director = attrs.director; model.year = attrs.year; model.pixel = attrs.pixel; model.featuredOrder = attrs.featured_order; model.featuredPriority = attrs.featured_priority; model.spotlight = attrs.spotlight; model.hub = attrs.hub; model.thumbnailUrl = attrs.thumbnail_url; model.posterUrl = attrs.poster_url; model.heroUrl = attrs.hero_url; model.graphicUrl = attrs.graphic_url; model.providerId = attrs.provider_id; model.providerName = attrs.provider_name; model.startDate = attrs.start_date; model.endDate = attrs.end_date; if (relationships) { if (relationships.sources && relationships.sources.data && Array.isArray(relationships.sources.data)) { const sources = relationships.sources.data; model.sources = sources.map((source) => this.mapIncluded(source , included)) } if (relationships.places && relationships.places.data && Array.isArray(relationships.places.data)) { const places = relationships.places.data; model.places = places.map((place) => this.mapIncluded(place , included)) } if (relationships.pois && relationships.pois.data && Array.isArray(relationships.pois.data)) { const pois = relationships.pois.data; model.pois = pois.map((poi) => this.mapIncluded(poi , included)) } } return model; } toResource(model: IVideo): IVideoResource { const resource: IVideoResource = { id: model.id, type: videoType, attributes: { url: model.url, tags: model.tags, iframe_embed: model.iframeEmbed, html5_embed: model.html5Embed, modify_date: model.updatedAt, create_date: model.createdAt, name: model.name, slug: model.slug, live: model.live, reference_id: model.referenceId, short_description: model.shortDescription, description: model.longDescription, duration: model.duration, is_360: model.isSpherical, episode: model.episode, season: model.season, format: model.format, host: model.host, director: model.director, year: model.year, pixel: model.pixel, featured_order: model.featuredOrder, featured_priority: model.featuredPriority, spotlight: model.spotlight, hub: model.hub, thumbnail_url: model.thumbnailUrl, poster_url: model.posterUrl, hero_url: model.heroUrl, graphic_url: model.graphicUrl, provider_id: model.providerId, provider_name: model.providerName, start_date: model.startDate, end_date: model.endDate, } }; resource.relationships = {}; if (model.sources) { resource.relationships.sources = { data: model.sources.map(({ id }) => ({ id: id, type: videoSourceType, })) }; } 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 = this.mappers[resource.type]; if (!mapper) { return resourceIdentifier; } return mapper.toModel(resource, included); } } export default VideoMapper;