start upgrading eslint

This commit is contained in:
Matteo Pagliazzi
2019-10-08 16:57:10 +02:00
parent 90c917f69e
commit 621787915c
304 changed files with 5992 additions and 6394 deletions

View File

@@ -1,10 +1,11 @@
{
"root": true,
"env": {
"node": true,
},
"extends": [
"habitrpg",
"habitrpg/esnext"
"habitrpg/lib/node"
],
"rules": {
'no-param-reassign': ['error', {
props: false,
}],
}
}

View File

@@ -4,12 +4,12 @@ import apidoc from 'apidoc';
const APIDOC_DEST_PATH = './apidoc_build';
const APIDOC_SRC_PATH = './website/server';
gulp.task('apidoc:clean', (done) => {
gulp.task('apidoc:clean', done => {
clean(APIDOC_DEST_PATH, done);
});
gulp.task('apidoc', gulp.series('apidoc:clean', (done) => {
let result = apidoc.createDoc({
gulp.task('apidoc', gulp.series('apidoc:clean', done => {
const result = apidoc.createDoc({
src: APIDOC_SRC_PATH,
dest: APIDOC_DEST_PATH,
});
@@ -21,6 +21,4 @@ gulp.task('apidoc', gulp.series('apidoc:clean', (done) => {
}
}));
gulp.task('apidoc:watch', gulp.series('apidoc', (done) => {
return gulp.watch(`${APIDOC_SRC_PATH}/**/*.js`, gulp.series('apidoc', done));
}));
gulp.task('apidoc:watch', gulp.series('apidoc', done => gulp.watch(`${APIDOC_SRC_PATH}/**/*.js`, gulp.series('apidoc', done))));

View File

@@ -1,32 +1,28 @@
import gulp from 'gulp';
import babel from 'gulp-babel';
gulp.task('build:src', () => {
return gulp.src('website/server/**/*.js')
gulp.task('build:src', () => gulp.src('website/server/**/*.js')
.pipe(babel())
.pipe(gulp.dest('website/transpiled-babel/'));
});
.pipe(gulp.dest('website/transpiled-babel/')));
gulp.task('build:common', () => {
return gulp.src('website/common/script/**/*.js')
gulp.task('build:common', () => gulp.src('website/common/script/**/*.js')
.pipe(babel())
.pipe(gulp.dest('website/common/transpiled-babel/'));
});
.pipe(gulp.dest('website/common/transpiled-babel/')));
gulp.task('build:server', gulp.series('build:src', 'build:common', done => done()));
gulp.task('build:prod', gulp.series(
'build:server',
'apidoc',
done => done()
done => done(),
));
let buildArgs = [];
const buildArgs = [];
if (process.env.NODE_ENV === 'production') { // eslint-disable-line no-process-env
buildArgs.push('build:prod');
}
gulp.task('build', gulp.series(buildArgs, (done) => {
gulp.task('build', gulp.series(buildArgs, done => {
done();
}));

View File

@@ -1,22 +1,26 @@
import mongoose from 'mongoose';
import logger from '../website/server/libs/logger';
import nconf from 'nconf';
import repl from 'repl';
import gulp from 'gulp';
import logger from '../website/server/libs/logger';
// Add additional properties to the repl's context
let improveRepl = (context) => {
const improveRepl = context => {
// Let "exit" and "quit" terminate the console
['exit', 'quit'].forEach((term) => {
Object.defineProperty(context, term, { get () {
['exit', 'quit'].forEach(term => {
Object.defineProperty(context, term, {
get () { // eslint-disable-line getter-return
process.exit();
}});
},
});
});
// "clear" clears the screen
Object.defineProperty(context, 'clear', { get () {
Object.defineProperty(context, 'clear', {
get () { // eslint-disable-line getter-return
process.stdout.write('\u001B[2J\u001B[0;0f');
}});
},
});
context.Challenge = require('../website/server/models/challenge').model; // eslint-disable-line global-require
context.Group = require('../website/server/models/group').model; // eslint-disable-line global-require
@@ -30,14 +34,14 @@ let improveRepl = (context) => {
mongoose.connect(
nconf.get('NODE_DB_URI'),
mongooseOptions,
(err) => {
err => {
if (err) throw err;
logger.info('Connected with Mongoose');
}
},
);
};
gulp.task('console', (done) => {
gulp.task('console', done => {
improveRepl(repl.start({
prompt: 'Habitica > ',
}).context);

View File

@@ -16,17 +16,17 @@ const IMG_DIST_PATH = 'website/client/src/assets/images/sprites/';
const CSS_DIST_PATH = 'website/client/src/assets/css/sprites/';
function checkForSpecialTreatment (name) {
let regex = /^hair|skin|beard|mustach|shirt|flower|^headAccessory_special_\w+Ears|^eyewear_special_\w+TopFrame|^eyewear_special_\w+HalfMoon/;
const regex = /^hair|skin|beard|mustach|shirt|flower|^headAccessory_special_\w+Ears|^eyewear_special_\w+TopFrame|^eyewear_special_\w+HalfMoon/;
return name.match(regex) || name === 'head_0';
}
function calculateImgDimensions (img, addPadding) {
let dims = sizeOf(img);
let requiresSpecialTreatment = checkForSpecialTreatment(img);
const requiresSpecialTreatment = checkForSpecialTreatment(img);
if (requiresSpecialTreatment) {
let newWidth = dims.width < 90 ? 90 : dims.width;
let newHeight = dims.height < 90 ? 90 : dims.height;
const newWidth = dims.width < 90 ? 90 : dims.width;
const newHeight = dims.height < 90 ? 90 : dims.height;
dims = {
width: newWidth,
height: newHeight,
@@ -41,17 +41,17 @@ function calculateImgDimensions (img, addPadding) {
if (!dims.width || !dims.height) console.error('MISSING DIMENSIONS:', dims); // eslint-disable-line no-console
let totalPixelSize = dims.width * dims.height + padding;
const totalPixelSize = dims.width * dims.height + padding;
return totalPixelSize;
}
function calculateSpritesheetsSrcIndicies (src) {
let totalPixels = 0;
let slices = [0];
const slices = [0];
each(src, (img, index) => {
let imageSize = calculateImgDimensions(img, true);
const imageSize = calculateImgDimensions(img, true);
totalPixels += imageSize;
if (totalPixels > MAX_SPRITESHEET_SIZE) {
@@ -64,10 +64,10 @@ function calculateSpritesheetsSrcIndicies (src) {
}
function cssVarMap (sprite) {
// For hair, skins, beards, etc. we want to output a '.customize-options.WHATEVER' class, which works as a
// 60x60 image pointing at the proper part of the 90x90 sprite.
// For hair, skins, beards, etc. we want to output a '.customize-options.WHATEVER' class,
// which works as a 60x60 image pointing at the proper part of the 90x90 sprite.
// We set up the custom info here, and the template makes use of it.
let requiresSpecialTreatment = checkForSpecialTreatment(sprite.name);
const requiresSpecialTreatment = checkForSpecialTreatment(sprite.name);
if (requiresSpecialTreatment) {
sprite.custom = {
px: {
@@ -78,23 +78,21 @@ function cssVarMap (sprite) {
},
};
}
if (sprite.name.indexOf('shirt') !== -1)
sprite.custom.px.offsetY = `-${ sprite.y + 35 }px`; // even more for shirts
if (sprite.name.indexOf('shirt') !== -1) sprite.custom.px.offsetY = `-${sprite.y + 35}px`; // even more for shirts
if (sprite.name.indexOf('hair_base') !== -1) {
let styleArray = sprite.name.split('_').slice(2, 3);
if (Number(styleArray[0]) > 14)
sprite.custom.px.offsetY = `-${ sprite.y }px`; // don't crop updos
const styleArray = sprite.name.split('_').slice(2, 3);
if (Number(styleArray[0]) > 14) sprite.custom.px.offsetY = `-${sprite.y}px`; // don't crop updos
}
}
function createSpritesStream (name, src) {
let spritesheetSliceIndicies = calculateSpritesheetsSrcIndicies(src);
let stream = mergeStream();
const spritesheetSliceIndicies = calculateSpritesheetsSrcIndicies(src);
const stream = mergeStream();
each(spritesheetSliceIndicies, (start, index) => {
let slicedSrc = src.slice(start, spritesheetSliceIndicies[index + 1]);
const slicedSrc = src.slice(start, spritesheetSliceIndicies[index + 1]);
let spriteData = gulp.src(slicedSrc)
const spriteData = gulp.src(slicedSrc)
.pipe(spritesmith({
imgName: `spritesmith-${name}-${index}.png`,
cssName: `spritesmith-${name}-${index}.css`,
@@ -104,12 +102,12 @@ function createSpritesStream (name, src) {
cssVarMap,
}));
let imgStream = spriteData.img
const imgStream = spriteData.img
.pipe(vinylBuffer())
.pipe(imagemin())
.pipe(gulp.dest(IMG_DIST_PATH));
let cssStream = spriteData.css
const cssStream = spriteData.css
.pipe(gulp.dest(CSS_DIST_PATH));
stream.add(imgStream);
@@ -120,32 +118,32 @@ function createSpritesStream (name, src) {
}
gulp.task('sprites:main', () => {
let mainSrc = sync('website/raw_sprites/spritesmith/**/*.png');
const mainSrc = sync('website/raw_sprites/spritesmith/**/*.png');
return createSpritesStream('main', mainSrc);
});
gulp.task('sprites:largeSprites', () => {
let largeSrc = sync('website/raw_sprites/spritesmith_large/**/*.png');
const largeSrc = sync('website/raw_sprites/spritesmith_large/**/*.png');
return createSpritesStream('largeSprites', largeSrc);
});
gulp.task('sprites:clean', (done) => {
gulp.task('sprites:clean', done => {
clean(`${IMG_DIST_PATH}spritesmith*,${CSS_DIST_PATH}spritesmith*}`, done);
});
gulp.task('sprites:checkCompiledDimensions', gulp.series('sprites:main', 'sprites:largeSprites', (done) => {
gulp.task('sprites:checkCompiledDimensions', gulp.series('sprites:main', 'sprites:largeSprites', done => {
console.log('Verifiying that images do not exceed max dimensions'); // eslint-disable-line no-console
let numberOfSheetsThatAreTooBig = 0;
let distSpritesheets = sync(`${IMG_DIST_PATH}*.png`);
const distSpritesheets = sync(`${IMG_DIST_PATH}*.png`);
each(distSpritesheets, (img) => {
let spriteSize = calculateImgDimensions(img);
each(distSpritesheets, img => {
const spriteSize = calculateImgDimensions(img);
if (spriteSize > MAX_SPRITESHEET_SIZE) {
numberOfSheetsThatAreTooBig++;
let name = basename(img, '.png');
numberOfSheetsThatAreTooBig += 1;
const name = basename(img, '.png');
console.error(`WARNING: ${name} might be too big - ${spriteSize} > ${MAX_SPRITESHEET_SIZE}`); // eslint-disable-line no-console
}
});
@@ -155,7 +153,8 @@ gulp.task('sprites:checkCompiledDimensions', gulp.series('sprites:main', 'sprite
console.error( // eslint-disable-line no-console
`${numberOfSheetsThatAreTooBig} sheets might too big for mobile Safari to be able to handle
them, but there is a margin of error in these calculations so it is probably okay. Mention
this to an admin so they can test a staging site on mobile Safari after your PR is merged.`);
this to an admin so they can test a staging site on mobile Safari after your PR is merged.`,
);
} else {
console.log('All images are within the correct dimensions'); // eslint-disable-line no-console
}

View File

@@ -1,9 +1,9 @@
import gulp from 'gulp';
import nodemon from 'gulp-nodemon';
let pkg = require('../package.json');
const pkg = require('../package.json');
gulp.task('nodemon', (done) => {
gulp.task('nodemon', done => {
nodemon({
script: pkg.main,
ignore: [

View File

@@ -1,11 +1,11 @@
import {
pipe,
} from './taskHelper';
import mongoose from 'mongoose';
import { exec } from 'child_process';
import gulp from 'gulp';
import os from 'os';
import nconf from 'nconf';
import {
pipe,
} from './taskHelper';
// TODO rewrite
@@ -20,41 +20,40 @@ const CONTENT_TEST_COMMAND = 'npm run test:content';
const CONTENT_OPTIONS = { maxBuffer: 1024 * 500 };
/* Helper methods for reporting test summary */
let testResults = [];
let testCount = (stdout, regexp) => {
let match = stdout.match(regexp);
return parseInt(match && match[1] || 0, 10);
const testResults = [];
const testCount = (stdout, regexp) => {
const match = stdout.match(regexp);
return parseInt(match && (match[1] || 0), 10);
};
let testBin = (string, additionalEnvVariables = '') => {
const testBin = (string, additionalEnvVariables = '') => {
if (os.platform() === 'win32') {
if (additionalEnvVariables !== '') {
additionalEnvVariables = additionalEnvVariables.split(' ').join('&&set ');
additionalEnvVariables = `set ${additionalEnvVariables}&&`;
}
return `set NODE_ENV=test&&${additionalEnvVariables}${string}`;
} else {
return `NODE_ENV=test ${additionalEnvVariables} ${string}`;
}
return `NODE_ENV=test ${additionalEnvVariables} ${string}`;
};
gulp.task('test:nodemon', gulp.series(function setupNodemon (done) {
gulp.task('test:nodemon', gulp.series(done => {
process.env.PORT = TEST_SERVER_PORT; // eslint-disable-line no-process-env
process.env.NODE_DB_URI = TEST_DB_URI; // eslint-disable-line no-process-env
done();
}, 'nodemon'));
gulp.task('test:prepare:mongo', (cb) => {
mongoose.connect(TEST_DB_URI, (err) => {
gulp.task('test:prepare:mongo', cb => {
mongoose.connect(TEST_DB_URI, err => {
if (err) return cb(`Unable to connect to mongo database. Are you sure it's running? \n\n${err}`);
mongoose.connection.dropDatabase((err2) => {
mongoose.connection.dropDatabase(err2 => {
if (err2) return cb(err2);
mongoose.connection.close(cb);
});
});
});
gulp.task('test:prepare:server', gulp.series('test:prepare:mongo', (done) => {
gulp.task('test:prepare:server', gulp.series('test:prepare:mongo', done => {
if (!server) {
server = exec(testBin('node ./website/server/index.js', `NODE_DB_URI=${TEST_DB_URI} PORT=${TEST_SERVER_PORT}`), (error, stdout, stderr) => {
if (error) {
@@ -73,45 +72,43 @@ gulp.task('test:prepare:build', gulp.series('build', done => done()));
gulp.task('test:prepare', gulp.series(
'test:prepare:build',
'test:prepare:mongo',
done => done()
done => done(),
));
gulp.task('test:sanity', (cb) => {
let runner = exec(
gulp.task('test:sanity', cb => {
const runner = exec(
testBin(SANITY_TEST_COMMAND),
(err) => {
err => {
if (err) {
process.exit(1);
}
cb();
}
},
);
pipe(runner);
});
gulp.task('test:common', gulp.series('test:prepare:build', (cb) => {
let runner = exec(
gulp.task('test:common', gulp.series('test:prepare:build', cb => {
const runner = exec(
testBin(COMMON_TEST_COMMAND),
(err) => {
err => {
if (err) {
process.exit(1);
}
cb();
}
},
);
pipe(runner);
}));
gulp.task('test:common:clean', (cb) => {
gulp.task('test:common:clean', cb => {
pipe(exec(testBin(COMMON_TEST_COMMAND), () => cb()));
});
gulp.task('test:common:watch', gulp.series('test:common:clean', () => {
return gulp.watch(['common/script/**/*', 'test/common/**/*'], gulp.series('test:common:clean', done => done()));
}));
gulp.task('test:common:watch', gulp.series('test:common:clean', () => gulp.watch(['common/script/**/*', 'test/common/**/*'], gulp.series('test:common:clean', done => done()))));
gulp.task('test:common:safe', gulp.series('test:prepare:build', (cb) => {
let runner = exec(
gulp.task('test:common:safe', gulp.series('test:prepare:build', cb => {
const runner = exec(
testBin(COMMON_TEST_COMMAND),
(err, stdout) => { // eslint-disable-line handle-callback-err
testResults.push({
@@ -121,35 +118,33 @@ gulp.task('test:common:safe', gulp.series('test:prepare:build', (cb) => {
pend: testCount(stdout, /(\d+) pending/),
});
cb();
}
},
);
pipe(runner);
}));
gulp.task('test:content', gulp.series('test:prepare:build', (cb) => {
let runner = exec(
gulp.task('test:content', gulp.series('test:prepare:build', cb => {
const runner = exec(
testBin(CONTENT_TEST_COMMAND),
CONTENT_OPTIONS,
(err) => {
err => {
if (err) {
process.exit(1);
}
cb();
}
},
);
pipe(runner);
}));
gulp.task('test:content:clean', (cb) => {
gulp.task('test:content:clean', cb => {
pipe(exec(testBin(CONTENT_TEST_COMMAND), CONTENT_OPTIONS, () => cb()));
});
gulp.task('test:content:watch', gulp.series('test:content:clean', () => {
return gulp.watch(['common/script/content/**', 'test/**'], gulp.series('test:content:clean', done => done()));
}));
gulp.task('test:content:watch', gulp.series('test:content:clean', () => gulp.watch(['common/script/content/**', 'test/**'], gulp.series('test:content:clean', done => done()))));
gulp.task('test:content:safe', gulp.series('test:prepare:build', (cb) => {
let runner = exec(
gulp.task('test:content:safe', gulp.series('test:prepare:build', cb => {
const runner = exec(
testBin(CONTENT_TEST_COMMAND),
CONTENT_OPTIONS,
(err, stdout) => { // eslint-disable-line handle-callback-err
@@ -160,81 +155,77 @@ gulp.task('test:content:safe', gulp.series('test:prepare:build', (cb) => {
pend: testCount(stdout, /(\d+) pending/),
});
cb();
}
},
);
pipe(runner);
}));
gulp.task('test:api:unit', (done) => {
let runner = exec(
gulp.task('test:api:unit', done => {
const runner = exec(
testBin('istanbul cover --dir coverage/api-unit node_modules/mocha/bin/_mocha -- test/api/unit --recursive --require ./test/helpers/start-server'),
(err) => {
err => {
if (err) {
process.exit(1);
}
done();
}
},
);
pipe(runner);
});
gulp.task('test:api:unit:watch', () => {
return gulp.watch(['website/server/libs/*', 'test/api/unit/**/*', 'website/server/controllers/**/*'], gulp.series('test:api:unit', done => done()));
});
gulp.task('test:api:unit:watch', () => gulp.watch(['website/server/libs/*', 'test/api/unit/**/*', 'website/server/controllers/**/*'], gulp.series('test:api:unit', done => done())));
gulp.task('test:api-v3:integration', (done) => {
let runner = exec(
gulp.task('test:api-v3:integration', done => {
const runner = exec(
testBin('istanbul cover --dir coverage/api-v3-integration --report lcovonly node_modules/mocha/bin/_mocha -- test/api/v3/integration --recursive --require ./test/helpers/start-server'),
{ maxBuffer: 500 * 1024 },
(err) => {
err => {
if (err) {
process.exit(1);
}
done();
}
},
);
pipe(runner);
});
gulp.task('test:api-v3:integration:watch', () => {
return gulp.watch([
gulp.task('test:api-v3:integration:watch', () => gulp.watch([
'website/server/controllers/api-v3/**/*', 'common/script/ops/*', 'website/server/libs/*.js',
'test/api/v3/integration/**/*',
], gulp.series('test:api-v3:integration', done => done()));
});
], gulp.series('test:api-v3:integration', done => done())));
gulp.task('test:api-v3:integration:separate-server', (done) => {
let runner = exec(
gulp.task('test:api-v3:integration:separate-server', done => {
const runner = exec(
testBin('mocha test/api/v3/integration --recursive --require ./test/helpers/start-server', 'LOAD_SERVER=0'),
{ maxBuffer: 500 * 1024 },
(err) => done(err)
err => done(err),
);
pipe(runner);
});
gulp.task('test:api-v4:integration', (done) => {
let runner = exec(
gulp.task('test:api-v4:integration', done => {
const runner = exec(
testBin('istanbul cover --dir coverage/api-v4-integration --report lcovonly node_modules/mocha/bin/_mocha -- test/api/v4 --recursive --require ./test/helpers/start-server'),
{ maxBuffer: 500 * 1024 },
(err) => {
err => {
if (err) {
process.exit(1);
}
done();
}
},
);
pipe(runner);
});
gulp.task('test:api-v4:integration:separate-server', (done) => {
let runner = exec(
gulp.task('test:api-v4:integration:separate-server', done => {
const runner = exec(
testBin('mocha test/api/v4 --recursive --require ./test/helpers/start-server', 'LOAD_SERVER=0'),
{ maxBuffer: 500 * 1024 },
(err) => done(err)
err => done(err),
);
pipe(runner);
@@ -247,11 +238,11 @@ gulp.task('test', gulp.series(
'test:api:unit',
'test:api-v3:integration',
'test:api-v4:integration',
done => done()
done => done(),
));
gulp.task('test:api-v3', gulp.series(
'test:api:unit',
'test:api-v3:integration',
done => done()
done => done(),
));

View File

@@ -14,7 +14,7 @@ const ENGLISH_LOCALE = `${LOCALES}en/`;
function getArrayOfLanguages () {
let languages = fs.readdirSync(LOCALES);
const languages = fs.readdirSync(LOCALES);
languages.shift(); // Remove README.md from array of languages
return languages;
@@ -23,18 +23,16 @@ function getArrayOfLanguages () {
const ALL_LANGUAGES = getArrayOfLanguages();
function stripOutNonJsonFiles (collection) {
let onlyJson = _.filter(collection, (file) => {
return file.match(/[a-zA-Z]*\.json/);
});
const onlyJson = _.filter(collection, file => file.match(/[a-zA-Z]*\.json/));
return onlyJson;
}
function eachTranslationFile (languages, cb) {
let jsonFiles = stripOutNonJsonFiles(fs.readdirSync(ENGLISH_LOCALE));
const jsonFiles = stripOutNonJsonFiles(fs.readdirSync(ENGLISH_LOCALE));
_.each(languages, (lang) => {
_.each(jsonFiles, (filename) => {
_.each(languages, lang => {
_.each(jsonFiles, filename => {
let parsedTranslationFile;
try {
const translationFile = fs.readFileSync(`${LOCALES}${lang}/${filename}`);
@@ -43,8 +41,8 @@ function eachTranslationFile (languages, cb) {
return cb(err);
}
let englishFile = fs.readFileSync(ENGLISH_LOCALE + filename);
let parsedEnglishFile = JSON.parse(englishFile);
const englishFile = fs.readFileSync(ENGLISH_LOCALE + filename);
const parsedEnglishFile = JSON.parse(englishFile);
cb(null, lang, filename, parsedEnglishFile, parsedTranslationFile);
});
@@ -71,9 +69,9 @@ function formatMessageForPosting (msg, items) {
}
function getStringsWith (json, interpolationRegex) {
let strings = {};
const strings = {};
_.each(json, (fileName) => {
_.each(json, fileName => {
const rawFile = fs.readFileSync(ENGLISH_LOCALE + fileName);
const parsedJson = JSON.parse(rawFile);
@@ -93,66 +91,69 @@ const malformedStringExceptions = {
feedPet: true,
};
gulp.task('transifex:missingFiles', (done) => {
let missingStrings = [];
gulp.task('transifex:missingFiles', done => {
const missingStrings = [];
eachTranslationFile(ALL_LANGUAGES, (error) => {
eachTranslationFile(ALL_LANGUAGES, error => {
if (error) {
missingStrings.push(error.path);
}
});
if (!_.isEmpty(missingStrings)) {
let message = 'the following files were missing from the translations folder';
let formattedMessage = formatMessageForPosting(message, missingStrings);
const message = 'the following files were missing from the translations folder';
const formattedMessage = formatMessageForPosting(message, missingStrings);
postToSlack(formattedMessage, SLACK_CONFIG);
}
done();
});
gulp.task('transifex:missingStrings', (done) => {
let missingStrings = [];
gulp.task('transifex:missingStrings', done => {
const missingStrings = [];
eachTranslationString(ALL_LANGUAGES, (language, filename, key, englishString, translationString) => {
eachTranslationString(ALL_LANGUAGES, (lang, filename, key, englishString, translationString) => {
if (!translationString) {
let errorString = `${language} - ${filename} - ${key} - ${englishString}`;
const errorString = `${lang} - ${filename} - ${key} - ${englishString}`;
missingStrings.push(errorString);
}
});
if (!_.isEmpty(missingStrings)) {
let message = 'The following strings are not translated';
let formattedMessage = formatMessageForPosting(message, missingStrings);
const message = 'The following strings are not translated';
const formattedMessage = formatMessageForPosting(message, missingStrings);
postToSlack(formattedMessage, SLACK_CONFIG);
}
done();
});
gulp.task('transifex:malformedStrings', (done) => {
let jsonFiles = stripOutNonJsonFiles(fs.readdirSync(ENGLISH_LOCALE));
let interpolationRegex = /<%= [a-zA-Z]* %>/g;
let stringsToLookFor = getStringsWith(jsonFiles, interpolationRegex);
gulp.task('transifex:malformedStrings', done => {
const jsonFiles = stripOutNonJsonFiles(fs.readdirSync(ENGLISH_LOCALE));
const interpolationRegex = /<%= [a-zA-Z]* %>/g;
const stringsToLookFor = getStringsWith(jsonFiles, interpolationRegex);
let stringsWithMalformedInterpolations = [];
let stringsWithIncorrectNumberOfInterpolations = [];
const stringsWithMalformedInterpolations = [];
const stringsWithIncorrectNumberOfInterpolations = [];
_.each(ALL_LANGUAGES, (lang) => {
_.each(ALL_LANGUAGES, lang => {
_.each(stringsToLookFor, (strings, filename) => {
let translationFile = fs.readFileSync(`${LOCALES}${lang}/${filename}`);
let parsedTranslationFile = JSON.parse(translationFile);
const translationFile = fs.readFileSync(`${LOCALES}${lang}/${filename}`);
const parsedTranslationFile = JSON.parse(translationFile);
_.each(strings, (value, key) => { // eslint-disable-line max-nested-callbacks
let translationString = parsedTranslationFile[key];
const translationString = parsedTranslationFile[key];
if (!translationString) return;
let englishOccurences = stringsToLookFor[filename][key];
let translationOccurences = translationString.match(interpolationRegex);
const englishOccurences = stringsToLookFor[filename][key];
const translationOccurences = translationString.match(interpolationRegex);
if (!translationOccurences) {
let malformedString = `${lang} - ${filename} - ${key} - ${translationString}`;
const malformedString = `${lang} - ${filename} - ${key} - ${translationString}`;
stringsWithMalformedInterpolations.push(malformedString);
} else if (englishOccurences.length !== translationOccurences.length && !malformedStringExceptions[key]) {
let missingInterpolationString = `${lang} - ${filename} - ${key} - ${translationString}`;
} else if (
englishOccurences.length !== translationOccurences.length
&& !malformedStringExceptions[key]
) {
const missingInterpolationString = `${lang} - ${filename} - ${key} - ${translationString}`;
stringsWithIncorrectNumberOfInterpolations.push(missingInterpolationString);
}
});
@@ -160,14 +161,17 @@ gulp.task('transifex:malformedStrings', (done) => {
});
if (!_.isEmpty(stringsWithMalformedInterpolations)) {
let message = 'The following strings have malformed or missing interpolations';
let formattedMessage = formatMessageForPosting(message, stringsWithMalformedInterpolations);
const message = 'The following strings have malformed or missing interpolations';
const formattedMessage = formatMessageForPosting(message, stringsWithMalformedInterpolations);
postToSlack(formattedMessage, SLACK_CONFIG);
}
if (!_.isEmpty(stringsWithIncorrectNumberOfInterpolations)) {
let message = 'The following strings have a different number of string interpolations';
let formattedMessage = formatMessageForPosting(message, stringsWithIncorrectNumberOfInterpolations);
const message = 'The following strings have a different number of string interpolations';
const formattedMessage = formatMessageForPosting(
message,
stringsWithIncorrectNumberOfInterpolations,
);
postToSlack(formattedMessage, SLACK_CONFIG);
}
done();
@@ -176,5 +180,5 @@ gulp.task('transifex:malformedStrings', (done) => {
gulp.task(
'transifex',
gulp.series('transifex:missingFiles', 'transifex:missingStrings', 'transifex:malformedStrings'),
(done) => done()
done => done(),
);

View File

@@ -4,7 +4,7 @@ import nconf from 'nconf';
import net from 'net';
import { post } from 'superagent';
import { sync as glob } from 'glob';
import Mocha from 'mocha';
import Mocha from 'mocha'; // eslint-disable-line import/no-extraneous-dependencies
import { resolve } from 'path';
/*
@@ -19,15 +19,15 @@ export const conf = nconf;
* its tasks.
*/
export function kill (proc) {
let killProcess = (pid) => {
const killProcess = pid => {
psTree(pid, (_, pids) => {
if (pids.length) {
pids.forEach(kill); return;
}
try {
exec(/^win/.test(process.platform) ?
`taskkill /PID ${pid} /T /F` :
`kill -9 ${pid}`);
exec(/^win/.test(process.platform)
? `taskkill /PID ${pid} /T /F`
: `kill -9 ${pid}`);
} catch (e) {
console.log(e); // eslint-disable-line no-console
}
@@ -46,10 +46,9 @@ export function kill (proc) {
export function awaitPort (port, max = 60) {
return new Promise((rej, res) => {
let socket;
let timeout;
let interval;
timeout = setTimeout(() => {
const timeout = setTimeout(() => {
clearInterval(interval);
rej(`Timed out after ${max} seconds`);
}, max * 1000);
@@ -71,10 +70,10 @@ export function awaitPort (port, max = 60) {
* Pipe the child's stdin and stderr to the parent process.
*/
export function pipe (child) {
child.stdout.on('data', (data) => {
child.stdout.on('data', data => {
process.stdout.write(data);
});
child.stderr.on('data', (data) => {
child.stderr.on('data', data => {
process.stderr.write(data);
});
}
@@ -83,7 +82,7 @@ export function pipe (child) {
* Post request to notify configured slack channel
*/
export function postToSlack (msg, config = {}) {
let slackUrl = nconf.get('SLACK_URL');
const slackUrl = nconf.get('SLACK_URL');
if (!slackUrl) {
console.error('No slack post url specified. Your message was:'); // eslint-disable-line no-console
@@ -99,7 +98,7 @@ export function postToSlack (msg, config = {}) {
text: msg,
icon_emoji: `:${config.emoji || 'gulp'}:`, // eslint-disable-line camelcase
})
.end((err) => {
.end(err => {
if (err) console.error('Unable to post to slack', err); // eslint-disable-line no-console
});
}
@@ -107,15 +106,15 @@ export function postToSlack (msg, config = {}) {
export function runMochaTests (files, server, cb) {
require('../test/helpers/globals.helper'); // eslint-disable-line global-require
let mocha = new Mocha({reporter: 'spec'});
let tests = glob(files);
const mocha = new Mocha({ reporter: 'spec' });
const tests = glob(files);
tests.forEach((test) => {
tests.forEach(test => {
delete require.cache[resolve(test)];
mocha.addFile(test);
});
mocha.run((numberOfFailures) => {
mocha.run(numberOfFailures => {
if (!process.env.RUN_INTEGRATION_TEST_FOREVER) { // eslint-disable-line no-process-env
if (server) kill(server);
process.exit(numberOfFailures);

View File

@@ -2,14 +2,14 @@ import { model as Challenges } from '../../website/server/models/challenge';
import { model as User } from '../../website/server/models/user';
async function syncChallengeToMembers (challenges) {
let challengSyncPromises = challenges.map(async (challenge) => {
let users = await User.find({
const challengSyncPromises = challenges.map(async challenge => {
const users = await User.find({
// _id: '',
challenges: challenge._id,
}).exec();
let promises = [];
users.forEach((user) => {
const promises = [];
users.forEach(user => {
promises.push(challenge.syncToUser(user));
promises.push(challenge.save());
promises.push(user.save());
@@ -22,7 +22,7 @@ async function syncChallengeToMembers (challenges) {
}
async function syncChallenges (lastChallengeDate) {
let query = {
const query = {
// _id: '',
};
@@ -30,14 +30,14 @@ async function syncChallenges (lastChallengeDate) {
query.createdOn = { $lte: lastChallengeDate };
}
let challengesFound = await Challenges.find(query)
const challengesFound = await Challenges.find(query)
.limit(10)
.sort('-createdAt')
.exec();
let syncedChallenges = await syncChallengeToMembers(challengesFound)
const syncedChallenges = await syncChallengeToMembers(challengesFound)
.catch(reason => console.error(reason));
let lastChallenge = challengesFound[challengesFound.length - 1];
const lastChallenge = challengesFound[challengesFound.length - 1];
if (lastChallenge) syncChallenges(lastChallenge.createdAt);
return syncedChallenges;
}

View File

@@ -5,7 +5,9 @@
db.users.update(
{ _id: '' },
{$set: {
{
$set: {
'purchased.plan.dateTerminated': moment().add('month', 1).toDate(),
}}
},
},
);

View File

@@ -18,6 +18,6 @@ db.users.update(
},
},
{multi: true}
{ multi: true },
);

View File

@@ -1,5 +1,5 @@
// mongo habitrpg ./node_modules/moment/moment.js ./migrations/current_period_end.js
db.users.update(
{ _id: '' },
{$set: {'purchased.plan.dateTerminated': moment().add({days: 7}).toDate()}}
{ $set: { 'purchased.plan.dateTerminated': moment().add({ days: 7 }).toDate() } },
);

View File

@@ -39,37 +39,51 @@
// needed. Do not miss any of them!
let uuid = '30fb2640-7121-4968-ace5-f385e60ea6c5';
const uuid = '30fb2640-7121-4968-ace5-f385e60ea6c5';
db.users.aggregate([
{$match: {
{
$match: {
_id: uuid,
}},
{$project: {
},
},
{
$project: {
_id: 0, todos: 1,
}},
},
},
{ $unwind: '$todos' },
{$group: {
{
$group: {
_id: { taskid: '$todos.id' },
count: { $sum: 1 },
}},
{$match: {
},
},
{
$match: {
count: { $gt: 1 },
}},
{$project: {
},
},
{
$project: {
'_id.taskid': 1,
}},
{$group: {
},
},
{
$group: {
_id: { taskid: '$todos.id' },
troublesomeIds: { $addToSet: '$_id.taskid' },
}},
{$project: {
},
},
{
$project: {
_id: 0,
troublesomeIds: 1,
}},
]).forEach((data) => {
},
},
]).forEach(data => {
// print( "\n" ); printjson(data);
data.troublesomeIds.forEach((taskid) => {
data.troublesomeIds.forEach(taskid => {
print(`non-unique task: ${taskid}`);
db.users.update({
_id: uuid,
@@ -83,6 +97,5 @@ db.users.aggregate([
db.users.update(
{ _id: uuid },
{ $pull: { todos: { id: 'de666' } } },
{multi: false }
{ multi: false },
);

View File

@@ -1,10 +1,9 @@
let oldId = '';
let newId = '';
let newUser = db.users.findOne({_id: newId});
const oldId = '';
const newId = '';
const newUser = db.users.findOne({ _id: newId });
db.users.update({ _id: oldId }, { $set: { auth: newUser.auth } });
// remove the auth on the new user (which is a template account). The account will be preened automatically later,
// this allows us to keep the account around a few days in case there was a mistake
db.users.update({ _id: newId }, { $unset: { auth: 1 } });

View File

@@ -5,8 +5,8 @@
* Past in the text of a unique habit here to find the user, then you can restore their UUID
*/
db.users.find().forEach((user) => {
db.users.find().forEach(user => {
user.tasks = user.habits.concat(user.dailys).concat(user.todos).concat(user.rewards);
let found = _.some(user.tasks, {text: ''});
const found = _.some(user.tasks, { text: '' });
if (found) printjson({ id: user._id, auth: user.auth });
});

View File

@@ -2,12 +2,14 @@
db.users.update(
{ _id: '' },
{$set: {
{
$set: {
'purchased.plan.customerId': 'temporary',
'purchased.plan.paymentMethod': 'Stripe',
'purchased.plan.planId': 'basic_earned',
'purchased.plan.dateTerminated': moment().add('month', 1).toDate(),
}}
},
},
);
// var m = 12;
// db.users.update(

View File

@@ -1,5 +1,5 @@
db.users.update(
{},
{ $inc: { 'achievements.habiticaDays': 1 } },
{multi: 1}
{ multi: 1 },
);

View File

@@ -13,7 +13,7 @@ import { model as Group } from '../../website/server/models/group';
// @TODO: this should probably be a GroupManager library method
async function addUnlimitedSubscription (groupId, dateTerminated) {
let group = await Group.findOne({_id: groupId});
const group = await Group.findOne({ _id: groupId });
group.purchased.plan.customerId = 'group-unlimited';
group.purchased.plan.dateCreated = new Date();
@@ -22,7 +22,7 @@ async function addUnlimitedSubscription (groupId, dateTerminated) {
group.purchased.plan.planId = 'group_monthly';
group.purchased.plan.dateTerminated = null;
if (dateTerminated) {
let dateToEnd = moment(dateTerminated).toDate();
const dateToEnd = moment(dateTerminated).toDate();
group.purchased.plan.dateTerminated = dateToEnd;
}
// group.purchased.plan.owner = ObjectId();
@@ -32,11 +32,11 @@ async function addUnlimitedSubscription (groupId, dateTerminated) {
}
module.exports = async function addUnlimitedSubscriptionCreator () {
let groupId = process.argv[2];
const groupId = process.argv[2];
if (!groupId) throw Error('Group ID is required');
let dateTerminated = process.argv[3];
const dateTerminated = process.argv[3];
await addUnlimitedSubscription(groupId, dateTerminated);
};

View File

@@ -3,9 +3,9 @@ import { model as User } from '../../website/server/models/user';
// @TODO: this should probably be a GroupManager library method
async function createGroup (name, privacy, type, leaderId) {
let user = await User.findOne({_id: leaderId});
const user = await User.findOne({ _id: leaderId });
let group = new Group({
const group = new Group({
name,
privacy,
type,
@@ -18,12 +18,10 @@ async function createGroup (name, privacy, type, leaderId) {
}
module.exports = async function groupCreator () {
let name = process.argv[2];
let privacy = process.argv[3];
let type = process.argv[4];
let leaderId = process.argv[5];
const name = process.argv[2];
const privacy = process.argv[3];
const type = process.argv[4];
const leaderId = process.argv[5];
await createGroup(name, privacy, type, leaderId);
};

View File

@@ -8,26 +8,24 @@ import { model as Group } from '../../website/server/models/group';
import { model as User } from '../../website/server/models/user';
async function handOutJackalopes () {
let promises = [];
let cursor = User.find({
const promises = [];
const cursor = User.find({
'purchased.plan.customerId': 'habitrpg',
}).cursor();
cursor.on('data', async (user) => {
cursor.on('data', async user => {
console.log(`User: ${user._id}`);
let groupList = [];
if (user.party._id) groupList.push(user.party._id);
groupList = groupList.concat(user.guilds);
let subscribedGroup =
await Group.findOne({
const subscribedGroup = await Group.findOne({
_id: { $in: groupList },
'purchased.plan.planId': 'group_monthly',
'purchased.plan.dateTerminated': null,
},
{_id: 1}
);
{ _id: 1 });
if (subscribedGroup) {
User.update({ _id: user._id }, { $set: { 'items.mounts.Jackalope-RoyalPurple': true } }).exec();

View File

@@ -12,8 +12,8 @@ import stripePayments from '../../website/server/libs/payments/stripe';
const CONNECTION_STRING = nconf.get('MIGRATION_CONNECT_STRING');
let dbGroups = monk(CONNECTION_STRING).get('groups', { castIds: false });
let dbUsers = monk(CONNECTION_STRING).get('users', { castIds: false });
const dbGroups = monk(CONNECTION_STRING).get('groups', { castIds: false });
const dbUsers = monk(CONNECTION_STRING).get('users', { castIds: false });
async function fixGroupPlanMembers () {
console.info('Group ID, Customer ID, Plan ID, Quantity, Recorded Member Count, Actual Member Count');
@@ -40,7 +40,7 @@ async function fixGroupPlanMembers () {
memberCount: 1,
'purchased.plan': 1,
},
}
},
).each(async (group, { close, pause, resume }) => { // eslint-disable-line no-unused-vars
pause();
groupPlanCount++;
@@ -52,7 +52,7 @@ async function fixGroupPlanMembers () {
{ 'party._id': group._id },
{ guilds: group._id },
],
}
},
);
const incorrectMemberCount = group.memberCount !== canonicalMemberCount;
@@ -73,7 +73,7 @@ async function fixGroupPlanMembers () {
$set: {
memberCount: canonicalMemberCount,
},
}
},
);
if (!groupUpdate) return;
@@ -83,14 +83,14 @@ async function fixGroupPlanMembers () {
await stripePayments.chargeForAdditionalGroupMember(group);
await dbGroups.update(
{ _id: group._id },
{$set: {'purchased.plan.quantity': canonicalMemberCount + 2}}
{ $set: { 'purchased.plan.quantity': canonicalMemberCount + 2 } },
);
}
if (incorrectQuantity) {
await dbGroups.update(
{ _id: group._id },
{$set: {'purchased.plan.quantity': canonicalMemberCount + 2}}
{ $set: { 'purchased.plan.quantity': canonicalMemberCount + 2 } },
);
}
@@ -98,7 +98,7 @@ async function fixGroupPlanMembers () {
}).then(() => {
console.info(`Fixed ${fixedGroupCount} out of ${groupPlanCount} active Group Plans`);
return process.exit(0);
}).catch((err) => {
}).catch(err => {
console.log(err);
return process.exit(1);
});

View File

@@ -13,21 +13,19 @@ import { model as Group } from '../../website/server/models/group';
import * as payments from '../../website/server/libs/payments';
async function updateGroupsWithGroupPlans () {
let cursor = Group.find({
const cursor = Group.find({
'purchased.plan.planId': 'group_monthly',
'purchased.plan.dateTerminated': null,
}).cursor();
let promises = [];
const promises = [];
cursor.on('data', (group) => {
cursor.on('data', group => {
promises.push(payments.addSubscriptionToGroupUsers(group));
promises.push(group.save());
});
cursor.on('close', async () => {
return await Promise.all(promises);
});
cursor.on('close', async () => await Promise.all(promises));
}
module.exports = updateGroupsWithGroupPlans;

View File

@@ -18,11 +18,12 @@ setUpServer();
// Replace this with your migration
const processUsers = require('');
processUsers()
.then(function success () {
.then(() => {
process.exit(0);
})
.catch(function failure (err) {
.catch(err => {
console.log(err);
process.exit(1);
});

View File

@@ -1,18 +1,19 @@
/* let migrationName = 'new_stuff.js'; */
let authorName = 'Sabe'; // in case script author needs to know when their ...
let authorUuid = '7f14ed62-5408-4e1b-be83-ada62d504931'; // ... own data is done
const authorName = 'Sabe'; // in case script author needs to know when their ...
const authorUuid = '7f14ed62-5408-4e1b-be83-ada62d504931'; // ... own data is done
/*
* set the newStuff flag in all user accounts so they see a Bailey message
*/
let monk = require('monk');
let connectionString = 'mongodb://localhost:27017/habitrpg?auto_reconnect=true'; // FOR TEST DATABASE
let dbUsers = monk(connectionString).get('users', { castIds: false });
const monk = require('monk');
const connectionString = 'mongodb://localhost:27017/habitrpg?auto_reconnect=true'; // FOR TEST DATABASE
const dbUsers = monk(connectionString).get('users', { castIds: false });
function processUsers (lastId) {
// specify a query to limit the affected users (empty for all users):
let query = {
const query = {
'flags.newStuff': { $ne: true },
};
@@ -28,13 +29,13 @@ function processUsers (lastId) {
fields: [], // specify fields we are interested in to limit retrieved data (empty if we're not reading data):
})
.then(updateUsers)
.catch((err) => {
.catch(err => {
console.log(err);
return exiting(1, `ERROR! ${err}`);
});
}
let progressCount = 1000;
const progressCount = 1000;
let count = 0;
function updateUsers (users) {
@@ -44,8 +45,8 @@ function updateUsers (users) {
return;
}
let userPromises = users.map(updateUser);
let lastUser = users[users.length - 1];
const userPromises = users.map(updateUser);
const lastUser = users[users.length - 1];
return Promise.all(userPromises)
.then(() => {
@@ -56,7 +57,7 @@ function updateUsers (users) {
function updateUser (user) {
count++;
let set = {'flags.newStuff': true};
const set = { 'flags.newStuff': true };
dbUsers.update({ _id: user._id }, { $set: set });

View File

@@ -1,18 +1,19 @@
let migrationName = 'restock_armoire.js';
let authorName = 'Sabe'; // in case script author needs to know when their ...
let authorUuid = '7f14ed62-5408-4e1b-be83-ada62d504931'; // ... own data is done
const migrationName = 'restock_armoire.js';
const authorName = 'Sabe'; // in case script author needs to know when their ...
const authorUuid = '7f14ed62-5408-4e1b-be83-ada62d504931'; // ... own data is done
/*
* Remove flag stating that the Enchanted Armoire is empty, for when new equipment is added
*/
let monk = require('monk');
let connectionString = 'mongodb://localhost:27017/habitrpg?auto_reconnect=true'; // FOR TEST DATABASE
let dbUsers = monk(connectionString).get('users', { castIds: false });
const monk = require('monk');
const connectionString = 'mongodb://localhost:27017/habitrpg?auto_reconnect=true'; // FOR TEST DATABASE
const dbUsers = monk(connectionString).get('users', { castIds: false });
function processUsers (lastId) {
// specify a query to limit the affected users (empty for all users):
let query = {
const query = {
'flags.armoireEmpty': true,
};
@@ -28,13 +29,13 @@ function processUsers (lastId) {
fields: [], // specify fields we are interested in to limit retrieved data (empty if we're not reading data):
})
.then(updateUsers)
.catch((err) => {
.catch(err => {
console.log(err);
return exiting(1, `ERROR! ${err}`);
});
}
let progressCount = 1000;
const progressCount = 1000;
let count = 0;
function updateUsers (users) {
@@ -44,8 +45,8 @@ function updateUsers (users) {
return;
}
let userPromises = users.map(updateUser);
let lastUser = users[users.length - 1];
const userPromises = users.map(updateUser);
const lastUser = users[users.length - 1];
return Promise.all(userPromises)
.then(() => {
@@ -56,7 +57,7 @@ function updateUsers (users) {
function updateUser (user) {
count++;
let set = {migration: migrationName, 'flags.armoireEmpty': false};
const set = { migration: migrationName, 'flags.armoireEmpty': false };
dbUsers.update({ _id: user._id }, { $set: set });

View File

@@ -1,6 +1,6 @@
let migrationName = 'restock_armoire_for_users_that_need_it.js';
let authorName = 'Alys (ALittleYellowSpider)'; // in case script author needs to know when their ...
let authorUuid = '3e595299-3d8a-4a10-bfe0-88f555e4aa0c'; // ... own data is done
const migrationName = 'restock_armoire_for_users_that_need_it.js';
const authorName = 'Alys (ALittleYellowSpider)'; // in case script author needs to know when their ...
const authorUuid = '3e595299-3d8a-4a10-bfe0-88f555e4aa0c'; // ... own data is done
/*
* Remove flag stating that the Enchanted Armoire is empty,
@@ -18,15 +18,16 @@ let authorUuid = '3e595299-3d8a-4a10-bfe0-88f555e4aa0c'; // ... own data is done
*
*/
let connectionString = 'mongodb://localhost:27017/habitrpg?auto_reconnect=true'; // FOR TEST DATABASE
const connectionString = 'mongodb://localhost:27017/habitrpg?auto_reconnect=true'; // FOR TEST DATABASE
let monk = require('monk');
let dbUsers = monk(connectionString).get('users', { castIds: false });
const monk = require('monk');
const dbUsers = monk(connectionString).get('users', { castIds: false });
function processUsers (lastId) {
// specify a query to limit the affected users (empty for all users):
let query = {
const query = {
'auth.timestamps.loggedin': { $gt: new Date('2016-01-04') },
// '_id': authorUuid // FOR TESTING
};
@@ -52,13 +53,13 @@ function processUsers (lastId) {
}, // specify fields we are interested in to limit retrieved data (empty if we're not reading data):
})
.then(updateUsers)
.catch((err) => {
.catch(err => {
console.log(err);
return exiting(1, `ERROR! ${err}`);
});
}
let progressCount = 1000;
const progressCount = 1000;
let count = 0;
function updateUsers (users) {
@@ -68,8 +69,8 @@ function updateUsers (users) {
return;
}
let userPromises = users.map(updateUser);
let lastUser = users[users.length - 1];
const userPromises = users.map(updateUser);
const lastUser = users[users.length - 1];
return Promise.all(userPromises)
.then(() => {
@@ -80,7 +81,7 @@ function updateUsers (users) {
function updateUser (user) {
count++;
let set = {migration: migrationName, 'flags.armoireEmpty': false};
const set = { migration: migrationName, 'flags.armoireEmpty': false };
if (user.flags.armoireEmpty) {

View File

@@ -1,22 +1,24 @@
/* let migrationName = 'restore_profile_data.js'; */
let authorName = 'ThehollidayInn'; // in case script author needs to know when their ...
let authorUuid = ''; // ... own data is done
const authorName = 'ThehollidayInn'; // in case script author needs to know when their ...
const authorUuid = ''; // ... own data is done
/*
* Check if users have empty profile data in new database and update it with old database info
*/
let monk = require('monk');
let connectionString = ''; // FOR TEST DATABASE
let dbUsers = monk(connectionString).get('users', { castIds: false });
const monk = require('monk');
let monk2 = require('monk');
let oldDbConnectionString = 'mongodb://localhost:27017/habitrpg?auto_reconnect=true'; // FOR TEST DATABASE
let olDbUsers = monk2(oldDbConnectionString).get('users', { castIds: false });
const connectionString = ''; // FOR TEST DATABASE
const dbUsers = monk(connectionString).get('users', { castIds: false });
const monk2 = require('monk');
const oldDbConnectionString = 'mongodb://localhost:27017/habitrpg?auto_reconnect=true'; // FOR TEST DATABASE
const olDbUsers = monk2(oldDbConnectionString).get('users', { castIds: false });
function processUsers (lastId) {
// specify a query to limit the affected users (empty for all users):
let query = {
const query = {
// 'profile.name': 'profile name not found',
'profile.blurb': null,
// 'auth.timestamps.loggedin': {$gt: new Date('11/30/2016')},
@@ -34,13 +36,13 @@ function processUsers (lastId) {
fields: ['_id', 'profile', 'auth.timestamps.loggedin'], // specify fields we are interested in to limit retrieved data (empty if we're not reading data):
})
.then(updateUsers)
.catch((err) => {
.catch(err => {
console.log(err);
return exiting(1, `ERROR! ${err}`);
});
}
let progressCount = 1000;
const progressCount = 1000;
let count = 0;
function updateUsers (users) {
@@ -50,13 +52,11 @@ function updateUsers (users) {
return;
}
let userPaymentPromises = users.map(updateUser);
let lastUser = users[users.length - 1];
const userPaymentPromises = users.map(updateUser);
const lastUser = users[users.length - 1];
return Promise.all(userPaymentPromises)
.then(() => {
return processUsers(lastUser._id);
});
.then(() => processUsers(lastUser._id));
}
function updateUser (user) {
@@ -64,14 +64,14 @@ function updateUser (user) {
if (!user.profile.name || user.profile.name === 'profile name not found' || !user.profile.imageUrl || !user.profile.blurb) {
return olDbUsers.findOne({ _id: user._id }, '_id profile')
.then((oldUserData) => {
.then(oldUserData => {
if (!oldUserData) return;
// specify user data to change:
let set = {};
const set = {};
if (oldUserData.profile.name === 'profile name not found') return;
let userNeedsProfileName = !user.profile.name || user.profile.name === 'profile name not found';
const userNeedsProfileName = !user.profile.name || user.profile.name === 'profile name not found';
if (userNeedsProfileName && oldUserData.profile.name) {
set['profile.name'] = oldUserData.profile.name;
}

View File

@@ -1,8 +1,9 @@
let request = require('superagent');
let last = require('lodash/last');
let AWS = require('aws-sdk');
const request = require('superagent');
const last = require('lodash/last');
const AWS = require('aws-sdk');
const config = require('../config');
let config = require('../config');
const S3_DIRECTORY = 'mobileApp/images'; // config.S3.SPRITES_DIRECTORY;
AWS.config.update({
@@ -11,8 +12,8 @@ AWS.config.update({
// region: config.get('S3_REGION'),
});
let BUCKET_NAME = config.S3.bucket;
let s3 = new AWS.S3();
const BUCKET_NAME = config.S3.bucket;
const s3 = new AWS.S3();
// Adapted from http://stackoverflow.com/a/22210077/2601552
function uploadFile (buffer, fileName) {
@@ -21,7 +22,7 @@ function uploadFile (buffer, fileName) {
Body: buffer,
Key: fileName,
Bucket: BUCKET_NAME,
}, (error) => {
}, error => {
if (error) {
reject(error);
} else {
@@ -33,9 +34,9 @@ function uploadFile (buffer, fileName) {
}
function getFileName (file) {
let piecesOfPath = file.split('/');
let name = last(piecesOfPath);
let fullName = S3_DIRECTORY + name;
const piecesOfPath = file.split('/');
const name = last(piecesOfPath);
const fullName = S3_DIRECTORY + name;
return fullName;
}
@@ -44,7 +45,7 @@ function getFileFromUrl (url) {
return new Promise((resolve, reject) => {
request.get(url).end((err, res) => {
if (err) return reject(err);
let file = res.body;
const file = res.body;
resolve(file);
});
});
@@ -52,25 +53,21 @@ function getFileFromUrl (url) {
let commit = '78f94e365c72cc58f66857d5941105638db7d35c';
commit = 'df0dbaba636c9ce424cc7040f7bd7fc1aa311015';
let gihuburl = `https://api.github.com/repos/HabitRPG/habitica/commits/${commit}`;
const gihuburl = `https://api.github.com/repos/HabitRPG/habitica/commits/${commit}`;
let currentIndex = 0;
function uploadToS3 (start, end, filesUrls) {
let urls = filesUrls.slice(start, end);
const urls = filesUrls.slice(start, end);
if (urls.length === 0) {
console.log('done');
return;
}
let promises = urls.map(fullUrl => {
return getFileFromUrl(fullUrl)
.then((buffer) => {
return uploadFile(buffer, getFileName(fullUrl));
});
});
const promises = urls.map(fullUrl => getFileFromUrl(fullUrl)
.then(buffer => uploadFile(buffer, getFileName(fullUrl))));
console.log(promises.length);
return Promise.all(promises)
@@ -86,12 +83,10 @@ function uploadToS3 (start, end, filesUrls) {
request.get(gihuburl)
.end((err, res) => {
console.log(err);
let files = res.body.files;
const { files } = res.body;
let filesUrls = [''];
filesUrls = files.map(file => {
return file.raw_url;
});
filesUrls = files.map(file => file.raw_url);
uploadToS3(currentIndex, currentIndex + 50, filesUrls);
});

View File

@@ -9,11 +9,12 @@
const monk = require('monk');
const _ = require('lodash');
const moment = require('moment');
const connectionString = 'mongodb://localhost:27017/habitrpg?auto_reconnect=true'; // FOR TEST DATABASE
const dbTasks = monk(connectionString).get('tasks', { castIds: false });
function processChallengeHabits (lastId) {
let query = {
const query = {
'challenge.id': { $exists: true },
userId: { $exists: false },
type: 'habit',
@@ -30,13 +31,13 @@ function processChallengeHabits (lastId) {
limit: 500,
})
.then(updateChallengeHabits)
.catch((err) => {
.catch(err => {
console.log(err);
return exiting(1, `ERROR! ${err}`);
});
}
let progressCount = 1000;
const progressCount = 1000;
let count = 0;
function updateChallengeHabits (habits) {
@@ -46,13 +47,11 @@ function updateChallengeHabits (habits) {
return;
}
let habitsPromises = habits.map(updateChallengeHabit);
let lastHabit = habits[habits.length - 1];
const habitsPromises = habits.map(updateChallengeHabit);
const lastHabit = habits[habits.length - 1];
return Promise.all(habitsPromises)
.then(() => {
return processChallengeHabits(lastHabit._id);
});
.then(() => processChallengeHabits(lastHabit._id));
}
function updateChallengeHabit (habit) {
@@ -76,13 +75,12 @@ function updateChallengeHabit (habit) {
entry.scoreDirection = entry.value > previousValue ? 'up' : 'down';
}
})
.groupBy(entry => { // group entries by aggregateBy
return moment(entry.date).format('YYYYMMDD');
})
.groupBy(entry => // group entries by aggregateBy
moment(entry.date).format('YYYYMMDD'))
.toPairs() // [key, entry]
.sortBy(([key]) => key) // sort by date
.map(keyEntryPair => {
let entries = keyEntryPair[1]; // 1 is entry, 0 is key
const entries = keyEntryPair[1]; // 1 is entry, 0 is key
let scoredUp = 0;
let scoredDown = 0;

View File

@@ -9,12 +9,13 @@ const authorUuid = 'ed4c688c-6652-4a92-9d03-a5a79844174a'; // ... own data is do
const monk = require('monk');
const _ = require('lodash');
const moment = require('moment');
const connectionString = 'mongodb://localhost:27017/habitrpg?auto_reconnect=true'; // FOR TEST DATABASE
const dbTasks = monk(connectionString).get('tasks', { castIds: false });
const dbUsers = monk(connectionString).get('users', { castIds: false });
function processUsers (lastId) {
let query = {
const query = {
migration: { $ne: migrationName },
};
@@ -30,13 +31,13 @@ function processUsers (lastId) {
fields: ['_id', 'preferences.timezoneOffset', 'preferences.dayStart'],
})
.then(updateUsers)
.catch((err) => {
.catch(err => {
console.log(err);
return exiting(1, `ERROR! ${err}`);
});
}
let progressCount = 1000;
const progressCount = 1000;
let count = 0;
function updateUsers (users) {
@@ -46,13 +47,11 @@ function updateUsers (users) {
return;
}
let usersPromises = users.map(updateUser);
let lastUser = users[users.length - 1];
const usersPromises = users.map(updateUser);
const lastUser = users[users.length - 1];
return Promise.all(usersPromises)
.then(() => {
return processUsers(lastUser._id);
});
.then(() => processUsers(lastUser._id));
}
function updateHabit (habit, timezoneOffset, dayStart) {
@@ -82,7 +81,7 @@ function updateHabit (habit, timezoneOffset, dayStart) {
.toPairs() // [key, entry]
.sortBy(([key]) => key) // sort by date
.map(keyEntryPair => {
let entries = keyEntryPair[1]; // 1 is entry, 0 is key
const entries = keyEntryPair[1]; // 1 is entry, 0 is key
let scoredUp = 0;
let scoredDown = 0;
@@ -116,8 +115,8 @@ function updateHabit (habit, timezoneOffset, dayStart) {
function updateUser (user) {
count++;
const timezoneOffset = user.preferences.timezoneOffset;
const dayStart = user.preferences.dayStart;
const { timezoneOffset } = user.preferences;
const { dayStart } = user.preferences;
if (count % progressCount === 0) console.warn(`${count} ${user._id}`);
if (user._id === authorUuid) console.warn(`${authorName} being processed`);
@@ -126,15 +125,11 @@ function updateUser (user) {
type: 'habit',
userId: user._id,
})
.then(habits => {
return Promise.all(habits.map(habit => updateHabit(habit, timezoneOffset, dayStart)));
})
.then(() => {
return dbUsers.update({_id: user._id}, {
.then(habits => Promise.all(habits.map(habit => updateHabit(habit, timezoneOffset, dayStart))))
.then(() => dbUsers.update({ _id: user._id }, {
$set: { migration: migrationName },
});
})
.catch((err) => {
}))
.catch(err => {
console.log(err);
return exiting(1, `ERROR! ${err}`);
});

View File

@@ -1,18 +1,19 @@
/* let migrationName = 'tasks-set-everyX'; */
let authorName = 'Sabe'; // in case script author needs to know when their ...
let authorUuid = '7f14ed62-5408-4e1b-be83-ada62d504931'; // ... own data is done
const authorName = 'Sabe'; // in case script author needs to know when their ...
const authorUuid = '7f14ed62-5408-4e1b-be83-ada62d504931'; // ... own data is done
/*
* Iterates over all tasks and sets invalid everyX values (less than 0 or more than 9999 or not an int) field to 0
*/
let monk = require('monk');
let connectionString = 'mongodb://localhost:27017/habitrpg?auto_reconnect=true';
let dbTasks = monk(connectionString).get('tasks', { castIds: false });
const monk = require('monk');
const connectionString = 'mongodb://localhost:27017/habitrpg?auto_reconnect=true';
const dbTasks = monk(connectionString).get('tasks', { castIds: false });
function processTasks (lastId) {
// specify a query to limit the affected tasks (empty for all tasks):
let query = {
const query = {
type: 'daily',
everyX: {
$not: {
@@ -35,13 +36,13 @@ function processTasks (lastId) {
fields: [],
})
.then(updateTasks)
.catch((err) => {
.catch(err => {
console.log(err);
return exiting(1, `ERROR! ${err}`);
});
}
let progressCount = 1000;
const progressCount = 1000;
let count = 0;
function updateTasks (tasks) {
@@ -51,18 +52,16 @@ function updateTasks (tasks) {
return;
}
let taskPromises = tasks.map(updatetask);
let lasttask = tasks[tasks.length - 1];
const taskPromises = tasks.map(updatetask);
const lasttask = tasks[tasks.length - 1];
return Promise.all(taskPromises)
.then(() => {
return processTasks(lasttask._id);
});
.then(() => processTasks(lasttask._id));
}
function updatetask (task) {
count++;
let set = {everyX: 0};
const set = { everyX: 0 };
dbTasks.update({ _id: task._id }, { $set: set });

View File

@@ -1,6 +1,5 @@
/* let migrationName = 'tasks-set-yesterdaily'; */
let authorName = 'TheHollidayInn'; // in case script author needs to know when their ...
let authorUuid = ''; // ... own data is done
// ... own data is done
/*
* Iterates over all tasks and sets the yseterDaily field to True
@@ -8,10 +7,13 @@ let authorUuid = ''; // ... own data is done
import monk from 'monk';
let connectionString = 'mongodb://localhost:27017/habitrpg?auto_reconnect=true'; // FOR TEST DATABASE
let dbTasks = monk(connectionString).get('tasks', { castIds: false });
const authorName = 'TheHollidayInn'; // in case script author needs to know when their ...
const authorUuid = '';
let progressCount = 1000;
const connectionString = 'mongodb://localhost:27017/habitrpg?auto_reconnect=true'; // FOR TEST DATABASE
const dbTasks = monk(connectionString).get('tasks', { castIds: false });
const progressCount = 1000;
let count = 0;
function exiting (code, msg) {
@@ -36,7 +38,7 @@ function displayData () {
function updatetask (task) {
count++;
let set = {yesterDaily: true};
const set = { yesterDaily: true };
dbTasks.update({ _id: task._id }, { $set: set });
@@ -51,18 +53,17 @@ function updateTasks (tasks) {
return;
}
let taskPromises = tasks.map(updatetask);
let lasttask = tasks[tasks.length - 1];
const taskPromises = tasks.map(updatetask);
const lasttask = tasks[tasks.length - 1];
return Promise.all(taskPromises)
.then(() => {
return processTasks(lasttask._id); // eslint-disable-line no-use-before-define
});
.then(() => processTasks(lasttask._id), // eslint-disable-line no-use-before-define
);
}
function processTasks (lastId) {
// specify a query to limit the affected tasks (empty for all tasks):
let query = {
const query = {
yesterDaily: false,
};
@@ -79,7 +80,7 @@ function processTasks (lastId) {
],
})
.then(updateTasks)
.catch((err) => {
.catch(err => {
console.log(err);
return exiting(1, `ERROR! ${err}`);
});

View File

@@ -9,6 +9,7 @@ let authorUuid = ''; // ... own data is done
*/
const monk = require('monk');
const connectionString = '';
const Users = monk(connectionString).get('users', { castIds: false });
@@ -19,9 +20,9 @@ module.exports = async function accountTransfer () {
const fromAccount = await Users.findOne({ _id: fromAccountId });
const toAccount = await Users.findOne({ _id: toAccountId });
const newMounts = Object.assign({}, fromAccount.items.mounts, toAccount.items.mounts);
const newPets = Object.assign({}, fromAccount.items.pets, toAccount.items.pets);
const newBackgrounds = Object.assign({}, fromAccount.purchased.background, toAccount.purchased.background);
const newMounts = { ...fromAccount.items.mounts, ...toAccount.items.mounts };
const newPets = { ...fromAccount.items.pets, ...toAccount.items.pets };
const newBackgrounds = { ...fromAccount.purchased.background, ...toAccount.purchased.background };
await Users.update({ _id: toAccountId }, {
$set: {
@@ -30,7 +31,7 @@ module.exports = async function accountTransfer () {
'purchased.background': newBackgrounds,
},
})
.then((result) => {
.then(result => {
console.log(result);
});
};

View File

@@ -9,6 +9,7 @@ const authorUuid = ''; // ... own data is done
*/
const monk = require('monk');
const connectionString = 'mongodb://localhost/new-habit';
const Users = monk(connectionString).get('users', { castIds: false });
@@ -19,13 +20,13 @@ function getAchievementUpdate (newUser, oldUser) {
const oldAchievements = oldUser.achievements;
const newAchievements = newUser.achievements;
let achievementsUpdate = Object.assign({}, newAchievements);
const achievementsUpdate = { ...newAchievements };
// ultimateGearSets
if (!achievementsUpdate.ultimateGearSets && oldAchievements.ultimateGearSets) {
achievementsUpdate.ultimateGearSets = oldAchievements.ultimateGearSets;
} else if (oldAchievements.ultimateGearSets) {
for (let index in oldAchievements.ultimateGearSets) {
for (const index in oldAchievements.ultimateGearSets) {
if (oldAchievements.ultimateGearSets[index]) achievementsUpdate.ultimateGearSets[index] = true;
}
}
@@ -37,7 +38,7 @@ function getAchievementUpdate (newUser, oldUser) {
// Quests
if (!achievementsUpdate.quests) achievementsUpdate.quests = {};
for (let index in oldAchievements.quests) {
for (const index in oldAchievements.quests) {
if (!achievementsUpdate.quests[index]) {
achievementsUpdate.quests[index] = oldAchievements.quests[index];
} else {
@@ -54,7 +55,7 @@ function getAchievementUpdate (newUser, oldUser) {
// All others
const indexsToIgnore = ['ultimateGearSets', 'challenges', 'quests', 'rebirthLevel'];
for (let index in oldAchievements) {
for (const index in oldAchievements) {
if (indexsToIgnore.indexOf(index) !== -1) continue; // eslint-disable-line no-continue
if (!achievementsUpdate[index]) {
@@ -75,7 +76,7 @@ module.exports = async function achievementRestore () {
];
/* eslint-disable no-await-in-loop */
for (let index in userIds) {
for (const index in userIds) {
const userId = userIds[index];
const oldUser = await UsersOld.findOne({ _id: userId }, 'achievements');
const newUser = await Users.findOne({ _id: userId }, 'achievements');
@@ -86,7 +87,8 @@ module.exports = async function achievementRestore () {
$set: {
achievements: achievementUpdate,
},
});
},
);
console.log(`Updated ${userId}`);
/* eslint-enable no-await-in-loop */
}

View File

@@ -1,8 +1,9 @@
/* eslint-disable no-console */
import { sendTxn } from '../../website/server/libs/email';
import { model as User } from '../../website/server/models/user';
import moment from 'moment';
import nconf from 'nconf';
import { sendTxn } from '../../website/server/libs/email';
import { model as User } from '../../website/server/models/user';
const BASE_URL = nconf.get('BASE_URL');
const EMAIL_SLUG = 'mandrill-email-slug'; // Set email template to send
const MIGRATION_NAME = 'bulk-email';
@@ -18,14 +19,14 @@ async function updateUser (user) {
sendTxn(
user,
EMAIL_SLUG,
[{name: 'BASE_URL', content: BASE_URL}] // Add variables from template
[{ name: 'BASE_URL', content: BASE_URL }], // Add variables from template
);
return await User.update({ _id: user._id }, { $set: { migration: MIGRATION_NAME } }).exec();
}
module.exports = async function processUsers () {
let query = {
const query = {
migration: { $ne: MIGRATION_NAME },
'auth.timestamps.loggedin': { $gt: moment().subtract(2, 'weeks').toDate() }, // customize or remove to target different populations
};

View File

@@ -1,11 +1,12 @@
/* eslint-disable no-console */
const MIGRATION_NAME = 'full-stable';
import each from 'lodash/each';
import keys from 'lodash/keys';
import content from '../../website/common/script/content/index';
import { model as User } from '../../website/server/models/user';
const MIGRATION_NAME = 'full-stable';
const progressCount = 1000;
let count = 0;
@@ -20,28 +21,28 @@ async function updateUser (user) {
set.migration = MIGRATION_NAME;
each(keys(content.pets), (pet) => {
each(keys(content.pets), pet => {
set[`items.pets.${pet}`] = 5;
});
each(keys(content.premiumPets), (pet) => {
each(keys(content.premiumPets), pet => {
set[`items.pets.${pet}`] = 5;
});
each(keys(content.questPets), (pet) => {
each(keys(content.questPets), pet => {
set[`items.pets.${pet}`] = 5;
});
each(keys(content.specialPets), (pet) => {
each(keys(content.specialPets), pet => {
set[`items.pets.${pet}`] = 5;
});
each(keys(content.mounts), (mount) => {
each(keys(content.mounts), mount => {
set[`items.mounts.${mount}`] = true;
});
each(keys(content.premiumMounts), (mount) => {
each(keys(content.premiumMounts), mount => {
set[`items.mounts.${mount}`] = true;
});
each(keys(content.questMounts), (mount) => {
each(keys(content.questMounts), mount => {
set[`items.mounts.${mount}`] = true;
});
each(keys(content.specialMounts), (mount) => {
each(keys(content.specialMounts), mount => {
set[`items.mounts.${mount}`] = true;
});
@@ -51,7 +52,7 @@ async function updateUser (user) {
}
module.exports = async function processUsers () {
let query = {
const query = {
migration: { $ne: MIGRATION_NAME },
'auth.local.username': 'olson22',
};

View File

@@ -1,9 +1,10 @@
/* eslint-disable no-console */
const MIGRATION_NAME = 'mystery_items_201909';
const MYSTERY_ITEMS = ['armor_mystery_201909', 'head_mystery_201909'];
import { model as User } from '../../website/server/models/user';
import { model as UserNotification } from '../../website/server/models/userNotification';
const MIGRATION_NAME = 'mystery_items_201909';
const MYSTERY_ITEMS = ['armor_mystery_201909', 'head_mystery_201909'];
const progressCount = 1000;
let count = 0;
@@ -33,7 +34,7 @@ async function updateUser (user) {
}
module.exports = async function processUsers () {
let query = {
const query = {
migration: { $ne: MIGRATION_NAME },
'purchased.plan.customerId': { $ne: null },
$or: [

View File

@@ -1,9 +1,10 @@
/* eslint-disable no-console */
const MIGRATION_NAME = '20190314_pi_day';
import { v4 as uuid } from 'uuid';
import { model as User } from '../../website/server/models/user';
const MIGRATION_NAME = '20190314_pi_day';
const progressCount = 1000;
let count = 0;
@@ -39,7 +40,7 @@ async function updateUser (user) {
}
module.exports = async function processUsers () {
let query = {
const query = {
migration: { $ne: MIGRATION_NAME },
'auth.timestamps.loggedin': { $gt: new Date('2019-02-15') },
};

View File

@@ -8,11 +8,12 @@ const authorUuid = 'ed4c688c-6652-4a92-9d03-a5a79844174a'; // ... own data is do
const connectionString = 'mongodb://localhost:27017/habitrpg?auto_reconnect=true'; // FOR TEST DATABASE
const monk = require('monk');
const dbUsers = monk(connectionString).get('users', { castIds: false });
function processUsers (lastId) {
// specify a query to limit the affected users (empty for all users):
let query = {
const query = {
migration: { $ne: migrationName },
$or: [
{ 'auth.facebook.id': { $exists: true } },
@@ -31,13 +32,13 @@ function processUsers (lastId) {
limit: 250,
})
.then(updateUsers)
.catch((err) => {
.catch(err => {
console.log(err);
return exiting(1, `ERROR! ${err}`);
});
}
let progressCount = 1000;
const progressCount = 1000;
let count = 0;
function updateUsers (users) {
@@ -47,8 +48,8 @@ function updateUsers (users) {
return;
}
let userPromises = users.map(updateUser);
let lastUser = users[users.length - 1];
const userPromises = users.map(updateUser);
const lastUser = users[users.length - 1];
return Promise.all(userPromises)
.then(() => {

View File

@@ -1,9 +1,10 @@
/* eslint-disable no-console */
const MIGRATION_NAME = '20181203_take_this';
import { v4 as uuid } from 'uuid';
import { model as User } from '../../website/server/models/user';
const MIGRATION_NAME = '20181203_take_this';
const progressCount = 1000;
let count = 0;
@@ -41,13 +42,12 @@ async function updateUser (user) {
if (push) {
return await User.update({ _id: user._id }, { $set: set, $push: push }).exec();
} else {
return await User.update({_id: user._id}, {$set: set}).exec();
}
return await User.update({ _id: user._id }, { $set: set }).exec();
}
module.exports = async function processUsers () {
let query = {
const query = {
migration: { $ne: MIGRATION_NAME },
challenges: '00708425-d477-41a5-bf27-6270466e7976',
};

View File

@@ -8,22 +8,24 @@ let authorUuid = ''; // ... own data is done
* This migraition will copy user data from prod to test
*/
let monk = require('monk');
let testConnectionSting = ''; // FOR TEST DATABASE
let usersTest = monk(testConnectionSting).get('users', { castIds: false });
let groupsTest = monk(testConnectionSting).get('groups', { castIds: false });
let challengesTest = monk(testConnectionSting).get('challenges', { castIds: false });
let tasksTest = monk(testConnectionSting).get('tasks', { castIds: false });
let monk2 = require('monk');
let liveConnectString = ''; // FOR TEST DATABASE
let userLive = monk2(liveConnectString).get('users', { castIds: false });
let groupsLive = monk2(liveConnectString).get('groups', { castIds: false });
let challengesLive = monk2(liveConnectString).get('challenges', { castIds: false });
let tasksLive = monk2(liveConnectString).get('tasks', { castIds: false });
import uniq from 'lodash/uniq';
const monk = require('monk');
const testConnectionSting = ''; // FOR TEST DATABASE
const usersTest = monk(testConnectionSting).get('users', { castIds: false });
const groupsTest = monk(testConnectionSting).get('groups', { castIds: false });
const challengesTest = monk(testConnectionSting).get('challenges', { castIds: false });
const tasksTest = monk(testConnectionSting).get('tasks', { castIds: false });
const monk2 = require('monk');
const liveConnectString = ''; // FOR TEST DATABASE
const userLive = monk2(liveConnectString).get('users', { castIds: false });
const groupsLive = monk2(liveConnectString).get('groups', { castIds: false });
const challengesLive = monk2(liveConnectString).get('challenges', { castIds: false });
const tasksLive = monk2(liveConnectString).get('tasks', { castIds: false });
// Variabls for updating
/*
let userIds = [
@@ -36,11 +38,11 @@ let challengeIds = [];
let tasksIds = [];
async function processUsers () {
let userPromises = [];
const userPromises = [];
// {_id: {$in: userIds}}
return userLive.find({ guilds: 'b0764d64-8276-45a1-afa5-5ca9a5c64ca0' })
.each((user) => {
.each(user => {
if (user.guilds.length > 0) groupIds = groupIds.concat(user.guilds);
if (user.party._id) groupIds.push(user.party._id);
if (user.challenges.length > 0) challengeIds = challengeIds.concat(user.challenges);
@@ -49,56 +51,48 @@ async function processUsers () {
if (user.tasksOrder.dailys.length > 0) tasksIds = tasksIds.concat(user.tasksOrder.dailys);
if (user.tasksOrder.habits.length > 0) tasksIds = tasksIds.concat(user.tasksOrder.habits);
let userPromise = usersTest.update({_id: user._id}, user, {upsert: true});
const userPromise = usersTest.update({ _id: user._id }, user, { upsert: true });
userPromises.push(userPromise);
}).then(() => {
return Promise.all(userPromises);
})
}).then(() => Promise.all(userPromises))
.then(() => {
console.log('Done User');
});
}
function processGroups () {
let promises = [];
let groupsToQuery = uniq(groupIds);
const promises = [];
const groupsToQuery = uniq(groupIds);
return groupsLive.find({ _id: { $in: groupsToQuery } })
.each((group) => {
let promise = groupsTest.update({_id: group._id}, group, {upsert: true});
.each(group => {
const promise = groupsTest.update({ _id: group._id }, group, { upsert: true });
promises.push(promise);
}).then(() => {
return Promise.all(promises);
})
}).then(() => Promise.all(promises))
.then(() => {
console.log('Done Group');
});
}
function processChallenges () {
let promises = [];
let challengesToQuery = uniq(challengeIds);
const promises = [];
const challengesToQuery = uniq(challengeIds);
return challengesLive.find({ _id: { $in: challengesToQuery } })
.each((challenge) => {
let promise = challengesTest.update({_id: challenge._id}, challenge, {upsert: true});
.each(challenge => {
const promise = challengesTest.update({ _id: challenge._id }, challenge, { upsert: true });
promises.push(promise);
}).then(() => {
return Promise.all(promises);
})
}).then(() => Promise.all(promises))
.then(() => {
console.log('Done Challenge');
});
}
function processTasks () {
let promises = [];
let tasksToQuery = uniq(tasksIds);
const promises = [];
const tasksToQuery = uniq(tasksIds);
return tasksLive.find({ _id: { $in: tasksToQuery } })
.each((task) => {
let promise = tasksTest.update({_id: task._id}, task, {upsert: true});
.each(task => {
const promise = tasksTest.update({ _id: task._id }, task, { upsert: true });
promises.push(promise);
}).then(() => {
return Promise.all(promises);
})
}).then(() => Promise.all(promises))
.then(() => {
console.log('Done Tasks');
});

View File

@@ -1,6 +1,5 @@
'use strict';
const MongoClient = require('mongodb').MongoClient;
const { MongoClient } = require('mongodb');
const logger = require('./logger');
let dbConnection;

View File

@@ -1,10 +1,9 @@
'use strict';
const chalk = require('chalk');
function loggerGenerator (type, color) {
return function logger () {
let args = Array.from(arguments).map(arg => chalk[color](arg));
const args = Array.from(arguments).map(arg => chalk[color](arg));
console[type].apply(null, args);
};
}

View File

@@ -1,30 +1,31 @@
'use strict';
let logger = require('./logger');
const logger = require('./logger');
class Timer {
constructor (options) {
options = options || {};
let warningThreshold = options.minutesWarningThreshold || 10;
const warningThreshold = options.minutesWarningThreshold || 10;
this.count = 0;
this._minutesWarningThreshold = warningThreshold * 60;
if (!options.disableAutoStart) this.start();
}
start () {
this._internalTimer = setInterval(() => {
this.count++;
let shouldWarn = this._minutesWarningThreshold < this.count;
let logStyle = shouldWarn ? 'error' : 'warn';
let dangerMessage = shouldWarn ? 'DANGER: ' : '';
const shouldWarn = this._minutesWarningThreshold < this.count;
const logStyle = shouldWarn ? 'error' : 'warn';
const dangerMessage = shouldWarn ? 'DANGER: ' : '';
if (this.count % 30 === 0) {
logger[logStyle](`${dangerMessage}Process has been running for`, this.count / 60, 'minutes');
}
}, 1000);
}
stop () {
if (!this._internalTimer) {
throw new Error('Timer has not started');

View File

@@ -1,4 +1,3 @@
'use strict';
function unique (array) {
return Array.from(new Set(array));

905
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -72,7 +72,7 @@
"npm": "^6"
},
"scripts": {
"lint": "eslint --ext .js . && cd website/client && npm run lint",
"lint": "eslint --ext .js ./website/common --fix",
"test": "npm run lint && gulp test && gulp apidoc",
"test:build": "gulp test:prepare:build",
"test:api-v3": "gulp test:api-v3",
@@ -101,8 +101,8 @@
"chai": "^4.1.2",
"chai-as-promised": "^7.1.1",
"chalk": "^2.4.1",
"eslint": "^4.19.1",
"eslint-config-habitrpg": "^4.0.0",
"eslint": "^6.5.1",
"eslint-config-habitrpg": "^6.0.3",
"eslint-plugin-mocha": "^5.0.0",
"expect.js": "^0.3.1",
"istanbul": "^1.1.0-alpha.1",

View File

@@ -1,13 +1,13 @@
/* eslint-disable no-console */
import axios from 'axios';
import { model as User } from '../website/server/models/user';
import nconf from 'nconf';
import { model as User } from '../website/server/models/user';
const AMPLITUDE_KEY = nconf.get('AMPLITUDE_KEY');
const AMPLITUDE_SECRET = nconf.get('AMPLITUDE_SECRET');
const BASE_URL = nconf.get('BASE_URL');
async function _deleteAmplitudeData (userId, email) {
async function deleteAmplitudeData (userId, email) {
const response = await axios.post(
'https://amplitude.com/api/2/deletions/users',
{
@@ -19,22 +19,24 @@ async function _deleteAmplitudeData (userId, email) {
username: AMPLITUDE_KEY,
password: AMPLITUDE_SECRET,
},
}
).catch((err) => {
},
).catch(err => {
console.log(err.response.data);
});
if (response) console.log(`${response.status} ${response.statusText}`);
}
async function _deleteHabiticaData (user, email) {
async function deleteHabiticaData (user, email) {
await User.update(
{ _id: user._id },
{$set: {
{
$set: {
'auth.local.email': email,
'auth.local.hashed_password': '$2a$10$QDnNh1j1yMPnTXDEOV38xOePEWFd4X8DSYwAM8XTmqmacG5X0DKjW',
'auth.local.passwordHashMethod': 'bcrypt',
}}
},
},
);
const response = await axios.delete(
`${BASE_URL}/api/v3/user`,
@@ -46,8 +48,8 @@ async function _deleteHabiticaData (user, email) {
'x-api-user': user._id,
'x-api-key': user.apiToken,
},
}
).catch((err) => {
},
).catch(err => {
console.log(err.response.data);
});
@@ -57,14 +59,15 @@ async function _deleteHabiticaData (user, email) {
}
}
async function _processEmailAddress (email) {
async function processEmailAddress (email) {
const emailRegex = new RegExp(`^${email}$`, 'i');
const users = await User.find({
$or: [
{ 'auth.local.email': emailRegex },
{ 'auth.facebook.emails.value': emailRegex },
{ 'auth.google.emails.value': emailRegex },
]},
],
},
{
_id: 1,
apiToken: 1,
@@ -75,14 +78,14 @@ async function _processEmailAddress (email) {
console.log(`No users found with email address ${email}`);
} else {
for (const user of users) {
await _deleteAmplitudeData(user._id, email); // eslint-disable-line no-await-in-loop
await _deleteHabiticaData(user, email); // eslint-disable-line no-await-in-loop
await deleteAmplitudeData(user._id, email); // eslint-disable-line no-await-in-loop
await deleteHabiticaData(user, email); // eslint-disable-line no-await-in-loop
}
}
}
function deleteUserData (emails) {
const emailPromises = emails.map(_processEmailAddress);
const emailPromises = emails.map(processEmailAddress);
return Promise.all(emailPromises);
}

View File

@@ -12,11 +12,12 @@ const nconf = require('nconf');
const _ = require('lodash');
const paypal = require('paypal-rest-sdk');
const blocks = require('../website/common').content.subscriptionBlocks;
const live = nconf.get('PAYPAL_MODE') === 'live';
nconf.argv().env().file('user', path.join(path.resolve(__dirname, '../config.json')));
let OP = 'create'; // list get update create create-webprofile
const OP = 'create'; // list get update create create-webprofile
paypal.configure({
mode: nconf.get('PAYPAL_MODE'), // sandbox or live
@@ -25,8 +26,8 @@ paypal.configure({
});
// https://developer.paypal.com/docs/api/#billing-plans-and-agreements
let billingPlanTitle = 'Habitica Subscription';
let billingPlanAttributes = {
const billingPlanTitle = 'Habitica Subscription';
const billingPlanAttributes = {
description: billingPlanTitle,
type: 'INFINITE',
merchant_preferences: {
@@ -41,7 +42,7 @@ let billingPlanAttributes = {
}],
};
_.each(blocks, (block) => {
_.each(blocks, block => {
block.definition = _.cloneDeep(billingPlanAttributes);
_.merge(block.definition.payment_definitions[0], {
name: `${billingPlanTitle} ($${block.price} every ${block.months} months, recurring)`,
@@ -67,7 +68,7 @@ switch (OP) {
});
break;
case 'update':
let updatePayload = {
const updatePayload = {
op: 'replace',
path: '/merchant_preferences',
value: {
@@ -86,7 +87,7 @@ switch (OP) {
return console.log({ err, plan });
}
let billingPlanUpdateAttributes = [{
const billingPlanUpdateAttributes = [{
op: 'replace',
path: '/',
value: {
@@ -101,7 +102,7 @@ switch (OP) {
});
break;
case 'create-webprofile':
let webexpinfo = {
const webexpinfo = {
name: 'HabiticaProfile',
input_fields: {
no_shipping: 1,

View File

@@ -1,4 +1,3 @@
'use strict';
let pathToCommon;

View File

@@ -1,6 +1,5 @@
{
"extends": [
"habitrpg/browser",
"habitrpg/esnext"
"habitrpg/lib/node",
]
}

View File

@@ -1,8 +1,8 @@
import each from 'lodash/each';
let achievementsData = {};
const achievementsData = {};
let worldQuestAchievs = {
const worldQuestAchievs = {
dilatoryQuest: {
icon: 'achievement-dilatory',
titleKey: 'achievementDilatory',
@@ -31,7 +31,7 @@ let worldQuestAchievs = {
};
Object.assign(achievementsData, worldQuestAchievs);
let seasonalSpellAchievs = {
const seasonalSpellAchievs = {
snowball: {
icon: 'achievement-snowball',
titleKey: 'annoyingFriends',
@@ -55,7 +55,7 @@ let seasonalSpellAchievs = {
};
Object.assign(achievementsData, seasonalSpellAchievs);
let masterAchievs = {
const masterAchievs = {
beastMaster: {
icon: 'achievement-rat',
titleKey: 'beastMasterName',
@@ -77,7 +77,7 @@ let masterAchievs = {
};
Object.assign(achievementsData, masterAchievs);
let basicAchievs = {
const basicAchievs = {
partyUp: {
icon: 'achievement-partyUp',
titleKey: 'partyUpName',
@@ -160,7 +160,7 @@ let basicAchievs = {
};
Object.assign(achievementsData, basicAchievs);
let specialAchievs = {
const specialAchievs = {
contributor: {
icon: 'achievement-boot',
titleKey: 'contribName',
@@ -201,7 +201,7 @@ let specialAchievs = {
};
Object.assign(achievementsData, specialAchievs);
let holidayAchievs = {
const holidayAchievs = {
habiticaDays: {
icon: 'achievement-habiticaDay',
singularTitleKey: 'habiticaDay',
@@ -226,7 +226,7 @@ let holidayAchievs = {
};
Object.assign(achievementsData, holidayAchievs);
let ultimateGearAchievs = ['healer', 'rogue', 'warrior', 'mage'].reduce((achievs, type) => {
const ultimateGearAchievs = ['healer', 'rogue', 'warrior', 'mage'].reduce((achievs, type) => {
achievs[`${type}UltimateGear`] = {
icon: `achievement-ultimate-${type}`,
titleKey: 'ultimGearName',
@@ -236,7 +236,7 @@ let ultimateGearAchievs = ['healer', 'rogue', 'warrior', 'mage'].reduce((achievs
}, {});
Object.assign(achievementsData, ultimateGearAchievs);
let cardAchievs = ['greeting', 'thankyou', 'nye', 'valentine', 'birthday', 'congrats', 'getwell', 'goodluck'].reduce((achievs, type) => {
const cardAchievs = ['greeting', 'thankyou', 'nye', 'valentine', 'birthday', 'congrats', 'getwell', 'goodluck'].reduce((achievs, type) => {
achievs[`${type}Cards`] = {
icon: `achievement-${type}`,
titleKey: `${type}CardAchievementTitle`,

View File

@@ -2,7 +2,7 @@ import forOwn from 'lodash/forOwn';
import t from '../translation';
/* eslint-disable camelcase */
let backgrounds = {
const backgrounds = {
backgrounds062014: {
beach: {
text: t('backgroundBeachText'),
@@ -948,10 +948,10 @@ let backgrounds = {
};
/* eslint-enable quote-props */
let flat = {};
const flat = {};
forOwn(backgrounds, function prefillBackgroundSet (backgroundsInSet, set) {
forOwn(backgroundsInSet, function prefillBackground (background, bgKey) {
forOwn(backgrounds, (backgroundsInSet, set) => {
forOwn(backgroundsInSet, (background, bgKey) => {
background.key = bgKey;
background.set = set;
background.price = 7;

View File

@@ -1,17 +1,17 @@
import forOwn from 'lodash/forOwn';
import clone from 'lodash/clone';
import hair from './hair';
import shirts from './shirt.js';
import skins from './skin.js';
import sizes from './size.js';
import backgrounds from './backgrounds.js';
import chairs from './chair.js';
import forOwn from 'lodash/forOwn';
import clone from 'lodash/clone';
let reorderedBgs = {};
const reorderedBgs = {};
forOwn(backgrounds, function restructureBackgroundSet (value, key) {
forOwn(value, function restructureBackground (bgObject, bgKey) {
let bg = clone(bgObject);
forOwn(backgrounds, (value, key) => {
forOwn(value, (bgObject, bgKey) => {
const bg = clone(bgObject);
bg.set = {
text: key,
key,
@@ -22,7 +22,7 @@ forOwn(backgrounds, function restructureBackgroundSet (value, key) {
});
let appearances = {
const appearances = {
hair,
shirt: shirts,
size: sizes,

View File

@@ -1,7 +1,7 @@
import forOwn from 'lodash/forOwn';
export default function prefillAppearances (obj) {
forOwn(obj, function prefillAppearance (value, key) {
forOwn(obj, (value, key) => {
value.key = key;
if (!value.price) {
value.price = 0;

View File

@@ -10,14 +10,28 @@ export default prefill({
winterHairColors: { setPrice: 5, availableUntil: '2016-01-01' },
pastelHairColors: { setPrice: 5, availableUntil: '2016-01-01' },
rainbowHairColors: { setPrice: 5, text: t('rainbowColors') },
shimmerHairColors: {setPrice: 5, availableFrom: '2019-04-09', availableUntil: '2019-05-02', text: t('shimmerColors')},
hauntedHairColors: {setPrice: 5, availableFrom: '2018-10-11', availableUntil: '2018-11-02', text: t('hauntedColors')},
winteryHairColors: {setPrice: 5, availableFrom: '2019-01-08', availableUntil: '2019-02-02', text: t('winteryColors')},
shimmerHairColors: {
setPrice: 5, availableFrom: '2019-04-09', availableUntil: '2019-05-02', text: t('shimmerColors'),
},
hauntedHairColors: {
setPrice: 5, availableFrom: '2018-10-11', availableUntil: '2018-11-02', text: t('hauntedColors'),
},
winteryHairColors: {
setPrice: 5, availableFrom: '2019-01-08', availableUntil: '2019-02-02', text: t('winteryColors'),
},
rainbowSkins: { setPrice: 5, text: t('rainbowSkins') },
animalSkins: { setPrice: 5, text: t('animalSkins') },
pastelSkins: {setPrice: 5, availableFrom: '2019-04-09', availableUntil: '2019-05-02', text: t('pastelSkins')},
pastelSkins: {
setPrice: 5, availableFrom: '2019-04-09', availableUntil: '2019-05-02', text: t('pastelSkins'),
},
spookySkins: { setPrice: 5, availableUntil: '2016-01-01', text: t('spookySkins') },
supernaturalSkins: {setPrice: 5, availableFrom: '2018-10-11', availableUntil: '2018-11-02', text: t('supernaturalSkins')},
splashySkins: {setPrice: 5, availableFrom: '2019-07-02', availableUntil: '2019-08-02', text: t('splashySkins')},
winterySkins: {setPrice: 5, availableFrom: '2019-01-08', availableUntil: '2019-02-02', text: t('winterySkins')},
supernaturalSkins: {
setPrice: 5, availableFrom: '2018-10-11', availableUntil: '2018-11-02', text: t('supernaturalSkins'),
},
splashySkins: {
setPrice: 5, availableFrom: '2019-07-02', availableUntil: '2019-08-02', text: t('splashySkins'),
},
winterySkins: {
setPrice: 5, availableFrom: '2019-01-08', availableUntil: '2019-02-02', text: t('winterySkins'),
},
});

View File

@@ -264,6 +264,10 @@ export const QUEST_SERIES_ACHIEVEMENTS = {
};
export const ANIMAL_COLOR_ACHIEVEMENTS = [
{color: 'Base', petAchievement: 'backToBasics', petNotificationType: 'ACHIEVEMENT_BACK_TO_BASICS', mountAchievement: 'allYourBase', mountNotificationType: 'ACHIEVEMENT_ALL_YOUR_BASE'},
{color: 'Desert', petAchievement: 'dustDevil', petNotificationType: 'ACHIEVEMENT_DUST_DEVIL', mountAchievement: 'aridAuthority', mountNotificationType: 'ACHIEVEMENT_ARID_AUTHORITY'},
{
color: 'Base', petAchievement: 'backToBasics', petNotificationType: 'ACHIEVEMENT_BACK_TO_BASICS', mountAchievement: 'allYourBase', mountNotificationType: 'ACHIEVEMENT_ALL_YOUR_BASE',
},
{
color: 'Desert', petAchievement: 'dustDevil', petNotificationType: 'ACHIEVEMENT_DUST_DEVIL', mountAchievement: 'aridAuthority', mountNotificationType: 'ACHIEVEMENT_ARID_AUTHORITY',
},
];

View File

@@ -19,13 +19,11 @@ function applyEggDefaults (set, config) {
}
function hasQuestAchievementFunction (key) {
return (user) => {
return user.achievements.quests &&
user.achievements.quests[key] > 0;
};
return user => user.achievements.quests
&& user.achievements.quests[key] > 0;
}
let drops = {
const drops = {
Wolf: {
text: t('dropEggWolfText'),
mountText: t('dropEggWolfMountText'),
@@ -73,7 +71,7 @@ let drops = {
},
};
let quests = {
const quests = {
Gryphon: {
text: t('questEggGryphonText'),
mountText: t('questEggGryphonMountText'),
@@ -150,11 +148,11 @@ let quests = {
mountText: t('questEggTRexMountText'),
adjective: t('questEggTRexAdjective'),
canBuy (user) {
let questAchievements = user.achievements.quests;
const questAchievements = user.achievements.quests;
return questAchievements && (
questAchievements.trex > 0 ||
questAchievements.trex_undead > 0
questAchievements.trex > 0
|| questAchievements.trex_undead > 0
);
},
},
@@ -406,7 +404,7 @@ applyEggDefaults(quests, {
},
});
let all = assign({}, drops, quests);
const all = assign({}, drops, quests);
export {
drops,

View File

@@ -2,7 +2,7 @@ import t from './translation';
const NUMBER_OF_QUESTIONS = 12;
let faq = {
const faq = {
questions: [],
stillNeedHelp: {
ios: t('iosFaqStillNeedHelp'),
@@ -11,7 +11,7 @@ let faq = {
};
for (let i = 0; i <= NUMBER_OF_QUESTIONS; i++) {
let question = {
const question = {
question: t(`faqQuestion${i}`),
ios: t(`iosFaqAnswer${i}`),
android: t(`androidFaqAnswer${i}`),

View File

@@ -9,7 +9,7 @@ import {armor as specialArmor} from './sets/special';
import { armor as mysteryArmor } from './sets/mystery';
import { armor as armoireArmor } from './sets/armoire';
let armor = {
const armor = {
base: baseArmor,
warrior: warriorArmor,

View File

@@ -3,11 +3,10 @@ import {back as baseBack} from './sets/base';
import { back as mysteryBack } from './sets/mystery';
import { back as specialBack } from './sets/special';
let back = {
const back = {
base: baseBack,
mystery: mysteryBack,
special: specialBack,
};
export default back;

View File

@@ -4,7 +4,7 @@ import {body as mysteryBody} from './sets/mystery';
import { body as specialBody } from './sets/special';
import { body as armoireBody } from './sets/armoire';
let body = {
const body = {
base: baseBody,
mystery: mysteryBody,
special: specialBody,

View File

@@ -4,7 +4,7 @@ import {eyewear as armoireEyewear} from './sets/armoire';
import { eyewear as mysteryEyewear } from './sets/mystery';
import { eyewear as specialEyewear } from './sets/special';
let eyewear = {
const eyewear = {
base: baseEyewear,
special: specialEyewear,
mystery: mysteryEyewear,

View File

@@ -1,7 +1,5 @@
import isBoolean from 'lodash/isBoolean';
export function ownsItem (item) {
return (user) => {
return item && isBoolean(user.items.gear.owned[item]);
};
return user => item && isBoolean(user.items.gear.owned[item]);
}

View File

@@ -4,7 +4,7 @@ import {headAccessory as specialHeadAccessory} from './sets/special';
import { headAccessory as mysteryHeadAccessory } from './sets/mystery';
import { headAccessory as armoireHeadAccessory } from './sets/armoire';
let headAccessory = {
const headAccessory = {
base: baseHeadAccessory,
special: specialHeadAccessory,
mystery: mysteryHeadAccessory,
@@ -12,4 +12,3 @@ let headAccessory = {
};
export default headAccessory;

View File

@@ -9,7 +9,7 @@ import {head as armoireHead} from './sets/armoire';
import { head as mysteryHead } from './sets/mystery';
import { head as specialHead } from './sets/special';
let head = {
const head = {
base: baseHead,
warrior: warriorHead,

View File

@@ -17,7 +17,7 @@ import body from './body';
import headAccessory from './head-accessory';
import eyewear from './eyewear';
let gear = {
const gear = {
weapon,
armor,
head,
@@ -32,15 +32,15 @@ let gear = {
The gear is exported as a tree (defined above), and a flat list (eg, {weapon_healer_1: .., shield_special_0: ...}) since
they are needed in different forms at different points in the app
*/
let flat = {};
const flat = {};
each(GEAR_TYPES, (type) => {
let allGearTypes = CLASSES.concat(['base', 'special', 'mystery', 'armoire']);
each(GEAR_TYPES, type => {
const allGearTypes = CLASSES.concat(['base', 'special', 'mystery', 'armoire']);
each(allGearTypes, (klass) => {
each(allGearTypes, klass => {
each(gear[type][klass], (item, index) => {
let key = `${type}_${klass}_${index}`;
let set = `${klass}-${index}`;
const key = `${type}_${klass}_${index}`;
const set = `${klass}-${index}`;
defaults(item, {
type,
@@ -52,21 +52,17 @@ each(GEAR_TYPES, (type) => {
int: 0,
per: 0,
con: 0,
canBuy: () => {
return false;
},
canBuy: () => false,
});
if (item.event) {
let canOwnFuncTrue = () => {
return true;
};
let _canOwn = item.canOwn || canOwnFuncTrue;
const canOwnFuncTrue = () => true;
const _canOwn = item.canOwn || canOwnFuncTrue;
item.canOwn = (user) => {
let userHasOwnedItem = ownsItem(key)(user);
let eventIsCurrent = moment().isAfter(item.event.start) && moment().isBefore(item.event.end);
let compatibleWithUserClass = item.specialClass ? user.stats.class === item.specialClass : true;
item.canOwn = user => {
const userHasOwnedItem = ownsItem(key)(user);
const eventIsCurrent = moment().isAfter(item.event.start) && moment().isBefore(item.event.end);
const compatibleWithUserClass = item.specialClass ? user.stats.class === item.specialClass : true;
return _canOwn(user) && (userHasOwnedItem || eventIsCurrent) && compatibleWithUserClass;
};

View File

@@ -1,7 +1,7 @@
import { ownsItem } from '../gear-helper';
import t from '../../translation';
let armor = {
const armor = {
lunarArmor: {
text: t('armorArmoireLunarArmorText'),
notes: t('armorArmoireLunarArmorNotes', { str: 7, int: 7 }),
@@ -500,7 +500,7 @@ let armor = {
},
};
let body = {
const body = {
cozyScarf: {
text: t('bodyArmoireCozyScarfText'),
notes: t('bodyArmoireCozyScarfNotes', { attrs: 5 }),
@@ -512,7 +512,7 @@ let body = {
},
};
let eyewear = {
const eyewear = {
plagueDoctorMask: {
text: t('eyewearArmoirePlagueDoctorMaskText'),
notes: t('eyewearArmoirePlagueDoctorMaskNotes', { attrs: 5 }),
@@ -531,7 +531,7 @@ let eyewear = {
},
};
let head = {
const head = {
lunarCrown: {
text: t('headArmoireLunarCrownText'),
notes: t('headArmoireLunarCrownNotes', { con: 7, per: 7 }),
@@ -1022,7 +1022,7 @@ let head = {
},
};
let shield = {
const shield = {
gladiatorShield: {
text: t('shieldArmoireGladiatorShieldText'),
notes: t('shieldArmoireGladiatorShieldNotes', { con: 5, str: 5 }),
@@ -1301,7 +1301,7 @@ let shield = {
},
};
let headAccessory = {
const headAccessory = {
comicalArrow: {
text: t('headAccessoryArmoireComicalArrowText'),
notes: t('headAccessoryArmoireComicalArrowNotes', { str: 10 }),
@@ -1319,7 +1319,7 @@ let headAccessory = {
},
};
let weapon = {
const weapon = {
basicCrossbow: {
text: t('weaponArmoireBasicCrossbowText'),
notes: t('weaponArmoireBasicCrossbowNotes', { str: 5, per: 5, con: 5 }),

View File

@@ -1,6 +1,6 @@
import t from '../../translation';
let armor = {
const armor = {
0: {
text: t('armorBase0Text'),
notes: t('armorBase0Notes'),
@@ -8,7 +8,7 @@ let armor = {
},
};
let back = {
const back = {
0: {
text: t('backBase0Text'),
notes: t('backBase0Notes'),
@@ -16,7 +16,7 @@ let back = {
},
};
let body = {
const body = {
0: {
text: t('bodyBase0Text'),
notes: t('bodyBase0Notes'),
@@ -24,7 +24,7 @@ let body = {
},
};
let eyewear = {
const eyewear = {
0: {
text: t('eyewearBase0Text'),
notes: t('eyewearBase0Notes'),
@@ -33,7 +33,7 @@ let eyewear = {
},
};
let head = {
const head = {
0: {
text: t('headBase0Text'),
notes: t('headBase0Notes'),
@@ -41,7 +41,7 @@ let head = {
},
};
let headAccessory = {
const headAccessory = {
0: {
text: t('headAccessoryBase0Text'),
notes: t('headAccessoryBase0Notes'),
@@ -50,7 +50,7 @@ let headAccessory = {
},
};
let shield = {
const shield = {
0: {
text: t('shieldBase0Text'),
notes: t('shieldBase0Notes'),
@@ -58,7 +58,7 @@ let shield = {
},
};
let weapon = {
const weapon = {
0: {
text: t('weaponBase0Text'),
notes: t('weaponBase0Notes'),

View File

@@ -1,6 +1,6 @@
import t from '../../translation';
let armor = {
const armor = {
1: {
text: t('armorHealer1Text'),
notes: t('armorHealer1Notes', { con: 6 }),
@@ -34,7 +34,7 @@ let armor = {
},
};
let head = {
const head = {
1: {
text: t('headHealer1Text'),
notes: t('headHealer1Notes', { int: 2 }),
@@ -68,7 +68,7 @@ let head = {
},
};
let shield = {
const shield = {
1: {
text: t('shieldHealer1Text'),
notes: t('shieldHealer1Notes', { con: 2 }),
@@ -102,7 +102,7 @@ let shield = {
},
};
let weapon = {
const weapon = {
0: {
text: t('weaponHealer0Text'),

View File

@@ -1,6 +1,6 @@
import t from '../../translation';
let armor = {
const armor = {
201402: {
text: t('armorMystery201402Text'),
notes: t('armorMystery201402Notes'),
@@ -279,7 +279,7 @@ let armor = {
},
};
let back = {
const back = {
201402: {
text: t('backMystery201402Text'),
notes: t('backMystery201402Notes'),
@@ -390,7 +390,7 @@ let back = {
},
};
let body = {
const body = {
201705: {
text: t('bodyMystery201705Text'),
notes: t('bodyMystery201705Notes'),
@@ -417,7 +417,7 @@ let body = {
},
};
let eyewear = {
const eyewear = {
201503: {
text: t('eyewearMystery201503Text'),
notes: t('eyewearMystery201503Notes'),
@@ -474,7 +474,7 @@ let eyewear = {
},
};
let head = {
const head = {
201402: {
text: t('headMystery201402Text'),
notes: t('headMystery201402Notes'),
@@ -771,7 +771,7 @@ let head = {
},
};
let headAccessory = {
const headAccessory = {
201403: {
text: t('headAccessoryMystery201403Text'),
notes: t('headAccessoryMystery201403Notes'),
@@ -846,7 +846,7 @@ let headAccessory = {
},
};
let shield = {
const shield = {
201601: {
text: t('shieldMystery201601Text'),
notes: t('shieldMystery201601Notes'),
@@ -897,7 +897,7 @@ let shield = {
},
};
let weapon = {
const weapon = {
201411: {
text: t('weaponMystery201411Text'),
notes: t('weaponMystery201411Notes'),

View File

@@ -1,6 +1,6 @@
import t from '../../translation';
let armor = {
const armor = {
1: {
text: t('armorRogue1Text'),
notes: t('armorRogue1Notes', { per: 6 }),
@@ -34,7 +34,7 @@ let armor = {
},
};
let head = {
const head = {
1: {
text: t('headRogue1Text'),
notes: t('headRogue1Notes', { per: 2 }),
@@ -68,7 +68,7 @@ let head = {
},
};
let weapon = {
const weapon = {
0: {
text: t('weaponRogue0Text'),
notes: t('weaponRogue0Notes'),
@@ -114,7 +114,7 @@ let weapon = {
},
};
let shield = {
const shield = {
0: {
text: t('weaponRogue0Text'),
notes: t('weaponRogue0Notes'),

File diff suppressed because it is too large Load Diff

View File

@@ -1,16 +1,14 @@
import { ownsItem } from '../../gear-helper';
import t from '../../../translation';
let isBackerOfLevel = (tierRequirement, ownedItem) => {
return (user) => {
let backer = user.backer;
let tier = Number(backer && backer.tier);
const isBackerOfLevel = (tierRequirement, ownedItem) => user => {
const { backer } = user;
const tier = Number(backer && backer.tier);
return tier >= tierRequirement || ownsItem(ownedItem)(user);
};
};
let armorSpecial0 = {
const armorSpecial0 = {
text: t('armorSpecial0Text'),
notes: t('armorSpecial0Notes', { con: 20 }),
con: 20,
@@ -18,7 +16,7 @@ let armorSpecial0 = {
canOwn: isBackerOfLevel(45, 'armor_special_0'),
};
let armorSpecial2 = {
const armorSpecial2 = {
text: t('armorSpecial2Text'),
notes: t('armorSpecial2Notes', { attrs: 25 }),
int: 25,
@@ -27,7 +25,7 @@ let armorSpecial2 = {
canOwn: isBackerOfLevel(300, 'armor_special_2'),
};
let headSpecial0 = {
const headSpecial0 = {
text: t('headSpecial0Text'),
notes: t('headSpecial0Notes', { int: 20 }),
int: 20,
@@ -35,7 +33,7 @@ let headSpecial0 = {
canOwn: isBackerOfLevel(45, 'head_special_0'),
};
let headSpecial2 = {
const headSpecial2 = {
text: t('headSpecial2Text'),
notes: t('headSpecial2Notes', { attrs: 25 }),
int: 25,
@@ -44,7 +42,7 @@ let headSpecial2 = {
canOwn: isBackerOfLevel(300, 'head_special_2'),
};
let shieldSpecial0 = {
const shieldSpecial0 = {
text: t('shieldSpecial0Text'),
notes: t('shieldSpecial0Notes', { per: 20 }),
per: 20,
@@ -52,7 +50,7 @@ let shieldSpecial0 = {
canOwn: isBackerOfLevel(45, 'shield_special_0'),
};
let weaponSpecial0 = {
const weaponSpecial0 = {
text: t('weaponSpecial0Text'),
notes: t('weaponSpecial0Notes', { str: 20 }),
str: 20,
@@ -60,7 +58,7 @@ let weaponSpecial0 = {
canOwn: isBackerOfLevel(70, 'weapon_special_0'),
};
let weaponSpecial2 = {
const weaponSpecial2 = {
text: t('weaponSpecial2Text'),
notes: t('weaponSpecial2Notes', { attrs: 25 }),
str: 25,
@@ -69,7 +67,7 @@ let weaponSpecial2 = {
canOwn: isBackerOfLevel(300, 'weapon_special_2'),
};
let weaponSpecial3 = {
const weaponSpecial3 = {
text: t('weaponSpecial3Text'),
notes: t('weaponSpecial3Notes', { attrs: 17 }),
str: 17,

View File

@@ -1,16 +1,14 @@
import { ownsItem } from '../../gear-helper';
import t from '../../../translation';
let isContributorOfLevel = (tierRequirement, ownedItem) => {
return (user) => {
let contributor = user.contributor;
let tier = contributor && contributor.level;
const isContributorOfLevel = (tierRequirement, ownedItem) => user => {
const { contributor } = user;
const tier = contributor && contributor.level;
return Number(tier) >= tierRequirement || ownsItem(ownedItem)(user);
};
};
let armorSpecial1 = {
const armorSpecial1 = {
text: t('armorSpecial1Text'),
notes: t('armorSpecial1Notes', { attrs: 6 }),
con: 6,
@@ -21,7 +19,7 @@ let armorSpecial1 = {
canOwn: isContributorOfLevel(2, 'armor_special_1'),
};
let headSpecial1 = {
const headSpecial1 = {
text: t('headSpecial1Text'),
notes: t('headSpecial1Notes', { attrs: 6 }),
con: 6,
@@ -32,7 +30,7 @@ let headSpecial1 = {
canOwn: isContributorOfLevel(3, 'head_special_1'),
};
let shieldSpecial1 = {
const shieldSpecial1 = {
text: t('shieldSpecial1Text'),
notes: t('shieldSpecial1Notes', { attrs: 6 }),
con: 6,
@@ -43,7 +41,7 @@ let shieldSpecial1 = {
canOwn: isContributorOfLevel(5, 'shield_special_1'),
};
let weaponSpecial1 = {
const weaponSpecial1 = {
text: t('weaponSpecial1Text'),
notes: t('weaponSpecial1Notes', { attrs: 6 }),
str: 6,
@@ -54,15 +52,15 @@ let weaponSpecial1 = {
canOwn: isContributorOfLevel(4, 'weapon_special_1'),
};
let weaponSpecialCritical = {
const weaponSpecialCritical = {
text: t('weaponSpecialCriticalText'),
notes: t('weaponSpecialCriticalNotes', { attrs: 40 }),
str: 40,
per: 40,
value: 200,
canOwn: (user) => {
let hasCriticalFlag = user.contributor && user.contributor.critical;
let alreadyHasItem = ownsItem('weapon_special_critical')(user);
canOwn: user => {
const hasCriticalFlag = user.contributor && user.contributor.critical;
const alreadyHasItem = ownsItem('weapon_special_critical')(user);
return hasCriticalFlag || alreadyHasItem;
},

View File

@@ -1,6 +1,6 @@
import t from '../../../translation';
let armorSpecialTakeThis = {
const armorSpecialTakeThis = {
text: t('armorSpecialTakeThisText'),
notes: t('armorSpecialTakeThisNotes', { attrs: 5 }),
value: 0,
@@ -10,7 +10,7 @@ let armorSpecialTakeThis = {
str: 5,
};
let backSpecialTakeThis = {
const backSpecialTakeThis = {
text: t('backSpecialTakeThisText'),
notes: t('backSpecialTakeThisNotes', { attrs: 1 }),
value: 0,
@@ -20,7 +20,7 @@ let backSpecialTakeThis = {
str: 1,
};
let bodySpecialTakeThis = {
const bodySpecialTakeThis = {
text: t('bodySpecialTakeThisText'),
notes: t('bodySpecialTakeThisNotes', { attrs: 1 }),
value: 0,
@@ -30,7 +30,7 @@ let bodySpecialTakeThis = {
str: 1,
};
let headSpecialTakeThis = {
const headSpecialTakeThis = {
text: t('headSpecialTakeThisText'),
notes: t('headSpecialTakeThisNotes', { attrs: 5 }),
value: 0,
@@ -40,7 +40,7 @@ let headSpecialTakeThis = {
str: 5,
};
let shieldSpecialTakeThis = {
const shieldSpecialTakeThis = {
text: t('shieldSpecialTakeThisText'),
notes: t('shieldSpecialTakeThisNotes', { attrs: 5 }),
value: 0,
@@ -50,7 +50,7 @@ let shieldSpecialTakeThis = {
str: 5,
};
let weaponSpecialTakeThis = {
const weaponSpecialTakeThis = {
text: t('weaponSpecialTakeThisText'),
notes: t('weaponSpecialTakeThisNotes', { attrs: 5 }),
value: 0,

View File

@@ -1,48 +1,48 @@
import t from '../../../translation';
let backSpecialWonderconRed = {
const backSpecialWonderconRed = {
text: t('backSpecialWonderconRedText'),
notes: t('backSpecialWonderconRedNotes'),
value: 0,
mystery: 'wondercon',
};
let backSpecialWonderconBlack = {
const backSpecialWonderconBlack = {
text: t('backSpecialWonderconBlackText'),
notes: t('backSpecialWonderconBlackNotes'),
value: 0,
mystery: 'wondercon',
};
let bodySpecialWonderconRed = {
const bodySpecialWonderconRed = {
text: t('bodySpecialWonderconRedText'),
notes: t('bodySpecialWonderconRedNotes'),
value: 0,
mystery: 'wondercon',
};
let bodySpecialWonderconGold = {
const bodySpecialWonderconGold = {
text: t('bodySpecialWonderconGoldText'),
notes: t('bodySpecialWonderconGoldNotes'),
value: 0,
mystery: 'wondercon',
};
let bodySpecialWonderconBlack = {
const bodySpecialWonderconBlack = {
text: t('bodySpecialWonderconBlackText'),
notes: t('bodySpecialWonderconBlackNotes'),
value: 0,
mystery: 'wondercon',
};
let eyewearSpecialWonderconRed = {
const eyewearSpecialWonderconRed = {
text: t('eyewearSpecialWonderconRedText'),
notes: t('eyewearSpecialWonderconRedNotes'),
value: 0,
mystery: 'wondercon',
};
let eyewearSpecialWonderconBlack = {
const eyewearSpecialWonderconBlack = {
text: t('eyewearSpecialWonderconBlackText'),
notes: t('eyewearSpecialWonderconBlackNotes'),
value: 0,

View File

@@ -1,6 +1,6 @@
import t from '../../translation';
let armor = {
const armor = {
1: {
text: t('armorWarrior1Text'),
notes: t('armorWarrior1Notes', { con: 3 }),
@@ -34,7 +34,7 @@ let armor = {
},
};
let head = {
const head = {
1: {
text: t('headWarrior1Text'),
notes: t('headWarrior1Notes', { str: 2 }),
@@ -68,7 +68,7 @@ let head = {
},
};
let shield = {
const shield = {
1: {
text: t('shieldWarrior1Text'),
notes: t('shieldWarrior1Notes', { con: 2 }),
@@ -102,10 +102,12 @@ let shield = {
},
};
let weapon = {
const weapon = {
0: {
text: t('weaponWarrior0Text'),
notes: t('weaponWarrior0Notes'), value: 1 },
notes: t('weaponWarrior0Notes'),
value: 1,
},
1: {
text: t('weaponWarrior1Text'),
notes: t('weaponWarrior1Notes', { str: 3 }),

View File

@@ -1,6 +1,6 @@
import t from '../../translation';
let armor = {
const armor = {
1: {
text: t('armorWizard1Text'),
notes: t('armorWizard1Notes', { int: 2 }),
@@ -34,7 +34,7 @@ let armor = {
},
};
let head = {
const head = {
1: {
text: t('headWizard1Text'),
notes: t('headWizard1Notes', { per: 2 }),
@@ -68,18 +68,20 @@ let head = {
},
};
let shield = {
const shield = {
// Wizard's weapons are two handed
// And thus do not have shields
// But the content structure still expects an object
};
let weapon = {
const weapon = {
0: {
twoHanded: true,
text: t('weaponWizard0Text'),
notes: t('weaponWizard0Notes'), value: 0 },
notes: t('weaponWizard0Notes'),
value: 0,
},
1: {
twoHanded: true,
text: t('weaponWizard1Text'),

View File

@@ -11,9 +11,9 @@ import {shield as armoireShield} from './sets/armoire';
import { shield as mysteryShield } from './sets/mystery';
import { shield as specialShield } from './sets/special';
let rogueShield = cloneDeep(rogueWeapon);
const rogueShield = cloneDeep(rogueWeapon);
let shield = {
const shield = {
base: baseShield,
warrior: warriorShield,

View File

@@ -11,7 +11,7 @@ import {weapon as armoireWeapon} from './sets/armoire';
import { weapon as mysteryWeapon } from './sets/mystery';
import { weapon as specialWeapon } from './sets/special';
let weapon = {
const weapon = {
base: baseWeapon,
warrior: warriorWeapon,
@@ -46,12 +46,12 @@ const rtlLanguages = [
'ur', /* 'اردو', Urdu */
'yi', /* 'ייִדיש', Yiddish */
];
for (let key in weapon) {
for (const key in weapon) {
const set = weapon[key];
for (let weaponKey in set) {
for (const weaponKey in set) {
const item = set[weaponKey];
const oldnotes = item.notes;
item.notes = (lang) => {
item.notes = lang => {
const twoHandedText = item.twoHanded ? t('twoHandedItem')(lang) : '';
if (rtlLanguages.indexOf(lang) !== -1) {

View File

@@ -6,13 +6,11 @@ import t from './translation';
const CURRENT_SEASON = 'October';
function hasQuestAchievementFunction (key) {
return (user) => {
return user.achievements.quests &&
user.achievements.quests[key] > 0;
};
return user => user.achievements.quests
&& user.achievements.quests[key] > 0;
}
let drops = {
const drops = {
Base: {
value: 2,
text: t('hatchingPotionBase'),
@@ -55,7 +53,7 @@ let drops = {
},
};
let premium = {
const premium = {
RoyalPurple: {
value: 2,
text: t('hatchingPotionRoyalPurple'),
@@ -279,7 +277,7 @@ each(wacky, (pot, key) => {
});
});
let all = assign({}, drops, premium, wacky);
const all = assign({}, drops, premium, wacky);
export {
drops,

View File

@@ -12,8 +12,6 @@ import {
ANIMAL_COLOR_ACHIEVEMENTS,
} from './constants';
const api = {};
import achievements from './achievements';
import * as eggs from './eggs';
@@ -37,6 +35,8 @@ import loginIncentives from './loginIncentives';
import officialPinnedItems from './officialPinnedItems';
const api = {};
api.achievements = achievements;
api.questSeriesAchievements = QUEST_SERIES_ACHIEVEMENTS;
api.animalColorAchievements = ANIMAL_COLOR_ACHIEVEMENTS;
@@ -810,8 +810,7 @@ api.food = {
/* eslint-enable camelcase */
};
each(api.food, (food, key) => {
return defaults(food, {
each(api.food, (food, key) => defaults(food, {
value: 1,
key,
notes: t('foodNotes'),
@@ -819,8 +818,7 @@ each(api.food, (food, key) => {
return false;
},
canDrop: false,
});
});
}));
api.appearances = appearances;

View File

@@ -4,7 +4,7 @@ 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
export default function getLoginIncentives (api) {
let loginIncentives = {
const loginIncentives = {
1: {
rewardKey: ['armor_special_bardRobes'],
reward: [api.gear.flat.armor_special_bardRobes],
@@ -645,7 +645,7 @@ export default 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(index => {
if (loginIncentives[index] && loginIncentives[index].rewardKey) {
loginIncentives[index].nextRewardAt = nextRewardKey;
nextRewardKey = index;
@@ -659,7 +659,7 @@ export default function getLoginIncentives (api) {
});
let prevRewardKey;
range(MAX_INCENTIVES + 1).forEach(function addPrevRewardLink (index) {
range(MAX_INCENTIVES + 1).forEach(index => {
loginIncentives[index].prevRewardKey = prevRewardKey;
if (loginIncentives[index].rewardKey) prevRewardKey = index;
});

View File

@@ -1,7 +1,7 @@
import each from 'lodash/each';
import t from './translation';
let mysterySets = {
const mysterySets = {
201402: {
start: '2014-02-22',
end: '2014-02-28',

View File

@@ -6,9 +6,9 @@ import {
USER_CAN_OWN_QUEST_CATEGORIES,
} from './constants';
let userCanOwnQuestCategories = USER_CAN_OWN_QUEST_CATEGORIES;
const userCanOwnQuestCategories = USER_CAN_OWN_QUEST_CATEGORIES;
let quests = {
const quests = {
dilatory: {
text: t('questDilatoryText'),
notes: t('questDilatoryNotes'),
@@ -3527,9 +3527,7 @@ each(quests, (v, key) => {
}
});
let questsByLevel = sortBy(quests, (quest) => {
return quest.lvl || 0;
});
const questsByLevel = sortBy(quests, quest => quest.lvl || 0);
export {
quests,

View File

@@ -1,5 +1,5 @@
import t from './translation';
import each from 'lodash/each';
import t from './translation';
import { NotAuthorized } from '../libs/errors';
import statsComputed from '../libs/statsComputed';
import crit from '../fns/crit';
@@ -35,7 +35,7 @@ function calculateBonus (value, stat, critVal = 1, statScale = 0.5) {
return (value < 0 ? 1 : value + 1) + stat * statScale * critVal;
}
let spells = {};
const spells = {};
spells.wizard = {
fireball: { // Burst of Flames
@@ -60,8 +60,8 @@ spells.wizard = {
target: 'party',
notes: t('spellWizardMPHealNotes'),
cast (user, target) {
each(target, (member) => {
let bonus = statsComputed(user).int;
each(target, member => {
const bonus = statsComputed(user).int;
if (user._id !== member._id && member.stats.class !== 'wizard') {
member.stats.mp += Math.ceil(diminishingReturns(bonus, 25, 125));
}
@@ -75,8 +75,8 @@ spells.wizard = {
target: 'party',
notes: t('spellWizardEarthNotes'),
cast (user, target) {
each(target, (member) => {
let bonus = statsComputed(user).int - user.stats.buffs.int;
each(target, member => {
const bonus = statsComputed(user).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));
});
@@ -102,7 +102,7 @@ spells.warrior = {
target: 'task',
notes: t('spellWarriorSmashNotes'),
cast (user, target) {
let bonus = statsComputed(user).str * crit.crit(user, 'con');
const bonus = statsComputed(user).str * crit.crit(user, 'con');
target.value += diminishingReturns(bonus, 2.5, 35);
if (!user.party.quest.progress.up) user.party.quest.progress.up = 0;
user.party.quest.progress.up += diminishingReturns(bonus, 55, 70);
@@ -115,7 +115,7 @@ spells.warrior = {
target: 'self',
notes: t('spellWarriorDefensiveStanceNotes'),
cast (user) {
let bonus = statsComputed(user).con - user.stats.buffs.con;
const bonus = statsComputed(user).con - user.stats.buffs.con;
if (!user.stats.buffs.con) user.stats.buffs.con = 0;
user.stats.buffs.con += Math.ceil(diminishingReturns(bonus, 40, 200));
},
@@ -127,8 +127,8 @@ spells.warrior = {
target: 'party',
notes: t('spellWarriorValorousPresenceNotes'),
cast (user, target) {
each(target, (member) => {
let bonus = statsComputed(user).str - user.stats.buffs.str;
each(target, member => {
const bonus = statsComputed(user).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));
});
@@ -141,8 +141,8 @@ spells.warrior = {
target: 'party',
notes: t('spellWarriorIntimidateNotes'),
cast (user, target) {
each(target, (member) => {
let bonus = statsComputed(user).con - user.stats.buffs.con;
each(target, member => {
const bonus = statsComputed(user).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));
});
@@ -158,7 +158,7 @@ spells.rogue = {
target: 'task',
notes: t('spellRoguePickPocketNotes'),
cast (user, target) {
let bonus = calculateBonus(target.value, statsComputed(user).per);
const bonus = calculateBonus(target.value, statsComputed(user).per);
user.stats.gp += diminishingReturns(bonus, 25, 75);
},
},
@@ -169,8 +169,8 @@ spells.rogue = {
target: 'task',
notes: t('spellRogueBackStabNotes'),
cast (user, target, req) {
let _crit = crit.crit(user, 'str', 0.3);
let bonus = calculateBonus(target.value, statsComputed(user).str, _crit);
const _crit = crit.crit(user, 'str', 0.3);
const bonus = calculateBonus(target.value, statsComputed(user).str, _crit);
user.stats.exp += diminishingReturns(bonus, 75, 50);
user.stats.gp += diminishingReturns(bonus, 18, 75);
updateStats(user, user.stats, req);
@@ -183,8 +183,8 @@ spells.rogue = {
target: 'party',
notes: t('spellRogueToolsOfTradeNotes'),
cast (user, target) {
each(target, (member) => {
let bonus = statsComputed(user).per - user.stats.buffs.per;
each(target, member => {
const bonus = statsComputed(user).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));
});
@@ -223,7 +223,7 @@ spells.healer = {
target: 'tasks',
notes: t('spellHealerBrightnessNotes'),
cast (user, tasks) {
each(tasks, (task) => {
each(tasks, task => {
if (task.type !== 'reward') {
task.value += 4 * (statsComputed(user).int / (statsComputed(user).int + 40));
}
@@ -237,8 +237,8 @@ spells.healer = {
target: 'party',
notes: t('spellHealerProtectAuraNotes'),
cast (user, target) {
each(target, (member) => {
let bonus = statsComputed(user).con - user.stats.buffs.con;
each(target, member => {
const bonus = statsComputed(user).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));
});
@@ -251,7 +251,7 @@ spells.healer = {
target: 'party',
notes: t('spellHealerHealAllNotes'),
cast (user, target) {
each(target, (member) => {
each(target, member => {
member.stats.hp += (statsComputed(user).con + statsComputed(user).int + 5) * 0.04;
if (member.stats.hp > 50) member.stats.hp = 50;
});
@@ -397,7 +397,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++;
});
@@ -407,13 +407,15 @@ spells.special = {
const senderName = user.profile.name;
target.items.special.nyeReceived.push(senderName);
if (target.addNotification) target.addNotification('CARD_RECEIVED', {
if (target.addNotification) {
target.addNotification('CARD_RECEIVED', {
card: 'nye',
from: {
id: user._id,
name: senderName,
},
});
}
target.flags.cardReceived = true;
user.stats.gp -= 10;
@@ -432,7 +434,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++;
});
@@ -442,13 +444,15 @@ spells.special = {
const senderName = user.profile.name;
target.items.special.valentineReceived.push(senderName);
if (target.addNotification) target.addNotification('CARD_RECEIVED', {
if (target.addNotification) {
target.addNotification('CARD_RECEIVED', {
card: 'valentine',
from: {
id: user._id,
name: senderName,
},
});
}
target.flags.cardReceived = true;
user.stats.gp -= 10;
@@ -467,7 +471,7 @@ spells.special = {
if (!user.achievements.greeting) user.achievements.greeting = 0;
user.achievements.greeting++;
} else {
each([user, target], (u) => {
each([user, target], u => {
if (!u.achievements.greeting) u.achievements.greeting = 0;
u.achievements.greeting++;
});
@@ -477,13 +481,15 @@ spells.special = {
const senderName = user.profile.name;
target.items.special.greetingReceived.push(senderName);
if (target.addNotification) target.addNotification('CARD_RECEIVED', {
if (target.addNotification) {
target.addNotification('CARD_RECEIVED', {
card: 'greeting',
from: {
id: user._id,
name: senderName,
},
});
}
target.flags.cardReceived = true;
user.stats.gp -= 10;
@@ -502,7 +508,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++;
});
@@ -512,13 +518,15 @@ spells.special = {
const senderName = user.profile.name;
target.items.special.thankyouReceived.push(senderName);
if (target.addNotification) target.addNotification('CARD_RECEIVED', {
if (target.addNotification) {
target.addNotification('CARD_RECEIVED', {
card: 'thankyou',
from: {
id: user._id,
name: senderName,
},
});
}
target.flags.cardReceived = true;
user.stats.gp -= 10;
@@ -537,7 +545,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++;
});
@@ -547,13 +555,15 @@ spells.special = {
const senderName = user.profile.name;
target.items.special.birthdayReceived.push(senderName);
if (target.addNotification) target.addNotification('CARD_RECEIVED', {
if (target.addNotification) {
target.addNotification('CARD_RECEIVED', {
card: 'birthday',
from: {
id: user._id,
name: senderName,
},
});
}
target.flags.cardReceived = true;
user.stats.gp -= 10;
@@ -572,7 +582,7 @@ spells.special = {
if (!user.achievements.congrats) user.achievements.congrats = 0;
user.achievements.congrats++;
} else {
each([user, target], (u) => {
each([user, target], u => {
if (!u.achievements.congrats) u.achievements.congrats = 0;
u.achievements.congrats++;
});
@@ -582,13 +592,15 @@ spells.special = {
const senderName = user.profile.name;
target.items.special.congratsReceived.push(senderName);
if (target.addNotification) target.addNotification('CARD_RECEIVED', {
if (target.addNotification) {
target.addNotification('CARD_RECEIVED', {
card: 'congrats',
from: {
id: user._id,
name: senderName,
},
});
}
target.flags.cardReceived = true;
user.stats.gp -= 10;
@@ -607,7 +619,7 @@ spells.special = {
if (!user.achievements.getwell) user.achievements.getwell = 0;
user.achievements.getwell++;
} else {
each([user, target], (u) => {
each([user, target], u => {
if (!u.achievements.getwell) u.achievements.getwell = 0;
u.achievements.getwell++;
});
@@ -617,13 +629,15 @@ spells.special = {
const senderName = user.profile.name;
target.items.special.getwellReceived.push(senderName);
if (target.addNotification) target.addNotification('CARD_RECEIVED', {
if (target.addNotification) {
target.addNotification('CARD_RECEIVED', {
card: 'getwell',
from: {
id: user._id,
name: senderName,
},
});
}
target.flags.cardReceived = true;
user.stats.gp -= 10;
@@ -642,7 +656,7 @@ spells.special = {
if (!user.achievements.goodluck) user.achievements.goodluck = 0;
user.achievements.goodluck++;
} else {
each([user, target], (u) => {
each([user, target], u => {
if (!u.achievements.goodluck) u.achievements.goodluck = 0;
u.achievements.goodluck++;
});
@@ -652,13 +666,15 @@ spells.special = {
const senderName = user.profile.name;
target.items.special.goodluckReceived.push(senderName);
if (target.addNotification) target.addNotification('CARD_RECEIVED', {
if (target.addNotification) {
target.addNotification('CARD_RECEIVED', {
card: 'goodluck',
from: {
id: user._id,
name: senderName,
},
});
}
target.flags.cardReceived = true;
user.stats.gp -= 10;
@@ -666,10 +682,10 @@ spells.special = {
},
};
each(spells, (spellClass) => {
each(spells, spellClass => {
each(spellClass, (spell, key) => {
spell.key = key;
let _cast = spell.cast;
const _cast = spell.cast;
spell.cast = function castSpell (user, target, req) {
_cast(user, target, req);
user.stats.mp -= spell.mana;

View File

@@ -10,16 +10,16 @@ import {
} from './hatching-potions';
import t from './translation';
let petInfo = {};
let mountInfo = {};
const petInfo = {};
const mountInfo = {};
function constructSet (type, eggs, potions) {
let pets = {};
let mounts = {};
const pets = {};
const mounts = {};
each(eggs, (egg) => {
each(potions, (potion) => {
let key = `${egg.key}-${potion.key}`;
each(eggs, egg => {
each(potions, potion => {
const key = `${egg.key}-${potion.key}`;
function getAnimalData (text) {
return {
@@ -49,11 +49,11 @@ function constructSet (type, eggs, potions) {
}
function constructPetOnlySet (type, eggs, potions) {
let pets = {};
const pets = {};
each(eggs, (egg) => {
each(potions, (potion) => {
let key = `${egg.key}-${potion.key}`;
each(eggs, egg => {
each(potions, potion => {
const key = `${egg.key}-${potion.key}`;
function getAnimalData (text) {
return {
@@ -76,12 +76,12 @@ function constructPetOnlySet (type, eggs, potions) {
return pets;
}
let [dropPets, dropMounts] = constructSet('drop', dropEggs, dropPotions);
let [premiumPets, premiumMounts] = constructSet('premium', dropEggs, premiumPotions);
let [questPets, questMounts] = constructSet('quest', questEggs, dropPotions);
let wackyPets = constructPetOnlySet('wacky', dropEggs, wackyPotions);
const [dropPets, dropMounts] = constructSet('drop', dropEggs, dropPotions);
const [premiumPets, premiumMounts] = constructSet('premium', dropEggs, premiumPotions);
const [questPets, questMounts] = constructSet('quest', questEggs, dropPotions);
const wackyPets = constructPetOnlySet('wacky', dropEggs, wackyPotions);
let specialPets = {
const specialPets = {
'Wolf-Veteran': 'veteranWolf',
'Wolf-Cerberus': 'cerberusPup',
'Dragon-Hydra': 'hydra',
@@ -106,7 +106,7 @@ let specialPets = {
'Gryphon-Gryphatrice': 'gryphatrice',
};
let specialMounts = {
const specialMounts = {
'BearCub-Polar': 'polarBear',
'LionCub-Ethereal': 'etherealLion',
'MantisShrimp-Base': 'mantisShrimp',

View File

@@ -1,7 +1,7 @@
/* eslint-disable camelcase */
import each from 'lodash/each';
let subscriptionBlocks = {
const subscriptionBlocks = {
basic_earned: {
target: 'user',
canSubscribe: true,
@@ -50,8 +50,6 @@ let subscriptionBlocks = {
},
};
each(subscriptionBlocks, function createKeys (b, k) {
return b.key = k;
});
each(subscriptionBlocks, (b, k) => b.key = k);
export default subscriptionBlocks;

View File

@@ -7,19 +7,17 @@ import reduce from 'lodash/reduce';
import mysterySets from './mystery-sets';
import gear from './gear';
let mystery = mysterySets;
const mystery = mysterySets;
each(mystery, (v, k) => {
return v.items = filter(gear.flat, {
each(mystery, (v, k) => v.items = filter(gear.flat, {
mystery: k,
});
});
}));
let timeTravelerStore = (user) => {
const timeTravelerStore = user => {
let ownedKeys;
let owned = user.items.gear.owned;
let mysteryItems = user.purchased.plan.mysteryItems;
let unopenedGifts = typeof mysteryItems.toObject === 'function' ? mysteryItems.toObject() : mysteryItems;
const { owned } = user.items.gear;
const { mysteryItems } = user.purchased.plan;
const 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) => {

View File

@@ -9,9 +9,8 @@ const DROP_ANIMALS = keys(content.pets);
export function beastMasterProgress (pets = {}) {
let count = 0;
each(DROP_ANIMALS, (animal) => {
if (pets[animal] > 0 || pets[animal] === -1)
count++;
each(DROP_ANIMALS, animal => {
if (pets[animal] > 0 || pets[animal] === -1) count++;
});
return count;
@@ -20,7 +19,7 @@ export function beastMasterProgress (pets = {}) {
export function beastCount (pets = {}) {
let count = 0;
each(DROP_ANIMALS, (animal) => {
each(DROP_ANIMALS, animal => {
if (pets[animal] > 0) count++;
});
@@ -30,9 +29,8 @@ export function beastCount (pets = {}) {
export function dropPetsCurrentlyOwned (pets = {}) {
let count = 0;
each(DROP_ANIMALS, (animal) => {
if (pets[animal] > 0)
count++;
each(DROP_ANIMALS, animal => {
if (pets[animal] > 0) count++;
});
return count;
@@ -41,36 +39,35 @@ export function dropPetsCurrentlyOwned (pets = {}) {
export function mountMasterProgress (mounts = {}) {
let count = 0;
each(DROP_ANIMALS, (animal) => {
if (mounts[animal])
count++;
each(DROP_ANIMALS, animal => {
if (mounts[animal]) count++;
});
return count;
}
export function remainingGearInSet (userGear = {}, set) {
let gear = filter(content.gear.flat, (item) => {
let setMatches = item.klass === set;
let hasItem = userGear[item.key];
const gear = filter(content.gear.flat, item => {
const setMatches = item.klass === set;
const hasItem = userGear[item.key];
return setMatches && !hasItem;
});
let count = size(gear);
const count = size(gear);
return count;
}
export function questsOfCategory (userQuests = {}, category) {
let quests = filter(content.quests, (quest) => {
let categoryMatches = quest.category === category;
let hasQuest = userQuests[quest.key];
const quests = filter(content.quests, quest => {
const categoryMatches = quest.category === category;
const hasQuest = userQuests[quest.key];
return categoryMatches && hasQuest;
});
let count = size(quests);
const count = size(quests);
return count;
}

View File

@@ -28,11 +28,11 @@ export const DAY_MAPPING_STRING_TO_NUMBER = invert(DAY_MAPPING);
*/
function sanitizeOptions (o) {
let ref = Number(o.dayStart || 0);
let dayStart = !Number.isNaN(ref) && ref >= 0 && ref <= 24 ? ref : 0;
const ref = Number(o.dayStart || 0);
const dayStart = !Number.isNaN(ref) && ref >= 0 && ref <= 24 ? ref : 0;
let timezoneOffset;
let timezoneOffsetDefault = Number(moment().zone());
const timezoneOffsetDefault = Number(moment().zone());
if (isFinite(o.timezoneOffsetOverride)) {
timezoneOffset = Number(o.timezoneOffsetOverride);
@@ -46,7 +46,7 @@ function sanitizeOptions (o) {
timezoneOffset = timezoneOffsetDefault;
}
let now = o.now ? moment(o.now).zone(timezoneOffset) : moment().zone(timezoneOffset);
const now = o.now ? moment(o.now).zone(timezoneOffset) : moment().zone(timezoneOffset);
// return a new object, we don't want to add "now" to user object
return {
dayStart,
@@ -56,7 +56,7 @@ function sanitizeOptions (o) {
}
export function startOfWeek (options = {}) {
let o = sanitizeOptions(options);
const o = sanitizeOptions(options);
return moment(o.now).startOf('week');
}
@@ -69,8 +69,8 @@ export function startOfWeek (options = {}) {
*/
export function startOfDay (options = {}) {
let o = sanitizeOptions(options);
let dayStart = moment(o.now).startOf('day').add({ hours: o.dayStart });
const o = sanitizeOptions(options);
const dayStart = moment(o.now).startOf('day').add({ hours: o.dayStart });
if (moment(o.now).hour() < o.dayStart) {
dayStart.subtract({ days: 1 });
@@ -84,9 +84,9 @@ export function startOfDay (options = {}) {
*/
export function daysSince (yesterday, options = {}) {
let o = sanitizeOptions(options);
let startOfNow = startOfDay(defaults({ now: o.now }, o));
let startOfYesterday = startOfDay(defaults({ now: yesterday }, o));
const o = sanitizeOptions(options);
const startOfNow = startOfDay(defaults({ now: o.now }, o));
const startOfYesterday = startOfDay(defaults({ now: yesterday }, o));
return startOfNow.diff(startOfYesterday, 'days');
}
@@ -99,22 +99,22 @@ export function shouldDo (day, dailyTask, options = {}) {
if (dailyTask.type !== 'daily' || dailyTask.startDate === null || dailyTask.everyX < 1 || dailyTask.everyX > 9999) {
return false;
}
let o = sanitizeOptions(options);
let startOfDayWithCDSTime = startOfDay(defaults({ now: day }, o));
const o = sanitizeOptions(options);
const startOfDayWithCDSTime = startOfDay(defaults({ now: day }, o));
// The time portion of the Start Date is never visible to or modifiable by the user so we must ignore it.
// Therefore, we must also ignore the time portion of the user's day start (startOfDayWithCDSTime), otherwise the date comparison will be wrong for some times.
// NB: The user's day start date has already been converted to the PREVIOUS day's date if the time portion was before CDS.
let startDate = moment(dailyTask.startDate).zone(o.timezoneOffset).startOf('day');
const startDate = moment(dailyTask.startDate).zone(o.timezoneOffset).startOf('day');
if (startDate > startOfDayWithCDSTime.startOf('day') && !options.nextDue) {
return false; // Daily starts in the future
}
let daysOfTheWeek = [];
const daysOfTheWeek = [];
if (dailyTask.repeat) {
for (let [repeatDay, active] of Object.entries(dailyTask.repeat)) {
for (const [repeatDay, active] of Object.entries(dailyTask.repeat)) {
if (!isFinite(DAY_MAPPING_STRING_TO_NUMBER[repeatDay])) continue; // eslint-disable-line no-continue
if (active) daysOfTheWeek.push(parseInt(DAY_MAPPING_STRING_TO_NUMBER[repeatDay], 10));
}
@@ -122,36 +122,36 @@ export function shouldDo (day, dailyTask, options = {}) {
if (dailyTask.frequency === 'daily') {
if (!dailyTask.everyX) return false; // error condition
let schedule = moment(startDate).recur()
const schedule = moment(startDate).recur()
.every(dailyTask.everyX).days();
if (options.nextDue) {
let filteredDates = [];
const filteredDates = [];
for (let i = 1; filteredDates.length < 6; i++) {
let calcDate = moment(startDate).add(dailyTask.everyX * i, 'days');
const calcDate = moment(startDate).add(dailyTask.everyX * i, 'days');
if (calcDate > startOfDayWithCDSTime) filteredDates.push(calcDate);
}
return filteredDates;
}
return schedule.matches(startOfDayWithCDSTime);
} else if (dailyTask.frequency === 'weekly') {
} if (dailyTask.frequency === 'weekly') {
let schedule = moment(startDate).recur();
let differenceInWeeks = moment(startOfDayWithCDSTime).diff(moment(startDate), 'week');
let matchEveryX = differenceInWeeks % dailyTask.everyX === 0;
const differenceInWeeks = moment(startOfDayWithCDSTime).diff(moment(startDate), 'week');
const matchEveryX = differenceInWeeks % dailyTask.everyX === 0;
if (daysOfTheWeek.length === 0) return false;
schedule = schedule.every(daysOfTheWeek).daysOfWeek();
if (options.nextDue) {
let filteredDates = [];
const filteredDates = [];
for (let i = 0; filteredDates.length < 6; i++) {
for (let j = 0; j < daysOfTheWeek.length && filteredDates.length < 6; j++) {
let calcDate = moment(startDate).day(daysOfTheWeek[j]).add(dailyTask.everyX * i, 'weeks');
const calcDate = moment(startDate).day(daysOfTheWeek[j]).add(dailyTask.everyX * i, 'weeks');
if (calcDate > startOfDayWithCDSTime) filteredDates.push(calcDate);
}
}
let sortedDates = filteredDates.sort((date1, date2) => {
const sortedDates = filteredDates.sort((date1, date2) => {
if (date1.toDate() > date2.toDate()) return 1;
if (date2.toDate() > date1.toDate()) return -1;
return 0;
@@ -160,15 +160,15 @@ export function shouldDo (day, dailyTask, options = {}) {
}
return schedule.matches(startOfDayWithCDSTime) && matchEveryX;
} else if (dailyTask.frequency === 'monthly') {
} if (dailyTask.frequency === 'monthly') {
let schedule = moment(startDate).recur();
// Use startOf to ensure that we are always comparing month
// to the next rather than a month from the day
let differenceInMonths = moment(startOfDayWithCDSTime).startOf('month')
const differenceInMonths = moment(startOfDayWithCDSTime).startOf('month')
.diff(moment(startDate).startOf('month'), 'month', true);
let matchEveryX = differenceInMonths % dailyTask.everyX === 0;
const matchEveryX = differenceInMonths % dailyTask.everyX === 0;
if (dailyTask.weeksOfMonth && dailyTask.weeksOfMonth.length > 0) {
if (daysOfTheWeek.length === 0) return false;
@@ -176,13 +176,13 @@ export function shouldDo (day, dailyTask, options = {}) {
.every(dailyTask.weeksOfMonth).weeksOfMonthByDay();
if (options.nextDue) {
let filteredDates = [];
const filteredDates = [];
for (let i = 1; filteredDates.length < 6; i++) {
let recurDate = moment(startDate).add(dailyTask.everyX * i, 'months');
let calcDate = recurDate.clone();
const recurDate = moment(startDate).add(dailyTask.everyX * i, 'months');
const calcDate = recurDate.clone();
calcDate.day(daysOfTheWeek[0]);
let startDateWeek = Math.ceil(moment(startDate).date() / 7);
const startDateWeek = Math.ceil(moment(startDate).date() / 7);
let calcDateWeek = Math.ceil(calcDate.date() / 7);
// adjust week since weeks will rollover to other months
@@ -193,19 +193,19 @@ export function shouldDo (day, dailyTask, options = {}) {
calcDateWeek = Math.ceil(calcDate.date() / 7);
if (calcDate >= startOfDayWithCDSTime &&
calcDateWeek === startDateWeek && calcDate.month() === recurDate.month()) filteredDates.push(calcDate);
if (calcDate >= startOfDayWithCDSTime
&& calcDateWeek === startDateWeek && calcDate.month() === recurDate.month()) filteredDates.push(calcDate);
}
return filteredDates;
}
return schedule.matches(startOfDayWithCDSTime) && matchEveryX;
} else if (dailyTask.daysOfMonth && dailyTask.daysOfMonth.length > 0) {
} if (dailyTask.daysOfMonth && dailyTask.daysOfMonth.length > 0) {
schedule = schedule.every(dailyTask.daysOfMonth).daysOfMonth();
if (options.nextDue) {
let filteredDates = [];
const filteredDates = [];
for (let i = 1; filteredDates.length < 6; i++) {
let calcDate = moment(startDate).add(dailyTask.everyX * i, 'months');
const calcDate = moment(startDate).add(dailyTask.everyX * i, 'months');
if (calcDate >= startOfDayWithCDSTime) filteredDates.push(calcDate);
}
return filteredDates;
@@ -213,15 +213,15 @@ export function shouldDo (day, dailyTask, options = {}) {
}
return schedule.matches(startOfDayWithCDSTime) && matchEveryX;
} else if (dailyTask.frequency === 'yearly') {
} if (dailyTask.frequency === 'yearly') {
let schedule = moment(startDate).recur();
schedule = schedule.every(dailyTask.everyX).years();
if (options.nextDue) {
let filteredDates = [];
const filteredDates = [];
for (let i = 1; filteredDates.length < 6; i++) {
let calcDate = moment(startDate).add(dailyTask.everyX * i, 'years');
const calcDate = moment(startDate).add(dailyTask.everyX * i, 'years');
if (calcDate > startOfDayWithCDSTime) filteredDates.push(calcDate);
}
return filteredDates;

View File

@@ -16,17 +16,17 @@ import splitWhitespace from '../libs/splitWhitespace';
function getStatToAllocate (user) {
let suggested;
let statsObj = user.stats.toObject ? user.stats.toObject() : user.stats;
const statsObj = user.stats.toObject ? user.stats.toObject() : user.stats;
switch (user.preferences.allocationMode) {
case 'flat': {
let stats = pick(statsObj, splitWhitespace('con str per int'));
const stats = pick(statsObj, splitWhitespace('con str per int'));
return invert(stats)[min(values(stats))];
}
case 'classbased': {
let preference;
let lvlDiv7 = statsObj.lvl / 7;
let ideal = [lvlDiv7 * 3, lvlDiv7 * 2, lvlDiv7, lvlDiv7];
const lvlDiv7 = statsObj.lvl / 7;
const ideal = [lvlDiv7 * 3, lvlDiv7 * 2, lvlDiv7, lvlDiv7];
switch (statsObj.class) {
case 'wizard': {
@@ -46,14 +46,14 @@ function getStatToAllocate (user) {
}
}
let diff = [
const diff = [
statsObj[preference[0]] - ideal[0],
statsObj[preference[1]] - ideal[1],
statsObj[preference[2]] - ideal[2],
statsObj[preference[3]] - ideal[3],
];
suggested = findIndex(diff, (val) => {
suggested = findIndex(diff, val => {
if (val === min(diff)) return true;
});
@@ -76,7 +76,7 @@ function getStatToAllocate (user) {
}
export default function autoAllocate (user) {
let statToIncrease = getStatToAllocate(user);
const statToIncrease = getStatToAllocate(user);
return user.stats[statToIncrease]++;
}

View File

@@ -2,12 +2,11 @@ import predictableRandom from './predictableRandom';
import statsComputed from '../libs/statsComputed';
function crit (user, stat = 'str', chance = 0.03) {
let s = statsComputed(user)[stat];
const s = statsComputed(user)[stat];
if (predictableRandom(user) <= chance * (1 + s / 100)) {
return 1.5 + 4 * s / (s + 200);
} else {
return 1;
}
return 1;
}
export default { crit };

View File

@@ -2,8 +2,8 @@ import content from '../content/index';
import i18n from '../i18n';
export default function handleTwoHanded (user, item, type = 'equipped', req = {}) {
let currentShield = content.gear.flat[user.items.gear[type].shield];
let currentWeapon = content.gear.flat[user.items.gear[type].weapon];
const currentShield = content.gear.flat[user.items.gear[type].shield];
const currentWeapon = content.gear.flat[user.items.gear[type].weapon];
let message;

View File

@@ -15,12 +15,11 @@ export default function predictableRandom (user, seed) {
seed = reduce(stats, (accumulator, val) => {
if (isNumber(val)) {
return accumulator + val;
} else {
return accumulator;
}
return accumulator;
}, 0);
}
let x = Math.sin(seed++) * 10000;
const x = Math.sin(seed++) * 10000;
return x - Math.floor(x);
}

View File

@@ -16,9 +16,8 @@ import statsComputed from '../libs/statsComputed';
// Clone a drop object maintaining its functions so that we can change it without affecting the original item
function cloneDropItem (drop) {
return cloneDeepWith(drop, (val) => {
return isFunction(val) ? val : undefined; // undefined will be handled by lodash
});
return cloneDeepWith(drop, val => (isFunction(val) ? val : undefined), // undefined will be handled by lodash
);
}
function trueRandom () {
@@ -31,19 +30,19 @@ export default function randomDrop (user, options, req = {}, analytics) {
let dropMultiplier;
let rarity;
let predictableRandom = options.predictableRandom || trueRandom;
let task = options.task;
const predictableRandom = options.predictableRandom || trueRandom;
const { task } = options;
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 + statsComputed(user).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) => { // +50% per checklist item complete. TODO: make this into X individual drop chances instead
return m + (i.completed ? 1 : 0); // eslint-disable-line indent
}, 0) || 0)); // eslint-disable-line indent
chance *= task.priority // Task priority: +50% for Medium, +100% for Hard
* (1 + (task.streak / 100 || 0)) // Streak bonus: +1% per streak
* (1 + statsComputed(user).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) => // +50% per checklist item complete. TODO: make this into X individual drop chances instead
m + (i.completed ? 1 : 0), // eslint-disable-line indent
0) || 0)); // eslint-disable-line indent
chance = diminishingReturns(chance, 0.75);
if (predictableRandom() < chance) {
@@ -60,8 +59,8 @@ export default function randomDrop (user, options, req = {}, analytics) {
dropMultiplier = 1;
}
if (daysSince(user.items.lastDrop.date, user.preferences) === 0 &&
user.items.lastDrop.count >= dropMultiplier * (5 + Math.floor(statsComputed(user).per / 25) + (user.contributor.level || 0))) {
if (daysSince(user.items.lastDrop.date, user.preferences) === 0
&& user.items.lastDrop.count >= dropMultiplier * (5 + Math.floor(statsComputed(user).per / 25) + (user.contributor.level || 0))) {
return;
}
@@ -104,9 +103,7 @@ export default function randomDrop (user, options, req = {}, analytics) {
} else { // common, 40% of 30%
acceptableDrops = ['Base', 'White', 'Desert'];
}
drop = cloneDropItem(randomVal(pickBy(content.hatchingPotions, (v, k) => {
return acceptableDrops.indexOf(k) >= 0;
})));
drop = cloneDropItem(randomVal(pickBy(content.hatchingPotions, (v, k) => acceptableDrops.indexOf(k) >= 0)));
user.items.hatchingPotions[drop.key] = user.items.hatchingPotions[drop.key] || 0;
user.items.hatchingPotions[drop.key]++;

View File

@@ -2,9 +2,9 @@ import each from 'lodash/each';
import content from '../content/index';
export default function resetGear (user) {
let gear = user.items.gear;
const { gear } = user.items;
each(['equipped', 'costume'], function resetUserGear (type) {
each(['equipped', 'costume'], type => {
gear[type] = {};
gear[type].armor = 'armor_base_0';
gear[type].weapon = 'weapon_warrior_0';
@@ -14,7 +14,7 @@ export default function resetGear (user) {
// Gear.owned is (was) 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, (v, k) => {
if (gear.owned[k] && content.gear.flat[k] && content.gear.flat[k].value) {
gear.owned[k] = false;
}

View File

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

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