WFCD/warframe-worldstate-data

View on GitHub
tools/translation.js

Summary

Maintainability
A
0 mins
Test Coverage
import data from '../exports.js';

/**
 * Rough Titlecase!
 * @param {string} str string to be titlecased
 * @returns {string} titlecased string
 */
export const toTitleCase = (str) => {
  return str.replace(/\w\S*/g, (txt) => txt.charAt(0).toUpperCase() + txt.substring(1).toLowerCase());
};

/**
 * Utility function to split the resource name and return somewhat human-readable string
 * @param {string} str localization resource key
 * @returns {string} human-readable string
 */
export const splitResourceName = (str) =>
  str
    .split(/([A-Z]?[^A-Z]*)/g)
    .filter(Boolean)
    .join(' ');

export const lastResourceName = (str) => (typeof str === 'string' ? str.split?.('/').reverse()[0] : str);

const i18n = (locale = 'en') => data[locale] || data;

const keyInData = (key, dataOverride) => (key in i18n(dataOverride) ? i18n(dataOverride)[key] : key);

/**
 *
 * @param {string} color - The internal color name
 * @param {string} dataOverride locale for use with translation
 * @returns {Object | undefined}
 */
export const archonShard = (color, dataOverride = 'en') => keyInData('archonShards', dataOverride)[color];

/**
 *
 * @param {string} color - The internal color name
 * @param {string} dataOverride locale for use with translation
 * @returns {string}
 */
export const archonShardColor = (color, dataOverride = 'en') => archonShard(color, dataOverride)?.value ?? color;

/**
 *
 * @param {string} color - The internal color name
 * @param {string} upgradeType - The upgrade type
 * @param {string} dataOverride locale for use with translation
 * @returns {string}
 */
export const archonShardUpgradeType = (color, upgradeType, dataOverride = 'en') =>
  archonShard(color, dataOverride)?.upgradeTypes[upgradeType]?.value ?? lastResourceName(upgradeType);

/**
 *
 * @param {string} key - The data key
 * @param {string} dataOverride locale for use with translation
 * @returns {string} faction name
 */
export const faction = (key, dataOverride = 'en') => keyInData('factions', dataOverride)[key]?.value ?? key;

const solNode = (key, thing, dataOverride = 'en') =>
  keyInData('solNodes', dataOverride)?.[key]?.[thing] ?? lastResourceName(key) ?? key;

/**
 *
 * @param {string} key - The data key
 * @param {string} dataOverride locale for use with translation
 * @returns {string} node name
 */
export const node = (key, dataOverride = 'en') => solNode(key, 'value', dataOverride);

/**
 *
 * @param {string} key - The data key
 * @param {string} dataOverride locale for use with translation
 * @returns {string} mission type of the node
 */
export const nodeMissionType = (key, dataOverride = 'en') => solNode(key, 'type', dataOverride);
/**
 *
 * @param {string} key - The data key
 * @param {string} dataOverride locale for use with translation
 * @returns {string} faction that controls the node
 */
export const nodeEnemy = (key, dataOverride = 'en') => {
  return key in i18n(dataOverride).solNodes ? i18n(dataOverride).solNodes[key].enemy : (lastResourceName(key) ?? key);
};

/**
 *
 * @param {string} key - The data key
 * @param {string} dataOverride locale for use with translation
 * @returns {string} localization for language string
 */
export const languageString = (key, dataOverride = 'en') => {
  const lowerKey = String(key).toLowerCase();
  return (
    keyInData('languages', dataOverride)[lowerKey]?.value ??
    keyInData('languages', dataOverride)[key]?.value ??
    (key ? toTitleCase(splitResourceName(lastResourceName(String(key)))) : key)
  );
};

/**
 *
 * @param {string} key - The data key
 * @param {string} dataOverride locale for use with translation
 * @returns {string} localization for language description
 */
export const languageDesc = (key, dataOverride = 'en') => {
  const lowerKey = String(key).toLowerCase();
  return (
    i18n(dataOverride).languages[lowerKey]?.desc ??
    i18n(dataOverride).languages[key]?.desc ??
    (key ? `[PH] ${toTitleCase(splitResourceName(lastResourceName(String(key))))} Desc` : key)
  );
};

/**
 *
 * @param {string} key - The data key
 * @param {string} dataOverride locale for use with translation
 * @returns {string} translation for mission type
 */
export const missionType = (key, dataOverride = 'en') => {
  const keyBased = key && typeof key === 'string' && toTitleCase((key ?? '').replace(/^MT_/, ''));
  return key in i18n(dataOverride).missionTypes ? i18n(dataOverride).missionTypes[key].value : keyBased;
};

const conclave = (key, thing, dataOverride = 'en') => keyInData('conclave', dataOverride)?.[thing]?.[key]?.value ?? key;

/**
 *
 * @param {string} key - The data key
 * @param {string} dataOverride locale for use with translation
 * @returns {string} conclave mode
 */
export const conclaveMode = (key, dataOverride = 'en') => conclave(key, 'modes', dataOverride);

/**
 *
 * @param {string} key - The data key
 * @param {string} dataOverride locale for use with translation
 * @returns {string} conclave category
 */
export const conclaveCategory = (key, dataOverride = 'en') => conclave(key, 'categories', dataOverride);

const fissure = (key, dataOverride = 'en') => keyInData('fissureModifiers', dataOverride)?.[key] ?? key;

/**
 *
 * @param {string} key - The data key
 * @param {string} dataOverride locale for use with translation
 * @returns {string} fissure modifier data
 */
export const fissureModifier = (key, dataOverride = 'en') => fissure(key, dataOverride)?.value ?? key;

/**
 *
 * @param {string} key - The data key
 * @param {string} dataOverride locale for use with translation
 * @returns {number | string} fissure tier
 */
export const fissureTier = (key, dataOverride = 'en') => fissure(key, dataOverride).num ?? key;

/**
 *
 * @param {string} key - The data key
 * @param {string} dataOverride locale for use with translation
 * @returns {string} syndicate name
 */
export const syndicate = (key, dataOverride = 'en') => i18n(dataOverride).syndicates[key]?.name ?? key;

/**
 *
 * @param {string} key - The data key
 * @param {string} dataOverride locale for use with translation
 * @returns {string} upgrade type
 */
export const upgrade = (key, dataOverride = 'en') => i18n(dataOverride).upgradeTypes[key]?.value ?? key;

const oppo = (key, dataOverride = 'en') => i18n(dataOverride).operationTypes[key];

/**
 *
 * @param {string} key - The data key
 * @param {string} dataOverride locale for use with translation
 * @returns {string} mathematical operation value
 */
export const operation = (key, dataOverride = 'en') => oppo(key, dataOverride)?.value ?? key;

/**
 *
 * @param {string} key - The data key
 * @param {string} dataOverride locale for use with translation
 * @returns {string} symbol of mathematical operation
 */
export const operationSymbol = (key, dataOverride = 'en') => oppo(key, dataOverride)?.symbol ?? key;

const sortie = (key, dataOverride = 'en') => i18n(dataOverride).sortie.bosses[key];

/**
 * @param {string} key - The data key
 * @param {string} dataOverride locale for use with translation
 * @returns {string} sortie boss name
 */
export const sortieBoss = (key, dataOverride = 'en') => sortie(key, dataOverride)?.name ?? key;

/**
 * @param {string} key - The data key
 * @param {string} dataOverride locale for use with translation
 * @returns {string} faction for a sortie based on the boss
 */
export const sortieFaction = (key, dataOverride = 'en') => sortie(key, dataOverride)?.faction ?? key;

/**
 *
 * @param {string} key - The data key
 * @param {string} dataOverride locale for use with translation
 * @returns {string} sortie modifier data
 */
export const sortieModifier = (key, dataOverride = 'en') => i18n(dataOverride).sortie.modifierTypes?.[key] ?? key;

/**
 * @param {string} key - The data key
 * @param {string} dataOverride locale for use with translation
 * @returns {string} sortie modifier description
 */
export const sortieModDesc = (key, dataOverride = 'en') => i18n(dataOverride).sortie.modifierDescriptions?.[key] ?? key;

/**
 * Retrieve the localized region for a given key
 * @param {string | number} key - The region key
 * @param {string} dataOverride - The locale to use for translations
 * @returns {string} localized region name
 */
export const region = (key, dataOverride = 'en') => (key && i18n(dataOverride).persistentEnemy?.regions[key]) ?? key;

/**
 * Retrieve conclave challenge name for the given key and locale
 * @param {string} key key to retrieve
 * @param {string} dataOverride locale key override
 * @returns {{
 *   title: string,
 *   description: string,
 *   standing: number,
 * }} - The conclave challenge name for the given key
 */
export const conclaveChallenge = (key, dataOverride = 'en') => {
  const splitKey = lastResourceName(String(key));

  if (i18n(dataOverride).conclave?.challenges?.[splitKey]) {
    return i18n(dataOverride).conclave.challenges[splitKey];
  }
  return {
    title: toTitleCase(splitResourceName(splitKey)),
    description: toTitleCase(splitResourceName(splitKey)),
    standing: 0,
  };
};

/**
 * Get the steel path data for given key
 * @param {string} dataOverride - The locale to use for translations
 * @returns {string} - The steel path data for the given key
 */
export const steelPath = (dataOverride = 'en') => (i18n(dataOverride) || /* istanbul ignore next */ data).steelPath;

const valMapping = (key, map) => {
  let val = 'None';
  Object.keys(map).forEach((k) => {
    if (key.includes(k)) {
      val = map[k];
    }
  });
  return val;
};

const focusMap = {
  'Focus/Attack': 'Madurai',
  'Focus/Defense': 'Vazarin',
  'Focus/Tactic': 'Naramon',
  'Focus/Power': 'Zenurik',
  'Focus/Ward': 'Unairu',
};
/**
 * Translate the given focus school
 * @param {string} focus The focus school to translate
 * @returns {string} The translated focus school
 */
export const translateFocus = (focus = '') => valMapping(focus, focusMap);

const polarityMap = {
  AP_ATTACK: 'Madurai',
  AP_DEFENSE: 'Vazarin',
  AP_TACTIC: 'Naramon',
  AP_POWER: 'Zenurik',
  AP_WARD: 'Unairu',
  AP_UMBRA: 'Umbra',
  AP_ANY: 'Aura',
};

/**
 * Translate the given polarity
 * @param {string?} pol The polarity to translate
 * @returns {string} The translated polarity
 */
export const translatePolarity = (pol = '') => valMapping(pol, polarityMap);

/**
 * An object containing functions to convert in-game names to their localizations
 * @typedef {Record<string, function>} Translator
 * @property {function} faction          - Converts faction names
 * @property {function} node             - Converts star map node names
 * @property {function} nodeMissionType  - Returns the mission type of given node
 * @property {function} nodeEnemy        - Returns the faction that controls a given node
 * @property {function} languageString   - Converts generic language strings
 * @property {function} languageDesc     - Converts generic language strings
 *                                          and retrieves the description
 * @property {function} missionType      - Converts mission types
 * @property {function} conclaveMode     - Converts conclave modes
 * @property {function} conclaveCategory - Converts conclave challenge categories
 * @property {function} fissureModifier  - Converts fissure mission modifiers
 * @property {function} syndicate        - Converts syndicate names
 * @property {function} upgrade          - Converts upgrade types
 * @property {function} operation        - Converts operation types
 * @property {function} sortieBoss       - Converts sortie boss names
 * @property {function} sortieModifier    - Converts sortie modifier types
 * @property {function} sortieModDesc    - Converts sortie modifier type descriptions
 * @property {function} region           - Converts persistent enemy region indicies
 * @property {function} conclaveChallenge - Convert conclave identifiers into standing data
 * @property {function} steelPath        -  Retrieve Steel Path rotation data for locale
 * @property {function} toTitleCase      - Format provided string as titlecase
 * @property {function} translateFocus   - Translate focus schools
 * @property {function} translatePolarity - Translate polarities
 * @property {function} archonShard      - Converts archon shard names
 * @property {function} archonShardColor - Converts archon shard names to in-game color values
 * @property {function} archonShardUpgradeType - Convert archon shard upgrade type
 */
export default {
  faction,
  node,
  nodeMissionType,
  nodeEnemy,
  languageString,
  languageDesc,
  missionType,
  conclaveMode,
  conclaveCategory,
  fissureModifier,
  fissureTier,
  syndicate,
  upgrade,
  operation,
  operationSymbol,
  sortieBoss,
  sortieModifier,
  sortieModDesc,
  sortieFaction,
  region,
  conclaveChallenge,
  steelPath,
  toTitleCase,
  translateFocus,
  translatePolarity,
  archonShard,
  archonShardColor,
  archonShardUpgradeType,
};