warframe-worldstate-data 1.32.6 → 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/.nvmrc CHANGED
@@ -1 +1 @@
1
- lts/gallium
1
+ lts/hydrogen
package/README.md CHANGED
@@ -24,13 +24,19 @@ npm i -S git://github.com/wfcd/warframe-worldstate-data.git
24
24
  ## Usage
25
25
 
26
26
  ```javascript
27
- const worldstateData = require('warframe-worldstate-data');
27
+ import worldstateData from 'warframe-worldstate-data';
28
28
  const nodes = worldstateData.solNodes;
29
29
 
30
30
  const erpo = nodes['SolNode903'];
31
31
  const {enemy, value, type} = erpo;
32
32
  ```
33
33
 
34
+ ### Utilities
35
+ ```javascript
36
+ import utilities from 'warframe-worldstate-data/utilities';
37
+ const { getLanguage } = utilities;
38
+ ```
39
+
34
40
  ## Available data and formatting
35
41
 
36
42
  | JSON | Data Accessor | Description |
package/exports.js CHANGED
@@ -1,6 +1,4 @@
1
- 'use strict';
2
-
3
- const safeRequire = require('./safeRequire');
1
+ import safeImport from './safeImport.js';
4
2
 
5
3
  const locales = ['de', 'es', 'fr', 'it', 'ko', 'pl', 'pt', 'ru', 'zh', 'cs', 'sr', 'uk'];
6
4
 
@@ -36,6 +34,19 @@ const locales = ['de', 'es', 'fr', 'it', 'ko', 'pl', 'pt', 'ru', 'zh', 'cs', 'sr
36
34
  * @typedef {Object} Conclave
37
35
  */
38
36
 
37
+ /**
38
+ * Steel Path Offering
39
+ * @typedef {Object} SteelPathOffering
40
+ * @property {string} name The item being offered
41
+ * @property {string} cost The cost of the item
42
+ */
43
+ /**
44
+ * Steel Path
45
+ * @typedef {Object} SteelPath
46
+ * @property {Array<SteelPathOffering>} rotation A list of offerings for the Steel Path
47
+ * @property {Array<SteelPathOffering>} evergreen Constantly available list of items
48
+ */
49
+
39
50
  /**
40
51
  * Bundles all the data for a particular language
41
52
  * @typedef {Object} WorldstateLangBundle
@@ -57,70 +68,75 @@ const locales = ['de', 'es', 'fr', 'it', 'ko', 'pl', 'pt', 'ru', 'zh', 'cs', 'sr
57
68
  * @property {Object} upgradeTypes Global upgrade types that are modified by #operationTypes
58
69
  * @property {Array<SynthesisTarget>} synthTargets Synthesis target data for
59
70
  * optimal locations to find targets.
71
+ * @property {Object<string, Record<'name', string>>} syndicates Syndicate data
72
+ * @property {SteelPath} steelPath Steel Path mission type translations
60
73
  */
61
74
 
62
- /* eslint-disable global-require */
63
- /**
64
- * English United States translations bundle,
65
- * default translations
66
- * @type {WorldstateLangBundle}
67
- */
68
- const enUS = {
69
- arcanes: require('./data/arcanes.json'),
70
- conclave: require('./data/conclaveData.json'),
71
- events: require('./data/eventsData.json'),
72
- factions: require('./data/factionsData.json'),
73
- fissureModifiers: require('./data/fissureModifiers.json'),
74
- languages: require('./data/languages.json'),
75
- missionTypes: require('./data/missionTypes.json'),
76
- operationTypes: require('./data/operationTypes.json'),
77
- persistentEnemy: require('./data/persistentEnemyData.json'),
78
- solNodes: require('./data/solNodes.json'),
79
- sortie: require('./data/sortieData.json'),
80
- syndicates: require('./data/syndicatesData.json'),
81
- tutorials: require('./data/tutorials.json'),
82
- upgradeTypes: require('./data/upgradeTypes.json'),
83
- synthTargets: require('./data/synthTargets.json'),
84
- steelPath: require('./data/steelPath.json'),
85
- };
86
- /* eslint-enable global-require */
87
-
88
- const bundle = {
75
+ const makeBundle = async () => {
89
76
  /**
90
- * English United States translations
77
+ * English United States translations bundle,
78
+ * default translations
91
79
  * @type {WorldstateLangBundle}
92
80
  */
93
- en_US: enUS,
94
- en: enUS,
95
- ...enUS,
96
- locales,
97
- };
81
+ const enUS = {
82
+ arcanes: await safeImport('./data/arcanes.json'),
83
+ conclave: await safeImport('./data/conclaveData.json'),
84
+ events: await safeImport('./data/eventsData.json'),
85
+ factions: await safeImport('./data/factionsData.json'),
86
+ fissureModifiers: await safeImport('./data/fissureModifiers.json'),
87
+ languages: await safeImport('./data/languages.json'),
88
+ missionTypes: await safeImport('./data/missionTypes.json'),
89
+ operationTypes: await safeImport('./data/operationTypes.json'),
90
+ persistentEnemy: await safeImport('./data/persistentEnemyData.json'),
91
+ solNodes: await safeImport('./data/solNodes.json'),
92
+ sortie: await safeImport('./data/sortieData.json'),
93
+ syndicates: await safeImport('./data/syndicatesData.json'),
94
+ tutorials: await safeImport('./data/tutorials.json'),
95
+ upgradeTypes: await safeImport('./data/upgradeTypes.json'),
96
+ synthTargets: await safeImport('./data/synthTargets.json'),
97
+ steelPath: await safeImport('./data/steelPath.json'),
98
+ };
99
+ /* eslint-enable global-require */
98
100
 
99
- locales.forEach((locale) => {
100
- /**
101
- * Translations bundle for $locale
102
- * @type {WorldstateLangBundle}
103
- */
104
- bundle[locale] = {
105
- arcanes: safeRequire(`./data/${locale}/arcanes.json`, []),
106
- conclave: safeRequire(`./data/${locale}/conclaveData.json`, {}),
107
- events: safeRequire(`./data/${locale}/eventsData.json`, {}),
108
- factions: safeRequire(`./data/${locale}/factionsData.json`, {}),
109
- fissureModifiers: safeRequire(`./data/${locale}/fissureModifiers.json`, {}),
110
- languages: safeRequire(`./data/${locale}/languages.json`, {}),
111
- missionTypes: safeRequire(`./data/${locale}/missionTypes.json`, {}),
112
- operationTypes: safeRequire(`./data/${locale}/operationTypes.json`, {}),
113
- persistentEnemy: safeRequire(`./data/${locale}/persistentEnemyData.json`, {}),
114
- solNodes: safeRequire(`./data/${locale}/solNodes.json`, []),
115
- sortie: safeRequire(`./data/${locale}/sortieData.json`, []),
116
- syndicates: safeRequire(`./data/${locale}/syndicatesData.json`, []),
117
- tutorials: safeRequire(`./data/${locale}/tutorials.json`, []),
118
- upgradeTypes: safeRequire(`./data/${locale}/upgradeTypes.json`, []),
119
- synthTargets: safeRequire(`./data/${locale}/synthTargets.json`, []),
120
- steelPath: safeRequire(`./data/${locale}/steelPath.json`, []),
101
+ const bundle = {
102
+ /**
103
+ * English United States translations
104
+ * @type {WorldstateLangBundle}
105
+ */
106
+ en_US: enUS,
107
+ en: enUS,
108
+ ...enUS,
109
+ locales,
121
110
  };
122
- });
123
111
 
124
- locales.push('en');
112
+ // eslint-disable-next-line no-restricted-syntax
113
+ for await (const locale of locales) {
114
+ /**
115
+ * Translations bundle for $locale
116
+ * @type {WorldstateLangBundle}
117
+ */
118
+ bundle[locale] = {
119
+ arcanes: await safeImport(`./data/${locale}/arcanes.json`, enUS.arcanes),
120
+ conclave: await safeImport(`./data/${locale}/conclaveData.json`, enUS.conclave),
121
+ events: await safeImport(`./data/${locale}/eventsData.json`, enUS.events),
122
+ factions: await safeImport(`./data/${locale}/factionsData.json`, enUS.factions),
123
+ fissureModifiers: await safeImport(`./data/${locale}/fissureModifiers.json`, enUS.fissureModifiers),
124
+ languages: await safeImport(`./data/${locale}/languages.json`, enUS.languages),
125
+ missionTypes: await safeImport(`./data/${locale}/missionTypes.json`, enUS.missionTypes),
126
+ operationTypes: await safeImport(`./data/${locale}/operationTypes.json`, enUS.operationTypes),
127
+ persistentEnemy: await safeImport(`./data/${locale}/persistentEnemyData.json`, enUS.persistentEnemy),
128
+ solNodes: await safeImport(`./data/${locale}/solNodes.json`, enUS.solNodes),
129
+ sortie: await safeImport(`./data/${locale}/sortieData.json`, enUS.sortie),
130
+ syndicates: await safeImport(`./data/${locale}/syndicatesData.json`, enUS.syndicates),
131
+ tutorials: await safeImport(`./data/${locale}/tutorials.json`, enUS.tutorials),
132
+ upgradeTypes: await safeImport(`./data/${locale}/upgradeTypes.json`, enUS.upgradeTypes),
133
+ synthTargets: await safeImport(`./data/${locale}/synthTargets.json`, enUS.synthTargets),
134
+ steelPath: await safeImport(`./data/${locale}/steelPath.json`, enUS.steelPath),
135
+ };
136
+ }
137
+
138
+ locales.push('en');
139
+ return bundle;
140
+ };
125
141
 
126
- module.exports = bundle;
142
+ export default await makeBundle();
package/package.json CHANGED
@@ -1,32 +1,38 @@
1
1
  {
2
2
  "name": "warframe-worldstate-data",
3
- "version": "1.32.6",
3
+ "version": "2.0.1",
4
4
  "description": "Warframe data for use with warframe-worldstate-parser",
5
5
  "main": "exports.js",
6
+ "type": "module",
7
+ "exports": {
8
+ ".": "./exports.js",
9
+ "./utilities": "./tools/utilities.js"
10
+ },
6
11
  "directories": {
7
12
  "test": "test"
8
13
  },
9
14
  "devDependencies": {
10
- "chai": "^4.2.0",
15
+ "@types/chai": "^4.3.11",
16
+ "@types/chai-json-schema": "^1.4.9",
17
+ "c8": "^9.1.0",
18
+ "chai": "^5.0.3",
11
19
  "chai-json": "^1.0.0",
12
- "chai-json-schema": "^1.5.1",
13
- "coveralls": "^3.1.0",
14
- "eslint": "^6.8.0",
15
- "eslint-config-airbnb-base": "^14.0.0",
16
- "eslint-plugin-import": "^2.18.2",
17
- "mocha": "^10.2.0",
18
- "nyc": "^15.1.0",
20
+ "chai-json-schema-ajv": "^5.2.4",
21
+ "coveralls": "^3.1.1",
22
+ "install-peerdeps": "^3.0.3",
23
+ "mocha": "^10.3.0",
19
24
  "precommit-hook": "^3.0.0",
20
- "sinon": "^8.1.1",
21
- "sinon-chai": "^3.4.0"
25
+ "sinon": "^17.0.1",
26
+ "sinon-chai": "^3.7.0"
22
27
  },
23
28
  "scripts": {
24
29
  "lint": "eslint --ignore-path .gitignore .",
25
30
  "lint:fix": "eslint --ignore-path .gitignore . --fix",
26
- "test": "nyc mocha",
27
- "coverage": "npm test && nyc report --reporter=text-lcov | coveralls",
28
- "sort": "python tools/sort_languages.py",
29
- "validate": "npm run lint:fix && npm run test && git add -u ."
31
+ "test": "c8 mocha",
32
+ "coverage": "npm test && c8 report --reporter=text-lcov | coveralls",
33
+ "sort": "node tools/sort_languages.py",
34
+ "validate": "npm run lint:fix && npm run test && git add -u .",
35
+ "postinstall": "install-peerdeps @wfcd/eslint-config@^1.5.0 -S"
30
36
  },
31
37
  "repository": {
32
38
  "type": "git",
@@ -67,47 +73,34 @@
67
73
  "branch": "master"
68
74
  },
69
75
  "engines": {
70
- "node": ">=8.17.0"
76
+ "node": ">=18.19.0"
71
77
  },
72
- "eslintIgnore": [],
78
+ "eslintIgnore": [
79
+ ".github/**",
80
+ "docs/**",
81
+ "data/**"
82
+ ],
73
83
  "eslintConfig": {
74
- "extends": "airbnb-base",
84
+ "extends": "@wfcd/eslint-config/esm",
85
+ "parser": "@babel/eslint-parser",
75
86
  "parserOptions": {
76
- "sourceType": "script"
77
- },
78
- "rules": {
79
- "valid-jsdoc": [
80
- "error",
81
- {
82
- "requireReturn": false,
83
- "requireReturnDescription": false,
84
- "preferType": {
85
- "String": "string",
86
- "Number": "number",
87
- "Boolean": "boolean",
88
- "Function": "function",
89
- "object": "Object",
90
- "date": "Date",
91
- "error": "Error"
92
- },
93
- "prefer": {
94
- "return": "returns"
95
- }
96
- }
97
- ],
98
- "strict": [
99
- "error",
100
- "safe"
101
- ],
102
- "linebreak-style": "off",
103
- "no-restricted-syntax": [
104
- "off"
105
- ],
106
- "no-await-in-loop": "off",
107
- "import/no-unresolved": 0
87
+ "sourceType": "module",
88
+ "ecmaVersion": 6,
89
+ "ecmaFeatures": {
90
+ "modules": true
91
+ }
108
92
  }
109
93
  },
110
- "nyc": {
94
+ "babel": {
95
+ "presets": [
96
+ "@babel/preset-env"
97
+ ],
98
+ "plugins": [
99
+ "@babel/plugin-proposal-class-properties",
100
+ "@babel/plugin-proposal-private-methods"
101
+ ]
102
+ },
103
+ "c8": {
111
104
  "exclude": [
112
105
  "test/**"
113
106
  ],
@@ -117,7 +110,10 @@
117
110
  ],
118
111
  "skip-full": true
119
112
  },
120
- "mocha": {},
113
+ "mocha": {
114
+ "spec": "test/**/*.spec.js"
115
+ },
116
+ "prettier": "@wfcd/eslint-config/prettier",
121
117
  "pre-commit": [
122
118
  "validate"
123
119
  ]
package/safeImport.js ADDED
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Safely require path, fall back to fallback if module cannot load
3
+ * @param {string} path Path to attempt to load
4
+ * @param {Object} fallback fallback response if error or no module
5
+ * @returns {Promise<any>} module or the default object
6
+ */
7
+ const safeImport = async (path, fallback = {}) => {
8
+ try {
9
+ const mod = await import(path, path.includes('.json') ? { assert: { type: 'json' } } : {});
10
+ if (mod?.default) return mod.default;
11
+ return mod;
12
+ } catch (error) {
13
+ if ((process.env.LOG_LEVEL || 'ERROR').toUpperCase() === 'DEBUG') {
14
+ // eslint-disable-next-line no-console
15
+ console.debug(`Failed to load module at ${path} ... returning fallback`);
16
+ }
17
+ return fallback;
18
+ }
19
+ };
20
+
21
+ export default safeImport;
@@ -0,0 +1,15 @@
1
+ /**
2
+ * @description Insist that the provided data has the required properties.
3
+ * @param {Object} thing to encourage to have data
4
+ * @param {string[]} args arguments to ensure
5
+ */
6
+ /* eslint-disable-line import/prefer-default-export */ export const insist = (thing, ...args) => {
7
+ if (!thing || !Object.keys(thing).length) {
8
+ throw new TypeError(`The provided data does not have the required properties.`);
9
+ }
10
+ args.forEach((arg) => {
11
+ if (!thing[arg]) {
12
+ throw new TypeError(`The provided data does not have the required properties.`);
13
+ }
14
+ });
15
+ };
@@ -0,0 +1,89 @@
1
+ const epochZero = {
2
+ $date: {
3
+ $numberLong: 0,
4
+ },
5
+ };
6
+
7
+ const pieceIsSmoller = (seconds, ceiling, label, timePieces) => {
8
+ if (seconds >= ceiling) {
9
+ timePieces.push(`${Math.floor(seconds / ceiling)}${label}`);
10
+ seconds = Math.floor(seconds) % ceiling;
11
+ }
12
+ return { seconds, timePieces };
13
+ };
14
+
15
+ /**
16
+ * @param {number} millis The number of milliseconds in the time delta
17
+ * @returns {string} formatted time delta
18
+ */
19
+ export const timeDeltaToString = (millis) => {
20
+ if (typeof millis !== 'number') {
21
+ throw new TypeError('millis should be a number');
22
+ }
23
+
24
+ let timePieces = [];
25
+ const prefix = millis < 0 ? '-' : '';
26
+ let seconds = Math.abs(millis / 1000);
27
+
28
+ // Seconds in a day
29
+ ({ seconds, timePieces } = pieceIsSmoller(seconds, 86400, 'd', timePieces));
30
+
31
+ // Seconds in an hour
32
+ ({ seconds, timePieces } = pieceIsSmoller(seconds, 3600, 'h', timePieces));
33
+
34
+ // Seconds in a minute
35
+ ({ seconds, timePieces } = pieceIsSmoller(seconds, 60, 'm', timePieces));
36
+
37
+ /* istanbul ignore else */
38
+ if (seconds >= 0) {
39
+ timePieces.push(`${Math.floor(seconds)}s`);
40
+ }
41
+ return `${prefix}${timePieces.join(' ')}`;
42
+ };
43
+
44
+ /**
45
+ * Returns the number of milliseconds between now and a given date
46
+ * @param {Date} d The date from which the current time will be subtracted
47
+ * @param {function} [now] A function that returns the current UNIX time in milliseconds
48
+ * @returns {number} The number of milliseconds after the given date to now
49
+ */
50
+ export const fromNow = (d, now = Date.now) => {
51
+ return d.getTime() - now();
52
+ };
53
+
54
+ /**
55
+ * Returns the number of milliseconds between a given date and now
56
+ * @param {Date} d The date that the current time will be subtracted from
57
+ * @param {function} [now] A function that returns the current UNIX time in milliseconds
58
+ * @returns {number} The number of milliseconds after now to the given date
59
+ */
60
+ export const toNow = (d, now = Date.now) => {
61
+ return now() - d.getTime();
62
+ };
63
+
64
+ /**
65
+ * Returns a new Date constructed from a worldState date object
66
+ * @param {Object} d The worldState date object
67
+ * @returns {Date} parsed date from DE date format
68
+ */
69
+ export const parseDate = (d) => {
70
+ const safeD = d || epochZero;
71
+ const dt = safeD.$date || epochZero.$date;
72
+ return new Date(safeD.$date ? Number(dt.$numberLong) : 1000 * d.sec);
73
+ };
74
+
75
+ /**
76
+ * An object containing functions to format dates and times
77
+ * @typedef {Record<string, Function>} TimeDateFunctions
78
+ * @property {Function} timeDeltaToString - Converts a time difference to a string
79
+ * @property {Function} fromNow - Returns the number of milliseconds between now and
80
+ * a given date
81
+ * @property {Function} toNow - Returns the number of milliseconds between a given
82
+ * date and now
83
+ */
84
+ export default {
85
+ timeDeltaToString,
86
+ fromNow,
87
+ toNow,
88
+ parseDate,
89
+ };
@@ -0,0 +1,334 @@
1
+ import data from '../exports.js';
2
+
3
+ /**
4
+ * Rough Titlecase!
5
+ * @param {string} str string to be titlecased
6
+ * @returns {string} titlecased string
7
+ */
8
+ export const toTitleCase = (str) => {
9
+ return str.replace(/\w\S*/g, (txt) => txt.charAt(0).toUpperCase() + txt.substring(1).toLowerCase());
10
+ };
11
+
12
+ /**
13
+ * Utility function to split the resource name and return somewhat human-readable string
14
+ * @param {string} str localization resource key
15
+ * @returns {string} human-readable string
16
+ */
17
+ export const splitResourceName = (str) =>
18
+ str
19
+ .split(/([A-Z]?[^A-Z]*)/g)
20
+ .filter(Boolean)
21
+ .join(' ');
22
+
23
+ export const lastResourceName = (str) => (typeof str === 'string' ? str.split?.('/').slice?.(-1)[0] : str);
24
+
25
+ const i18n = (locale = 'en') => data[locale] || data;
26
+
27
+ const keyInData = (key, dataOverride) => (key in i18n(dataOverride) ? i18n(dataOverride)[key] : key);
28
+
29
+ /**
30
+ *
31
+ * @param {string} key - The data key
32
+ * @param {string} dataOverride locale for use with translation
33
+ * @returns {string} faction name
34
+ */
35
+ export const faction = (key, dataOverride = 'en') => keyInData('factions', dataOverride)[key]?.value ?? key;
36
+
37
+ const solNode = (key, thing, dataOverride = 'en') =>
38
+ keyInData('solNodes', dataOverride)?.[key]?.[thing] ?? lastResourceName(key) ?? key;
39
+
40
+ /**
41
+ *
42
+ * @param {string} key - The data key
43
+ * @param {string} dataOverride locale for use with translation
44
+ * @returns {string} node name
45
+ */
46
+ export const node = (key, dataOverride = 'en') => solNode(key, 'value', dataOverride);
47
+
48
+ /**
49
+ *
50
+ * @param {string} key - The data key
51
+ * @param {string} dataOverride locale for use with translation
52
+ * @returns {string} mission type of the node
53
+ */
54
+ export const nodeMissionType = (key, dataOverride = 'en') => solNode(key, 'type', dataOverride);
55
+ /**
56
+ *
57
+ * @param {string} key - The data key
58
+ * @param {string} dataOverride locale for use with translation
59
+ * @returns {string} faction that controls the node
60
+ */
61
+ export const nodeEnemy = (key, dataOverride = 'en') => {
62
+ return key in i18n(dataOverride).solNodes ? i18n(dataOverride).solNodes[key].enemy : lastResourceName(key) ?? key;
63
+ };
64
+
65
+ /**
66
+ *
67
+ * @param {string} key - The data key
68
+ * @param {string} dataOverride locale for use with translation
69
+ * @returns {string} localization for language string
70
+ */
71
+ export const languageString = (key, dataOverride = 'en') => {
72
+ const lowerKey = String(key).toLowerCase();
73
+ return (
74
+ keyInData('languages', dataOverride)[lowerKey]?.value ??
75
+ keyInData('languages', dataOverride)[key]?.value ??
76
+ toTitleCase(splitResourceName(lastResourceName(String(key)))) ??
77
+ key
78
+ );
79
+ };
80
+
81
+ /**
82
+ *
83
+ * @param {string} key - The data key
84
+ * @param {string} dataOverride locale for use with translation
85
+ * @returns {string} localization for language description
86
+ */
87
+ export const languageDesc = (key, dataOverride = 'en') => {
88
+ const lowerKey = String(key).toLowerCase();
89
+ return (
90
+ i18n(dataOverride).languages[lowerKey]?.desc ??
91
+ i18n(dataOverride).languages[key]?.desc ??
92
+ (key ? `[PH] ${toTitleCase(splitResourceName(lastResourceName(String(key))))} Desc` : key)
93
+ );
94
+ };
95
+
96
+ /**
97
+ *
98
+ * @param {string} key - The data key
99
+ * @param {string} dataOverride locale for use with translation
100
+ * @returns {string} translation for mission type
101
+ */
102
+ export const missionType = (key, dataOverride = 'en') => {
103
+ const keyBased = key && typeof key === 'string' && toTitleCase((key ?? '').replace(/^MT_/, ''));
104
+ return key in i18n(dataOverride).missionTypes ? i18n(dataOverride).missionTypes[key].value : keyBased;
105
+ };
106
+
107
+ const conclave = (key, thing, dataOverride = 'en') => keyInData('conclave', dataOverride)?.[thing]?.[key]?.value ?? key;
108
+
109
+ /**
110
+ *
111
+ * @param {string} key - The data key
112
+ * @param {string} dataOverride locale for use with translation
113
+ * @returns {string} conclave mode
114
+ */
115
+ export const conclaveMode = (key, dataOverride = 'en') => conclave(key, 'modes', dataOverride);
116
+
117
+ /**
118
+ *
119
+ * @param {string} key - The data key
120
+ * @param {string} dataOverride locale for use with translation
121
+ * @returns {string} conclave category
122
+ */
123
+ export const conclaveCategory = (key, dataOverride = 'en') => conclave(key, 'categories', dataOverride);
124
+
125
+ const fissure = (key, dataOverride = 'en') => keyInData('fissureModifiers', dataOverride)?.[key] ?? key;
126
+
127
+ /**
128
+ *
129
+ * @param {string} key - The data key
130
+ * @param {string} dataOverride locale for use with translation
131
+ * @returns {string} fissure modifier data
132
+ */
133
+ export const fissureModifier = (key, dataOverride = 'en') => fissure(key, dataOverride)?.value ?? key;
134
+
135
+ /**
136
+ *
137
+ * @param {string} key - The data key
138
+ * @param {string} dataOverride locale for use with translation
139
+ * @returns {number | string} fissure tier
140
+ */
141
+ export const fissureTier = (key, dataOverride = 'en') => fissure(key, dataOverride).num ?? key;
142
+
143
+ /**
144
+ *
145
+ * @param {string} key - The data key
146
+ * @param {string} dataOverride locale for use with translation
147
+ * @returns {string} syndicate name
148
+ */
149
+ export const syndicate = (key, dataOverride = 'en') => i18n(dataOverride).syndicates[key]?.value ?? key;
150
+
151
+ /**
152
+ *
153
+ * @param {string} key - The data key
154
+ * @param {string} dataOverride locale for use with translation
155
+ * @returns {string} upgrade type
156
+ */
157
+ export const upgrade = (key, dataOverride = 'en') => i18n(dataOverride).upgradeTypes[key]?.value ?? key;
158
+
159
+ const oppo = (key, dataOverride = 'en') => i18n(dataOverride).operationTypes[key];
160
+
161
+ /**
162
+ *
163
+ * @param {string} key - The data key
164
+ * @param {string} dataOverride locale for use with translation
165
+ * @returns {string} mathematical operation value
166
+ */
167
+ export const operation = (key, dataOverride = 'en') => oppo(key, dataOverride)?.value ?? key;
168
+
169
+ /**
170
+ *
171
+ * @param {string} key - The data key
172
+ * @param {string} dataOverride locale for use with translation
173
+ * @returns {string} symbol of mathematical operation
174
+ */
175
+ export const operationSymbol = (key, dataOverride = 'en') => oppo(key, dataOverride)?.symbol ?? key;
176
+
177
+ const sortie = (key, dataOverride = 'en') => i18n(dataOverride).sortie.bosses[key];
178
+
179
+ /**
180
+ * @param {string} key - The data key
181
+ * @param {string} dataOverride locale for use with translation
182
+ * @returns {string} sortie boss name
183
+ */
184
+ export const sortieBoss = (key, dataOverride = 'en') => sortie(key, dataOverride)?.name ?? key;
185
+
186
+ /**
187
+ * @param {string} key - The data key
188
+ * @param {string} dataOverride locale for use with translation
189
+ * @returns {string} faction for a sortie based on the boss
190
+ */
191
+ export const sortieFaction = (key, dataOverride = 'en') => sortie(key, dataOverride)?.faction ?? key;
192
+
193
+ /**
194
+ *
195
+ * @param {string} key - The data key
196
+ * @param {string} dataOverride locale for use with translation
197
+ * @returns {string} sortie modifier data
198
+ */
199
+ export const sortieModifier = (key, dataOverride = 'en') => i18n(dataOverride).sortie.modifierTypes?.[key] ?? key;
200
+
201
+ /**
202
+ * @param {string} key - The data key
203
+ * @param {string} dataOverride locale for use with translation
204
+ * @returns {string} sortie modifier description
205
+ */
206
+ export const sortieModDesc = (key, dataOverride = 'en') => i18n(dataOverride).sortie.modifierDescriptions?.[key] ?? key;
207
+
208
+ /**
209
+ * Retrieve the localized region for a given key
210
+ * @param {string | number} key - The region key
211
+ * @param {string} dataOverride - The locale to use for translations
212
+ * @returns {string} localized region name
213
+ */
214
+ export const region = (key, dataOverride = 'en') => (key && i18n(dataOverride).persistentEnemy?.regions[key]) ?? key;
215
+
216
+ /**
217
+ * Retrieve conclave challenge name for the given key and locale
218
+ * @param {string} key key to retrieve
219
+ * @param {string} dataOverride locale key override
220
+ * @returns {string} - The conclave challenge name for the given key
221
+ */
222
+ export const conclaveChallenge = (key, dataOverride = 'en') => {
223
+ const splitKey = lastResourceName(String(key));
224
+
225
+ if (i18n(dataOverride).conclave?.challenges?.[splitKey]) {
226
+ return i18n(dataOverride).conclave.challenges[splitKey];
227
+ }
228
+ return {
229
+ title: toTitleCase(splitResourceName(splitKey)),
230
+ description: toTitleCase(splitResourceName(splitKey)),
231
+ standing: 0,
232
+ };
233
+ };
234
+
235
+ /**
236
+ * Get the steel path data for given key
237
+ * @param {string} dataOverride - The locale to use for translations
238
+ * @returns {string} - The steel path data for the given key
239
+ */
240
+ export const steelPath = (dataOverride = 'en') => (i18n(dataOverride) || /* istanbul ignore next */ data).steelPath;
241
+
242
+ const valMapping = (key, map) => {
243
+ let val = 'None';
244
+ Object.keys(map).forEach((k) => {
245
+ if (key.includes(k)) {
246
+ val = map[k];
247
+ }
248
+ });
249
+ return val;
250
+ };
251
+
252
+ const focusMap = {
253
+ 'Focus/Attack': 'Madurai',
254
+ 'Focus/Defense': 'Varazin',
255
+ 'Focus/Tactic': 'Naramon',
256
+ 'Focus/Power': 'Zenurik',
257
+ 'Focus/Ward': 'Unairu',
258
+ };
259
+ /**
260
+ * Translate the given focus school
261
+ * @param {string} focus The focus school to translate
262
+ * @returns {string} The translated focus school
263
+ */
264
+ export const translateFocus = (focus = '') => valMapping(focus, focusMap);
265
+
266
+ const polarityMap = {
267
+ AP_ATTACK: 'Madurai',
268
+ AP_DEFENSE: 'Varazin',
269
+ AP_TACTIC: 'Naramon',
270
+ AP_POWER: 'Zenurik',
271
+ AP_WARD: 'Unairu',
272
+ };
273
+
274
+ /**
275
+ * Translate the given polarity
276
+ * @param {string?} pol The polarity to translate
277
+ * @returns {string} The translated polarity
278
+ */
279
+ export const translatePolarity = (pol = '') => valMapping(pol, polarityMap);
280
+
281
+ /**
282
+ * An object containing functions to convert in-game names to their localizations
283
+ * @typedef {Record<string, function>} Translator
284
+ * @property {function} faction - Converts faction names
285
+ * @property {function} node - Converts star map node names
286
+ * @property {function} nodeMissionType - Returns the mission type of given node
287
+ * @property {function} nodeEnemy - Returns the faction that controls a given node
288
+ * @property {function} languageString - Converts generic language strings
289
+ * @property {function} languageDesc - Converts generic language strings
290
+ * and retrieves the description
291
+ * @property {function} missionType - Converts mission types
292
+ * @property {function} conclaveMode - Converts conclave modes
293
+ * @property {function} conclaveCategory - Converts conclave challenge categories
294
+ * @property {function} fissureModifier - Converts fissure mission modifiers
295
+ * @property {function} syndicate - Converts syndicate names
296
+ * @property {function} upgrade - Converts upgrade types
297
+ * @property {function} operation - Converts operation types
298
+ * @property {function} sortieBoss - Converts sortie boss names
299
+ * @property {function} sortieModifier - Converts sortie modifier types
300
+ * @property {function} sortieModDesc - Converts sortie modifier type descriptions
301
+ * @property {function} region - Converts persistent enemy region indicies
302
+ * @property {function} conclaveChallenge - Convert conclave identifiers into standing data
303
+ * @property {function} steelPath - Retrieve Steel Path rotation data for locale
304
+ * @property {function} toTitleCase - Format provided string as titlecase
305
+ * @property {function} translateFocus - Translate focus schools
306
+ * @property {function} translatePolarity - Translate polarities
307
+ */
308
+ export default {
309
+ faction,
310
+ node,
311
+ nodeMissionType,
312
+ nodeEnemy,
313
+ languageString,
314
+ languageDesc,
315
+ missionType,
316
+ conclaveMode,
317
+ conclaveCategory,
318
+ fissureModifier,
319
+ fissureTier,
320
+ syndicate,
321
+ upgrade,
322
+ operation,
323
+ operationSymbol,
324
+ sortieBoss,
325
+ sortieModifier,
326
+ sortieModDesc,
327
+ sortieFaction,
328
+ region,
329
+ conclaveChallenge,
330
+ steelPath,
331
+ toTitleCase,
332
+ translateFocus,
333
+ translatePolarity,
334
+ };
@@ -0,0 +1,3 @@
1
+ export * from './integrity.js';
2
+ export * from './timeDate.js';
3
+ export * from './translation.js';
package/safeRequire.js DELETED
@@ -1,22 +0,0 @@
1
- 'use strict';
2
-
3
- /**
4
- * Safely require path, fall back to fallback if module cannot loa
5
- * @param {[type]} path Path to attempt to load
6
- * @param {[type]} fallback [description]
7
- * @returns {any} module or the default object
8
- */
9
- const safeRequire = (path, fallback = {}) => {
10
- try {
11
- // eslint-disable-next-line global-require, import/no-dynamic-require
12
- return require(path);
13
- } catch (error) {
14
- if ((process.env.LOG_LEVEL || 'ERROR').toUpperCase() === 'DEBUG') {
15
- // eslint-disable-next-line no-console
16
- console.debug(`Failed to load module at ${path} ... returning fallback`);
17
- }
18
- return fallback;
19
- }
20
- };
21
-
22
- module.exports = safeRequire;