@applicaster/quick-brick-core
Version:
Core package for Applicaster's Quick Brick App
133 lines (109 loc) • 3 kB
text/typescript
import * as R from "ramda";
import url from "url";
import atob from "atob";
import { isScreenPlayable } from "@applicaster/zapp-react-native-utils/navigationUtils/itemTypes";
import { log_warning } from "../logger";
import { isTV } from "@applicaster/zapp-react-native-utils/reactUtils";
type UrlSchemeParams = Record<string, unknown>;
type UrlScheme = {
host?: string | null;
path?: string | null;
scheme?: string;
query?: UrlSchemeParams;
fragment?: string;
};
const escapedChars = [
[/"/g, '"'], // eslint-disable-line quotes
[/'/g, "'"],
[/</g, "<"],
[/>/g, ">"],
[/&/g, "&"],
];
const unescape = R.compose(...R.map(R.apply(R.replace), escapedChars));
/**
* tries to decode a url encoded to a base64 string.
* returns the original string if decoding is not possible or fails
*/
export function decodeUrl(urlString: string): string {
try {
return atob(decodeURIComponent(urlString));
} catch (error) {
log_warning(`couldn't decode url: ${urlString}`, { error, urlString });
return urlString;
}
}
/**
* parses a url string into an object, providing values for the different parts of the url
* @param `urlString` to parse
* @returns url object - see UrlScheme type above
*/
export function parseUrl(urlString: string): UrlScheme {
const {
protocol,
hostname: host,
pathname: path,
query,
hash,
} = url.parse(unescape(urlString), true, true);
const { data_source } = query;
const scheme = R.replace(":", "", protocol || "");
const fragment = R.replace("#", "", hash || "");
if (query.data_source) {
query.data_source = decodeUrl(data_source as string);
}
return {
scheme,
host,
path,
query,
fragment,
};
}
function goToHome({ navigator }) {
navigator.goHome();
}
function navigateTo({ data, navigator, pushScreen = false }) {
const newData = { ...data, isDeepLink: true };
if (isTV()) {
navigator.replace(newData);
return;
}
if (isScreenPlayable(navigator.currentRoute)) {
navigator.goBack(); // TODO: check it on start
navigator.push(newData);
return;
}
const navigatorMethod = pushScreen ? "push" : "replace";
navigator?.[navigatorMethod]?.(newData);
}
export function handlePresentNavigation({
data = null,
navigator,
pushScreen = false,
}: {
data?: any;
navigator: any;
pushScreen?: any;
}) {
if (R.isNil(data)) {
goToHome({ navigator });
} else {
navigateTo({ data, navigator, pushScreen });
}
}
export function findRiver({ screen_id, rivers }) {
return rivers?.[screen_id] || null;
}
export function isInternalUrl(url = "") {
const { query } = parseUrl(url);
return query?.isInternalLink;
}
export function getKeyFromStorage(
key: keyof SessionStorageKeys,
sessionData: Partial<SessionStorageKeys>
): string {
if (!sessionData[key]) {
throw new Error(`${key} is not available in session storage data`);
}
return String(sessionData[key]).replace(/"/g, "");
}