mirror of
https://github.com/HabitRPG/habitica.git
synced 2025-12-17 22:57:21 +01:00
Upgrade lodash to v4 and lint more files (#8495)
* common: import lodash modules separately * remove test/content from .eslintignore, fix with eslint --fix content/index * lint test/content * lint content/index except for lodash methods * upgrade server/models * upgrade server/middlewares and server/libs * port server/controllers/top-level * port server/controllers/api-v3 * port views and tests * client old port lodash and _(, missing _. * upgrade client-old * port common/script (root level files only) * port common/script/fns * port common/libs * port common/script/ops * port common/script/content and common/script/libs/shops.js * misc fixes * misc fixes * misc fixes * more tests fixes * fix payments test stubbing, down to 2 failing tests * remove more instances of lodash wrapping * fix bug where toObject does not clone object * fix tests * upgrade migration or add lodash 4 note * update shrinkwrap * fix linting * upgrade eslint-config-habitrpg * update shrinkwrap * recompile shrinkwrap
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import content from '../content/index';
|
||||
import i18n from '../i18n';
|
||||
import { get } from 'lodash';
|
||||
import get from 'lodash/get';
|
||||
|
||||
let achievs = {};
|
||||
let achievsContent = content.achievements;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import _ from 'lodash';
|
||||
import get from 'lodash/get';
|
||||
|
||||
// TODO remove completely, only used in client
|
||||
|
||||
module.exports = _.get;
|
||||
module.exports = get;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import _ from 'lodash';
|
||||
import set from 'lodash/set';
|
||||
|
||||
// TODO remove completely, only used in client
|
||||
|
||||
module.exports = _.set;
|
||||
module.exports = set;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import _ from 'lodash';
|
||||
import isEmpty from 'lodash/isEmpty';
|
||||
import filter from 'lodash/filter';
|
||||
|
||||
/*
|
||||
are any tags active?
|
||||
@@ -7,7 +8,7 @@ are any tags active?
|
||||
// TODO move to client
|
||||
|
||||
module.exports = function noTags (tags) {
|
||||
return _.isEmpty(tags) || _.isEmpty(_.filter(tags, (t) => {
|
||||
return isEmpty(tags) || isEmpty(filter(tags, (t) => {
|
||||
return t;
|
||||
}));
|
||||
};
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
// An utility to pick deep properties from an object.
|
||||
// Works like _.pick but supports nested props (ie pickDeep(obj, ['deep.property']))
|
||||
|
||||
import _ from 'lodash';
|
||||
import each from 'lodash/each';
|
||||
import set from 'lodash/set';
|
||||
import get from 'lodash/get';
|
||||
|
||||
module.exports = function pickDeep (obj, properties) {
|
||||
if (!_.isArray(properties)) throw new Error('"properties" must be an array');
|
||||
if (!Array.isArray(properties)) throw new Error('"properties" must be an array');
|
||||
|
||||
let result = {};
|
||||
_.each(properties, (prop) => _.set(result, prop, _.get(obj, prop)));
|
||||
each(properties, (prop) => set(result, prop, get(obj, prop)));
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import moment from 'moment';
|
||||
import _ from 'lodash';
|
||||
import filter from 'lodash/filter';
|
||||
|
||||
// TODO used only in v2
|
||||
|
||||
module.exports = function preenTodos (tasks) {
|
||||
return _.filter(tasks, (t) => {
|
||||
return filter(tasks, (t) => {
|
||||
return !t.completed || t.challenge && t.challenge.id || moment(t.dateCompleted).isAfter(moment().subtract({
|
||||
days: 3,
|
||||
}));
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import _ from 'lodash';
|
||||
import values from 'lodash/values';
|
||||
import keys from 'lodash/keys';
|
||||
|
||||
function trueRandom () {
|
||||
return Math.random();
|
||||
@@ -7,7 +8,7 @@ function trueRandom () {
|
||||
// Get a random property from an object
|
||||
// returns random property (the value)
|
||||
module.exports = function randomVal (obj, options = {}) {
|
||||
let array = options.key ? _.keys(obj) : _.values(obj);
|
||||
let array = options.key ? keys(obj) : values(obj);
|
||||
let random = options.predictableRandom || trueRandom();
|
||||
|
||||
array.sort();
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
import _ from 'lodash';
|
||||
import isEmpty from 'lodash/isEmpty';
|
||||
import maxBy from 'lodash/maxBy';
|
||||
import values from 'lodash/values';
|
||||
import uuid from './uuid';
|
||||
|
||||
/*
|
||||
@@ -8,7 +10,7 @@ import uuid from './uuid';
|
||||
*/
|
||||
|
||||
module.exports = function refPush (reflist, item) {
|
||||
item.sort = _.isEmpty(reflist) ? 0 : _.max(reflist, 'sort').sort + 1;
|
||||
item.sort = isEmpty(reflist) ? 0 : maxBy(values(reflist), 'sort').sort + 1;
|
||||
|
||||
if (!(item.id && !reflist[item.id])) {
|
||||
item.id = uuid();
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
import _ from 'lodash';
|
||||
import pickBy from 'lodash.pickby'; // Not available in lodash 3
|
||||
import values from 'lodash/values';
|
||||
import map from 'lodash/map';
|
||||
import keys from 'lodash/keys';
|
||||
import each from 'lodash/each';
|
||||
import eachRight from 'lodash/eachRight';
|
||||
import toArray from 'lodash/toArray';
|
||||
import pickBy from 'lodash/pickBy';
|
||||
import sortBy from 'lodash/sortBy';
|
||||
import content from '../content/index';
|
||||
import i18n from '../i18n';
|
||||
|
||||
@@ -22,10 +28,9 @@ shops.getMarketCategories = function getMarket (user, language) {
|
||||
notes: i18n.t('dropsExplanation', language),
|
||||
};
|
||||
|
||||
eggsCategory.items = _(content.questEggs)
|
||||
.values()
|
||||
eggsCategory.items = sortBy(values(content.questEggs)
|
||||
.filter(egg => egg.canBuy(user))
|
||||
.concat(_.values(content.dropEggs))
|
||||
.concat(values(content.dropEggs))
|
||||
.map(egg => {
|
||||
return {
|
||||
key: egg.key,
|
||||
@@ -37,7 +42,7 @@ shops.getMarketCategories = function getMarket (user, language) {
|
||||
currency: 'gems',
|
||||
purchaseType: 'eggs',
|
||||
};
|
||||
}).sortBy('key').value();
|
||||
}), 'key');
|
||||
categories.push(eggsCategory);
|
||||
|
||||
let hatchingPotionsCategory = {
|
||||
@@ -45,8 +50,7 @@ shops.getMarketCategories = function getMarket (user, language) {
|
||||
text: i18n.t('hatchingPotions', language),
|
||||
notes: i18n.t('dropsExplanation', language),
|
||||
};
|
||||
hatchingPotionsCategory.items = _(content.hatchingPotions)
|
||||
.values()
|
||||
hatchingPotionsCategory.items = sortBy(values(content.hatchingPotions)
|
||||
.filter(hp => !hp.limited)
|
||||
.map(hatchingPotion => {
|
||||
return {
|
||||
@@ -59,7 +63,7 @@ shops.getMarketCategories = function getMarket (user, language) {
|
||||
currency: 'gems',
|
||||
purchaseType: 'hatchingPotions',
|
||||
};
|
||||
}).sortBy('key').value();
|
||||
}), 'key');
|
||||
categories.push(hatchingPotionsCategory);
|
||||
|
||||
let premiumHatchingPotionsCategory = {
|
||||
@@ -67,8 +71,7 @@ shops.getMarketCategories = function getMarket (user, language) {
|
||||
text: i18n.t('magicHatchingPotions', language),
|
||||
notes: i18n.t('premiumPotionNoDropExplanation', language),
|
||||
};
|
||||
premiumHatchingPotionsCategory.items = _(content.hatchingPotions)
|
||||
.values()
|
||||
premiumHatchingPotionsCategory.items = sortBy(values(content.hatchingPotions)
|
||||
.filter(hp => hp.limited && hp.canBuy())
|
||||
.map(premiumHatchingPotion => {
|
||||
return {
|
||||
@@ -81,7 +84,7 @@ shops.getMarketCategories = function getMarket (user, language) {
|
||||
currency: 'gems',
|
||||
purchaseType: 'hatchingPotions',
|
||||
};
|
||||
}).sortBy('key').value();
|
||||
}), 'key');
|
||||
categories.push(premiumHatchingPotionsCategory);
|
||||
|
||||
let foodCategory = {
|
||||
@@ -89,8 +92,7 @@ shops.getMarketCategories = function getMarket (user, language) {
|
||||
text: i18n.t('food', language),
|
||||
notes: i18n.t('dropsExplanation', language),
|
||||
};
|
||||
foodCategory.items = _(content.food)
|
||||
.values()
|
||||
foodCategory.items = sortBy(values(content.food)
|
||||
.filter(food => food.canDrop || food.key === 'Saddle')
|
||||
.map(foodItem => {
|
||||
return {
|
||||
@@ -103,7 +105,7 @@ shops.getMarketCategories = function getMarket (user, language) {
|
||||
currency: 'gems',
|
||||
purchaseType: 'food',
|
||||
};
|
||||
}).sortBy('key').value();
|
||||
}), 'key');
|
||||
categories.push(foodCategory);
|
||||
|
||||
return categories;
|
||||
@@ -112,13 +114,13 @@ shops.getMarketCategories = function getMarket (user, language) {
|
||||
shops.getQuestShopCategories = function getQuestShopCategories (user, language) {
|
||||
let categories = [];
|
||||
|
||||
_.each(content.userCanOwnQuestCategories, type => {
|
||||
each(content.userCanOwnQuestCategories, type => {
|
||||
let category = {
|
||||
identifier: type,
|
||||
text: i18n.t(`${type}Quests`, language),
|
||||
};
|
||||
|
||||
category.items = _(content.questsByLevel)
|
||||
category.items = content.questsByLevel
|
||||
.filter(quest => quest.canBuy(user) && quest.category === type)
|
||||
.map(quest => {
|
||||
let locked = lockQuest(quest, user);
|
||||
@@ -137,7 +139,7 @@ shops.getQuestShopCategories = function getQuestShopCategories (user, language)
|
||||
class: locked ? `inventory_quest_scroll_locked inventory_quest_scroll_${quest.key}_locked` : `inventory_quest_scroll inventory_quest_scroll_${quest.key}`,
|
||||
purchaseType: 'quests',
|
||||
};
|
||||
}).value();
|
||||
});
|
||||
|
||||
categories.push(category);
|
||||
});
|
||||
@@ -190,7 +192,7 @@ shops.getTimeTravelersCategories = function getTimeTravelersCategories (user, la
|
||||
purchaseAll: true,
|
||||
};
|
||||
|
||||
category.items = _.map(set.items, item => {
|
||||
category.items = map(set.items, item => {
|
||||
return {
|
||||
key: item.key,
|
||||
text: item.text(language),
|
||||
@@ -228,19 +230,19 @@ shops.getSeasonalShopCategories = function getSeasonalShopCategories (user, lang
|
||||
|
||||
let categories = [];
|
||||
|
||||
let flatGearArray = _.toArray(content.gear.flat);
|
||||
let flatGearArray = toArray(content.gear.flat);
|
||||
|
||||
let spells = pickBy(content.spells.special, (spell, key) => {
|
||||
return _.indexOf(AVAILABLE_SPELLS, key) !== -1;
|
||||
return AVAILABLE_SPELLS.indexOf(key) !== -1;
|
||||
});
|
||||
|
||||
if (_.keys(spells).length > 0) {
|
||||
if (keys(spells).length > 0) {
|
||||
let category = {
|
||||
identifier: 'spells',
|
||||
text: i18n.t('seasonalItems', language),
|
||||
};
|
||||
|
||||
category.items = _.map(spells, (spell, key) => {
|
||||
category.items = map(spells, (spell, key) => {
|
||||
return {
|
||||
key,
|
||||
text: spell.text(language),
|
||||
@@ -258,16 +260,16 @@ shops.getSeasonalShopCategories = function getSeasonalShopCategories (user, lang
|
||||
}
|
||||
|
||||
let quests = pickBy(content.quests, (quest, key) => {
|
||||
return _.indexOf(AVAILABLE_QUESTS, key) !== -1;
|
||||
return AVAILABLE_QUESTS.indexOf(key) !== -1;
|
||||
});
|
||||
|
||||
if (_.keys(quests).length > 0) {
|
||||
if (keys(quests).length > 0) {
|
||||
let category = {
|
||||
identifier: 'quests',
|
||||
text: i18n.t('quests', language),
|
||||
};
|
||||
|
||||
category.items = _.map(quests, (quest, key) => {
|
||||
category.items = map(quests, (quest, key) => {
|
||||
return {
|
||||
key,
|
||||
text: quest.text(language),
|
||||
@@ -294,12 +296,9 @@ shops.getSeasonalShopCategories = function getSeasonalShopCategories (user, lang
|
||||
text: AVAILABLE_SETS[key],
|
||||
};
|
||||
|
||||
category.items = _(flatGearArray).filter((gear) => {
|
||||
if (gear.index !== key) {
|
||||
return false;
|
||||
}
|
||||
return user.items.gear.owned[gear.key] === undefined;
|
||||
}).where({index: key}).map(gear => {
|
||||
category.items = flatGearArray.filter((gear) => {
|
||||
return user.items.gear.owned[gear.key] === undefined && gear.index === key;
|
||||
}).map(gear => {
|
||||
return {
|
||||
key: gear.key,
|
||||
text: gear.text(language),
|
||||
@@ -312,7 +311,8 @@ shops.getSeasonalShopCategories = function getSeasonalShopCategories (user, lang
|
||||
purchaseType: 'gear',
|
||||
class: `shop_${gear.key}`,
|
||||
};
|
||||
}).value();
|
||||
});
|
||||
|
||||
if (category.items.length > 0) {
|
||||
categories.push(category);
|
||||
}
|
||||
@@ -325,23 +325,22 @@ shops.getSeasonalShopCategories = function getSeasonalShopCategories (user, lang
|
||||
shops.getBackgroundShopSets = function getBackgroundShopSets (language) {
|
||||
let sets = [];
|
||||
|
||||
_.eachRight(content.backgrounds, (group, key) => {
|
||||
eachRight(content.backgrounds, (group, key) => {
|
||||
let set = {
|
||||
identifier: key,
|
||||
text: i18n.t(key, language),
|
||||
};
|
||||
|
||||
set.items = _(group)
|
||||
.map((background, bgKey) => {
|
||||
return {
|
||||
key: bgKey,
|
||||
text: background.text(language),
|
||||
notes: background.notes(language),
|
||||
value: background.price,
|
||||
currency: background.currency || 'gems',
|
||||
purchaseType: 'backgrounds',
|
||||
};
|
||||
}).value();
|
||||
set.items = map(group, (background, bgKey) => {
|
||||
return {
|
||||
key: bgKey,
|
||||
text: background.text(language),
|
||||
notes: background.notes(language),
|
||||
value: background.price,
|
||||
currency: background.currency || 'gems',
|
||||
purchaseType: 'backgrounds',
|
||||
};
|
||||
});
|
||||
|
||||
sets.push(set);
|
||||
});
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
import _ from 'lodash';
|
||||
import each from 'lodash/each';
|
||||
import get from 'lodash/get';
|
||||
import values from 'lodash/values';
|
||||
import content from '../content/index';
|
||||
import * as statHelpers from '../statHelpers';
|
||||
|
||||
@@ -11,9 +13,9 @@ function equipmentStatBonusComputed (stat, user) {
|
||||
// if toObject doesn't exist, we're on the client side and can assume the object is already plain JSON
|
||||
// see http://stackoverflow.com/questions/25767334/underscore-js-keys-and-omit-not-working-as-expected
|
||||
let equipped = user.items.gear.equipped;
|
||||
let equippedKeys = !equipped.toObject ? _.values(equipped) : _.values(equipped.toObject());
|
||||
let equippedKeys = values(!equipped.toObject ? equipped : equipped.toObject());
|
||||
|
||||
_.each(equippedKeys, (equippedItem) => {
|
||||
each(equippedKeys, (equippedItem) => {
|
||||
let equipmentStat = gear[equippedItem][stat];
|
||||
let classBonusMultiplier = gear[equippedItem].klass === user.stats.class ||
|
||||
gear[equippedItem].specialClass === user.stats.class ? 0.5 : 0;
|
||||
@@ -35,9 +37,9 @@ module.exports = function statsComputed (user) {
|
||||
buff: {},
|
||||
levelBonus: {},
|
||||
};
|
||||
_.each(['per', 'con', 'str', 'int'], (stat) => {
|
||||
let baseStat = _.get(user, 'stats')[stat];
|
||||
let buff = _.get(user, 'stats.buffs')[stat];
|
||||
each(['per', 'con', 'str', 'int'], (stat) => {
|
||||
let baseStat = get(user, 'stats')[stat];
|
||||
let buff = get(user, 'stats.buffs')[stat];
|
||||
let equipmentBonus = equipmentStatBonusComputed(stat, user);
|
||||
|
||||
statBreakdown[stat] = equipmentBonus.gearBonus + equipmentBonus.classBonus + baseStat + buff;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { v4 as uuid } from 'uuid';
|
||||
import _ from 'lodash';
|
||||
import defaults from 'lodash/defaults';
|
||||
import moment from 'moment';
|
||||
|
||||
// Even though Mongoose handles task defaults, we want to make sure defaults are set on the client-side before
|
||||
@@ -15,7 +15,7 @@ module.exports = function taskDefaults (task = {}) {
|
||||
}
|
||||
|
||||
let defaultId = uuid();
|
||||
let defaults = {
|
||||
let defaultTaskObj = {
|
||||
_id: defaultId,
|
||||
text: task._id || defaultId,
|
||||
notes: '',
|
||||
@@ -31,16 +31,16 @@ module.exports = function taskDefaults (task = {}) {
|
||||
updatedAt: new Date(),
|
||||
};
|
||||
|
||||
_.defaults(task, defaults);
|
||||
defaults(task, defaultTaskObj);
|
||||
|
||||
if (task.type === 'habit' || task.type === 'daily') {
|
||||
_.defaults(task, {
|
||||
defaults(task, {
|
||||
history: [],
|
||||
});
|
||||
}
|
||||
|
||||
if (task.type === 'todo' || task.type === 'daily') {
|
||||
_.defaults(task, {
|
||||
defaults(task, {
|
||||
completed: false,
|
||||
collapseChecklist: false,
|
||||
checklist: [],
|
||||
@@ -48,7 +48,7 @@ module.exports = function taskDefaults (task = {}) {
|
||||
}
|
||||
|
||||
if (task.type === 'habit') {
|
||||
_.defaults(task, {
|
||||
defaults(task, {
|
||||
up: true,
|
||||
down: true,
|
||||
frequency: 'daily',
|
||||
@@ -58,7 +58,7 @@ module.exports = function taskDefaults (task = {}) {
|
||||
}
|
||||
|
||||
if (task.type === 'daily') {
|
||||
_.defaults(task, {
|
||||
defaults(task, {
|
||||
streak: 0,
|
||||
repeat: {
|
||||
m: true,
|
||||
|
||||
@@ -1,9 +1,13 @@
|
||||
import _ from 'lodash';
|
||||
import each from 'lodash/each';
|
||||
import lodashFind from 'lodash/find';
|
||||
import filter from 'lodash/filter';
|
||||
import sortBy from 'lodash/sortBy';
|
||||
import reduce from 'lodash/reduce';
|
||||
import content from '../content/index';
|
||||
|
||||
// Return the list of gear items available for purchase
|
||||
|
||||
let sortOrder = _.reduce(content.gearTypes, (accumulator, val, key) => {
|
||||
let sortOrder = reduce(content.gearTypes, (accumulator, val, key) => {
|
||||
accumulator[val] = key;
|
||||
return accumulator;
|
||||
}, {});
|
||||
@@ -11,15 +15,15 @@ let sortOrder = _.reduce(content.gearTypes, (accumulator, val, key) => {
|
||||
module.exports = function updateStore (user) {
|
||||
let changes = [];
|
||||
|
||||
_.each(content.gearTypes, (type) => {
|
||||
let found = _.find(content.gear.tree[type][user.stats.class], (item) => {
|
||||
each(content.gearTypes, (type) => {
|
||||
let found = lodashFind(content.gear.tree[type][user.stats.class], (item) => {
|
||||
return !user.items.gear.owned[item.key];
|
||||
});
|
||||
|
||||
if (found) changes.push(found);
|
||||
});
|
||||
|
||||
changes = changes.concat(_.filter(content.gear.flat, (val) => {
|
||||
changes = changes.concat(filter(content.gear.flat, (val) => {
|
||||
if (['special', 'mystery', 'armoire'].indexOf(val.klass) !== -1 && !user.items.gear.owned[val.key] && (val.canOwn ? val.canOwn(user) : false)) {
|
||||
return true;
|
||||
} else {
|
||||
@@ -27,5 +31,5 @@ module.exports = function updateStore (user) {
|
||||
}
|
||||
}));
|
||||
|
||||
return _.sortBy(changes, (change) => sortOrder[change.type]);
|
||||
return sortBy(changes, (change) => sortOrder[change.type]);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user