UNPKG

@applicaster/quick-brick-core

Version:

Core package for Applicaster's Quick Brick App

153 lines (119 loc) 3.66 kB
import * as R from "ramda"; import { RequestBuilder } from "@applicaster/zapp-pipes-v2-client"; import { TYPE, SCREEN_ID, FEED_LOCATOR, OMITTED_PARAMS } from "../const"; type Query = Record<string, unknown> & Partial<{ type: string; screen_id: string; feed_locator: string; id: string; position: number; state: "inline" | "fullscreen"; }>; type ResolveQueryDataArgs = { query: Query; rivers: Record<string, ZappRiver>; contentTypes: ZappContentTypes; }; type ResolvedQuery = { targetScreen: ZappRiver; entry?: Partial<ZappEntry>; }; export const queryIsValid = R.anyPass([ R.has(TYPE), R.has(SCREEN_ID), R.has(FEED_LOCATOR), ]); export const getTypeMappedScreen = (type, rivers, contentTypes) => R.compose( R.propOr(null, R.__, rivers), R.path([type, "screen_id"]) )(contentTypes); export const getEntryById = R.curry( (entries, { id }) => R.find(({ id: entryId }) => entryId == id, entries) // eslint-disable-line eqeqeq ); export const getEntryByPosition = R.curry((entries, { position }) => R.nth(Math.max(position - 1, 0), entries) ); // second arg is not used here, but required by R.curry export const getFirstEntry = R.curry((entries, _) => R.nth(0, entries)); export const getEntry = R.curry((entries, query) => R.cond([ [R.has("id"), getEntryById(entries)], [R.has("position"), getEntryByPosition(entries)], [R.T, getFirstEntry(entries)], ])(query) ); export const formatEntry = (query: Query): Partial<ZappEntry> => { const params = R.omit([...OMITTED_PARAMS], query); const extensions = R.clone(params); if (query.type) { params.type = { value: query.type }; } params.extensions = extensions; return params; }; export const getHomeScreenId = R.compose( R.prop("id"), R.find(R.propEq("home", true)), R.values ); export async function resolveQueryData({ query, rivers, contentTypes, }: ResolveQueryDataArgs): Promise<ResolvedQuery> { const { type, screen_id, feed_locator } = query; if (feed_locator) { const url = decodeURIComponent(feed_locator); const request = new RequestBuilder(); if (!url) { throw new Error("Feed locator is missing"); } const { response: feed, error } = await request .setUrl(url) .call<ZappFeed>(); if (error) { throw error; } const entries = feed?.entry ?? []; const selectedEntry = getEntry(entries, query); const typeMappedScreen = getTypeMappedScreen( type ?? selectedEntry?.type?.value, rivers, contentTypes ); const screen = R.prop(selectedEntry?.screen_type ?? screen_id, rivers); const targetScreen = screen ?? typeMappedScreen; return { targetScreen, entry: selectedEntry, }; } const typeMappedScreen = getTypeMappedScreen(type, rivers, contentTypes); const screenFromId = R.prop(screen_id, rivers); const targetScreen = screenFromId ?? typeMappedScreen; const data = { targetScreen, entry: formatEntry(query), }; return data; } const normalizeInitialPlayerState = (initialPlayerState: string): string => { return initialPlayerState.toLowerCase() === "inline" ? "inline" : "fullscreen"; }; export const withInitialPlayerState = (query, entry) => { const initialPlayerState = normalizeInitialPlayerState( R.pathOr("fullscreen", ["state"], query) ); const initialPlayerStateLens = R.lensPath([ "extensions", "initial_player_state", ]); return R.set(initialPlayerStateLens, initialPlayerState, entry); }; export function wait(delay = 200) { return new Promise((resolve) => setTimeout(resolve, delay)); }