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:
Matteo Pagliazzi 2017-03-01 17:10:48 +01:00 committed by GitHub
parent ef02e59590
commit 98c019a0b6
150 changed files with 4996 additions and 1533 deletions

View file

@ -8,16 +8,13 @@ dist/
dist-client/
# Not linted
migrations/*
website/client-old/
scripts/*
test/server_side/**/*
test/client-old/spec/**/*
# Temporarilly disabled. These should be removed when the linting errors are fixed TODO
website/common/script/content/index.js
migrations/*
scripts/*
website/common/browserify.js
test/content/**/*
Gruntfile.js
gulpfile.js
gulp

View file

@ -67,7 +67,7 @@ gulp.task('transifex:malformedStrings', () => {
let stringsWithIncorrectNumberOfInterpolations = [];
let count = 0;
_(ALL_LANGUAGES).each(function (lang) {
_.each(ALL_LANGUAGES, function (lang) {
_.each(stringsToLookFor, function (strings, file) {
let translationFile = fs.readFileSync(LOCALES + lang + '/' + file);
@ -89,7 +89,7 @@ gulp.task('transifex:malformedStrings', () => {
}
});
});
}).value();
});
if (!_.isEmpty(stringsWithMalformedInterpolations)) {
let message = 'The following strings have malformed or missing interpolations';
@ -114,7 +114,7 @@ function getArrayOfLanguages () {
function eachTranslationFile (languages, cb) {
let jsonFiles = stripOutNonJsonFiles(fs.readdirSync(ENGLISH_LOCALE));
_(languages).each((lang) => {
_.each(languages, (lang) => {
_.each(jsonFiles, (filename) => {
try {
var translationFile = fs.readFileSync(LOCALES + lang + '/' + filename);
@ -128,7 +128,7 @@ function eachTranslationFile (languages, cb) {
cb(null, lang, filename, parsedEnglishFile, parsedTranslationFile);
});
}).value();
});
}
function eachTranslationString (languages, cb) {
@ -153,7 +153,7 @@ function formatMessageForPosting (msg, items) {
function getStringsWith (json, interpolationRegex) {
var strings = {};
_(json).each(function (file_name) {
_.each(json, function (file_name) {
var raw_file = fs.readFileSync(ENGLISH_LOCALE + file_name);
var parsed_json = JSON.parse(raw_file);
@ -162,7 +162,7 @@ function getStringsWith (json, interpolationRegex) {
var match = value.match(interpolationRegex);
if (match) strings[file_name][key] = match;
});
}).value();
});
return strings;
}

View file

@ -1,5 +1,12 @@
// %mongo server:27017/dbname underscore.js my_commands.js
// %mongo server:27017/dbname underscore.js --shell
// IMPORTANT NOTE: this migration was written when we were using version 3 of lodash.
// We've now upgraded to lodash v4 but the code used in this migration has not been
// adapted to work with it. Before this migration is used again any lodash method should
// be checked for compatibility against the v4 changelog and changed if necessary.
// https://github.com/lodash/lodash/wiki/Changelog#v400
var habits = 0,
dailies = 0,
todos = 0,

View file

@ -3,6 +3,12 @@
*/
// mongo habitrpg ./node_modules/underscore/underscore.js ./migrations/20130326_migrate_pets.js
// IMPORTANT NOTE: this migration was written when we were using version 3 of lodash.
// We've now upgraded to lodash v4 but the code used in this migration has not been
// adapted to work with it. Before this migration is used again any lodash method should
// be checked for compatibility against the v4 changelog and changed if necessary.
// https://github.com/lodash/lodash/wiki/Changelog#v400
var mapping = {
bearcub: {name:'BearCub', modifier: 'Base'},
cactus: {name:'Cactus', modifier:'Base'},

View file

@ -4,6 +4,12 @@
// mongo habitrpg ./node_modules/underscore/underscore.js migrations/20130327_apply_tokens.js
// IMPORTANT NOTE: this migration was written when we were using version 3 of lodash.
// We've now upgraded to lodash v4 but the code used in this migration has not been
// adapted to work with it. Before this migration is used again any lodash method should
// be checked for compatibility against the v4 changelog and changed if necessary.
// https://github.com/lodash/lodash/wiki/Changelog#v400
var mapping = [
{
tier: 1,

View file

@ -6,6 +6,11 @@
* mongo habitrpg ./node_modules/underscore/underscore.js ./migrations/20130508_fix_duff_party_subscriptions.js
*/
// IMPORTANT NOTE: this migration was written when we were using version 3 of lodash.
// We've now upgraded to lodash v4 but the code used in this migration has not been
// adapted to work with it. Before this migration is used again any lodash method should
// be checked for compatibility against the v4 changelog and changed if necessary.
// https://github.com/lodash/lodash/wiki/Changelog#v400
// since our primary subscription will first hit parties now, we *definitely* need an index there
db.parties.ensureIndex( { 'members': 1}, {background: true} );

View file

@ -1,5 +1,11 @@
//mongo habitrpg ./node_modules/lodash/lodash.js migrations/20130602_survey_rewards.js
// IMPORTANT NOTE: this migration was written when we were using version 3 of lodash.
// We've now upgraded to lodash v4 but the code used in this migration has not been
// adapted to work with it. Before this migration is used again any lodash method should
// be checked for compatibility against the v4 changelog and changed if necessary.
// https://github.com/lodash/lodash/wiki/Changelog#v400
var members = []
members = _.uniq(members);

View file

@ -3,6 +3,12 @@
// Racer was notorious for adding duplicates, randomly deleting documents, etc. Once we pull the plug on old.habit,
// run this migration to cleanup all the corruption
// IMPORTANT NOTE: this migration was written when we were using version 3 of lodash.
// We've now upgraded to lodash v4 but the code used in this migration has not been
// adapted to work with it. Before this migration is used again any lodash method should
// be checked for compatibility against the v4 changelog and changed if necessary.
// https://github.com/lodash/lodash/wiki/Changelog#v400
db.users.find().forEach(function(user){
// remove corrupt tasks, which will either be null-value or no id

View file

@ -5,6 +5,12 @@
// @see http://stackoverflow.com/questions/14867697/mongoose-full-collection-scan
//Also, what do we think of a Mongoose Migration module? something like https://github.com/madhums/mongoose-migrate
// IMPORTANT NOTE: this migration was written when we were using version 3 of lodash.
// We've now upgraded to lodash v4 but the code used in this migration has not been
// adapted to work with it. Before this migration is used again any lodash method should
// be checked for compatibility against the v4 changelog and changed if necessary.
// https://github.com/lodash/lodash/wiki/Changelog#v400
db.users.find().forEach(function(user){
// Add invites to groups

View file

@ -8,6 +8,12 @@
var mongo = require('mongoskin');
var _ = require('lodash');
// IMPORTANT NOTE: this migration was written when we were using version 3 of lodash.
// We've now upgraded to lodash v4 but the code used in this migration has not been
// adapted to work with it. Before this migration is used again any lodash method should
// be checked for compatibility against the v4 changelog and changed if necessary.
// https://github.com/lodash/lodash/wiki/Changelog#v400
var backupUsers = mongo.db('localhost:27017/habitrpg_old?auto_reconnect').collection('users');
var liveUsers = mongo.db('localhost:27017/habitrpg_new?auto_reconnect').collection('users');

View file

@ -1,5 +1,11 @@
// node .migrations/20131127_restore_dayStart.js
// IMPORTANT NOTE: this migration was written when we were using version 3 of lodash.
// We've now upgraded to lodash v4 but the code used in this migration has not been
// adapted to work with it. Before this migration is used again any lodash method should
// be checked for compatibility against the v4 changelog and changed if necessary.
// https://github.com/lodash/lodash/wiki/Changelog#v400
var mongo = require('mongoskin');
var _ = require('lodash');

View file

@ -8,6 +8,12 @@ mongo = require('mongoskin')
_ = require('lodash')
async = require('async')
# IMPORTANT NOTE: this migration was written when we were using version 3 of lodash.
# We've now upgraded to lodash v4 but the code used in this migration has not been
# adapted to work with it. Before this migration is used again any lodash method should
# be checked for compatibility against the v4 changelog and changed if necessary.
# https://github.com/lodash/lodash/wiki/Changelog#v400
db = mongo.db('localhost:27017/habitrpg?auto_reconnect')
###

View file

@ -1,5 +1,11 @@
// node .migrations/20131221_restore_NaN_history.js
// IMPORTANT NOTE: this migration was written when we were using version 3 of lodash.
// We've now upgraded to lodash v4 but the code used in this migration has not been
// adapted to work with it. Before this migration is used again any lodash method should
// be checked for compatibility against the v4 changelog and changed if necessary.
// https://github.com/lodash/lodash/wiki/Changelog#v400
/**
* After the classes migration, users lost some history entries
*/

View file

@ -1,5 +1,11 @@
// node .migrations/20131225_restore_streaks.js
// IMPORTANT NOTE: this migration was written when we were using version 3 of lodash.
// We've now upgraded to lodash v4 but the code used in this migration has not been
// adapted to work with it. Before this migration is used again any lodash method should
// be checked for compatibility against the v4 changelog and changed if necessary.
// https://github.com/lodash/lodash/wiki/Changelog#v400
/**
* After the classes migration, users lost some history entries
*/

View file

@ -5,6 +5,12 @@ var migrationName = '20140823_remove_undefined_and_false_notifications';
var authorName = 'Alys'; // in case script author needs to know when their ...
var authorUuid = 'd904bd62-da08-416b-a816-ba797c9ee265'; //... own data is done
// IMPORTANT NOTE: this migration was written when we were using version 3 of lodash.
// We've now upgraded to lodash v4 but the code used in this migration has not been
// adapted to work with it. Before this migration is used again any lodash method should
// be checked for compatibility against the v4 changelog and changed if necessary.
// https://github.com/lodash/lodash/wiki/Changelog#v400
/**
* https://github.com/HabitRPG/habitrpg/pull/3907
*/

View file

@ -4,6 +4,12 @@ var migrationName = '20140829_change_headAccessory_to_eyewear';
var authorName = 'Alys'; // in case script author needs to know when their ...
var authorUuid = 'd904bd62-da08-416b-a816-ba797c9ee265'; //... own data is done
// IMPORTANT NOTE: this migration was written when we were using version 3 of lodash.
// We've now upgraded to lodash v4 but the code used in this migration has not been
// adapted to work with it. Before this migration is used again any lodash method should
// be checked for compatibility against the v4 changelog and changed if necessary.
// https://github.com/lodash/lodash/wiki/Changelog#v400
/**
* https://github.com/HabitRPG/habitrpg/issues/3645
*/

View file

@ -4,6 +4,11 @@
//
// node 20140831_increase_gems_for_previous_contributions.js > 20140831_increase_gems_for_previous_contributions_output.txt
// IMPORTANT NOTE: this migration was written when we were using version 3 of lodash.
// We've now upgraded to lodash v4 but the code used in this migration has not been
// adapted to work with it. Before this migration is used again any lodash method should
// be checked for compatibility against the v4 changelog and changed if necessary.
// https://github.com/lodash/lodash/wiki/Changelog#v400
var migrationName = '20140831_increase_gems_for_previous_contributions';

View file

@ -8,6 +8,12 @@ var authorUuid = 'd904bd62-da08-416b-a816-ba797c9ee265'; //... own data is done
* Convert Tier 7 contributors with admin flag to Tier 8 (moderators).
*/
// IMPORTANT NOTE: this migration was written when we were using version 3 of lodash.
// We've now upgraded to lodash v4 but the code used in this migration has not been
// adapted to work with it. Before this migration is used again any lodash method should
// be checked for compatibility against the v4 changelog and changed if necessary.
// https://github.com/lodash/lodash/wiki/Changelog#v400
var mongo = require('mongoskin');
var _ = require('lodash');

View file

@ -1,3 +1,9 @@
// IMPORTANT NOTE: this migration was written when we were using version 3 of lodash.
// We've now upgraded to lodash v4 but the code used in this migration has not been
// adapted to work with it. Before this migration is used again any lodash method should
// be checked for compatibility against the v4 changelog and changed if necessary.
// https://github.com/lodash/lodash/wiki/Changelog#v400
// require moment, lodash
db.users.find(
{'purchased.plan.customerId':{$ne:null}},

View file

@ -9,6 +9,12 @@ var authorUuid = 'd904bd62-da08-416b-a816-ba797c9ee265'; //... own data is done
var dbserver = 'localhost:27017' // CHANGE THIS FOR PRODUCTION DATABASE
// IMPORTANT NOTE: this migration was written when we were using version 3 of lodash.
// We've now upgraded to lodash v4 but the code used in this migration has not been
// adapted to work with it. Before this migration is used again any lodash method should
// be checked for compatibility against the v4 changelog and changed if necessary.
// https://github.com/lodash/lodash/wiki/Changelog#v400
var mongo = require('mongoskin');
var _ = require('lodash');

View file

@ -8,6 +8,12 @@ var authorUuid = 'd904bd62-da08-416b-a816-ba797c9ee265'; //... own data is done
var dbserver = 'localhost:27017' // CHANGE THIS FOR PRODUCTION DATABASE
// IMPORTANT NOTE: this migration was written when we were using version 3 of lodash.
// We've now upgraded to lodash v4 but the code used in this migration has not been
// adapted to work with it. Before this migration is used again any lodash method should
// be checked for compatibility against the v4 changelog and changed if necessary.
// https://github.com/lodash/lodash/wiki/Changelog#v400
var mongo = require('mongoskin');
var _ = require('lodash');

View file

@ -19,6 +19,12 @@ var authorUuid = 'd904bd62-da08-416b-a816-ba797c9ee265'; //... own data is done
var dbserver = 'localhost:27017' // CHANGE THIS FOR PRODUCTION DATABASE
// IMPORTANT NOTE: this migration was written when we were using version 3 of lodash.
// We've now upgraded to lodash v4 but the code used in this migration has not been
// adapted to work with it. Before this migration is used again any lodash method should
// be checked for compatibility against the v4 changelog and changed if necessary.
// https://github.com/lodash/lodash/wiki/Changelog#v400
var mongo = require('mongoskin');
var _ = require('lodash');
var moment = require('moment');

View file

@ -6,6 +6,12 @@ var authorUuid = 'd904bd62-da08-416b-a816-ba797c9ee265'; //... own data is done
* force all active players to rest in the inn due to massive server fail
*/
// IMPORTANT NOTE: this migration was written when we were using version 3 of lodash.
// We've now upgraded to lodash v4 but the code used in this migration has not been
// adapted to work with it. Before this migration is used again any lodash method should
// be checked for compatibility against the v4 changelog and changed if necessary.
// https://github.com/lodash/lodash/wiki/Changelog#v400
var dbserver = 'localhost:27017' // CHANGE THIS FOR PRODUCTION DATABASE
var mongo = require('mongoskin');

View file

@ -19,6 +19,12 @@ var authorUuid = 'd904bd62-da08-416b-a816-ba797c9ee265'; //... own data is done
* means minimal new testing.
*/
// IMPORTANT NOTE: this migration was written when we were using version 3 of lodash.
// We've now upgraded to lodash v4 but the code used in this migration has not been
// adapted to work with it. Before this migration is used again any lodash method should
// be checked for compatibility against the v4 changelog and changed if necessary.
// https://github.com/lodash/lodash/wiki/Changelog#v400
var dbserver = 'localhost:27017' // FOR TEST DATABASE
// var dbserver = 'username:password@ds031379-a0.mongolab.com:31379' // FOR PRODUCTION DATABASE
var dbname = 'habitrpg';

View file

@ -7,6 +7,12 @@ var migrationName = '20160111_challenges_condense_same_day_history_entries.js';
var dbserver = '';
var dbname = '';
// IMPORTANT NOTE: this migration was written when we were using version 3 of lodash.
// We've now upgraded to lodash v4 but the code used in this migration has not been
// adapted to work with it. Before this migration is used again any lodash method should
// be checked for compatibility against the v4 changelog and changed if necessary.
// https://github.com/lodash/lodash/wiki/Changelog#v400
var mongo = require('mongoskin');
var _ = require('lodash');
var moment = require('moment');

View file

@ -11,6 +11,12 @@ var dbserver = 'localhost:27017'; // FOR TEST DATABASE
// var dbserver = 'username:password@ds031379-a0.mongolab.com:31379'; // FOR PRODUCTION DATABASE
var dbname = 'habitrpg';
// IMPORTANT NOTE: this migration was written when we were using version 3 of lodash.
// We've now upgraded to lodash v4 but the code used in this migration has not been
// adapted to work with it. Before this migration is used again any lodash method should
// be checked for compatibility against the v4 changelog and changed if necessary.
// https://github.com/lodash/lodash/wiki/Changelog#v400
var mongo = require('mongoskin');
var _ = require('lodash');

View file

@ -14,6 +14,12 @@ var dbname = 'habitrpg';
var mongo = require('mongoskin');
var _ = require('lodash');
// IMPORTANT NOTE: this migration was written when we were using version 3 of lodash.
// We've now upgraded to lodash v4 but the code used in this migration has not been
// adapted to work with it. Before this migration is used again any lodash method should
// be checked for compatibility against the v4 changelog and changed if necessary.
// https://github.com/lodash/lodash/wiki/Changelog#v400
var dbUsers = mongo.db(dbserver + '/' + dbname + '?auto_reconnect').collection('users');
// specify a query to limit the affected users (empty for all users):

View file

@ -2,6 +2,12 @@ var uuid = require('uuid').v4;
var mongo = require('mongodb').MongoClient;
var _ = require('lodash');
// IMPORTANT NOTE: this migration was written when we were using version 3 of lodash.
// We've now upgraded to lodash v4 but the code used in this migration has not been
// adapted to work with it. Before this migration is used again any lodash method should
// be checked for compatibility against the v4 changelog and changed if necessary.
// https://github.com/lodash/lodash/wiki/Changelog#v400
var taskIds = require('checklists-no-id.json').map(function (obj) {
return obj._id;
});

View file

@ -6,6 +6,12 @@
// Due to some big user profiles it needs more RAM than is allowed by default by v8 (arounf 1.7GB).
// Run the script with --max-old-space-size=4096 to allow up to 4GB of RAM
// IMPORTANT NOTE: this migration was written when we were using version 3 of lodash.
// We've now upgraded to lodash v4 but the code used in this migration has not been
// adapted to work with it. Before this migration is used again any lodash method should
// be checked for compatibility against the v4 changelog and changed if necessary.
// https://github.com/lodash/lodash/wiki/Changelog#v400
console.log('Starting migrations/api_v3/challenges.js.');
require('babel-register');

View file

@ -9,6 +9,12 @@
// Run the script with --max-old-space-size=4096 to allow up to 4GB of RAM
console.log('Starting migrations/api_v3/challengesMembers.js.');
// IMPORTANT NOTE: this migration was written when we were using version 3 of lodash.
// We've now upgraded to lodash v4 but the code used in this migration has not been
// adapted to work with it. Before this migration is used again any lodash method should
// be checked for compatibility against the v4 changelog and changed if necessary.
// https://github.com/lodash/lodash/wiki/Changelog#v400
require('babel-register');
require('babel-polyfill');

View file

@ -8,6 +8,12 @@
// Run the script with --max-old-space-size=4096 to allow up to 4GB of RAM
console.log('Starting migrations/api_v3/coupons.js.');
// IMPORTANT NOTE: this migration was written when we were using version 3 of lodash.
// We've now upgraded to lodash v4 but the code used in this migration has not been
// adapted to work with it. Before this migration is used again any lodash method should
// be checked for compatibility against the v4 changelog and changed if necessary.
// https://github.com/lodash/lodash/wiki/Changelog#v400
require('babel-register');
require('babel-polyfill');

View file

@ -8,6 +8,12 @@
// Run the script with --max-old-space-size=4096 to allow up to 4GB of RAM
console.log('Starting migrations/api_v3/unsubscriptions.js.');
// IMPORTANT NOTE: this migration was written when we were using version 3 of lodash.
// We've now upgraded to lodash v4 but the code used in this migration has not been
// adapted to work with it. Before this migration is used again any lodash method should
// be checked for compatibility against the v4 changelog and changed if necessary.
// https://github.com/lodash/lodash/wiki/Changelog#v400
require('babel-register');
require('babel-polyfill');

View file

@ -16,6 +16,12 @@
// Run the script with --max-old-space-size=4096 to allow up to 4GB of RAM
console.log('Starting migrations/api_v3/groups.js.');
// IMPORTANT NOTE: this migration was written when we were using version 3 of lodash.
// We've now upgraded to lodash v4 but the code used in this migration has not been
// adapted to work with it. Before this migration is used again any lodash method should
// be checked for compatibility against the v4 changelog and changed if necessary.
// https://github.com/lodash/lodash/wiki/Changelog#v400
require('babel-register');
require('babel-polyfill');

View file

@ -9,6 +9,12 @@
// Run the script with --max-old-space-size=4096 to allow up to 4GB of RAM
console.log('Starting migrations/api_v3/users.js.');
// IMPORTANT NOTE: this migration was written when we were using version 3 of lodash.
// We've now upgraded to lodash v4 but the code used in this migration has not been
// adapted to work with it. Before this migration is used again any lodash method should
// be checked for compatibility against the v4 changelog and changed if necessary.
// https://github.com/lodash/lodash/wiki/Changelog#v400
require('babel-register');
require('babel-polyfill');

View file

@ -7,6 +7,6 @@
db.users.find().forEach(function(user){
user.tasks = user.habits.concat(user.dailys).concat(user.todos).concat(user.rewards);
var found = _.any(user.tasks, {text: ""})
var found = _.some(user.tasks, {text: ""})
if (found) printjson({id:user._id, auth:user.auth});
})

View file

@ -1,6 +1,9 @@
// EMAIL="x@y.com" node ./migrations/manual_password_reset.js
// Be sure to have PRODUCTION_DB in your config.json
// IMPORTANT: this script isn't updated to use the new password encryption that uses bcrypt
// using it will break accounts and should not be used until upgraded
var nconf = require('nconf'),
path = require('path');
nconf.argv().env().file('user', path.join(path.resolve(__dirname, '../config.json')));

3954
npm-shrinkwrap.json generated

File diff suppressed because it is too large Load diff

View file

@ -72,9 +72,7 @@
"js2xmlparser": "~1.0.0",
"less": "^2.7.1",
"less-loader": "^2.2.3",
"lodash": "^3.10.1",
"lodash.pickby": "^4.2.0",
"lodash.setwith": "^4.2.0",
"lodash": "^4.17.4",
"merge-stream": "^1.0.0",
"method-override": "^2.3.5",
"moment": "^2.13.0",
@ -172,7 +170,7 @@
"csv": "~0.3.6",
"deep-diff": "~0.1.4",
"eslint": "^3.0.0",
"eslint-config-habitrpg": "^2.0.0",
"eslint-config-habitrpg": "^3.0.0",
"eslint-friendly-formatter": "^2.0.5",
"eslint-loader": "^1.3.0",
"eslint-plugin-html": "^2.0.0",

View file

@ -6,7 +6,6 @@ import requireAgain from 'require-again';
import { recoverCron, cron } from '../../../../../website/server/libs/cron';
import { model as User } from '../../../../../website/server/models/user';
import * as Tasks from '../../../../../website/server/models/task';
import { clone } from 'lodash';
import common from '../../../../../website/common';
import analytics from '../../../../../website/server/libs/analyticsService';
@ -594,7 +593,7 @@ describe('cron', () => {
tasksByType.dailys[0].completed = true;
tasksByType.dailys[0].startDate = moment(new Date()).subtract({days: 1});
let previousBuffs = clone(user.stats.buffs);
let previousBuffs = user.stats.buffs.toObject();
cron({user, tasksByType, daysMissed, analytics});
@ -659,7 +658,7 @@ describe('cron', () => {
tasksByType.dailys[0].completed = false;
tasksByType.dailys[0].startDate = moment(new Date()).subtract({days: 1});
let previousBuffs = clone(user.stats.buffs);
let previousBuffs = user.stats.buffs.toObject();
cronOverride({user, tasksByType, daysMissed, analytics});

View file

@ -485,7 +485,6 @@ describe('payments/index', () => {
sandbox.spy(user.purchased.plan.mysteryItems, 'push');
data = { paymentMethod: 'PaymentMethod', user, sub: { key: 'basic_3mo' } };
await api.createSubscription(data);
expect(user.purchased.plan.mysteryItems.push).to.be.calledOnce;

View file

@ -4,7 +4,6 @@ import {
generateTodo,
generateDaily,
} from '../../../../helpers/api-unit.helper';
import { cloneDeep } from 'lodash';
import cronMiddleware from '../../../../../website/server/middlewares/cron';
import moment from 'moment';
import { model as User } from '../../../../../website/server/models/user';
@ -60,7 +59,7 @@ describe('cron middleware', () => {
cronMiddleware(req, res, done);
});
it('should clear todos older than 30 days for free users', async (done) => {
it('should clear todos older than 30 days for free users', async () => {
user.lastCron = moment(new Date()).subtract({days: 2});
let task = generateTodo(user);
task.dateCompleted = moment(new Date()).subtract({days: 31});
@ -68,16 +67,21 @@ describe('cron middleware', () => {
await task.save();
await user.save();
cronMiddleware(req, res, (err) => {
Tasks.Task.findOne({_id: task}, function (secondErr, taskFound) {
expect(secondErr).to.not.exist;
expect(taskFound).to.not.exist;
done(err);
await new Promise((resolve, reject) => {
cronMiddleware(req, res, (err) => {
if (err) return reject(err);
Tasks.Task.findOne({_id: task}, function (secondErr, taskFound) {
if (secondErr) return reject(err);
expect(secondErr).to.not.exist;
expect(taskFound).to.not.exist;
resolve();
});
});
});
});
it('should not clear todos older than 30 days for subscribed users', async (done) => {
it('should not clear todos older than 30 days for subscribed users', async () => {
user.purchased.plan.customerId = 'subscribedId';
user.purchased.plan.dateUpdated = moment('012013', 'MMYYYY');
user.lastCron = moment(new Date()).subtract({days: 2});
@ -87,16 +91,20 @@ describe('cron middleware', () => {
await task.save();
await user.save();
cronMiddleware(req, res, (err) => {
Tasks.Task.findOne({_id: task}, function (secondErr, taskFound) {
expect(secondErr).to.not.exist;
expect(taskFound).to.exist;
done(err);
await new Promise((resolve, reject) => {
cronMiddleware(req, res, (err) => {
if (err) return reject(err);
Tasks.Task.findOne({_id: task}, function (secondErr, taskFound) {
if (secondErr) return reject(secondErr);
expect(secondErr).to.not.exist;
expect(taskFound).to.exist;
resolve();
});
});
});
});
it('should clear todos older than 90 days for subscribed users', async (done) => {
it('should clear todos older than 90 days for subscribed users', async () => {
user.purchased.plan.customerId = 'subscribedId';
user.purchased.plan.dateUpdated = moment('012013', 'MMYYYY');
user.lastCron = moment(new Date()).subtract({days: 2});
@ -107,39 +115,49 @@ describe('cron middleware', () => {
await task.save();
await user.save();
cronMiddleware(req, res, (err) => {
Tasks.Task.findOne({_id: task}, function (secondErr, taskFound) {
expect(secondErr).to.not.exist;
expect(taskFound).to.not.exist;
done(err);
await new Promise((resolve, reject) => {
cronMiddleware(req, res, (err) => {
if (err) return reject(err);
Tasks.Task.findOne({_id: task}, function (secondErr, taskFound) {
if (secondErr) return reject(secondErr);
expect(secondErr).to.not.exist;
expect(taskFound).to.not.exist;
resolve();
});
});
});
});
it('should call next if user was not modified after cron', async (done) => {
it('should call next if user was not modified after cron', async () => {
let hpBefore = user.stats.hp;
user.lastCron = moment(new Date()).subtract({days: 2});
await user.save();
cronMiddleware(req, res, (err) => {
expect(hpBefore).to.equal(user.stats.hp);
done(err);
await new Promise((resolve, reject) => {
cronMiddleware(req, res, (err) => {
if (err) return reject(err);
expect(hpBefore).to.equal(user.stats.hp);
resolve();
});
});
});
it('updates user.auth.timestamps.loggedin and lastCron', async (done) => {
it('updates user.auth.timestamps.loggedin and lastCron', async () => {
user.lastCron = moment(new Date()).subtract({days: 2});
let now = new Date();
await user.save();
cronMiddleware(req, res, (err) => {
expect(moment(now).isSame(user.lastCron, 'day'));
expect(moment(now).isSame(user.auth.timestamps.loggedin, 'day'));
done(err);
await new Promise((resolve, reject) => {
cronMiddleware(req, res, (err) => {
if (err) return reject(err);
expect(moment(now).isSame(user.lastCron, 'day'));
expect(moment(now).isSame(user.auth.timestamps.loggedin, 'day'));
resolve();
});
});
});
it('does damage for missing dailies', async (done) => {
it('does damage for missing dailies', async () => {
let hpBefore = user.stats.hp;
user.lastCron = moment(new Date()).subtract({days: 2});
let daily = generateDaily(user);
@ -147,28 +165,34 @@ describe('cron middleware', () => {
await daily.save();
await user.save();
cronMiddleware(req, res, (err) => {
expect(user.stats.hp).to.be.lessThan(hpBefore);
done(err);
await new Promise((resolve, reject) => {
cronMiddleware(req, res, (err) => {
if (err) return reject(err);
expect(user.stats.hp).to.be.lessThan(hpBefore);
resolve();
});
});
});
it('updates tasks', async (done) => {
it('updates tasks', async () => {
user.lastCron = moment(new Date()).subtract({days: 2});
let todo = generateTodo(user);
let todoValueBefore = todo.value;
await user.save();
cronMiddleware(req, res, () => {
Tasks.Task.findOne({_id: todo._id}, function (err, todoFound) {
expect(err).to.not.exist;
expect(todoFound.value).to.be.lessThan(todoValueBefore);
done();
await new Promise((resolve, reject) => {
cronMiddleware(req, res, (err) => {
if (err) return reject(err);
Tasks.Task.findOne({_id: todo._id}, function (secondErr, todoFound) {
if (secondErr) return reject(secondErr);
expect(todoFound.value).to.be.lessThan(todoValueBefore);
resolve();
});
});
});
});
it('applies quest progress', async (done) => {
it('applies quest progress', async () => {
let hpBefore = user.stats.hp;
user.lastCron = moment(new Date()).subtract({days: 2});
let daily = generateDaily(user);
@ -192,17 +216,20 @@ describe('cron middleware', () => {
party.startQuest(user);
cronMiddleware(req, res, () => {
expect(user.stats.hp).to.be.lessThan(hpBefore);
done();
await new Promise((resolve, reject) => {
cronMiddleware(req, res, (err) => {
if (err) return reject(err);
expect(user.stats.hp).to.be.lessThan(hpBefore);
resolve();
});
});
});
it('recovers from failed cron and does not error when user is already cronning', async (done) => {
it('recovers from failed cron and does not error when user is already cronning', async () => {
user.lastCron = moment(new Date()).subtract({days: 2});
await user.save();
let updatedUser = cloneDeep(user);
let updatedUser = user.toObject();
updatedUser.nMatched = 0;
sandbox.spy(cronLib, 'recoverCron');
@ -215,10 +242,13 @@ describe('cron middleware', () => {
},
});
cronMiddleware(req, res, () => {
expect(cronLib.recoverCron).to.be.calledOnce;
await new Promise((resolve, reject) => {
cronMiddleware(req, res, (err) => {
if (err) return reject(err);
expect(cronLib.recoverCron).to.be.calledOnce;
done();
resolve();
});
});
});
});

View file

@ -1045,7 +1045,7 @@ describe('Group Model', () => {
expect(email.sendTxn).to.be.calledOnce;
let memberIds = _.pluck(email.sendTxn.args[0][0], '_id');
let memberIds = _.map(email.sendTxn.args[0][0], '_id');
let typeOfEmail = email.sendTxn.args[0][1];
expect(memberIds).to.have.a.lengthOf(2);
@ -1068,7 +1068,7 @@ describe('Group Model', () => {
expect(email.sendTxn).to.be.calledOnce;
let memberIds = _.pluck(email.sendTxn.args[0][0], '_id');
let memberIds = _.map(email.sendTxn.args[0][0], '_id');
expect(memberIds).to.have.a.lengthOf(1);
expect(memberIds).to.not.include(participatingMember._id);
@ -1089,7 +1089,7 @@ describe('Group Model', () => {
expect(email.sendTxn).to.be.calledOnce;
let memberIds = _.pluck(email.sendTxn.args[0][0], '_id');
let memberIds = _.map(email.sendTxn.args[0][0], '_id');
expect(memberIds).to.have.a.lengthOf(1);
expect(memberIds).to.not.include(participatingMember._id);

View file

@ -30,7 +30,9 @@ describe('Inventory Controller', function() {
suppressModals: {}
},
purchased: {
plan: {}
plan: {
mysteryItems: [],
},
},
});

View file

@ -15,13 +15,13 @@ import i18n from '../../../website/common/script/i18n';
function getFullArmoire () {
let fullArmoire = {};
_(content.gearTypes).each((type) => {
_(content.gear.tree[type].armoire).each((gearObject) => {
_.each(content.gearTypes, (type) => {
_.each(content.gear.tree[type].armoire, (gearObject) => {
let armoireKey = gearObject.key;
fullArmoire[armoireKey] = true;
}).value();
}).value();
});
});
return fullArmoire;
}

View file

@ -8,19 +8,19 @@ import {questions, stillNeedHelp} from '../../website/common/script/content/faq'
describe('FAQ Locales', () => {
describe('Questions', () => {
it('has a valid questions', () => {
each(questions, (question, key) => {
each(questions, (question) => {
expectValidTranslationString(question.question);
});
});
it('has a valid ios answers', () => {
each(questions, (question, key) => {
each(questions, (question) => {
expectValidTranslationString(question.ios);
});
});
it('has a valid web answers', () => {
each(questions, (question, key) => {
each(questions, (question) => {
expectValidTranslationString(question.web);
});
});

View file

@ -1,3 +1,4 @@
/* eslint-disable camelcase */
import {
expectValidTranslationString,
} from '../helpers/content.helper';
@ -68,7 +69,7 @@ describe('Gear', () => {
weapon_special_0: 70,
weapon_special_2: 300,
weapon_special_3: 300,
}
};
each(cases, (tierRequirement, key) => {
context(key, () => {

View file

@ -1,13 +1,13 @@
import {each} from 'lodash';
import {
expectValidTranslationString
expectValidTranslationString,
} from '../helpers/content.helper';
import mysterySets from '../../website/common/script/content/mystery-sets';
describe('Mystery Sets', () => {
it('has a valid text string', () => {
each(mysterySets, (set, key) => {
each(mysterySets, (set) => {
expectValidTranslationString(set.text);
});
});

View file

@ -1,29 +1,28 @@
import _ from 'lodash';
import {
generateUser,
} from '../helpers/common.helper';
import timeTravelers from '../../website/common/script/content/time-travelers'
import timeTravelers from '../../website/common/script/content/time-travelers';
describe('time-travelers store', () => {
let user;
beforeEach(() => {
user = generateUser();
});
let user;
beforeEach(() => {
user = generateUser();
});
it('removes owned sets from the time travelers store', () => {
user.items.gear.owned['head_mystery_201602'] = true;
expect(timeTravelers.timeTravelerStore(user)['201602']).to.not.exist;
expect(timeTravelers.timeTravelerStore(user)['201603']).to.exist;
});
it('removes owned sets from the time travelers store', () => {
user.items.gear.owned.head_mystery_201602 = true; // eslint-disable-line camelcase
expect(timeTravelers.timeTravelerStore(user)['201602']).to.not.exist;
expect(timeTravelers.timeTravelerStore(user)['201603']).to.exist;
});
it('removes unopened mystery item sets from the time travelers store', () => {
user.purchased = {
plan: {
mysteryItems: ['head_mystery_201602'],
},
};
expect(timeTravelers.timeTravelerStore(user)['201602']).to.not.exist;
expect(timeTravelers.timeTravelerStore(user)['201603']).to.exist;
});
it('removes unopened mystery item sets from the time travelers store', () => {
user.purchased = {
plan: {
mysteryItems: ['head_mystery_201602'],
},
};
expect(timeTravelers.timeTravelerStore(user)['201602']).to.not.exist;
expect(timeTravelers.timeTravelerStore(user)['201603']).to.exist;
});
});

View file

@ -1,6 +1,6 @@
import '../../website/server/libs/i18n';
import mongoose from 'mongoose';
import { defaultsDeep as defaults } from 'lodash';
import defaultsDeep from 'lodash/defaultsDeep';
import { model as User } from '../../website/server/models/user';
import { model as Group } from '../../website/server/models/group';
import { model as Challenge } from '../../website/server/models/challenge';
@ -45,7 +45,7 @@ export function generateRes (options = {}) {
},
};
return defaults(options, defaultRes);
return defaultsDeep(options, defaultRes);
}
export function generateReq (options = {}) {
@ -56,7 +56,7 @@ export function generateReq (options = {}) {
header: sandbox.stub().returns(null),
};
return defaults(options, defaultReq);
return defaultsDeep(options, defaultReq);
}
export function generateNext (func) {

View file

@ -219,7 +219,7 @@ window.habitrpg = angular.module('habitrpg',
// Remove empty values from the array and add any unordered task
$scope.group[type + 's'] = _.compact(orderedTasks).concat(unorderedTasks);
}).value();
});
$scope.group.approvals = [];
$rootScope.$broadcast('obj-updated', $scope.group);

View file

@ -18,11 +18,11 @@
var modelAccessor = $parse(attrs.ngModel);
return function (scope, element, attrs, controller) {
var availableTags = _.pluck(scope.group.members, 'profile.name');
var memberProfileNameToIdMap = _.object(_.map(scope.group.members, function(item) {
var availableTags = _.map(scope.group.members, 'profile.name');
var memberProfileNameToIdMap = _.fromPairs(_.map(scope.group.members, function(item) {
return [item.profile.name, item.id]
}));
var memberIdToProfileNameMap = _.object(_.map(scope.group.members, function(item) {
var memberIdToProfileNameMap = _.fromPairs(_.map(scope.group.members, function(item) {
return [item.id, item.profile.name]
}));

View file

@ -172,7 +172,7 @@ habitrpg.controller('GroupTasksCtrl', ['$scope', 'Shared', 'Tasks', 'User', '$ro
var content = task.notes;
if ($scope.group) {
var memberIdToProfileNameMap = _.object(_.map($scope.group.members, function(item) {
var memberIdToProfileNameMap = _.fromPairs(_.map($scope.group.members, function(item) {
return [item.id, item.profile.name]
}));

View file

@ -63,7 +63,7 @@ habitrpg.controller("ChallengesCtrl", ['$rootScope','$scope', 'Shared', 'User',
//If the user has one filter selected, assume that the user wants to default to that group
var defaultGroup;
//Our filters contain all groups, but we only want groups that have atleast one challenge
var groupsWithChallenges = _.uniq(_.pluck($scope.groupsFilter, '_id'));
var groupsWithChallenges = _.uniq(_.map($scope.groupsFilter, '_id'));
var len = groupsWithChallenges.length;
var filterCount = 0;
@ -108,11 +108,11 @@ habitrpg.controller("ChallengesCtrl", ['$rootScope','$scope', 'Shared', 'User',
reward: []
};
_(clonedTasks).each(function(val, type) {
_(clonedTasks).forEach(function(val, type) {
if (challenge[type + 's']) {
challenge[type + 's'].forEach(_cloneTaskAndPush);
}
}).value();
});
$scope.obj = $scope.newChallenge = {
name: challenge.name,
@ -446,7 +446,7 @@ habitrpg.controller("ChallengesCtrl", ['$rootScope','$scope', 'Shared', 'User',
};
$scope.filterInitialChallenges = function() {
$scope.groupsFilter = _.uniq(_.compact(_.pluck($scope.challenges, 'group')), function(g) {return g._id});
$scope.groupsFilter = _.uniqBy(_.compact(_.map($scope.challenges, 'group')), function(g) {return g._id});
$scope.search = {
group: _.transform($scope.groupsFilter, function(m,g) { m[g._id] = true;}),

View file

@ -19,7 +19,7 @@ habitrpg.controller("FiltersCtrl", ['$scope', '$rootScope', 'User', 'Shared',
$scope._editing = false;
} else {
tagsSnap = angular.copy(user.tags);
tagsSnap = _.object(_.pluck(tagsSnap,'id'), tagsSnap);
tagsSnap = _.zipObject(_.map(tagsSnap, 'id'), tagsSnap);
$scope._editing = true;
}
};

View file

@ -70,7 +70,7 @@ function($scope, $rootScope, User, $http, Notification, ApiUrl, Social) {
/**
* Debug functions. Note that the server route for gems is only available if process.env.DEBUG=true
*/
if (_.contains(['development','test'],window.env.NODE_ENV)) {
if (_.includes(['development','test'],window.env.NODE_ENV)) {
$scope.setHealthLow = function(){
User.set({

View file

@ -19,7 +19,7 @@ habitrpg.controller("GroupsCtrl", ['$scope', '$rootScope', 'Shared', 'Groups', '
// If the group is a guild, just check for an intersection with the
// current user's guilds, rather than checking the members of the group.
if(group.type === 'guild') {
return _.detect(User.user.guilds, function(guildId) { return guildId === group._id });
return _.find(User.user.guilds, function(guildId) { return guildId === group._id });
}
// Similarly, if we're dealing with the user's current party, return true.

View file

@ -89,7 +89,7 @@ habitrpg.controller("GuildsCtrl", ['$scope', 'Groups', 'User', 'Challenges', '$r
Challenges.getGroupChallenges(group._id)
.then(function(response) {
var challenges = _.pluck(_.filter(response.data.data, function(c) {
var challenges = _.map(_.filter(response.data.data, function(c) {
return c.group._id == group._id;
}), '_id');

View file

@ -134,7 +134,7 @@ habitrpg.controller("InventoryCtrl",
if ($scope.selectedEgg && $scope.selectedEgg.key == egg) {
return $scope.selectedEgg = null; // clicked same egg, unselect
}
var eggData = _.findWhere(Content.eggs, {key:egg});
var eggData = _.find(Content.eggs, {key:egg});
if (!$scope.selectedPotion) {
$scope.selectedEgg = eggData;
} else {
@ -148,7 +148,7 @@ habitrpg.controller("InventoryCtrl",
return $scope.selectedPotion = null; // clicked same egg, unselect
}
// we really didn't think through the way these things are stored and getting passed around...
var potionData = _.findWhere(Content.hatchingPotions, {key:potion});
var potionData = _.find(Content.hatchingPotions, {key:potion});
if (!$scope.selectedEgg) {
$scope.selectedPotion = potionData;
} else {
@ -175,7 +175,7 @@ habitrpg.controller("InventoryCtrl",
}
$scope.ownedItems = function(inventory){
return _.pick(inventory, function(v,k){return v>0;});
return _.pickBy(inventory, function(v,k){return v>0;});
}
$scope.hatch = function(egg, potion){
@ -274,7 +274,7 @@ habitrpg.controller("InventoryCtrl",
$scope.getSeasonalShopArray = function(set){
var flatGearArray = _.toArray(Content.gear.flat);
var filteredArray = _.where(flatGearArray, {index: set});
var filteredArray = _.filter(flatGearArray, {index: set});
return filteredArray;
};

View file

@ -62,7 +62,7 @@ habitrpg.controller('InviteToGroupCtrl', ['$scope', '$rootScope', 'User', 'Group
}
function _getOnlyUuids() {
var uuids = _.pluck($scope.invitees, 'uuid');
var uuids = _.map($scope.invitees, 'uuid');
var filteredUuids = _.filter(uuids, function(id) {
return id != '';
});

View file

@ -23,7 +23,7 @@ angular.module('habitrpg')
} else if (!(_.isEmpty(user.newMessages))) {
return messageValue;
} else if (!_.isEmpty(user.groupNotifications)) {
var groupNotificationTypes = _.pluck(user.groupNotifications, 'type');
var groupNotificationTypes = _.map(user.groupNotifications, 'type');
if (groupNotificationTypes.indexOf('GROUP_TASK_APPROVAL') !== -1) {
return groupApprovalRequested;
} else if (groupNotificationTypes.indexOf('GROUP_TASK_APPROVED') !== -1) {

View file

@ -156,7 +156,7 @@ habitrpg.controller("PartyCtrl", ['$rootScope','$scope','Groups','Chat','User','
//TODO: Move this to challenge service
Challenges.getGroupChallenges(group._id)
.then(function(response) {
var challenges = _.pluck(_.filter(response.data.data, function(c) {
var challenges = _.map(_.filter(response.data.data, function(c) {
return c.group._id == group._id;
}), '_id');

View file

@ -271,7 +271,7 @@ habitrpg.controller("RootCtrl", ['$scope', '$rootScope', '$location', 'User', '$
$rootScope.getGearArray = function(set){
var flatGearArray = _.toArray(Content.gear.flat);
var filteredArray = _.where(flatGearArray, {gearSet: set});
var filteredArray = _.filter(flatGearArray, {gearSet: set});
return filteredArray;
}

View file

@ -132,7 +132,7 @@
}
function _doesNotHaveAllowedHitType(properties) {
if (!_.contains(ALLOWED_HIT_TYPES, properties.hitType)) {
if (!_.includes(ALLOWED_HIT_TYPES, properties.hitType)) {
console.log('Hit type of Analytics event must be one of the following: ' + JSON.stringify(ALLOWED_HIT_TYPES));
return true;
}

View file

@ -184,7 +184,7 @@ function($rootScope, User, $timeout, $state, Analytics, Notification, Shared, So
}
_.each(chapters, function(chapter, k){
_(chapter).flattenDeep().each(function(step, i) {
_(chapter).flattenDeep().forEach(function(step, i) {
step.content = "<div><div class='" + (env.worldDmg.guide ? "npc_justin_broken" : "npc_justin") + " float-left'></div>" + step.content + "</div>";
$(step.element).popover('destroy'); // destroy existing hover popovers so we can add our own
step.onShow = function(){
@ -232,7 +232,7 @@ function($rootScope, User, $timeout, $state, Analytics, Notification, Shared, So
User.user.fns.updateStats(User.user.stats);
}
}
}).value();
});
});
var tour = {};

View file

@ -41,14 +41,14 @@
var equipmentTypes = ['weapon', 'armor', 'head', 'shield', 'back', 'body'];
_(equipmentTypes).each(function(type) {
_(equipmentTypes).forEach(function(type) {
var equippedItem = equipped[type];
if(gear[equippedItem]) {
var equipmentStat = gear[equippedItem][stat];
total += equipmentStat;
}
}).value();
});
return total;
}

View file

@ -402,7 +402,7 @@ angular.module('habitrpg')
_(cleansedTask.checklist).forEach(function(item) {
item.completed = false;
item.id = Shared.uuid();
}).value();
});
if (cleansedTask.type !== 'reward') {
delete cleansedTask.value;

View file

@ -66,7 +66,7 @@ angular.module('habitrpg')
// Remove empty values from the array and add any unordered task
user[type + 's'] = _.compact(orderedTasks).concat(unorderedTasks);
}).value();
});
}
function sync() {

View file

@ -28,7 +28,7 @@
<script>
import { mapState } from '../../store';
import { each } from 'lodash';
import each from 'lodash/each';
export default {
computed: {

View file

@ -1,4 +1,4 @@
import { each } from 'lodash';
import each from 'lodash/each';
let achievementsData = {};

View file

@ -1,4 +1,4 @@
import {forOwn} from 'lodash';
import forOwn from 'lodash/forOwn';
import t from '../translation';
/* eslint-disable camelcase */

View file

@ -4,7 +4,8 @@ import skins from './skin.js';
import sizes from './size.js';
import backgrounds from './backgrounds.js';
import chairs from './chair.js';
import {forOwn, clone} from 'lodash';
import forOwn from 'lodash/forOwn';
import clone from 'lodash/clone';
let reorderedBgs = {};

View file

@ -1,4 +1,4 @@
import {forOwn} from 'lodash';
import forOwn from 'lodash/forOwn';
module.exports = function prefillAppearances (obj) {
forOwn(obj, function prefillAppearance (value, key) {

View file

@ -1,8 +1,6 @@
import {
assign,
defaults,
each,
} from 'lodash';
import assign from 'lodash/assign';
import defaults from 'lodash/defaults';
import each from 'lodash/each';
import t from './translation';
function applyEggDefaults (set, config) {

View file

@ -1,4 +1,4 @@
import { isBoolean } from 'lodash';
import isBoolean from 'lodash/isBoolean';
export function ownsItem (item) {
return (user) => {

View file

@ -1,4 +1,5 @@
import {each, defaults} from 'lodash';
import each from 'lodash/each';
import defaults from 'lodash/defaults';
import moment from 'moment';
import {

View file

@ -1,4 +1,4 @@
import {cloneDeep} from 'lodash';
import cloneDeep from 'lodash/cloneDeep';
import {shield as baseShield} from './sets/base';

View file

@ -1,8 +1,6 @@
import {
assign,
defaults,
each,
} from 'lodash';
import assign from 'lodash/assign';
import defaults from 'lodash/defaults';
import each from 'lodash/each';
import t from './translation';
let drops = {

File diff suppressed because it is too large Load diff

View file

@ -1,6 +1,8 @@
import _ from 'lodash';
import range from 'lodash/range';
import { MAX_INCENTIVES } from '../constants';
// NOTE do not import this file alone but only access it through common.content
// so that it's already compiled
module.exports = function getLoginIncentives (api) {
let loginIncentives = {
1: {
@ -228,7 +230,7 @@ module.exports = function getLoginIncentives (api) {
// We could also, use a list, but then we would be cloning each of the rewards.
// Create a new array if we want the loginIncentives to be immutable in the future
let nextRewardKey;
_.range(MAX_INCENTIVES + 1).reverse().forEach(function addNextRewardLink (index) {
range(MAX_INCENTIVES + 1).reverse().forEach(function addNextRewardLink (index) {
if (loginIncentives[index] && loginIncentives[index].rewardKey) {
loginIncentives[index].nextRewardAt = nextRewardKey;
nextRewardKey = index;
@ -242,7 +244,7 @@ module.exports = function getLoginIncentives (api) {
});
let prevRewardKey;
_.range(MAX_INCENTIVES + 1).forEach(function addPrevRewardLink (index) {
range(MAX_INCENTIVES + 1).forEach(function addPrevRewardLink (index) {
loginIncentives[index].prevRewardKey = prevRewardKey;
if (loginIncentives[index].rewardKey) prevRewardKey = index;
});

View file

@ -1,4 +1,4 @@
import { each } from 'lodash';
import each from 'lodash/each';
import t from './translation';
let mysterySets = {

View file

@ -1,5 +1,5 @@
import t from './translation';
import _ from 'lodash';
import each from 'lodash/each';
import { NotAuthorized } from '../libs/errors';
/*
---------------------------------------------------------------
@ -56,7 +56,7 @@ spells.wizard = {
target: 'party',
notes: t('spellWizardMPHealNotes'),
cast (user, target) {
_.each(target, (member) => {
each(target, (member) => {
let bonus = user._statsComputed.int;
if (user._id !== member._id) {
member.stats.mp += Math.ceil(diminishingReturns(bonus, 25, 125));
@ -71,7 +71,7 @@ spells.wizard = {
target: 'party',
notes: t('spellWizardEarthNotes'),
cast (user, target) {
_.each(target, (member) => {
each(target, (member) => {
let bonus = user._statsComputed.int - user.stats.buffs.int;
if (!member.stats.buffs.int) member.stats.buffs.int = 0;
member.stats.buffs.int += Math.ceil(diminishingReturns(bonus, 30, 200));
@ -123,7 +123,7 @@ spells.warrior = {
target: 'party',
notes: t('spellWarriorValorousPresenceNotes'),
cast (user, target) {
_.each(target, (member) => {
each(target, (member) => {
let bonus = user._statsComputed.str - user.stats.buffs.str;
if (!member.stats.buffs.str) member.stats.buffs.str = 0;
member.stats.buffs.str += Math.ceil(diminishingReturns(bonus, 20, 200));
@ -137,7 +137,7 @@ spells.warrior = {
target: 'party',
notes: t('spellWarriorIntimidateNotes'),
cast (user, target) {
_.each(target, (member) => {
each(target, (member) => {
let bonus = user._statsComputed.con - user.stats.buffs.con;
if (!member.stats.buffs.con) member.stats.buffs.con = 0;
member.stats.buffs.con += Math.ceil(diminishingReturns(bonus, 24, 200));
@ -179,7 +179,7 @@ spells.rogue = {
target: 'party',
notes: t('spellRogueToolsOfTradeNotes'),
cast (user, target) {
_.each(target, (member) => {
each(target, (member) => {
let bonus = user._statsComputed.per - user.stats.buffs.per;
if (!member.stats.buffs.per) member.stats.buffs.per = 0;
member.stats.buffs.per += Math.ceil(diminishingReturns(bonus, 100, 50));
@ -218,7 +218,7 @@ spells.healer = {
target: 'tasks',
notes: t('spellHealerBrightnessNotes'),
cast (user, tasks) {
_.each(tasks, (task) => {
each(tasks, (task) => {
if (task.type !== 'reward') {
task.value += 4 * (user._statsComputed.int / (user._statsComputed.int + 40));
}
@ -232,7 +232,7 @@ spells.healer = {
target: 'party',
notes: t('spellHealerProtectAuraNotes'),
cast (user, target) {
_.each(target, (member) => {
each(target, (member) => {
let bonus = user._statsComputed.con - user.stats.buffs.con;
if (!member.stats.buffs.con) member.stats.buffs.con = 0;
member.stats.buffs.con += Math.ceil(diminishingReturns(bonus, 200, 200));
@ -246,7 +246,7 @@ spells.healer = {
target: 'party',
notes: t('spellHealerHealAllNotes'),
cast (user, target) {
_.each(target, (member) => {
each(target, (member) => {
member.stats.hp += (user._statsComputed.con + user._statsComputed.int + 5) * 0.04;
if (member.stats.hp > 50) member.stats.hp = 50;
});
@ -388,7 +388,7 @@ spells.special = {
if (!user.achievements.nye) user.achievements.nye = 0;
user.achievements.nye++;
} else {
_.each([user, target], (u) => {
each([user, target], (u) => {
if (!u.achievements.nye) u.achievements.nye = 0;
u.achievements.nye++;
});
@ -416,7 +416,7 @@ spells.special = {
if (!user.achievements.valentine) user.achievements.valentine = 0;
user.achievements.valentine++;
} else {
_.each([user, target], (u) => {
each([user, target], (u) => {
if (!u.achievements.valentine) u.achievements.valentine = 0;
u.achievements.valentine++;
});
@ -443,7 +443,7 @@ spells.special = {
if (user === target) {
user.achievements.greeting++;
} else {
_.each([user, target], (u) => {
each([user, target], (u) => {
if (!u.achievements.greeting) u.achievements.greeting = 0;
u.achievements.greeting++;
});
@ -471,7 +471,7 @@ spells.special = {
if (!user.achievements.thankyou) user.achievements.thankyou = 0;
user.achievements.thankyou++;
} else {
_.each([user, target], (u) => {
each([user, target], (u) => {
if (!u.achievements.thankyou) u.achievements.thankyou = 0;
u.achievements.thankyou++;
});
@ -499,7 +499,7 @@ spells.special = {
if (!user.achievements.birthday) user.achievements.birthday = 0;
user.achievements.birthday++;
} else {
_.each([user, target], (u) => {
each([user, target], (u) => {
if (!u.achievements.birthday) u.achievements.birthday = 0;
u.achievements.birthday++;
});
@ -516,8 +516,8 @@ spells.special = {
},
};
_.each(spells, (spellClass) => {
_.each(spellClass, (spell, key) => {
each(spells, (spellClass) => {
each(spellClass, (spell, key) => {
spell.key = key;
let _cast = spell.cast;
spell.cast = function castSpell (user, target, req) {

View file

@ -1,6 +1,4 @@
import {
each,
} from 'lodash';
import each from 'lodash/each';
import {
drops as dropEggs,
quests as questEggs,

View file

@ -1,5 +1,5 @@
/* eslint-disable camelcase */
import _ from 'lodash';
import each from 'lodash/each';
let subscriptionBlocks = {
basic_earned: {
@ -32,7 +32,7 @@ let subscriptionBlocks = {
},
};
_.each(subscriptionBlocks, function createKeys (b, k) {
each(subscriptionBlocks, function createKeys (b, k) {
return b.key = k;
});

View file

@ -1,11 +1,16 @@
import _ from 'lodash';
import each from 'lodash/each';
import filter from 'lodash/filter';
import keys from 'lodash/keys';
import union from 'lodash/union';
import reduce from 'lodash/reduce';
import mysterySets from './mystery-sets';
import gear from './gear';
let mystery = mysterySets;
_.each(mystery, (v, k) => {
return v.items = _.where(gear.flat, {
each(mystery, (v, k) => {
return v.items = filter(gear.flat, {
mystery: k,
});
});
@ -13,10 +18,11 @@ _.each(mystery, (v, k) => {
let timeTravelerStore = (user) => {
let ownedKeys;
let owned = user.items.gear.owned;
let unopenedGifts = user.purchased.plan.mysteryItems;
ownedKeys = _.keys((typeof owned.toObject === 'function' ? owned.toObject() : undefined) || owned);
ownedKeys = _.union(ownedKeys, unopenedGifts);
return _.reduce(mystery, (m, v, k) => {
let mysteryItems = user.purchased.plan.mysteryItems;
let unopenedGifts = typeof mysteryItems.toObject === 'function' ? mysteryItems.toObject() : mysteryItems;
ownedKeys = keys(typeof owned.toObject === 'function' ? owned.toObject() : owned);
ownedKeys = union(ownedKeys, unopenedGifts);
return reduce(mystery, (m, v, k) => {
if (k === 'wondercon' || ownedKeys.indexOf(v.items[0].key) !== -1) {
return m;
}

View file

@ -1,9 +1,7 @@
import {
each,
filter,
keys,
size,
} from 'lodash';
import each from 'lodash/each';
import filter from 'lodash/filter';
import keys from 'lodash/keys';
import size from 'lodash/size';
import content from './content/index';
const DROP_ANIMALS = keys(content.pets);

View file

@ -4,7 +4,8 @@
Cron and time / day functions
------------------------------------------------------
*/
import _ from 'lodash';
import defaults from 'lodash/defaults';
import invert from 'lodash/invert';
import moment from 'moment';
import 'moment-recur';
@ -18,7 +19,7 @@ export const DAY_MAPPING = {
6: 's',
};
export const DAY_MAPPING_STRING_TO_NUMBER = _.invert(DAY_MAPPING);
export const DAY_MAPPING_STRING_TO_NUMBER = invert(DAY_MAPPING);
/*
Each time we perform date maths (cron, task-due-days, etc), we need to consider user preferences.
@ -28,13 +29,13 @@ export const DAY_MAPPING_STRING_TO_NUMBER = _.invert(DAY_MAPPING);
function sanitizeOptions (o) {
let ref = Number(o.dayStart || 0);
let dayStart = !_.isNaN(ref) && ref >= 0 && ref <= 24 ? ref : 0;
let dayStart = !Number.isNaN(ref) && ref >= 0 && ref <= 24 ? ref : 0;
let timezoneOffset;
let timezoneOffsetDefault = Number(moment().zone());
if (_.isFinite(o.timezoneOffsetOverride)) {
if (Number.isFinite(o.timezoneOffsetOverride)) {
timezoneOffset = Number(o.timezoneOffsetOverride);
} else if (_.isFinite(o.timezoneOffset)) {
} else if (Number.isFinite(o.timezoneOffset)) {
timezoneOffset = Number(o.timezoneOffset);
} else {
timezoneOffset = timezoneOffsetDefault;
@ -84,7 +85,7 @@ export function startOfDay (options = {}) {
export function daysSince (yesterday, options = {}) {
let o = sanitizeOptions(options);
return startOfDay(_.defaults({ now: o.now }, o)).diff(startOfDay(_.defaults({ now: yesterday }, o)), 'days');
return startOfDay(defaults({ now: o.now }, o)).diff(startOfDay(defaults({ now: yesterday }, o)), 'days');
}
/*

View file

@ -1,4 +1,10 @@
import _ from 'lodash';
import min from 'lodash/min';
import pick from 'lodash/pick';
import values from 'lodash/values';
import invert from 'lodash/invert';
import findIndex from 'lodash/findIndex';
import max from 'lodash/max';
import splitWhitespace from '../libs/splitWhitespace';
/*
@ -14,8 +20,8 @@ function getStatToAllocate (user) {
switch (user.preferences.allocationMode) {
case 'flat': {
let stats = _.pick(statsObj, splitWhitespace('con str per int'));
return _.invert(stats)[_.min(stats)];
let stats = pick(statsObj, splitWhitespace('con str per int'));
return invert(stats)[min(values(stats))];
}
case 'classbased': {
let preference;
@ -47,14 +53,14 @@ function getStatToAllocate (user) {
statsObj[preference[3]] - ideal[3],
];
suggested = _.findIndex(diff, (val) => {
if (val === _.min(diff)) return true;
suggested = findIndex(diff, (val) => {
if (val === min(diff)) return true;
});
return suggested !== -1 ? preference[suggested] : 'str';
}
case 'taskbased': {
suggested = _.invert(statsObj.training)[_.max(statsObj.training)];
suggested = invert(statsObj.training)[max(values(statsObj.training))];
user.stats.training.str = 0;
user.stats.training.int = 0;

View file

@ -1,4 +1,6 @@
import _ from 'lodash';
import omit from 'lodash/omit';
import reduce from 'lodash/reduce';
import isNumber from 'lodash/isNumber';
// Because the same op needs to be performed on the client and the server (critical hits, item drops, etc),
// we need things to be "random", but technically predictable so that they don't go out-of-sync
@ -8,10 +10,10 @@ module.exports = function predictableRandom (user, seed) {
let stats = user.stats.toObject ? user.stats.toObject() : user.stats;
// These items are not part of the stat object but exists on the server (see controllers/user#getUser)
// we remove them in order to use the same user.stats both on server and on client
stats = _.omit(stats, 'toNextLevel', 'maxHealth', 'maxMP');
stats = omit(stats, ['toNextLevel', 'maxHealth', 'maxMP']);
seed = _.reduce(stats, (accumulator, val) => {
if (_.isNumber(val)) {
seed = reduce(stats, (accumulator, val) => {
if (isNumber(val)) {
return accumulator + val;
} else {
return accumulator;

View file

@ -1,4 +1,9 @@
import _ from 'lodash';
import cloneDeepWith from 'lodash/cloneDeepWith';
import isFunction from 'lodash/isFunction';
import min from 'lodash/min';
import reduce from 'lodash/reduce';
import filter from 'lodash/filter';
import pickBy from 'lodash/pickBy';
import content from '../content/index';
import i18n from '../i18n';
import { daysSince } from '../cron';
@ -10,8 +15,8 @@ import randomVal from '../libs/randomVal';
// Clone a drop object maintaining its functions so that we can change it without affecting the original item
function cloneDropItem (drop) {
return _.cloneDeep(drop, (val) => {
return _.isFunction(val) ? val : undefined; // undefined will be handled by lodash
return cloneDeepWith(drop, (val) => {
return isFunction(val) ? val : undefined; // undefined will be handled by lodash
});
}
@ -28,14 +33,14 @@ module.exports = function randomDrop (user, options, req = {}) {
let predictableRandom = options.predictableRandom || trueRandom;
let task = options.task;
let chance = _.min([Math.abs(task.value - 21.27), 37.5]) / 150 + 0.02;
let chance = min([Math.abs(task.value - 21.27), 37.5]) / 150 + 0.02;
chance *= task.priority * // Task priority: +50% for Medium, +100% for Hard
(1 + (task.streak / 100 || 0)) * // Streak bonus: +1% per streak
(1 + user._statsComputed.per / 100) * // PERception: +1% per point
(1 + (user.contributor.level / 40 || 0)) * // Contrib levels: +2.5% per level
(1 + (user.achievements.rebirths / 20 || 0)) * // Rebirths: +5% per achievement
(1 + (user.achievements.streak / 200 || 0)) * // Streak achievements: +0.5% per achievement
(user._tmp.crit || 1) * (1 + 0.5 * (_.reduce(task.checklist, (m, i) => {
(user._tmp.crit || 1) * (1 + 0.5 * (reduce(task.checklist, (m, i) => {
return m + (i.completed ? 1 : 0); // +50% per checklist item complete. TODO: make this into X individual drop chances instead
}, 0) || 0));
chance = diminishingReturns(chance, 0.75);
@ -63,7 +68,7 @@ module.exports = function randomDrop (user, options, req = {}) {
rarity = predictableRandom();
if (rarity > 0.6) { // food 40% chance
drop = cloneDropItem(randomVal(_.where(content.food, {
drop = cloneDropItem(randomVal(filter(content.food, {
canDrop: true,
})));
@ -98,7 +103,7 @@ module.exports = function randomDrop (user, options, req = {}) {
} else { // common, 40% of 30%
acceptableDrops = ['Base', 'White', 'Desert'];
}
drop = cloneDropItem(randomVal(_.pick(content.hatchingPotions, (v, k) => {
drop = cloneDropItem(randomVal(pickBy(content.hatchingPotions, (v, k) => {
return acceptableDrops.indexOf(k) >= 0;
})));
if (!user.items.hatchingPotions[drop.key]) {

View file

@ -1,10 +1,10 @@
import _ from 'lodash';
import each from 'lodash/each';
import content from '../content/index';
module.exports = function resetGear (user) {
let gear = user.items.gear;
_.each(['equipped', 'costume'], function resetUserGear (type) {
each(['equipped', 'costume'], function resetUserGear (type) {
gear[type] = {};
gear[type].armor = 'armor_base_0';
gear[type].weapon = 'weapon_warrior_0';
@ -14,7 +14,7 @@ module.exports = function resetGear (user) {
// Gear.owned is a Mongo object so the _.each function iterates over hidden properties.
// The content.gear.flat[k] check should prevent this causing an error
_.each(gear.owned, function resetOwnedGear (v, k) {
each(gear.owned, function resetOwnedGear (v, k) {
if (gear.owned[k] && content.gear.flat[k] && content.gear.flat[k].value) {
gear.owned[k] = false;
}

View file

@ -1,13 +1,15 @@
import content from '../content/index';
import _ from 'lodash';
import lodashFind from 'lodash/find';
import reduce from 'lodash/reduce';
import includes from 'lodash/includes';
module.exports = function ultimateGear (user) {
let owned = typeof window !== 'undefined' ? user.items.gear.owned : user.items.gear.owned.toObject();
content.classes.forEach((klass) => {
if (user.achievements.ultimateGearSets[klass] !== true) {
user.achievements.ultimateGearSets[klass] = _.reduce(['armor', 'shield', 'head', 'weapon'], (soFarGood, type) => {
let found = _.find(content.gear.tree[type][klass], {
user.achievements.ultimateGearSets[klass] = reduce(['armor', 'shield', 'head', 'weapon'], (soFarGood, type) => {
let found = lodashFind(content.gear.tree[type][klass], {
last: true,
});
return soFarGood && (!found || owned[found.key] === true);
@ -26,7 +28,7 @@ module.exports = function ultimateGear (user) {
ultimateGearSetValues = Object.values(user.achievements.ultimateGearSets);
}
let hasFullSet = _.includes(ultimateGearSetValues, true);
let hasFullSet = includes(ultimateGearSetValues, true);
if (hasFullSet && user.flags.armoireEnabled !== true) {
user.flags.armoireEnabled = true;

View file

@ -1,4 +1,4 @@
import _ from 'lodash';
import each from 'lodash/each';
import {
MAX_HEALTH,
MAX_STAT_POINTS,
@ -67,7 +67,7 @@ module.exports = function updateStats (user, stats, req = {}, analytics) {
user.items.eggs.Wolf = 1;
}
}
_.each({
each({
vice1: 30,
atom1: 15,
moonstone1: 60,

View file

@ -1,4 +1,6 @@
import _ from 'lodash';
import isString from 'lodash/isString';
import clone from 'lodash/clone';
import template from 'lodash/template';
let i18n = {
strings: null,
@ -10,7 +12,7 @@ function t (stringName) {
let vars = arguments[1];
let locale;
if (_.isString(arguments[1])) {
if (isString(arguments[1])) {
vars = null;
locale = arguments[1];
} else if (arguments[2]) {
@ -31,13 +33,13 @@ function t (stringName) {
string = i18n.translations[locale] && i18n.translations[locale][stringName];
}
let clonedVars = _.clone(vars) || {};
let clonedVars = clone(vars) || {};
clonedVars.locale = locale;
if (string) {
try {
return _.template(string)(clonedVars);
return template(string)(clonedVars);
} catch (_error) {
return 'Error processing the string. Please see Help > Report a Bug.';
}
@ -51,7 +53,7 @@ function t (stringName) {
}
try {
return _.template(stringNotFound)({
return template(stringNotFound)({
string: stringName,
});
} catch (_error) {

View file

@ -1,4 +1,4 @@
import _ from 'lodash';
import partial from 'lodash/partial';
// When using a common module from the website or the server NEVER import the module directly
// but access it through `api` (the main common) module, otherwise you would require the non transpiled version of the file in production.
@ -250,59 +250,59 @@ api.wrap = function wrapUser (user, main = true) {
if (main) {
user.ops = {
sleep: _.partial(importedOps.sleep, user),
revive: _.partial(importedOps.revive, user),
reset: _.partial(importedOps.reset, user),
reroll: _.partial(importedOps.reroll, user),
rebirth: _.partial(importedOps.rebirth, user),
allocateNow: _.partial(importedOps.allocateNow, user),
sortTask: _.partial(importedOps.sortTask, user),
updateTask: _.partial(importedOps.updateTask, user),
deleteTask: _.partial(importedOps.deleteTask, user),
addTask: _.partial(importedOps.addTask, user),
addTag: _.partial(importedOps.addTag, user),
sortTag: _.partial(importedOps.sortTag, user),
updateTag: _.partial(importedOps.updateTag, user),
deleteTag: _.partial(importedOps.deleteTag, user),
clearPMs: _.partial(importedOps.clearPMs, user),
deletePM: _.partial(importedOps.deletePM, user),
blockUser: _.partial(importedOps.blockUser, user),
feed: _.partial(importedOps.feed, user),
buySpecialSpell: _.partial(importedOps.buySpecialSpell, user),
purchase: _.partial(importedOps.purchase, user),
releasePets: _.partial(importedOps.releasePets, user),
releaseMounts: _.partial(importedOps.releaseMounts, user),
releaseBoth: _.partial(importedOps.releaseBoth, user),
buy: _.partial(importedOps.buy, user),
buyHealthPotion: _.partial(importedOps.buyHealthPotion, user),
buyArmoire: _.partial(importedOps.buyArmoire, user),
buyGear: _.partial(importedOps.buyGear, user),
buyQuest: _.partial(importedOps.buyQuest, user),
buyMysterySet: _.partial(importedOps.buyMysterySet, user),
hourglassPurchase: _.partial(importedOps.hourglassPurchase, user),
sell: _.partial(importedOps.sell, user),
equip: _.partial(importedOps.equip, user),
hatch: _.partial(importedOps.hatch, user),
unlock: _.partial(importedOps.unlock, user),
changeClass: _.partial(importedOps.changeClass, user),
disableClasses: _.partial(importedOps.disableClasses, user),
allocate: _.partial(importedOps.allocate, user),
readCard: _.partial(importedOps.readCard, user),
openMysteryItem: _.partial(importedOps.openMysteryItem, user),
score: _.partial(importedOps.scoreTask, user),
markPmsRead: _.partial(importedOps.markPmsRead, user),
sleep: partial(importedOps.sleep, user),
revive: partial(importedOps.revive, user),
reset: partial(importedOps.reset, user),
reroll: partial(importedOps.reroll, user),
rebirth: partial(importedOps.rebirth, user),
allocateNow: partial(importedOps.allocateNow, user),
sortTask: partial(importedOps.sortTask, user),
updateTask: partial(importedOps.updateTask, user),
deleteTask: partial(importedOps.deleteTask, user),
addTask: partial(importedOps.addTask, user),
addTag: partial(importedOps.addTag, user),
sortTag: partial(importedOps.sortTag, user),
updateTag: partial(importedOps.updateTag, user),
deleteTag: partial(importedOps.deleteTag, user),
clearPMs: partial(importedOps.clearPMs, user),
deletePM: partial(importedOps.deletePM, user),
blockUser: partial(importedOps.blockUser, user),
feed: partial(importedOps.feed, user),
buySpecialSpell: partial(importedOps.buySpecialSpell, user),
purchase: partial(importedOps.purchase, user),
releasePets: partial(importedOps.releasePets, user),
releaseMounts: partial(importedOps.releaseMounts, user),
releaseBoth: partial(importedOps.releaseBoth, user),
buy: partial(importedOps.buy, user),
buyHealthPotion: partial(importedOps.buyHealthPotion, user),
buyArmoire: partial(importedOps.buyArmoire, user),
buyGear: partial(importedOps.buyGear, user),
buyQuest: partial(importedOps.buyQuest, user),
buyMysterySet: partial(importedOps.buyMysterySet, user),
hourglassPurchase: partial(importedOps.hourglassPurchase, user),
sell: partial(importedOps.sell, user),
equip: partial(importedOps.equip, user),
hatch: partial(importedOps.hatch, user),
unlock: partial(importedOps.unlock, user),
changeClass: partial(importedOps.changeClass, user),
disableClasses: partial(importedOps.disableClasses, user),
allocate: partial(importedOps.allocate, user),
readCard: partial(importedOps.readCard, user),
openMysteryItem: partial(importedOps.openMysteryItem, user),
score: partial(importedOps.scoreTask, user),
markPmsRead: partial(importedOps.markPmsRead, user),
};
}
user.fns = {
handleTwoHanded: _.partial(importedFns.handleTwoHanded, user),
predictableRandom: _.partial(importedFns.predictableRandom, user),
crit: _.partial(importedFns.crit.crit, user),
randomDrop: _.partial(importedFns.randomDrop, user),
autoAllocate: _.partial(importedFns.autoAllocate, user),
updateStats: _.partial(importedFns.updateStats, user),
statsComputed: _.partial(statsComputed, user),
ultimateGear: _.partial(importedFns.ultimateGear, user),
handleTwoHanded: partial(importedFns.handleTwoHanded, user),
predictableRandom: partial(importedFns.predictableRandom, user),
crit: partial(importedFns.crit.crit, user),
randomDrop: partial(importedFns.randomDrop, user),
autoAllocate: partial(importedFns.autoAllocate, user),
updateStats: partial(importedFns.updateStats, user),
statsComputed: partial(statsComputed, user),
ultimateGear: partial(importedFns.ultimateGear, user),
};
Object.defineProperty(user, '_statsComputed', {

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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;
}));
};

View file

@ -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;
};

View file

@ -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,
}));

Some files were not shown because too many files have changed in this diff Show more