src/app/routes/utils/parseAvRoute/index.ts

Summary

Maintainability
A
35 mins
Test Coverage
A
100%
import services from '#lib/config/services/loadableConfig';
import { Services, Variants } from '#app/models/types/global';

type Query = string[];
type Platform = 'cps' | 'articles' | 'tipo';

// Asset ID regexes
const CPS_ID_REGEX = /([0-9]{5,9}|[a-z0-9\-_]+-[0-9]{5,9})$/;
const OPTIMO_ID_REGEX = /^c[a-zA-Z0-9]{10}o$/;
const TIPO_ID_REGEX =
  /^(c[a-zA-Z0-9]{10,11}t)|([a-z0-9]{8}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{12})$/;

const MEDIA_ID_REGEX = /^((?!portuguese)p[a-z0-9]{7,})$/;

const MEDIA_DELIMITERS = ['vpid', 'pid'];

// Language codes
const LANGS = [
  'am',
  'ar',
  'az',
  'bn',
  'cy',
  'en',
  'en-gb',
  'es',
  'fa',
  'fr',
  'gd',
  'gu',
  'ha',
  'hi',
  'id',
  'ig',
  'ja',
  'ko',
  'ky',
  'mr',
  'my',
  'ne',
  'om',
  'pa',
  'pcm',
  'ps',
  'pt',
  'pt-br',
  'ru',
  'ru-uk',
  'ru-ua',
  'rw',
  'si',
  'so',
  'sr-cyrl',
  'sr-latn',
  'sw',
  'ta',
  'te',
  'tg',
  'th',
  'ti',
  'tr',
  'uk',
  'ur',
  'uz',
  'uz-cyrl',
  'uz-latn',
  'vi',
  'yo',
  'zh-hans',
  'zh-hant',
];

const LANGS_REGEX = new RegExp(`^(${LANGS.join('|')})$`);

const SERVICES = Object.keys(services) as Services[];
const VARIANTS = ['lat', 'cyr', 'trad', 'simp'] as Variants[];

const extractService = (query: Query): Services | null => {
  const service = SERVICES.find(s => s !== 'ws' && query?.includes(s));

  return service ?? null;
};

const extractVariant = (query: Query): Variants | null => {
  const variant = VARIANTS.find(v => query?.includes(v));

  return variant ?? null;
};

const extractPlatform = (query: Query): Platform | null => {
  let platform: Platform | null = null;

  // eslint-disable-next-line no-restricted-syntax
  for (const id of query ?? []) {
    if (CPS_ID_REGEX.test(id)) {
      platform = 'cps';
      break;
    }
    if (OPTIMO_ID_REGEX.test(id)) {
      platform = 'articles';
      break;
    }
    if (TIPO_ID_REGEX.test(id)) {
      platform = 'tipo';
      break;
    }
  }

  return platform;
};

const extractAssetId = (query: Query) => {
  const assetId = query?.find((id: string) => {
    return (
      CPS_ID_REGEX.test(id) ||
      OPTIMO_ID_REGEX.test(id) ||
      TIPO_ID_REGEX.test(id)
    );
  });

  return assetId ?? null;
};

const extractMediaId = (query: Query) => {
  const mediaId = query?.find((id: string) => MEDIA_ID_REGEX.test(id));

  return mediaId ?? null;
};

const extractLang = (query: Query) => {
  const lang = query?.find((l: string) => LANGS_REGEX.test(l?.toLowerCase()));

  return lang ?? null;
};

const extractAmp = (query: Query) => {
  const amp = query?.includes('amp');

  return amp ?? null;
};

const extractMediaDelimiter = (query: Query) => {
  const mediaDelimiter = query?.find((id: string) =>
    MEDIA_DELIMITERS.includes(id),
  );

  return mediaDelimiter ?? null;
};

export default function parseAvRoute(resolvedUrl: string) {
  const resolvedUrlWithoutQuery = resolvedUrl.split('?')?.[0];

  const query = resolvedUrlWithoutQuery.split(/[/.]/).filter(Boolean);

  const isWsRoute = query.includes('ws');
  const isAmp = extractAmp(query);

  const service = extractService(query);
  const variant = extractVariant(query);
  const platform = extractPlatform(query);
  const assetId = extractAssetId(query);
  const mediaId = extractMediaId(query);
  const mediaDelimiter = extractMediaDelimiter(query);
  const lang = extractLang(query);

  return {
    isWsRoute,
    isAmp,
    service,
    variant,
    platform,
    assetId,
    mediaId,
    mediaDelimiter,
    lang,
  };
}