From 6147471326e96a523e078b138f2dbfb33b3192a2 Mon Sep 17 00:00:00 2001 From: Ornstein <6075693+SlayerOrnstein@users.noreply.github.com> Date: Thu, 26 Sep 2024 21:32:39 -0400 Subject: [PATCH] perf: filter items to just arsenal items and skins (#15) --- src/ArchonCrystal.js | 8 ++--- src/ItemConfig.js | 2 +- src/LoadOutInventory.js | 13 +++---- src/LoadOutItem.js | 8 +++-- src/Mission.js | 2 +- src/OperatorLoadOuts.js | 2 +- src/Profile.js | 4 +-- src/ProfileParser.js | 2 +- src/Skin.js | 7 ++-- src/Syndicate.js | 2 +- src/Util.js | 14 -------- src/Utils.js | 64 +++++++++++++++++++++++++++++++++ src/XpInfo.js | 7 ++-- test/unit/archonCrystal.spec.js | 2 +- test/unit/mission.spec.js | 2 +- test/unit/mock.spec.js | 4 +-- test/unit/stats.spec.js | 4 +-- test/unit/xpinfo.spec.js | 2 +- 18 files changed, 102 insertions(+), 47 deletions(-) delete mode 100644 src/Util.js create mode 100644 src/Utils.js diff --git a/src/ArchonCrystal.js b/src/ArchonCrystal.js index ecf24bf..d4aca76 100644 --- a/src/ArchonCrystal.js +++ b/src/ArchonCrystal.js @@ -8,19 +8,19 @@ export default class ArchonCrystal { /** * * @param {Object} crystal The archon crystal object - * @param {string} local The locale to get translations in + * @param {string} locale The locale to get translations in */ - constructor(crystal, local) { + constructor(crystal, locale = 'en') { /** * Archon shard color * @type {String} */ - this.color = archonShardColor(crystal.Color, local); + this.color = archonShardColor(crystal.Color, locale); /** * Archon shard modifier * @type {String} */ - this.modifier = archonShardUpgradeType(crystal.Color, crystal.UpgradeType, local); + this.modifier = archonShardUpgradeType(crystal.Color, crystal.UpgradeType, locale); } } diff --git a/src/ItemConfig.js b/src/ItemConfig.js index 0e40311..cc95261 100644 --- a/src/ItemConfig.js +++ b/src/ItemConfig.js @@ -1,7 +1,7 @@ import { colors } from 'warframe-items/utilities'; import Skin from './Skin.js'; -import mapToHex from './Util.js'; +import { mapToHex } from './Utils.js'; /** * Item customizations such as colors and applied skins diff --git a/src/LoadOutInventory.js b/src/LoadOutInventory.js index fde7143..2102c1c 100644 --- a/src/LoadOutInventory.js +++ b/src/LoadOutInventory.js @@ -10,8 +10,9 @@ export default class LoadOutInventory { /** * * @param {Object} item The loadout data + * @param {string} [locale='en'] The locale to return loudout items in */ - constructor(item) { + constructor(item, locale = 'en') { /** * Skins applied to weapons * @type {WeaponSkin} @@ -22,30 +23,30 @@ export default class LoadOutInventory { * An array of the player's currently equiped Warframe (or powersuits) * @type {LoadOutItem} */ - this.suits = item.Suits.map((s) => new LoadOutItem(s)); + this.suits = item.Suits.map((s) => new LoadOutItem(s, locale)); /** * An array of the player's currently equiped secondary weapon * @type {LoadOutItem | undefined} */ - this.secondary = item.Pistols?.map((p) => new LoadOutItem(p)); + this.secondary = item.Pistols?.map((p) => new LoadOutItem(p, locale)); /** * An array of the player's currently equiped primary weapon * @type {LoadOutItem | undefined} */ - this.primary = item.LongGuns?.map((lg) => new LoadOutItem(lg)); + this.primary = item.LongGuns?.map((lg) => new LoadOutItem(lg, locale)); /** * An array of the player's currently equiped melee weapon * @type {LoadOutItem | undefined} */ - this.melee = item.Melee?.map((m) => new LoadOutItem(m)); + this.melee = item.Melee?.map((m) => new LoadOutItem(m, locale)); /** * Items that have counted towards the players mastery rank * @type {XpInfo} */ - this.xpInfo = item.XPInfo.map((xp) => new XpInfo(xp)); + this.xpInfo = item.XPInfo.map((xp) => new XpInfo(xp, locale)); } } diff --git a/src/LoadOutItem.js b/src/LoadOutItem.js index 87e43e4..a1317a5 100644 --- a/src/LoadOutItem.js +++ b/src/LoadOutItem.js @@ -1,8 +1,9 @@ -import { colors, find } from 'warframe-items/utilities'; +import { colors } from 'warframe-items/utilities'; import { parseDate, toTitleCase } from 'warframe-worldstate-data/utilities'; import ItemConfig from './ItemConfig.js'; import Polarity from './Polarity.js'; +import { find } from './Utils.js'; /** * An an item in LoadOutInventory @@ -12,8 +13,9 @@ export default class LoadOutItem { /** * * @param {Object} weapon The loadout item from LoadoutInventory + * @param {string} [locale='en'] The locale to return item in */ - constructor(weapon) { + constructor(weapon, locale = 'en') { /** * Item ID * @type {String} @@ -26,7 +28,7 @@ export default class LoadOutItem { */ this.uniqueName = weapon.ItemType; - const item = find.findItem(weapon.ItemType); + const item = find(weapon.ItemType, locale); if (item) { /** * Item in-game name diff --git a/src/Mission.js b/src/Mission.js index 27730bd..bf72da6 100644 --- a/src/Mission.js +++ b/src/Mission.js @@ -10,7 +10,7 @@ export default class Mission { * @param {Object} mission The mission data * @param {string} locale The locale to return in */ - constructor(mission, locale) { + constructor(mission, locale = 'en') { const uniqueName = mission.type || mission.Tag; /** diff --git a/src/OperatorLoadOuts.js b/src/OperatorLoadOuts.js index d8f9f24..f3bf101 100644 --- a/src/OperatorLoadOuts.js +++ b/src/OperatorLoadOuts.js @@ -1,7 +1,7 @@ import { colors } from 'warframe-items/utilities'; import Skin from './Skin.js'; -import mapToHex from './Util.js'; +import { mapToHex } from './Utils.js'; /** * Player's operator loadout diff --git a/src/Profile.js b/src/Profile.js index c7d5d34..c48f569 100644 --- a/src/Profile.js +++ b/src/Profile.js @@ -17,7 +17,7 @@ export default class Profile { * @param {Object} profile The profile data to parse * @param {string} locale The locale to return in where possible */ - constructor(profile, locale) { + constructor(profile, locale = 'en') { /** * Player's acount ID * @type {Stirng} @@ -40,7 +40,7 @@ export default class Profile { * Current loadout * @type {LoadOutInventory} */ - this.loadout = new LoadOutInventory(profile.LoadOutInventory); + this.loadout = new LoadOutInventory(profile.LoadOutInventory, locale); /** * Railjack and drifter Intrinsics diff --git a/src/ProfileParser.js b/src/ProfileParser.js index bd128b8..43ba811 100644 --- a/src/ProfileParser.js +++ b/src/ProfileParser.js @@ -13,7 +13,7 @@ export default class ProfileParser { * @param {Object} data The data returned by getProfile endpoint * @param {string} locale The locale to return where possible */ - constructor(data, locale) { + constructor(data, locale = 'en') { /** * Player's profile * @type {Profile} diff --git a/src/Skin.js b/src/Skin.js index 5de919f..32da470 100644 --- a/src/Skin.js +++ b/src/Skin.js @@ -1,4 +1,4 @@ -import { find } from 'warframe-items/utilities'; +import { find } from './Utils.js'; /** * A skin class @@ -8,15 +8,16 @@ export default class Skin { /** * * @param {Object} skin The skin data to parse + * @param {string} [locale='en'] The locale to return skin item in */ - constructor(skin) { + constructor(skin, locale = 'en') { /** * Unique name * @type {String} */ this.uniqueName = skin.ItemType; - const item = find.findItem(skin.ItemType); + const item = find(skin.ItemType, locale); /** * The Warframe item that matches the unique name */ diff --git a/src/Syndicate.js b/src/Syndicate.js index 0d42882..abf6f68 100644 --- a/src/Syndicate.js +++ b/src/Syndicate.js @@ -9,7 +9,7 @@ export default class Syndicate { * @param {Object} affiliation The syndicate data * @param {string} locale locale code */ - constructor(affiliation, locale) { + constructor(affiliation, locale = 'en') { // TODO: name is readable but still might want to clean them up // i.e "NewLokaSyndicate" can be "New Loka"" instead diff --git a/src/Util.js b/src/Util.js deleted file mode 100644 index 358ffeb..0000000 --- a/src/Util.js +++ /dev/null @@ -1,14 +0,0 @@ -/** @module */ - -/** - * Map base10 int colors to hex color strings - * @param {Record} colors color map - * @returns {Record} - */ -export default function mapToHex(colors) { - const hex = {}; - Object.entries(colors).forEach(([key, /** @type {undefined | number} */ value]) => { - hex[key] = Math.abs(value).toString(16).toUpperCase(); - }); - return hex; -} diff --git a/src/Utils.js b/src/Utils.js new file mode 100644 index 0000000..8c00771 --- /dev/null +++ b/src/Utils.js @@ -0,0 +1,64 @@ +import Items from 'warframe-items'; + +/** @module */ + +/** + * Map base10 int colors to hex color strings + * @param {Record} colors color map + * @returns {Record} + */ +export const mapToHex = (colors) => { + const hex = {}; + Object.entries(colors).forEach(([key, /** @type {undefined | number} */ value]) => { + hex[key] = Math.abs(value).toString(16).toUpperCase(); + }); + return hex; +}; + +const categories = [ + 'Skins', + 'Primary', + 'Secondary', + 'Melee', + 'Arch-Melee', + 'Arch-Gun', + 'Warframes', + 'Archwing', + 'Sentinels', + 'Pets', +]; + +/** + * Find an item by Item#uniqueName + * @param {string} name string with which to query + * @param {string} [locale='en'] locale to use for internationalization + * @returns {Item} + */ +export const find = (name, locale = 'en') => { + const items = new Items({ + category: categories, + i18n: locale, + i18nOnObject: true, + }); + + const item = items.find((i) => i.uniqueName === name); + + let itemClone = { ...item }; + if (locale !== 'en' && itemClone.i18n[locale] && itemClone.i18n[locale]) { + itemClone = { ...itemClone, ...itemClone.i18n[locale] }; + + if (itemClone.abilities) { + itemClone.abilities = itemClone.abilities.map((ability) => ({ + uniqueName: ability.abilityUniqueName || ability.uniqueName || undefined, + name: ability.abilityName || ability.name, + description: ability.abilityDescription || ability.description, + imageName: ability.imageName ?? undefined, + })); + } + + delete itemClone.i18n; + return itemClone; + } + + return item; +}; diff --git a/src/XpInfo.js b/src/XpInfo.js index 2a469f8..c7ad60c 100644 --- a/src/XpInfo.js +++ b/src/XpInfo.js @@ -1,4 +1,4 @@ -import { find } from 'warframe-items/utilities'; +import { find } from './Utils.js'; /** * An item that has contributed to a player's mastery rank @@ -8,8 +8,9 @@ export default class XpInfo { /** * * @param {Object} info The info for a given ranked item + * @param {string} locale langauge to return item in */ - constructor(info) { + constructor(info, locale = 'en') { /** * Unique name * @type {String} @@ -26,6 +27,6 @@ export default class XpInfo { * The item corrosponding to the unique name. * @type {module:"warframe-items".Item | undefined} */ - this.item = find.findItem(info.ItemType); + this.item = find(info.ItemType, locale); } } diff --git a/test/unit/archonCrystal.spec.js b/test/unit/archonCrystal.spec.js index 27e92cf..a80e3ec 100644 --- a/test/unit/archonCrystal.spec.js +++ b/test/unit/archonCrystal.spec.js @@ -11,7 +11,7 @@ describe('ArchonShard', () => { UpgradeType: '/Lotus/Upgrades/Invigorations/ArchonCrystalUpgrades/ArchonCrystalUpgradeWarframeArmourMaxMythic', }; - const shard = new ArchonCrystal(shardData, 'en'); + const shard = new ArchonCrystal(shardData); assert.strictEqual(shard.color, 'Tauforged Azure'); assert.strictEqual(shard.modifier, '+225 Armor'); diff --git a/test/unit/mission.spec.js b/test/unit/mission.spec.js index b7c1363..51962d6 100644 --- a/test/unit/mission.spec.js +++ b/test/unit/mission.spec.js @@ -25,7 +25,7 @@ describe('Mission', () => { type: 'SolNode35', }; - const mission = new Mission(data, 'en'); + const mission = new Mission(data); assert.strictEqual(mission.node, 'Arcadia (Mars)'); assert.strictEqual(mission.nodeKey, data.type); diff --git a/test/unit/mock.spec.js b/test/unit/mock.spec.js index ca244c3..93d0ab0 100644 --- a/test/unit/mock.spec.js +++ b/test/unit/mock.spec.js @@ -11,8 +11,8 @@ describe('Mock ProfileParser', () => { it('should handle real data', function () { this.timeout(20000); - assert.isOk(new ProfileParser(ornstein, 'en')); - assert.isOk(new ProfileParser(tobiah, 'en')); + assert.isOk(new ProfileParser(ornstein)); + assert.isOk(new ProfileParser(tobiah)); }); }); }); diff --git a/test/unit/stats.spec.js b/test/unit/stats.spec.js index aeb7cb7..0feb3b4 100644 --- a/test/unit/stats.spec.js +++ b/test/unit/stats.spec.js @@ -11,8 +11,8 @@ describe('Mock ProfileParser', () => { it('should handle real data', function () { this.timeout(10000); - assert.isOk(new Stats(ornstein.Stats, 'en')); - assert.isOk(new Stats(tobiah.Stats, 'en')); + assert.isOk(new Stats(ornstein.Stats)); + assert.isOk(new Stats(tobiah.Stats)); }); }); }); diff --git a/test/unit/xpinfo.spec.js b/test/unit/xpinfo.spec.js index d0e78f4..ed22587 100644 --- a/test/unit/xpinfo.spec.js +++ b/test/unit/xpinfo.spec.js @@ -11,7 +11,7 @@ describe('XpInfo', () => { XP: 785691, }; - const xp = new XpInfo(data, 'en'); + const xp = new XpInfo(data); assert.strictEqual(xp.uniqueName, '/Lotus/Weapons/Grineer/LongGuns/GrineerAssaultRifle/TwinGrakatas'); assert.strictEqual(xp.item.name, 'Twin Grakatas');