diff --git a/.eslintrc b/.eslintrc index 17a4f64b77..e99b547ffc 100644 --- a/.eslintrc +++ b/.eslintrc @@ -1,10 +1,11 @@ { "root": true, - "env": { - "node": true, - }, "extends": [ - "habitrpg", - "habitrpg/esnext" + "habitrpg/lib/node" ], + "rules": { + 'no-param-reassign': ['error', { + props: false, + }], + } } diff --git a/gulp/gulp-apidoc.js b/gulp/gulp-apidoc.js index 6d34e6f026..55709fbdc2 100644 --- a/gulp/gulp-apidoc.js +++ b/gulp/gulp-apidoc.js @@ -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)))); diff --git a/gulp/gulp-build.js b/gulp/gulp-build.js index 87d2492902..535b0178b5 100644 --- a/gulp/gulp-build.js +++ b/gulp/gulp-build.js @@ -1,32 +1,28 @@ import gulp from 'gulp'; import babel from 'gulp-babel'; -gulp.task('build:src', () => { - return gulp.src('website/server/**/*.js') - .pipe(babel()) - .pipe(gulp.dest('website/transpiled-babel/')); -}); +gulp.task('build:src', () => gulp.src('website/server/**/*.js') + .pipe(babel()) + .pipe(gulp.dest('website/transpiled-babel/'))); -gulp.task('build:common', () => { - return gulp.src('website/common/script/**/*.js') - .pipe(babel()) - .pipe(gulp.dest('website/common/transpiled-babel/')); -}); +gulp.task('build:common', () => gulp.src('website/common/script/**/*.js') + .pipe(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(); -})); \ No newline at end of file +})); diff --git a/gulp/gulp-console.js b/gulp/gulp-console.js index 3fc83bb793..15038fd6b5 100644 --- a/gulp/gulp-console.js +++ b/gulp/gulp-console.js @@ -1,26 +1,30 @@ import mongoose from 'mongoose'; -import logger from '../website/server/libs/logger'; -import nconf from 'nconf'; -import repl from 'repl'; -import gulp from 'gulp'; +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 () { - process.exit(); - }}); + ['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 () { - process.stdout.write('\u001B[2J\u001B[0;0f'); - }}); + 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 - context.User = require('../website/server/models/user').model; // eslint-disable-line global-require + context.Group = require('../website/server/models/group').model; // eslint-disable-line global-require + context.User = require('../website/server/models/user').model; // eslint-disable-line global-require const isProd = nconf.get('NODE_ENV') === 'production'; const mongooseOptions = !isProd ? {} : { @@ -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); diff --git a/gulp/gulp-sprites.js b/gulp/gulp-sprites.js index 0327721af0..fce0bae980 100644 --- a/gulp/gulp-sprites.js +++ b/gulp/gulp-sprites.js @@ -4,9 +4,9 @@ import spritesmith from 'gulp.spritesmith'; import clean from 'rimraf'; import sizeOf from 'image-size'; import mergeStream from 'merge-stream'; -import {basename} from 'path'; -import {sync} from 'glob'; -import {each} from 'lodash'; +import { basename } from 'path'; +import { sync } from 'glob'; +import { each } from 'lodash'; import vinylBuffer from 'vinyl-buffer'; // https://github.com/Ensighten/grunt-spritesmith/issues/67#issuecomment-34786248 @@ -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,37 +64,35 @@ 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: { - offsetX: `-${ sprite.x + 25 }px`, - offsetY: `-${ sprite.y + 15 }px`, + offsetX: `-${sprite.x + 25}px`, + offsetY: `-${sprite.y + 15}px`, width: '60px', height: '60px', }, }; } - 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 } diff --git a/gulp/gulp-start.js b/gulp/gulp-start.js index cca07d433d..22132bfbda 100644 --- a/gulp/gulp-start.js +++ b/gulp/gulp-start.js @@ -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: [ diff --git a/gulp/gulp-tests.js b/gulp/gulp-tests.js index 7294a90574..00fa172bb9 100644 --- a/gulp/gulp-tests.js +++ b/gulp/gulp-tests.js @@ -1,60 +1,59 @@ +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'; -import mongoose from 'mongoose'; -import { exec } from 'child_process'; -import gulp from 'gulp'; -import os from 'os'; -import nconf from 'nconf'; +} from './taskHelper'; // TODO rewrite -const TEST_SERVER_PORT = 3003; +const TEST_SERVER_PORT = 3003; let server; -const TEST_DB_URI = nconf.get('TEST_DB_URI'); +const TEST_DB_URI = nconf.get('TEST_DB_URI'); const SANITY_TEST_COMMAND = 'npm run test:sanity'; const COMMON_TEST_COMMAND = 'npm run test:common'; const CONTENT_TEST_COMMAND = 'npm run test:content'; -const CONTENT_OPTIONS = {maxBuffer: 1024 * 500}; +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,38 +118,36 @@ 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 + (err, stdout) => { // eslint-disable-line handle-callback-err testResults.push({ suite: 'Content Specs\t', pass: testCount(stdout, /(\d+) passing/), @@ -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) => { + { maxBuffer: 500 * 1024 }, + err => { if (err) { process.exit(1); } done(); - } + }, ); pipe(runner); }); -gulp.task('test:api-v3:integration:watch', () => { - return 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.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.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) + { maxBuffer: 500 * 1024 }, + 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) => { + { maxBuffer: 500 * 1024 }, + 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) + { maxBuffer: 500 * 1024 }, + 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(), )); diff --git a/gulp/gulp-transifex-test.js b/gulp/gulp-transifex-test.js index 2403707ecf..b90f9d441e 100644 --- a/gulp/gulp-transifex-test.js +++ b/gulp/gulp-transifex-test.js @@ -1,6 +1,6 @@ -import fs from 'fs'; -import _ from 'lodash'; -import gulp from 'gulp'; +import fs from 'fs'; +import _ from 'lodash'; +import gulp from 'gulp'; import { postToSlack, conf } from './taskHelper'; const SLACK_CONFIG = { @@ -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() -); \ No newline at end of file + done => done(), +); diff --git a/gulp/taskHelper.js b/gulp/taskHelper.js index 270573ba70..b22897747e 100644 --- a/gulp/taskHelper.js +++ b/gulp/taskHelper.js @@ -1,11 +1,11 @@ -import { exec } from 'child_process'; -import psTree from 'ps-tree'; -import nconf from 'nconf'; -import net from 'net'; -import { post } from 'superagent'; -import { sync as glob } from 'glob'; -import Mocha from 'mocha'; -import { resolve } from 'path'; +import { exec } from 'child_process'; +import psTree from 'ps-tree'; +import nconf from 'nconf'; +import net from 'net'; +import { post } from 'superagent'; +import { sync as glob } from 'glob'; +import Mocha from 'mocha'; // eslint-disable-line import/no-extraneous-dependencies +import { resolve } from 'path'; /* * Get access to configruable values @@ -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,16 +46,15 @@ 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); interval = setInterval(() => { - socket = net.connect({port}, () => { + socket = net.connect({ port }, () => { clearInterval(interval); clearTimeout(timeout); socket.destroy(); @@ -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); diff --git a/migrations/challenges/sync-all-challenges.js b/migrations/challenges/sync-all-challenges.js index 7998aecdd1..519865e267 100644 --- a/migrations/challenges/sync-all-challenges.js +++ b/migrations/challenges/sync-all-challenges.js @@ -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; } diff --git a/migrations/command-line/apology_gems.js b/migrations/command-line/apology_gems.js index 347a63d141..f56b8e6323 100644 --- a/migrations/command-line/apology_gems.js +++ b/migrations/command-line/apology_gems.js @@ -1 +1 @@ -db.users.update({_id: {$in: ['']}}, {$inc: {balance: 0.5}}, {multi: true}); \ No newline at end of file +db.users.update({ _id: { $in: [''] } }, { $inc: { balance: 0.5 } }, { multi: true }); diff --git a/migrations/command-line/cancelSubscription.js b/migrations/command-line/cancelSubscription.js index f823bed40f..682568239e 100644 --- a/migrations/command-line/cancelSubscription.js +++ b/migrations/command-line/cancelSubscription.js @@ -4,8 +4,10 @@ // the FAQ (http://goo.gl/1uoPGQ) they insist... db.users.update( - {_id: ''}, - {$set: { - 'purchased.plan.dateTerminated': moment().add('month', 1).toDate(), - }} -); \ No newline at end of file + { _id: '' }, + { + $set: { + 'purchased.plan.dateTerminated': moment().add('month', 1).toDate(), + }, + }, +); diff --git a/migrations/command-line/contribs_plan.js b/migrations/command-line/contribs_plan.js index 548ff6f18f..a08b8acc0b 100644 --- a/migrations/command-line/contribs_plan.js +++ b/migrations/command-line/contribs_plan.js @@ -2,7 +2,7 @@ db.users.update( { - 'contributor.level': {$gte: 7}, + 'contributor.level': { $gte: 7 }, 'purchased.plan.customerId': null, }, @@ -18,6 +18,6 @@ db.users.update( }, }, - {multi: true} + { multi: true }, -); \ No newline at end of file +); diff --git a/migrations/command-line/current_period_end.js b/migrations/command-line/current_period_end.js index 56c9e8b45d..d91ff5a250 100644 --- a/migrations/command-line/current_period_end.js +++ b/migrations/command-line/current_period_end.js @@ -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()}} -); \ No newline at end of file + { _id: '' }, + { $set: { 'purchased.plan.dateTerminated': moment().add({ days: 7 }).toDate() } }, +); diff --git a/migrations/command-line/duplicatedTasksFindAndRemove.js b/migrations/command-line/duplicatedTasksFindAndRemove.js index 2dcdb10e5c..6fa6d3d1fb 100644 --- a/migrations/command-line/duplicatedTasksFindAndRemove.js +++ b/migrations/command-line/duplicatedTasksFindAndRemove.js @@ -39,38 +39,52 @@ // 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: { - _id: uuid, - }}, - {$project: { - _id: 0, todos: 1, - }}, - {$unwind: '$todos'}, - {$group: { - _id: { taskid: '$todos.id' }, - count: { $sum: 1 }, - }}, - {$match: { - count: { $gt: 1 }, - }}, - {$project: { - '_id.taskid': 1, - }}, - {$group: { - _id: { taskid: '$todos.id' }, - troublesomeIds: { $addToSet: '$_id.taskid' }, - }}, - {$project: { - _id: 0, - troublesomeIds: 1, - }}, -]).forEach((data) => { + { + $match: { + _id: uuid, + }, + }, + { + $project: { + _id: 0, todos: 1, + }, + }, + { $unwind: '$todos' }, + { + $group: { + _id: { taskid: '$todos.id' }, + count: { $sum: 1 }, + }, + }, + { + $match: { + count: { $gt: 1 }, + }, + }, + { + $project: { + '_id.taskid': 1, + }, + }, + { + $group: { + _id: { taskid: '$todos.id' }, + troublesomeIds: { $addToSet: '$_id.taskid' }, + }, + }, + { + $project: { + _id: 0, + troublesomeIds: 1, + }, + }, +]).forEach(data => { // print( "\n" ); printjson(data); - data.troublesomeIds.forEach((taskid) => { - print(`non-unique task: ${ taskid}`); + data.troublesomeIds.forEach(taskid => { + print(`non-unique task: ${taskid}`); db.users.update({ _id: uuid, todos: { $elemMatch: { id: taskid } }, @@ -81,8 +95,7 @@ db.users.aggregate([ }); db.users.update( - {_id: uuid}, - {$pull: { todos: { id: 'de666' } } }, - {multi: false } + { _id: uuid }, + { $pull: { todos: { id: 'de666' } } }, + { multi: false }, ); - diff --git a/migrations/command-line/facebook_to_local.js b/migrations/command-line/facebook_to_local.js index de707c4f05..04fd254965 100644 --- a/migrations/command-line/facebook_to_local.js +++ b/migrations/command-line/facebook_to_local.js @@ -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}}); +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}}); - +db.users.update({ _id: newId }, { $unset: { auth: 1 } }); diff --git a/migrations/command-line/find_unique_user.js b/migrations/command-line/find_unique_user.js index 378c6c8708..bb3e590df0 100644 --- a/migrations/command-line/find_unique_user.js +++ b/migrations/command-line/find_unique_user.js @@ -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: ''}); - if (found) printjson({id: user._id, auth: user.auth}); -}); \ No newline at end of file + const found = _.some(user.tasks, { text: '' }); + if (found) printjson({ id: user._id, auth: user.auth }); +}); diff --git a/migrations/command-line/freeMonth.js b/migrations/command-line/freeMonth.js index 2b9b19cccd..377e28b726 100644 --- a/migrations/command-line/freeMonth.js +++ b/migrations/command-line/freeMonth.js @@ -1,13 +1,15 @@ // mongo habitrpg ./node_modules/moment/moment.js ./migrations/freeMonth.js db.users.update( - {_id: ''}, - {$set: { - 'purchased.plan.customerId': 'temporary', - 'purchased.plan.paymentMethod': 'Stripe', - 'purchased.plan.planId': 'basic_earned', - 'purchased.plan.dateTerminated': moment().add('month', 1).toDate(), - }} + { _id: '' }, + { + $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( @@ -29,4 +31,4 @@ db.users.update( // trinkets: m/3 // } // }}} -// ) \ No newline at end of file +// ) diff --git a/migrations/command-line/habitica_day.js b/migrations/command-line/habitica_day.js index 9e4fd3af5b..61787298e1 100644 --- a/migrations/command-line/habitica_day.js +++ b/migrations/command-line/habitica_day.js @@ -1,5 +1,5 @@ db.users.update( {}, - {$inc: {'achievements.habiticaDays': 1}}, - {multi: 1} + { $inc: { 'achievements.habiticaDays': 1 } }, + { multi: 1 }, ); diff --git a/migrations/command-line/missing_gems.js b/migrations/command-line/missing_gems.js index 080bfbd687..fad6c750dd 100644 --- a/migrations/command-line/missing_gems.js +++ b/migrations/command-line/missing_gems.js @@ -1 +1 @@ -db.users.update({_id: ''}, {$inc: {balance: 5}}); \ No newline at end of file +db.users.update({ _id: '' }, { $inc: { balance: 5 } }); diff --git a/migrations/groups/add-unlimited-subscription.js b/migrations/groups/add-unlimited-subscription.js index 43fbe55b5d..2b2d99ecac 100644 --- a/migrations/groups/add-unlimited-subscription.js +++ b/migrations/groups/add-unlimited-subscription.js @@ -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); }; diff --git a/migrations/groups/create-group.js b/migrations/groups/create-group.js index b1d266890f..e81c4af38e 100644 --- a/migrations/groups/create-group.js +++ b/migrations/groups/create-group.js @@ -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); }; - - diff --git a/migrations/groups/habitrpg-jackalopes.js b/migrations/groups/habitrpg-jackalopes.js index a33ae3a2f3..2eb10a7e93 100644 --- a/migrations/groups/habitrpg-jackalopes.js +++ b/migrations/groups/habitrpg-jackalopes.js @@ -8,29 +8,27 @@ 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) => { - console.log(`User: ${ user._id}`); + 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({ - _id: {$in: groupList}, - 'purchased.plan.planId': 'group_monthly', - 'purchased.plan.dateTerminated': null, - }, - {_id: 1} - ); + const subscribedGroup = await Group.findOne({ + _id: { $in: groupList }, + 'purchased.plan.planId': 'group_monthly', + 'purchased.plan.dateTerminated': null, + }, + { _id: 1 }); if (subscribedGroup) { - User.update({_id: user._id}, {$set: {'items.mounts.Jackalope-RoyalPurple': true}}).exec(); + User.update({ _id: user._id }, { $set: { 'items.mounts.Jackalope-RoyalPurple': true } }).exec(); promises.push(user.save()); } }); diff --git a/migrations/groups/reconcile-group-plan-members.js b/migrations/groups/reconcile-group-plan-members.js index 06296090e4..05407ac16c 100644 --- a/migrations/groups/reconcile-group-plan-members.js +++ b/migrations/groups/reconcile-group-plan-members.js @@ -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'); @@ -24,15 +24,15 @@ async function fixGroupPlanMembers () { { $and: [ - {'purchased.plan.planId': {$ne: null}}, - {'purchased.plan.planId': {$ne: ''}}, - {'purchased.plan.customerId': {$ne: 'cus_9f0DV4g7WHRzpM'}}, // Demo groups - {'purchased.plan.customerId': {$ne: 'cus_9maalqDOFTrvqx'}}, + { 'purchased.plan.planId': { $ne: null } }, + { 'purchased.plan.planId': { $ne: '' } }, + { 'purchased.plan.customerId': { $ne: 'cus_9f0DV4g7WHRzpM' } }, // Demo groups + { 'purchased.plan.customerId': { $ne: 'cus_9maalqDOFTrvqx' } }, ], $or: [ - {'purchased.plan.dateTerminated': null}, - {'purchased.plan.dateTerminated': ''}, + { 'purchased.plan.dateTerminated': null }, + { 'purchased.plan.dateTerminated': '' }, ], }, { @@ -40,8 +40,8 @@ async function fixGroupPlanMembers () { memberCount: 1, 'purchased.plan': 1, }, - } - ).each(async (group, {close, pause, resume}) => { // eslint-disable-line no-unused-vars + }, + ).each(async (group, { close, pause, resume }) => { // eslint-disable-line no-unused-vars pause(); groupPlanCount++; @@ -49,10 +49,10 @@ async function fixGroupPlanMembers () { { $or: [ - {'party._id': group._id}, - {guilds: group._id}, + { '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; @@ -82,15 +82,15 @@ async function fixGroupPlanMembers () { if (group.purchased.plan.paymentMethod === 'Stripe') { await stripePayments.chargeForAdditionalGroupMember(group); await dbGroups.update( - {_id: group._id}, - {$set: {'purchased.plan.quantity': canonicalMemberCount + 2}} + { _id: group._id }, + { $set: { 'purchased.plan.quantity': canonicalMemberCount + 2 } }, ); } if (incorrectQuantity) { await dbGroups.update( - {_id: group._id}, - {$set: {'purchased.plan.quantity': canonicalMemberCount + 2}} + { _id: group._id }, + { $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); }); diff --git a/migrations/groups/update-groups-with-group-plans.js b/migrations/groups/update-groups-with-group-plans.js index d544f389ab..ac369609fa 100644 --- a/migrations/groups/update-groups-with-group-plans.js +++ b/migrations/groups/update-groups-with-group-plans.js @@ -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; diff --git a/migrations/migration-runner.js b/migrations/migration-runner.js index 39cec8b1aa..0b502c155b 100644 --- a/migrations/migration-runner.js +++ b/migrations/migration-runner.js @@ -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); }); diff --git a/migrations/new_stuff.js b/migrations/new_stuff.js index 3ee124ab6b..b367500d87 100644 --- a/migrations/new_stuff.js +++ b/migrations/new_stuff.js @@ -1,19 +1,20 @@ /* 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 = { - 'flags.newStuff': {$ne: true}, + const query = { + 'flags.newStuff': { $ne: true }, }; if (lastId) { @@ -23,18 +24,18 @@ function processUsers (lastId) { } dbUsers.find(query, { - sort: {_id: 1}, + sort: { _id: 1 }, limit: 250, 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}`); + 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,16 +57,16 @@ function updateUsers (users) { function updateUser (user) { count++; - let set = {'flags.newStuff': true}; + const set = { 'flags.newStuff': true }; - dbUsers.update({_id: user._id}, {$set: set}); + dbUsers.update({ _id: user._id }, { $set: set }); - if (count % progressCount === 0) console.warn(`${count } ${ user._id}`); - if (user._id === authorUuid) console.warn(`${authorName } processed`); + if (count % progressCount === 0) console.warn(`${count} ${user._id}`); + if (user._id === authorUuid) console.warn(`${authorName} processed`); } function displayData () { - console.warn(`\n${ count } users processed\n`); + console.warn(`\n${count} users processed\n`); return exiting(0); } @@ -77,7 +78,7 @@ function exiting (code, msg) { if (msg) { if (code) { console.error(msg); - } else { + } else { console.log(msg); } } diff --git a/migrations/restock_armoire.js b/migrations/restock_armoire.js index 5046998a3b..7e6471118f 100644 --- a/migrations/restock_armoire.js +++ b/migrations/restock_armoire.js @@ -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, }; @@ -23,18 +24,18 @@ function processUsers (lastId) { } dbUsers.find(query, { - sort: {_id: 1}, + sort: { _id: 1 }, limit: 250, 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}`); + 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,16 +57,16 @@ 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}); + dbUsers.update({ _id: user._id }, { $set: set }); - if (count % progressCount === 0) console.warn(`${count } ${ user._id}`); - if (user._id === authorUuid) console.warn(`${authorName } processed`); + if (count % progressCount === 0) console.warn(`${count} ${user._id}`); + if (user._id === authorUuid) console.warn(`${authorName} processed`); } function displayData () { - console.warn(`\n${ count } users processed\n`); + console.warn(`\n${count} users processed\n`); return exiting(0); } @@ -77,7 +78,7 @@ function exiting (code, msg) { if (msg) { if (code) { console.error(msg); - } else { + } else { console.log(msg); } } diff --git a/migrations/restock_armoire_for_users_that_need_it.js b/migrations/restock_armoire_for_users_that_need_it.js index 5bf0422d04..46dbeeeea1 100644 --- a/migrations/restock_armoire_for_users_that_need_it.js +++ b/migrations/restock_armoire_for_users_that_need_it.js @@ -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,16 +18,17 @@ 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 = { - 'auth.timestamps.loggedin': {$gt: new Date('2016-01-04')}, + const query = { + 'auth.timestamps.loggedin': { $gt: new Date('2016-01-04') }, // '_id': authorUuid // FOR TESTING }; @@ -35,7 +36,7 @@ function processUsers (lastId) { /* let fields = { 'flags.armoireEmpty': 1, 'items.gear.owned': 1, - };*/ + }; */ if (lastId) { query._id = { @@ -44,7 +45,7 @@ function processUsers (lastId) { } dbUsers.find(query, { - sort: {_id: 1}, + sort: { _id: 1 }, limit: 250, fields: { 'flags.armoireEmpty': 1, @@ -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}`); + 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) { @@ -90,7 +91,7 @@ function updateUser (user) { // console.log("don't change: " + user._id); // FOR TESTING } else { // console.log("change: " + user._id); // FOR TESTING - dbUsers.update({_id: user._id}, {$set: set}); + dbUsers.update({ _id: user._id }, { $set: set }); } } else { // this user already has armoire marked as containing items to be bought @@ -98,12 +99,12 @@ function updateUser (user) { // console.log("DON'T CHANGE: " + user._id); // FOR TESTING } - if (count % progressCount === 0) console.warn(`${count } ${ user._id}`); - if (user._id === authorUuid) console.warn(`${authorName } processed`); + if (count % progressCount === 0) console.warn(`${count} ${user._id}`); + if (user._id === authorUuid) console.warn(`${authorName} processed`); } function displayData () { - console.warn(`\n${ count } users processed\n`); + console.warn(`\n${count} users processed\n`); return exiting(0); } @@ -115,7 +116,7 @@ function exiting (code, msg) { if (msg) { if (code) { console.error(msg); - } else { + } else { console.log(msg); } } diff --git a/migrations/restore-profile-data.js b/migrations/restore-profile-data.js index 750a991efb..ae9254031b 100644 --- a/migrations/restore-profile-data.js +++ b/migrations/restore-profile-data.js @@ -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')}, @@ -29,18 +31,18 @@ function processUsers (lastId) { } dbUsers.find(query, { - sort: {_id: 1}, + sort: { _id: 1 }, limit: 250, 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}`); + return exiting(1, `ERROR! ${err}`); }); } -let progressCount = 1000; +const progressCount = 1000; let count = 0; function updateUsers (users) { @@ -50,28 +52,26 @@ 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) { count++; 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) => { + return olDbUsers.findOne({ _id: user._id }, '_id profile') + .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; } @@ -86,17 +86,17 @@ function updateUser (user) { if (Object.keys(set).length !== 0 && set.constructor === Object) { console.log(set); - return dbUsers.update({_id: user._id}, {$set: set}); + return dbUsers.update({ _id: user._id }, { $set: set }); } }); } - if (count % progressCount === 0) console.warn(`${count } ${ user._id}`); - if (user._id === authorUuid) console.warn(`${authorName } processed`); + if (count % progressCount === 0) console.warn(`${count} ${user._id}`); + if (user._id === authorUuid) console.warn(`${authorName} processed`); } function displayData () { - console.warn(`\n${ count } users processed\n`); + console.warn(`\n${count} users processed\n`); return exiting(0); } @@ -108,7 +108,7 @@ function exiting (code, msg) { if (msg) { if (code) { console.error(msg); - } else { + } else { console.log(msg); } } diff --git a/migrations/s3-upload.js b/migrations/s3-upload.js index 4a2d2efcd2..612da82cbc 100644 --- a/migrations/s3-upload.js +++ b/migrations/s3-upload.js @@ -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); }); diff --git a/migrations/tasks/habits-one-history-entry-per-day-challenges.js b/migrations/tasks/habits-one-history-entry-per-day-challenges.js index dcb05f48bf..410c34e44d 100644 --- a/migrations/tasks/habits-one-history-entry-per-day-challenges.js +++ b/migrations/tasks/habits-one-history-entry-per-day-challenges.js @@ -9,13 +9,14 @@ 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 = { - 'challenge.id': {$exists: true}, - userId: {$exists: false}, + const query = { + 'challenge.id': { $exists: true }, + userId: { $exists: false }, type: 'habit', }; @@ -26,17 +27,17 @@ function processChallengeHabits (lastId) { } dbTasks.find(query, { - sort: {_id: 1}, + sort: { _id: 1 }, limit: 500, }) .then(updateChallengeHabits) - .catch((err) => { + .catch(err => { console.log(err); - return exiting(1, `ERROR! ${ 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; @@ -107,16 +105,16 @@ function updateChallengeHabit (habit) { }) .value(); - return dbTasks.update({_id: habit._id}, { - $set: {history: habit.history}, + return dbTasks.update({ _id: habit._id }, { + $set: { history: habit.history }, }); } - if (count % progressCount === 0) console.warn(`${count } habits processed`); + if (count % progressCount === 0) console.warn(`${count} habits processed`); } function displayData () { - console.warn(`\n${ count } tasks processed\n`); + console.warn(`\n${count} tasks processed\n`); return exiting(0); } @@ -128,7 +126,7 @@ function exiting (code, msg) { if (msg) { if (code) { console.error(msg); - } else { + } else { console.log(msg); } } diff --git a/migrations/tasks/habits-one-history-entry-per-day-users.js b/migrations/tasks/habits-one-history-entry-per-day-users.js index 509aa71eb7..3405dee55a 100644 --- a/migrations/tasks/habits-one-history-entry-per-day-users.js +++ b/migrations/tasks/habits-one-history-entry-per-day-users.js @@ -9,13 +9,14 @@ 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 = { - migration: {$ne: migrationName}, + const query = { + migration: { $ne: migrationName }, }; if (lastId) { @@ -25,18 +26,18 @@ function processUsers (lastId) { } dbUsers.find(query, { - sort: {_id: 1}, + sort: { _id: 1 }, limit: 50, // just 50 users per time since we have to process all their habits as well fields: ['_id', 'preferences.timezoneOffset', 'preferences.dayStart'], }) .then(updateUsers) - .catch((err) => { + .catch(err => { console.log(err); - return exiting(1, `ERROR! ${ 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; @@ -107,8 +106,8 @@ function updateHabit (habit, timezoneOffset, dayStart) { }) .value(); - return dbTasks.update({_id: habit._id}, { - $set: {history: habit.history}, + return dbTasks.update({ _id: habit._id }, { + $set: { history: habit.history }, }); } } @@ -116,32 +115,28 @@ 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`); + if (count % progressCount === 0) console.warn(`${count} ${user._id}`); + if (user._id === authorUuid) console.warn(`${authorName} being processed`); return dbTasks.find({ type: 'habit', userId: user._id, }) - .then(habits => { - return Promise.all(habits.map(habit => updateHabit(habit, timezoneOffset, dayStart))); - }) - .then(() => { - return dbUsers.update({_id: user._id}, { - $set: {migration: migrationName}, - }); - }) - .catch((err) => { + .then(habits => Promise.all(habits.map(habit => updateHabit(habit, timezoneOffset, dayStart)))) + .then(() => dbUsers.update({ _id: user._id }, { + $set: { migration: migrationName }, + })) + .catch(err => { console.log(err); - return exiting(1, `ERROR! ${ err}`); + return exiting(1, `ERROR! ${err}`); }); } function displayData () { - console.warn(`\n${ count } tasks processed\n`); + console.warn(`\n${count} tasks processed\n`); return exiting(0); } @@ -153,7 +148,7 @@ function exiting (code, msg) { if (msg) { if (code) { console.error(msg); - } else { + } else { console.log(msg); } } diff --git a/migrations/tasks/tasks-set-everyX.js b/migrations/tasks/tasks-set-everyX.js index c507f80356..899d847bf7 100644 --- a/migrations/tasks/tasks-set-everyX.js +++ b/migrations/tasks/tasks-set-everyX.js @@ -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: { @@ -30,18 +31,18 @@ function processTasks (lastId) { } dbTasks.find(query, { - sort: {_id: 1}, + sort: { _id: 1 }, limit: 250, fields: [], }) .then(updateTasks) - .catch((err) => { + .catch(err => { console.log(err); - return exiting(1, `ERROR! ${ err}`); + return exiting(1, `ERROR! ${err}`); }); } -let progressCount = 1000; +const progressCount = 1000; let count = 0; function updateTasks (tasks) { @@ -51,27 +52,25 @@ 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}); + dbTasks.update({ _id: task._id }, { $set: set }); - if (count % progressCount === 0) console.warn(`${count } ${ task._id}`); - if (task._id === authorUuid) console.warn(`${authorName } processed`); + if (count % progressCount === 0) console.warn(`${count} ${task._id}`); + if (task._id === authorUuid) console.warn(`${authorName} processed`); } function displayData () { - console.warn(`\n${ count } tasks processed\n`); + console.warn(`\n${count} tasks processed\n`); return exiting(0); } @@ -83,7 +82,7 @@ function exiting (code, msg) { if (msg) { if (code) { console.error(msg); - } else { + } else { console.log(msg); } } diff --git a/migrations/tasks/tasks-set-yesterdailies.js b/migrations/tasks/tasks-set-yesterdailies.js index 253d871612..214ac15f9f 100644 --- a/migrations/tasks/tasks-set-yesterdailies.js +++ b/migrations/tasks/tasks-set-yesterdailies.js @@ -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) { @@ -22,7 +24,7 @@ function exiting (code, msg) { if (msg) { if (code) { console.error(msg); - } else { + } else { console.log(msg); } } @@ -30,18 +32,18 @@ function exiting (code, msg) { } function displayData () { - console.warn(`\n${ count } tasks processed\n`); + console.warn(`\n${count} tasks processed\n`); return exiting(0); } function updatetask (task) { count++; - let set = {yesterDaily: true}; + const set = { yesterDaily: true }; - dbTasks.update({_id: task._id}, {$set: set}); + dbTasks.update({ _id: task._id }, { $set: set }); - if (count % progressCount === 0) console.warn(`${count } ${ task._id}`); - if (task._id === authorUuid) console.warn(`${authorName } processed`); + if (count % progressCount === 0) console.warn(`${count} ${task._id}`); + if (task._id === authorUuid) console.warn(`${authorName} processed`); } function updateTasks (tasks) { @@ -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, }; @@ -73,15 +74,15 @@ function processTasks (lastId) { } dbTasks.find(query, { - sort: {_id: 1}, + sort: { _id: 1 }, limit: 250, fields: [ // specify fields we are interested in to limit retrieved data (empty if we're not reading data): ], }) .then(updateTasks) - .catch((err) => { + .catch(err => { console.log(err); - return exiting(1, `ERROR! ${ err}`); + return exiting(1, `ERROR! ${err}`); }); } diff --git a/migrations/users/account-transfer.js b/migrations/users/account-transfer.js index 42a9602aa1..b4f1d270c8 100644 --- a/migrations/users/account-transfer.js +++ b/migrations/users/account-transfer.js @@ -9,6 +9,7 @@ let authorUuid = ''; // ... own data is done */ const monk = require('monk'); + const connectionString = ''; const Users = monk(connectionString).get('users', { castIds: false }); @@ -16,21 +17,21 @@ module.exports = async function accountTransfer () { const fromAccountId = ''; const toAccountId = ''; - const fromAccount = await Users.findOne({_id: fromAccountId}); - const toAccount = await Users.findOne({_id: toAccountId}); + 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}, { + await Users.update({ _id: toAccountId }, { $set: { 'items.pets': newPets, 'items.mounts': newMounts, 'purchased.background': newBackgrounds, }, }) - .then((result) => { + .then(result => { console.log(result); }); }; diff --git a/migrations/users/achievement-restore.js b/migrations/users/achievement-restore.js index 45e7866398..dfe4d9b9db 100644 --- a/migrations/users/achievement-restore.js +++ b/migrations/users/achievement-restore.js @@ -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,10 +55,10 @@ 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]) { + if (!achievementsUpdate[index]) { achievementsUpdate[index] = oldAchievements[index]; continue; // eslint-disable-line no-continue } @@ -75,18 +76,19 @@ 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'); + const oldUser = await UsersOld.findOne({ _id: userId }, 'achievements'); + const newUser = await Users.findOne({ _id: userId }, 'achievements'); const achievementUpdate = getAchievementUpdate(newUser, oldUser); await Users.update( - {_id: userId}, + { _id: userId }, { $set: { achievements: achievementUpdate, }, - }); + }, + ); console.log(`Updated ${userId}`); /* eslint-enable no-await-in-loop */ } diff --git a/migrations/users/bulk-email.js b/migrations/users/bulk-email.js index adba28f805..55a0bcc06c 100644 --- a/migrations/users/bulk-email.js +++ b/migrations/users/bulk-email.js @@ -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,16 +19,16 @@ 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(); + return await User.update({ _id: user._id }, { $set: { migration: MIGRATION_NAME } }).exec(); } module.exports = async function processUsers () { - let query = { - migration: {$ne: MIGRATION_NAME}, - 'auth.timestamps.loggedin': {$gt: moment().subtract(2, 'weeks').toDate()}, // customize or remove to target different populations + const query = { + migration: { $ne: MIGRATION_NAME }, + 'auth.timestamps.loggedin': { $gt: moment().subtract(2, 'weeks').toDate() }, // customize or remove to target different populations }; const fields = { @@ -41,7 +42,7 @@ module.exports = async function processUsers () { const users = await User // eslint-disable-line no-await-in-loop .find(query) .limit(250) - .sort({_id: 1}) + .sort({ _id: 1 }) .select(fields) .lean() .exec(); diff --git a/migrations/users/full-stable.js b/migrations/users/full-stable.js index f41f76f359..17df7002f5 100644 --- a/migrations/users/full-stable.js +++ b/migrations/users/full-stable.js @@ -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,39 +21,39 @@ 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; }); if (count % progressCount === 0) console.warn(`${count} ${user._id}`); - 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 = { - migration: {$ne: MIGRATION_NAME}, + const query = { + migration: { $ne: MIGRATION_NAME }, 'auth.local.username': 'olson22', }; @@ -64,7 +65,7 @@ module.exports = async function processUsers () { const users = await User // eslint-disable-line no-await-in-loop .find(query) .limit(250) - .sort({_id: 1}) + .sort({ _id: 1 }) .select(fields) .lean() .exec(); diff --git a/migrations/users/mystery-items.js b/migrations/users/mystery-items.js index d44743e14c..f0b3ad5e96 100644 --- a/migrations/users/mystery-items.js +++ b/migrations/users/mystery-items.js @@ -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; @@ -29,12 +30,12 @@ async function updateUser (user) { if (count % progressCount === 0) console.warn(`${count} ${user._id}`); - return await User.update({_id: user._id}, {$set: set, $push: push, $addToSet: addToSet}).exec(); + return await User.update({ _id: user._id }, { $set: set, $push: push, $addToSet: addToSet }).exec(); } module.exports = async function processUsers () { - let query = { - migration: {$ne: MIGRATION_NAME}, + const query = { + migration: { $ne: MIGRATION_NAME }, 'purchased.plan.customerId': { $ne: null }, $or: [ { 'purchased.plan.dateTerminated': { $gte: new Date() } }, @@ -51,7 +52,7 @@ module.exports = async function processUsers () { const users = await User // eslint-disable-line no-await-in-loop .find(query) .limit(250) - .sort({_id: 1}) + .sort({ _id: 1 }) .select(fields) .lean() .exec(); diff --git a/migrations/users/pi-day.js b/migrations/users/pi-day.js index a954ba4b5a..3586194eab 100644 --- a/migrations/users/pi-day.js +++ b/migrations/users/pi-day.js @@ -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; @@ -29,19 +30,19 @@ async function updateUser (user) { set['items.gear.owned.head_special_piDay'] = false; set['items.gear.owned.shield_special_piDay'] = false; const push = [ - {type: 'marketGear', path: 'gear.flat.head_special_piDay', _id: uuid()}, - {type: 'marketGear', path: 'gear.flat.shield_special_piDay', _id: uuid()}, + { type: 'marketGear', path: 'gear.flat.head_special_piDay', _id: uuid() }, + { type: 'marketGear', path: 'gear.flat.shield_special_piDay', _id: uuid() }, ]; if (count % progressCount === 0) console.warn(`${count} ${user._id}`); - return await User.update({_id: user._id}, {$inc: inc, $set: set, $push: {pinnedItems: {$each: push}}}).exec(); + return await User.update({ _id: user._id }, { $inc: inc, $set: set, $push: { pinnedItems: { $each: push } } }).exec(); } module.exports = async function processUsers () { - let query = { - migration: {$ne: MIGRATION_NAME}, - 'auth.timestamps.loggedin': {$gt: new Date('2019-02-15')}, + const query = { + migration: { $ne: MIGRATION_NAME }, + 'auth.timestamps.loggedin': { $gt: new Date('2019-02-15') }, }; const fields = { @@ -53,7 +54,7 @@ module.exports = async function processUsers () { const users = await User // eslint-disable-line no-await-in-loop .find(query) .limit(250) - .sort({_id: 1}) + .sort({ _id: 1 }) .select(fields) .lean() .exec(); diff --git a/migrations/users/remove-social-users-extra-data.js b/migrations/users/remove-social-users-extra-data.js index b57a5c3ec3..2e63da3d30 100644 --- a/migrations/users/remove-social-users-extra-data.js +++ b/migrations/users/remove-social-users-extra-data.js @@ -8,12 +8,13 @@ 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 = { - migration: {$ne: migrationName}, + const query = { + migration: { $ne: migrationName }, $or: [ { 'auth.facebook.id': { $exists: true } }, { 'auth.google.id': { $exists: true } }, @@ -27,17 +28,17 @@ function processUsers (lastId) { } dbUsers.find(query, { - sort: {_id: 1}, + sort: { _id: 1 }, limit: 250, }) .then(updateUsers) - .catch((err) => { + .catch(err => { console.log(err); - return exiting(1, `ERROR! ${ 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(() => { @@ -82,12 +83,12 @@ function updateUser (user) { _id: user._id, }, update); - if (count % progressCount === 0) console.warn(`${count } ${ user._id}`); - if (user._id === authorUuid) console.warn(`${authorName } processed`); + if (count % progressCount === 0) console.warn(`${count} ${user._id}`); + if (user._id === authorUuid) console.warn(`${authorName} processed`); } function displayData () { - console.warn(`\n${ count } users processed\n`); + console.warn(`\n${count} users processed\n`); return exiting(0); } @@ -99,7 +100,7 @@ function exiting (code, msg) { if (msg) { if (code) { console.error(msg); - } else { + } else { console.log(msg); } } diff --git a/migrations/users/take-this.js b/migrations/users/take-this.js index 6d990b79f3..96a067d0be 100644 --- a/migrations/users/take-this.js +++ b/migrations/users/take-this.js @@ -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; @@ -19,36 +20,35 @@ async function updateUser (user) { push = false; } else if (typeof user.items.gear.owned.body_special_takeThis !== 'undefined') { set['items.gear.owned.back_special_takeThis'] = false; - push = {pinnedItems: {type: 'marketGear', path: 'gear.flat.back_special_takeThis', _id: uuid()}}; + push = { pinnedItems: { type: 'marketGear', path: 'gear.flat.back_special_takeThis', _id: uuid() } }; } else if (typeof user.items.gear.owned.head_special_takeThis !== 'undefined') { set['items.gear.owned.body_special_takeThis'] = false; - push = {pinnedItems: {type: 'marketGear', path: 'gear.flat.body_special_takeThis', _id: uuid()}}; + push = { pinnedItems: { type: 'marketGear', path: 'gear.flat.body_special_takeThis', _id: uuid() } }; } else if (typeof user.items.gear.owned.armor_special_takeThis !== 'undefined') { set['items.gear.owned.head_special_takeThis'] = false; - push = {pinnedItems: {type: 'marketGear', path: 'gear.flat.head_special_takeThis', _id: uuid()}}; + push = { pinnedItems: { type: 'marketGear', path: 'gear.flat.head_special_takeThis', _id: uuid() } }; } else if (typeof user.items.gear.owned.weapon_special_takeThis !== 'undefined') { set['items.gear.owned.armor_special_takeThis'] = false; - push = {pinnedItems: {type: 'marketGear', path: 'gear.flat.armor_special_takeThis', _id: uuid()}}; + push = { pinnedItems: { type: 'marketGear', path: 'gear.flat.armor_special_takeThis', _id: uuid() } }; } else if (typeof user.items.gear.owned.shield_special_takeThis !== 'undefined') { set['items.gear.owned.weapon_special_takeThis'] = false; - push = {pinnedItems: {type: 'marketGear', path: 'gear.flat.weapon_special_takeThis', _id: uuid()}}; + push = { pinnedItems: { type: 'marketGear', path: 'gear.flat.weapon_special_takeThis', _id: uuid() } }; } else { set['items.gear.owned.shield_special_takeThis'] = false; - push = {pinnedItems: {type: 'marketGear', path: 'gear.flat.shield_special_takeThis', _id: uuid()}}; + push = { pinnedItems: { type: 'marketGear', path: 'gear.flat.shield_special_takeThis', _id: uuid() } }; } if (count % progressCount === 0) console.warn(`${count} ${user._id}`); 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, $push: push }).exec(); } + return await User.update({ _id: user._id }, { $set: set }).exec(); } module.exports = async function processUsers () { - let query = { - migration: {$ne: MIGRATION_NAME}, + const query = { + migration: { $ne: MIGRATION_NAME }, challenges: '00708425-d477-41a5-bf27-6270466e7976', }; @@ -61,7 +61,7 @@ module.exports = async function processUsers () { const users = await User // eslint-disable-line no-await-in-loop .find(query) .limit(250) - .sort({_id: 1}) + .sort({ _id: 1 }) .select(fields) .lean() .exec(); diff --git a/migrations/users/users-to-test.js b/migrations/users/users-to-test.js index cf9f4cc92f..edb23e03db 100644 --- a/migrations/users/users-to-test.js +++ b/migrations/users/users-to-test.js @@ -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) => { + return userLive.find({ guilds: 'b0764d64-8276-45a1-afa5-5ca9a5c64ca0' }) + .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); - return groupsLive.find({_id: {$in: groupsToQuery}}) - .each((group) => { - let promise = groupsTest.update({_id: group._id}, group, {upsert: true}); + const promises = []; + const groupsToQuery = uniq(groupIds); + return groupsLive.find({ _id: { $in: groupsToQuery } }) + .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); - return challengesLive.find({_id: {$in: challengesToQuery}}) - .each((challenge) => { - let promise = challengesTest.update({_id: challenge._id}, challenge, {upsert: true}); + const promises = []; + const challengesToQuery = uniq(challengeIds); + return challengesLive.find({ _id: { $in: challengesToQuery } }) + .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); - return tasksLive.find({_id: {$in: tasksToQuery}}) - .each((task) => { - let promise = tasksTest.update({_id: task._id}, task, {upsert: true}); + const promises = []; + const tasksToQuery = uniq(tasksIds); + return tasksLive.find({ _id: { $in: tasksToQuery } }) + .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'); }); diff --git a/migrations/utils/connect.js b/migrations/utils/connect.js index 1b20d523ca..dfdcc84c08 100644 --- a/migrations/utils/connect.js +++ b/migrations/utils/connect.js @@ -1,6 +1,5 @@ -'use strict'; -const MongoClient = require('mongodb').MongoClient; +const { MongoClient } = require('mongodb'); const logger = require('./logger'); let dbConnection; diff --git a/migrations/utils/logger.js b/migrations/utils/logger.js index cf6d643e76..d93d78612b 100644 --- a/migrations/utils/logger.js +++ b/migrations/utils/logger.js @@ -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); }; } diff --git a/migrations/utils/timer.js b/migrations/utils/timer.js index cacdfc1b8b..b378ce060e 100644 --- a/migrations/utils/timer.js +++ b/migrations/utils/timer.js @@ -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'); diff --git a/migrations/utils/unique.js b/migrations/utils/unique.js index 0d222145c3..df9052e698 100644 --- a/migrations/utils/unique.js +++ b/migrations/utils/unique.js @@ -1,4 +1,3 @@ -'use strict'; function unique (array) { return Array.from(new Set(array)); diff --git a/package-lock.json b/package-lock.json index c28c02ce5b..679679b5e5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1096,27 +1096,16 @@ } }, "acorn": { - "version": "5.7.3", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.3.tgz", - "integrity": "sha512-T/zvzYRfbVojPWahDsE5evJdHb3oJoQfFbsrKM7w5Zcs++Tr257tia3BmMP8XYVjp1S9RZXQMh7gao96BlqZOw==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.1.0.tgz", + "integrity": "sha512-kL5CuoXA/dgxlBbVrflsflzQ3PAas7RYZB52NOm/6839iVYJgKMJ3cQJD+t2i5+qFa8h3MDpEOJiS64E8JLnSQ==", "dev": true }, "acorn-jsx": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz", - "integrity": "sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s=", - "dev": true, - "requires": { - "acorn": "^3.0.4" - }, - "dependencies": { - "acorn": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz", - "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo=", - "dev": true - } - } + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.0.2.tgz", + "integrity": "sha512-tiNTrP1MP0QrChmD2DdupCr6HWSFeKVw5d/dHTu4Y7rkAkRhU/Dt7dphAfIUyxtHpl/eBVip5uTNSpQJHylpAw==", + "dev": true }, "agent-base": { "version": "4.3.0", @@ -1137,12 +1126,6 @@ "uri-js": "^4.2.2" } }, - "ajv-keywords": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-2.1.1.tgz", - "integrity": "sha1-YXmX/F9gV2iUxDX5QNgZ4TW4B2I=", - "dev": true - }, "amazon-payments": { "version": "0.2.7", "resolved": "https://registry.npmjs.org/amazon-payments/-/amazon-payments-0.2.7.tgz", @@ -1618,6 +1601,16 @@ "integrity": "sha1-z+nYwmYoudxa7MYqn12PHzUsEZU=", "dev": true }, + "array-includes": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.0.3.tgz", + "integrity": "sha1-GEtI9i2S10UrsxsyMWXH+L0CJm0=", + "dev": true, + "requires": { + "define-properties": "^1.1.2", + "es-abstract": "^1.7.0" + } + }, "array-initial": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/array-initial/-/array-initial-1.1.0.tgz", @@ -1715,6 +1708,12 @@ "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=" }, + "astral-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", + "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", + "dev": true + }, "async": { "version": "1.5.2", "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", @@ -2701,19 +2700,10 @@ } } }, - "caller-path": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz", - "integrity": "sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=", - "dev": true, - "requires": { - "callsites": "^0.2.0" - } - }, "callsites": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz", - "integrity": "sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", "dev": true }, "camelcase": { @@ -2865,9 +2855,9 @@ } }, "chardet": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.4.2.tgz", - "integrity": "sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I=", + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", "dev": true }, "check-error": { @@ -2964,12 +2954,6 @@ "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-1.6.0.tgz", "integrity": "sha512-vsGdkwSCDpWmP80ncATX7iea5DWQemg1UgCW5J8tqjU3lYw4FBYuj89J0CTVomA7BEfvSZd84GmHko+MxFQU2A==" }, - "circular-json": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz", - "integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==", - "dev": true - }, "class-utils": { "version": "0.3.6", "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", @@ -3269,6 +3253,12 @@ } } }, + "confusing-browser-globals": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.9.tgz", + "integrity": "sha512-KbS1Y0jMtyPgIxjO7ZzMAuUpAKMt1SzCL9fsrKsX6b0zJPTaT0SiSPmewwVZg9UAO83HVIlEhZF84LIjZ0lmAw==", + "dev": true + }, "console-control-strings": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", @@ -3285,6 +3275,12 @@ "integrity": "sha1-oJX+B7IEZZVfL6/Si11yvM2UnUQ=", "optional": true }, + "contains-path": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz", + "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=", + "dev": true + }, "content-disposition": { "version": "0.5.3", "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", @@ -3963,9 +3959,9 @@ "integrity": "sha512-hvSnros73+qyZXhHFjx2CMLwoj3Fe7eR9EJsFsqmcI1bB2OBWL/+0YzaEaKssCHnj/6crawNnUyw74Gm2EKe+Q==" }, "doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", "dev": true, "requires": { "esutils": "^2.0.2" @@ -4190,6 +4186,12 @@ "shimmer": "^1.2.0" } }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, "enabled": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/enabled/-/enabled-1.0.2.tgz", @@ -4332,134 +4334,406 @@ "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" }, "eslint": { - "version": "4.19.1", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-4.19.1.tgz", - "integrity": "sha512-bT3/1x1EbZB7phzYu7vCr1v3ONuzDtX8WjuM9c0iYxe+cq+pwcKEoQjl7zd3RpC6YOLgnSy3cTN58M2jcoPDIQ==", + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-6.5.1.tgz", + "integrity": "sha512-32h99BoLYStT1iq1v2P9uwpyznQ4M2jRiFB6acitKz52Gqn+vPaMDUTB1bYi1WN4Nquj2w+t+bimYUG83DC55A==", "dev": true, "requires": { - "ajv": "^5.3.0", - "babel-code-frame": "^6.22.0", + "@babel/code-frame": "^7.0.0", + "ajv": "^6.10.0", "chalk": "^2.1.0", - "concat-stream": "^1.6.0", - "cross-spawn": "^5.1.0", - "debug": "^3.1.0", - "doctrine": "^2.1.0", - "eslint-scope": "^3.7.1", - "eslint-visitor-keys": "^1.0.0", - "espree": "^3.5.4", - "esquery": "^1.0.0", + "cross-spawn": "^6.0.5", + "debug": "^4.0.1", + "doctrine": "^3.0.0", + "eslint-scope": "^5.0.0", + "eslint-utils": "^1.4.2", + "eslint-visitor-keys": "^1.1.0", + "espree": "^6.1.1", + "esquery": "^1.0.1", "esutils": "^2.0.2", - "file-entry-cache": "^2.0.0", + "file-entry-cache": "^5.0.1", "functional-red-black-tree": "^1.0.1", - "glob": "^7.1.2", - "globals": "^11.0.1", - "ignore": "^3.3.3", + "glob-parent": "^5.0.0", + "globals": "^11.7.0", + "ignore": "^4.0.6", + "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", - "inquirer": "^3.0.6", - "is-resolvable": "^1.0.0", - "js-yaml": "^3.9.1", + "inquirer": "^6.4.1", + "is-glob": "^4.0.0", + "js-yaml": "^3.13.1", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.3.0", - "lodash": "^4.17.4", - "minimatch": "^3.0.2", + "lodash": "^4.17.14", + "minimatch": "^3.0.4", "mkdirp": "^0.5.1", "natural-compare": "^1.4.0", "optionator": "^0.8.2", - "path-is-inside": "^1.0.2", - "pluralize": "^7.0.0", "progress": "^2.0.0", - "regexpp": "^1.0.1", - "require-uncached": "^1.0.3", - "semver": "^5.3.0", - "strip-ansi": "^4.0.0", - "strip-json-comments": "~2.0.1", - "table": "4.0.2", - "text-table": "~0.2.0" + "regexpp": "^2.0.1", + "semver": "^6.1.2", + "strip-ansi": "^5.2.0", + "strip-json-comments": "^3.0.1", + "table": "^5.2.3", + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" }, "dependencies": { - "ajv": { - "version": "5.5.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", - "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", "dev": true, "requires": { - "co": "^4.6.0", - "fast-deep-equal": "^1.0.0", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.3.0" + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + } } }, - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } }, - "fast-deep-equal": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz", - "integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=", - "dev": true + "glob-parent": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.0.tgz", + "integrity": "sha512-qjtRgnIVmOfnKUE3NJAQEdk+lKrxfw8t5ke7SXtfMTHcjsBfOfWXCQfdb30zfDoZQ2IRSIiidmjtbHZPZ++Ihw==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } }, "ignore": { - "version": "3.3.10", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.10.tgz", - "integrity": "sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==", - "dev": true - }, - "json-schema-traverse": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", - "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=", - "dev": true - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", "dev": true }, "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", "dev": true, "requires": { - "ansi-regex": "^3.0.0" + "ansi-regex": "^4.1.0" } + }, + "strip-json-comments": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.0.1.tgz", + "integrity": "sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw==", + "dev": true } } }, + "eslint-config-airbnb-base": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-14.0.0.tgz", + "integrity": "sha512-2IDHobw97upExLmsebhtfoD3NAKhV4H0CJWP3Uprd/uk+cHuWYOczPVxQ8PxLFUAw7o3Th1RAU8u1DoUpr+cMA==", + "dev": true, + "requires": { + "confusing-browser-globals": "^1.0.7", + "object.assign": "^4.1.0", + "object.entries": "^1.1.0" + } + }, "eslint-config-habitrpg": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/eslint-config-habitrpg/-/eslint-config-habitrpg-4.0.0.tgz", - "integrity": "sha512-vZc/KjnNVL2BkDBQaQBF9JV16cnZyKa6djCCqH6iKhp8Uuye8Bym3eeLNEcnGkOtZfzJE61hDqiPZXQk7BiXJQ==", + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/eslint-config-habitrpg/-/eslint-config-habitrpg-6.0.3.tgz", + "integrity": "sha512-TYDXHE40Yu65uMHDqqepX0apOQvOGKZhvjz0Rki9CqL4HWO0QfHxv9Vi3mvVzY6+vrNvnUKs1s37SLTUMakiAg==", "dev": true, "requires": { - "eslint-plugin-lodash": "^2.3.5", - "eslint-plugin-mocha": "^4.7.0" + "eslint": "^6.5.1", + "eslint-config-airbnb-base": "^14.0.0", + "eslint-plugin-import": "^2.18.2", + "eslint-plugin-mocha": "^6.1.1", + "eslint-plugin-vue": "^5.2.3" }, "dependencies": { "eslint-plugin-mocha": { - "version": "4.12.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-mocha/-/eslint-plugin-mocha-4.12.1.tgz", - "integrity": "sha512-hxWtYHvLA0p/PKymRfDYh9Mxt5dYkg2Goy1vZDarTEEYfELP9ksga7kKG1NUKSQy27C8Qjc7YrSWTLUhOEOksA==", + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-mocha/-/eslint-plugin-mocha-6.1.1.tgz", + "integrity": "sha512-p/otruG425jRYDa28HjbBYYXoFNzq3Qp++gn5dbE44Kz4NvmIsSUKSV1T+RLYUcZOcdJKKAftXbaqkHFqReKoA==", "dev": true, - "optional": true, "requires": { - "ramda": "^0.25.0" + "ramda": "^0.26.1" } } } }, - "eslint-plugin-lodash": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-lodash/-/eslint-plugin-lodash-2.7.0.tgz", - "integrity": "sha512-sIEzx85Sy+Higf4W+oLCIyh7ym0OEcmJCzY8ukptlGfkcyVagzYBjhUt1JfkcpT4qZC68+7TzceJSqLu+qwYMg==", + "eslint-import-resolver-node": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.2.tgz", + "integrity": "sha512-sfmTqJfPSizWu4aymbPr4Iidp5yKm8yDkHp+Ir3YiTHiiDfxh69mOUsmiqW6RZ9zRXFaF64GtYmN7e+8GHBv6Q==", "dev": true, - "optional": true, "requires": { - "lodash": "~4.17.0" + "debug": "^2.6.9", + "resolve": "^1.5.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "eslint-module-utils": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.4.1.tgz", + "integrity": "sha512-H6DOj+ejw7Tesdgbfs4jeS4YMFrT8uI8xwd1gtQqXssaR0EQ26L+2O/w6wkYFy2MymON0fTwHmXBvvfLNZVZEw==", + "dev": true, + "requires": { + "debug": "^2.6.8", + "pkg-dir": "^2.0.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "^2.0.0" + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + }, + "pkg-dir": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", + "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", + "dev": true, + "requires": { + "find-up": "^2.1.0" + } + } + } + }, + "eslint-plugin-import": { + "version": "2.18.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.18.2.tgz", + "integrity": "sha512-5ohpsHAiUBRNaBWAF08izwUGlbrJoJJ+W9/TBwsGoR1MnlgfwMIKrFeSjWbt6moabiXW9xNvtFz+97KHRfI4HQ==", + "dev": true, + "requires": { + "array-includes": "^3.0.3", + "contains-path": "^0.1.0", + "debug": "^2.6.9", + "doctrine": "1.5.0", + "eslint-import-resolver-node": "^0.3.2", + "eslint-module-utils": "^2.4.0", + "has": "^1.0.3", + "minimatch": "^3.0.4", + "object.values": "^1.1.0", + "read-pkg-up": "^2.0.0", + "resolve": "^1.11.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "doctrine": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", + "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", + "dev": true, + "requires": { + "esutils": "^2.0.2", + "isarray": "^1.0.0" + } + }, + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "^2.0.0" + } + }, + "load-json-file": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", + "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "strip-bom": "^3.0.0" + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + }, + "path-type": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", + "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", + "dev": true, + "requires": { + "pify": "^2.0.0" + } + }, + "read-pkg": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", + "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", + "dev": true, + "requires": { + "load-json-file": "^2.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^2.0.0" + } + }, + "read-pkg-up": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", + "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", + "dev": true, + "requires": { + "find-up": "^2.0.0", + "read-pkg": "^2.0.0" + } + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true + } } }, "eslint-plugin-mocha": { @@ -4479,16 +4753,34 @@ } } }, + "eslint-plugin-vue": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-5.2.3.tgz", + "integrity": "sha512-mGwMqbbJf0+VvpGR5Lllq0PMxvTdrZ/ZPjmhkacrCHbubJeJOt+T6E3HUzAifa2Mxi7RSdJfC9HFpOeSYVMMIw==", + "dev": true, + "requires": { + "vue-eslint-parser": "^5.0.0" + } + }, "eslint-scope": { - "version": "3.7.3", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-3.7.3.tgz", - "integrity": "sha512-W+B0SvF4gamyCTmUc+uITPY0989iXVfKvhwtmJocTaYoc/3khEHmEmvfY/Gn9HA9VV75jrQECsHizkNw1b68FA==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.0.0.tgz", + "integrity": "sha512-oYrhJW7S0bxAFDvWqzvMPRm6pcgcnWc4QnofCAqRTRfQC0JcwenzGglTtsLyIuuWFfkqDG9vz67cnttSd53djw==", "dev": true, "requires": { "esrecurse": "^4.1.0", "estraverse": "^4.1.1" } }, + "eslint-utils": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.2.tgz", + "integrity": "sha512-eAZS2sEUMlIeCjBeubdj45dmBHQwPHWyBcT1VSYB7o9x9WRRqKxyUoiXlRjyAwzN7YEzHJlYg0NmzDRWx6GP4Q==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^1.0.0" + } + }, "eslint-visitor-keys": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz", @@ -4496,13 +4788,14 @@ "dev": true }, "espree": { - "version": "3.5.4", - "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.4.tgz", - "integrity": "sha512-yAcIQxtmMiB/jL32dzEp2enBeidsB7xWPLNiw3IIkpVds1P+h7qF9YwJq1yUNzp2OKXgAprs4F61ih66UsoD1A==", + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-6.1.1.tgz", + "integrity": "sha512-EYbr8XZUhWbYCqQRW0duU5LxzL5bETN6AjKBGy1302qqzPaCH10QbRg3Wvco79Z8x9WbiE8HYB4e75xl6qUYvQ==", "dev": true, "requires": { - "acorn": "^5.5.0", - "acorn-jsx": "^3.0.0" + "acorn": "^7.0.0", + "acorn-jsx": "^5.0.2", + "eslint-visitor-keys": "^1.1.0" } }, "esprima": { @@ -4814,13 +5107,13 @@ } }, "external-editor": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.2.0.tgz", - "integrity": "sha512-bSn6gvGxKt+b7+6TKEv1ZycHleA7aHhRHyAqJyp5pbUFuYYNIzpZnQDk7AsYckyWdEnTeAnay0aCy2aV6iTk9A==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", + "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", "dev": true, "requires": { - "chardet": "^0.4.0", - "iconv-lite": "^0.4.17", + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", "tmp": "^0.0.33" } }, @@ -5070,13 +5363,12 @@ } }, "file-entry-cache": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz", - "integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", + "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==", "dev": true, "requires": { - "flat-cache": "^1.2.1", - "object-assign": "^4.0.1" + "flat-cache": "^2.0.1" } }, "file-type": { @@ -5279,15 +5571,14 @@ "integrity": "sha512-lNaHNVymajmk0OJMBn8fVUAU1BtDeKIqKoVhk4xAALB57aALg6b4W0MfJ/cUE0g9YBXy5XhSlPIpYIJ7HaY/3Q==" }, "flat-cache": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.4.tgz", - "integrity": "sha512-VwyB3Lkgacfik2vhqR4uv2rvebqmDvFu4jlN/C1RzWoJEo8I7z4Q404oiqYCkq41mni8EzQnm95emU9seckwtg==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", + "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", "dev": true, "requires": { - "circular-json": "^0.3.1", - "graceful-fs": "^4.1.2", - "rimraf": "~2.6.2", - "write": "^0.2.1" + "flatted": "^2.0.0", + "rimraf": "2.6.3", + "write": "1.0.3" }, "dependencies": { "rimraf": { @@ -5301,6 +5592,12 @@ } } }, + "flatted": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.1.tgz", + "integrity": "sha512-a1hQMktqW9Nmqr5aktAux3JMNqaucxGcjtjWnZLHX7yyPCmlSV3M54nGYbqT8K+0GhF3NBgmJCc3ma+WOgX8Jg==", + "dev": true + }, "flush-write-stream": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz", @@ -7008,6 +7305,24 @@ "svgo": "^1.0.5" } }, + "import-fresh": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.1.0.tgz", + "integrity": "sha512-PpuksHKGt8rXfWEr9m9EHIpgyyaltBy8+eF6GJM0QCAxMgxCfucMF3mjecK2QsJr0amJW7gTqh5/wht0z2UhEQ==", + "dev": true, + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "dependencies": { + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true + } + } + }, "import-lazy": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-3.1.0.tgz", @@ -7158,24 +7473,23 @@ "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==" }, "inquirer": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-3.3.0.tgz", - "integrity": "sha512-h+xtnyk4EwKvFWHrUYsWErEVR+igKtLdchu+o0Z1RL7VU/jVMFbYir2bp6bAj8efFNxWqHX0dIss6fJQ+/+qeQ==", + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.5.2.tgz", + "integrity": "sha512-cntlB5ghuB0iuO65Ovoi8ogLHiWGs/5yNrtUcKjFhSSiVeAIVpD7koaSU9RM8mpXw5YDi9RdYXGQMaOURB7ycQ==", "dev": true, "requires": { - "ansi-escapes": "^3.0.0", - "chalk": "^2.0.0", + "ansi-escapes": "^3.2.0", + "chalk": "^2.4.2", "cli-cursor": "^2.1.0", "cli-width": "^2.0.0", - "external-editor": "^2.0.4", + "external-editor": "^3.0.3", "figures": "^2.0.0", - "lodash": "^4.3.0", + "lodash": "^4.17.12", "mute-stream": "0.0.7", "run-async": "^2.2.0", - "rx-lite": "^4.0.8", - "rx-lite-aggregates": "^4.0.8", + "rxjs": "^6.4.0", "string-width": "^2.1.0", - "strip-ansi": "^4.0.0", + "strip-ansi": "^5.1.0", "through": "^2.3.6" }, "dependencies": { @@ -7208,15 +7522,34 @@ "requires": { "is-fullwidth-code-point": "^2.0.0", "strip-ansi": "^4.0.0" + }, + "dependencies": { + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + } } }, "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", "dev": true, "requires": { - "ansi-regex": "^3.0.0" + "ansi-regex": "^4.1.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + } } } } @@ -7560,12 +7893,6 @@ "is-unc-path": "^1.0.0" } }, - "is-resolvable": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz", - "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==", - "dev": true - }, "is-retry-allowed": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz", @@ -9095,8 +9422,7 @@ "nice-try": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", - "optional": true + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==" }, "nise": { "version": "1.5.2", @@ -9546,6 +9872,18 @@ "isobject": "^3.0.0" } }, + "object.entries": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.0.tgz", + "integrity": "sha512-l+H6EQ8qzGRxbkHOd5I/aHRhHDKoQXQ8g0BYt4uSweQU1/J6dZUOyWh9a2Vky35YCKjzmgxOzta2hH6kf9HuXA==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.12.0", + "function-bind": "^1.1.1", + "has": "^1.0.3" + } + }, "object.getownpropertydescriptors": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz", @@ -9585,7 +9923,6 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.0.tgz", "integrity": "sha512-8mf0nKLAoFX6VlNVdhGj31SVYpaNFtUnuoOXWyFEstsWRgU837AK+JYM0iAxwkSzGRbwn8cbFmgbyxj1j4VbXg==", - "optional": true, "requires": { "define-properties": "^1.1.3", "es-abstract": "^1.12.0", @@ -9911,6 +10248,15 @@ } } }, + "parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "requires": { + "callsites": "^3.0.0" + } + }, "parse-data-uri": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/parse-data-uri/-/parse-data-uri-0.2.0.tgz", @@ -10249,12 +10595,6 @@ "irregular-plurals": "^2.0.0" } }, - "pluralize": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-7.0.0.tgz", - "integrity": "sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow==", - "dev": true - }, "pngjs": { "version": "3.4.0", "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-3.4.0.tgz", @@ -10454,11 +10794,10 @@ } }, "ramda": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.25.0.tgz", - "integrity": "sha512-GXpfrYVPwx3K7RQ6aYT8KPS8XViSXUVJT1ONhoKPE9VAleW42YE+U+8VEyGWt41EnEQW7gwecYJriTI0pKoecQ==", - "dev": true, - "optional": true + "version": "0.26.1", + "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.26.1.tgz", + "integrity": "sha512-hLWjpy7EnsDBb0p+Z3B7rPi3GDeRG5ZtiI33kJhTt+ORCd38AbAIjB/9zRIUoeTbE/AVX5ZkU7m6bznsvrf8eQ==", + "dev": true }, "range-parser": { "version": "1.2.1", @@ -10603,9 +10942,9 @@ "integrity": "sha512-TuAasHQNamyyJ2hb97IuBEif4qBHGjPHBS64sZwytpLEqtBQ1gPJTnOaQ6qmpET16cK14kkjbazl6+p0RRv0yw==" }, "regexpp": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-1.1.0.tgz", - "integrity": "sha512-LOPw8FpgdQF9etWMaAfG/WRthIdXJGYp4mJ2Jgn/2lpkbod9jPn0t9UqN7AxBOKNfzRbYyVfgc7Vk4t/MpnXgw==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", + "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==", "dev": true }, "regexpu-core": { @@ -10800,24 +11139,6 @@ "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=" }, - "require-uncached": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz", - "integrity": "sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=", - "dev": true, - "requires": { - "caller-path": "^0.1.0", - "resolve-from": "^1.0.0" - }, - "dependencies": { - "resolve-from": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz", - "integrity": "sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY=", - "dev": true - } - } - }, "require_optional": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/require_optional/-/require_optional-1.0.1.tgz", @@ -10943,19 +11264,13 @@ "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.1.9.tgz", "integrity": "sha512-DEqnSRTDw/Tc3FXf49zedI638Z9onwUotBMiUFKmrO2sdFKIbXamXGQ3Axd4qgphxKB4kw/qP1w5kTxnfU1B9Q==" }, - "rx-lite": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-4.0.8.tgz", - "integrity": "sha1-Cx4Rr4vESDbwSmQH6S2kJGe3lEQ=", - "dev": true - }, - "rx-lite-aggregates": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz", - "integrity": "sha1-dTuHqJoRyVRnxKwWJsTvxOBcZ74=", + "rxjs": { + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.3.tgz", + "integrity": "sha512-wuYsAYYFdWTAnAaPoKGNhfpWwKZbJW+HgAJ+mImp+Epl7BG8oNWBCTyRM8gba9k4lk8BgWdoYm21Mo/RYhhbgA==", "dev": true, "requires": { - "rx-lite": "*" + "tslib": "^1.9.0" } }, "safe-buffer": { @@ -11256,14 +11571,25 @@ "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==" }, "slice-ansi": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-1.0.0.tgz", - "integrity": "sha512-POqxBK6Lb3q6s047D/XsDVNPnF9Dl8JSaqe9h9lURl0OdNqy/ujDrOiIHtsqXMGbWWTIomRzAMaTyawAU//Reg==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", + "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", "dev": true, "requires": { + "ansi-styles": "^3.2.0", + "astral-regex": "^1.0.0", "is-fullwidth-code-point": "^2.0.0" }, "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, "is-fullwidth-code-point": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", @@ -11949,41 +12275,21 @@ } }, "table": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/table/-/table-4.0.2.tgz", - "integrity": "sha512-UUkEAPdSGxtRpiV9ozJ5cMTtYiqz7Ni1OGqLXRCynrvzdtR1p+cfOWe2RJLwvUG8hNanaSRjecIqwOjqeatDsA==", + "version": "5.4.6", + "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", + "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==", "dev": true, "requires": { - "ajv": "^5.2.3", - "ajv-keywords": "^2.1.0", - "chalk": "^2.1.0", - "lodash": "^4.17.4", - "slice-ansi": "1.0.0", - "string-width": "^2.1.1" + "ajv": "^6.10.2", + "lodash": "^4.17.14", + "slice-ansi": "^2.1.0", + "string-width": "^3.0.0" }, "dependencies": { - "ajv": { - "version": "5.5.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", - "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", - "dev": true, - "requires": { - "co": "^4.6.0", - "fast-deep-equal": "^1.0.0", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.3.0" - } - }, "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "fast-deep-equal": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz", - "integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", "dev": true }, "is-fullwidth-code-point": { @@ -11992,29 +12298,24 @@ "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", "dev": true }, - "json-schema-traverse": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", - "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=", - "dev": true - }, "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", "dev": true, "requires": { + "emoji-regex": "^7.0.1", "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" + "strip-ansi": "^5.1.0" } }, "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", "dev": true, "requires": { - "ansi-regex": "^3.0.0" + "ansi-regex": "^4.1.0" } } } @@ -12303,6 +12604,12 @@ "resolved": "https://registry.npmjs.org/triple-beam/-/triple-beam-1.3.0.tgz", "integrity": "sha512-XrHUvV5HpdLmIj4uVMxHggLbFSZYIn7HEWsqePZcI50pco+MPqJ50wMGY794X7AOOhxOBAjbkqfAbEe/QMp2Lw==" }, + "tslib": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", + "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==", + "dev": true + }, "tunnel-agent": { "version": "0.4.3", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.4.3.tgz", @@ -12870,6 +13177,12 @@ "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.3.tgz", "integrity": "sha512-pW0No1RGHgzlpHJO1nsVrHKpOEIxkGg1xB+v0ZmdNH5OAeAwzAVrCnI2/6Mtx+Uys6iaylxa+D3g4j63IKKjSQ==" }, + "v8-compile-cache": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.1.0.tgz", + "integrity": "sha512-usZBT3PW+LOjM25wbqIlZwPeJV+3OSz3M1k1Ws8snlW39dZyYL9lOGC5FgPVHfk0jKmjiDV8Z0mIbVQPiwFs7g==", + "dev": true + }, "v8flags": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-3.1.3.tgz", @@ -13059,6 +13372,58 @@ } } }, + "vue-eslint-parser": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-5.0.0.tgz", + "integrity": "sha512-JlHVZwBBTNVvzmifwjpZYn0oPWH2SgWv5dojlZBsrhablDu95VFD+hriB1rQGwbD+bms6g+rAFhQHk6+NyiS6g==", + "dev": true, + "requires": { + "debug": "^4.1.0", + "eslint-scope": "^4.0.0", + "eslint-visitor-keys": "^1.0.0", + "espree": "^4.1.0", + "esquery": "^1.0.1", + "lodash": "^4.17.11" + }, + "dependencies": { + "acorn": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.3.0.tgz", + "integrity": "sha512-/czfa8BwS88b9gWQVhc8eknunSA2DoJpJyTQkhheIf5E48u1N0R4q/YxxsAeqRrmK9TQ/uYfgLDfZo91UlANIA==", + "dev": true + }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "eslint-scope": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", + "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", + "dev": true, + "requires": { + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + } + }, + "espree": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-4.1.0.tgz", + "integrity": "sha512-I5BycZW6FCVIub93TeVY1s7vjhP9CY6cXCznIRfiig7nRviKZYdRnj/sHEWC6A7WE9RDWOFq9+7OsWSYz8qv2w==", + "dev": true, + "requires": { + "acorn": "^6.0.2", + "acorn-jsx": "^5.0.0", + "eslint-visitor-keys": "^1.0.0" + } + } + } + }, "w3counter": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/w3counter/-/w3counter-3.0.1.tgz", @@ -13228,9 +13593,9 @@ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" }, "write": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/write/-/write-0.2.1.tgz", - "integrity": "sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz", + "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==", "dev": true, "requires": { "mkdirp": "^0.5.1" diff --git a/package.json b/package.json index bd64a44378..bdb0af63a1 100644 --- a/package.json +++ b/package.json @@ -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", diff --git a/scripts/gdpr-delete-users.js b/scripts/gdpr-delete-users.js index c60c16d92f..91dd5af506 100644 --- a/scripts/gdpr-delete-users.js +++ b/scripts/gdpr-delete-users.js @@ -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: { - 'auth.local.email': email, - 'auth.local.hashed_password': '$2a$10$QDnNh1j1yMPnTXDEOV38xOePEWFd4X8DSYwAM8XTmqmacG5X0DKjW', - 'auth.local.passwordHashMethod': 'bcrypt', - }} + { _id: user._id }, + { + $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}, - ]}, + { '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); } diff --git a/scripts/paypalBillingSetup.js b/scripts/paypalBillingSetup.js index e99ffe31b8..2ef55af823 100644 --- a/scripts/paypalBillingSetup.js +++ b/scripts/paypalBillingSetup.js @@ -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)`, @@ -57,17 +58,17 @@ _.each(blocks, (block) => { switch (OP) { case 'list': - paypal.billingPlan.list({status: 'ACTIVE'}, (err, plans) => { - console.log({err, plans}); + paypal.billingPlan.list({ status: 'ACTIVE' }, (err, plans) => { + console.log({ err, plans }); }); break; case 'get': paypal.billingPlan.get(nconf.get('PAYPAL_BILLING_PLANS_basic_12mo'), (err, plan) => { - console.log({err, plan}); + console.log({ err, plan }); }); break; case 'update': - let updatePayload = { + const updatePayload = { op: 'replace', path: '/merchant_preferences', value: { @@ -75,7 +76,7 @@ switch (OP) { }, }; paypal.billingPlan.update(nconf.get('PAYPAL_BILLING_PLANS_basic_12mo'), updatePayload, (err, res) => { - console.log({err, plan: res}); + console.log({ err, plan: res }); }); break; case 'create': @@ -83,10 +84,10 @@ switch (OP) { if (err) return console.log(err); if (plan.state === 'ACTIVE') { - return console.log({err, plan}); + return console.log({ err, plan }); } - let billingPlanUpdateAttributes = [{ + const billingPlanUpdateAttributes = [{ op: 'replace', path: '/', value: { @@ -96,12 +97,12 @@ switch (OP) { // Activate the plan by changing status to Active paypal.billingPlan.update(plan.id, billingPlanUpdateAttributes, (err2, response) => { - console.log({err: err2, response, id: plan.id}); + console.log({ err: err2, response, id: plan.id }); }); }); break; case 'create-webprofile': - let webexpinfo = { + const webexpinfo = { name: 'HabiticaProfile', input_fields: { no_shipping: 1, diff --git a/website/common/index.js b/website/common/index.js index 04189fa8ab..c4fb1693bd 100644 --- a/website/common/index.js +++ b/website/common/index.js @@ -1,4 +1,3 @@ -'use strict'; let pathToCommon; diff --git a/website/common/script/.eslintrc b/website/common/script/.eslintrc index 4acd626597..05ff6f5ec3 100644 --- a/website/common/script/.eslintrc +++ b/website/common/script/.eslintrc @@ -1,6 +1,5 @@ { "extends": [ - "habitrpg/browser", - "habitrpg/esnext" + "habitrpg/lib/node", ] } diff --git a/website/common/script/constants.js b/website/common/script/constants.js index 8985bea89e..758d12c719 100644 --- a/website/common/script/constants.js +++ b/website/common/script/constants.js @@ -16,8 +16,8 @@ export const CHAT_FLAG_FROM_SHADOW_MUTE = 10; // a shadow-muted user's post star // @TODO use those constants to replace hard-coded numbers export const SUPPORTED_SOCIAL_NETWORKS = [ - {key: 'facebook', name: 'Facebook'}, - {key: 'google', name: 'Google'}, + { key: 'facebook', name: 'Facebook' }, + { key: 'google', name: 'Google' }, ]; export const GUILDS_PER_PAGE = 30; // number of guilds to return per page when using pagination diff --git a/website/common/script/content/achievements.js b/website/common/script/content/achievements.js index 2f29fe2327..1e8fef8972 100644 --- a/website/common/script/content/achievements.js +++ b/website/common/script/content/achievements.js @@ -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`, diff --git a/website/common/script/content/appearance/backgrounds.js b/website/common/script/content/appearance/backgrounds.js index 15a06aa79e..7686f95ee9 100644 --- a/website/common/script/content/appearance/backgrounds.js +++ b/website/common/script/content/appearance/backgrounds.js @@ -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; diff --git a/website/common/script/content/appearance/hair/base.js b/website/common/script/content/appearance/hair/base.js index 8075f57df4..f399c7d0ea 100644 --- a/website/common/script/content/appearance/hair/base.js +++ b/website/common/script/content/appearance/hair/base.js @@ -4,23 +4,23 @@ import sets from '../sets.js'; export default prefill({ 0: {}, 1: {}, - 2: {price: 2, set: sets.baseHair1}, + 2: { price: 2, set: sets.baseHair1 }, 3: {}, - 4: {price: 2, set: sets.baseHair1}, - 5: {price: 2, set: sets.baseHair1}, - 6: {price: 2, set: sets.baseHair1}, - 7: {price: 2, set: sets.baseHair1}, - 8: {price: 2, set: sets.baseHair1}, - 9: {price: 2, set: sets.baseHair2}, - 10: {price: 2, set: sets.baseHair2}, - 11: {price: 2, set: sets.baseHair2}, - 12: {price: 2, set: sets.baseHair2}, - 13: {price: 2, set: sets.baseHair2}, - 14: {price: 2, set: sets.baseHair2}, - 15: {price: 2, set: sets.baseHair3}, - 16: {price: 2, set: sets.baseHair3}, - 17: {price: 2, set: sets.baseHair3}, - 18: {price: 2, set: sets.baseHair3}, - 19: {price: 2, set: sets.baseHair3}, - 20: {price: 2, set: sets.baseHair3}, + 4: { price: 2, set: sets.baseHair1 }, + 5: { price: 2, set: sets.baseHair1 }, + 6: { price: 2, set: sets.baseHair1 }, + 7: { price: 2, set: sets.baseHair1 }, + 8: { price: 2, set: sets.baseHair1 }, + 9: { price: 2, set: sets.baseHair2 }, + 10: { price: 2, set: sets.baseHair2 }, + 11: { price: 2, set: sets.baseHair2 }, + 12: { price: 2, set: sets.baseHair2 }, + 13: { price: 2, set: sets.baseHair2 }, + 14: { price: 2, set: sets.baseHair2 }, + 15: { price: 2, set: sets.baseHair3 }, + 16: { price: 2, set: sets.baseHair3 }, + 17: { price: 2, set: sets.baseHair3 }, + 18: { price: 2, set: sets.baseHair3 }, + 19: { price: 2, set: sets.baseHair3 }, + 20: { price: 2, set: sets.baseHair3 }, }); diff --git a/website/common/script/content/appearance/hair/beard.js b/website/common/script/content/appearance/hair/beard.js index 120b3358b5..544227e7fc 100644 --- a/website/common/script/content/appearance/hair/beard.js +++ b/website/common/script/content/appearance/hair/beard.js @@ -3,7 +3,7 @@ import prefill from '../prefill.js'; export default prefill({ 0: {}, - 1: {price: 2, set: sets.facialHair}, - 2: {price: 2, set: sets.facialHair}, - 3: {price: 2, set: sets.facialHair}, + 1: { price: 2, set: sets.facialHair }, + 2: { price: 2, set: sets.facialHair }, + 3: { price: 2, set: sets.facialHair }, }); diff --git a/website/common/script/content/appearance/hair/color.js b/website/common/script/content/appearance/hair/color.js index 467da5b165..69398d2fcd 100644 --- a/website/common/script/content/appearance/hair/color.js +++ b/website/common/script/content/appearance/hair/color.js @@ -8,43 +8,43 @@ export default prefill({ red: {}, black: {}, - candycane: {price: 2, set: sets.winterHairColors}, - frost: {price: 2, set: sets.winterHairColors}, - winternight: {price: 2, set: sets.winterHairColors}, - holly: {price: 2, set: sets.winterHairColors}, + candycane: { price: 2, set: sets.winterHairColors }, + frost: { price: 2, set: sets.winterHairColors }, + winternight: { price: 2, set: sets.winterHairColors }, + holly: { price: 2, set: sets.winterHairColors }, - pblue: {price: 2, set: sets.pastelHairColors}, - pgreen: {price: 2, set: sets.pastelHairColors}, - porange: {price: 2, set: sets.pastelHairColors}, - ppink: {price: 2, set: sets.pastelHairColors}, - ppurple: {price: 2, set: sets.pastelHairColors}, - pyellow: {price: 2, set: sets.pastelHairColors}, + pblue: { price: 2, set: sets.pastelHairColors }, + pgreen: { price: 2, set: sets.pastelHairColors }, + porange: { price: 2, set: sets.pastelHairColors }, + ppink: { price: 2, set: sets.pastelHairColors }, + ppurple: { price: 2, set: sets.pastelHairColors }, + pyellow: { price: 2, set: sets.pastelHairColors }, - rainbow: {price: 2, set: sets.rainbowHairColors}, - yellow: {price: 2, set: sets.rainbowHairColors}, - green: {price: 2, set: sets.rainbowHairColors}, - purple: {price: 2, set: sets.rainbowHairColors}, - blue: {price: 2, set: sets.rainbowHairColors}, - TRUred: {price: 2, set: sets.rainbowHairColors}, + rainbow: { price: 2, set: sets.rainbowHairColors }, + yellow: { price: 2, set: sets.rainbowHairColors }, + green: { price: 2, set: sets.rainbowHairColors }, + purple: { price: 2, set: sets.rainbowHairColors }, + blue: { price: 2, set: sets.rainbowHairColors }, + TRUred: { price: 2, set: sets.rainbowHairColors }, - pblue2: {price: 2, set: sets.shimmerHairColors}, - pgreen2: {price: 2, set: sets.shimmerHairColors}, - porange2: {price: 2, set: sets.shimmerHairColors}, - ppink2: {price: 2, set: sets.shimmerHairColors}, - ppurple2: {price: 2, set: sets.shimmerHairColors}, - pyellow2: {price: 2, set: sets.shimmerHairColors}, + pblue2: { price: 2, set: sets.shimmerHairColors }, + pgreen2: { price: 2, set: sets.shimmerHairColors }, + porange2: { price: 2, set: sets.shimmerHairColors }, + ppink2: { price: 2, set: sets.shimmerHairColors }, + ppurple2: { price: 2, set: sets.shimmerHairColors }, + pyellow2: { price: 2, set: sets.shimmerHairColors }, - candycorn: {price: 2, set: sets.hauntedHairColors}, - ghostwhite: {price: 2, set: sets.hauntedHairColors}, - halloween: {price: 2, set: sets.hauntedHairColors}, - midnight: {price: 2, set: sets.hauntedHairColors}, - pumpkin: {price: 2, set: sets.hauntedHairColors}, - zombie: {price: 2, set: sets.hauntedHairColors}, + candycorn: { price: 2, set: sets.hauntedHairColors }, + ghostwhite: { price: 2, set: sets.hauntedHairColors }, + halloween: { price: 2, set: sets.hauntedHairColors }, + midnight: { price: 2, set: sets.hauntedHairColors }, + pumpkin: { price: 2, set: sets.hauntedHairColors }, + zombie: { price: 2, set: sets.hauntedHairColors }, - aurora: {price: 2, set: sets.winteryHairColors}, - festive: {price: 2, set: sets.winteryHairColors}, - hollygreen: {price: 2, set: sets.winteryHairColors}, - peppermint: {price: 2, set: sets.winteryHairColors}, - snowy: {price: 2, set: sets.winteryHairColors}, - winterstar: {price: 2, set: sets.winteryHairColors}, + aurora: { price: 2, set: sets.winteryHairColors }, + festive: { price: 2, set: sets.winteryHairColors }, + hollygreen: { price: 2, set: sets.winteryHairColors }, + peppermint: { price: 2, set: sets.winteryHairColors }, + snowy: { price: 2, set: sets.winteryHairColors }, + winterstar: { price: 2, set: sets.winteryHairColors }, }); diff --git a/website/common/script/content/appearance/hair/mustache.js b/website/common/script/content/appearance/hair/mustache.js index 5f13d0f962..6e382e5e8b 100644 --- a/website/common/script/content/appearance/hair/mustache.js +++ b/website/common/script/content/appearance/hair/mustache.js @@ -3,6 +3,6 @@ import prefill from '../prefill.js'; export default prefill({ 0: {}, - 1: {price: 2, set: sets.facialHair}, - 2: {price: 2, set: sets.facialHair}, + 1: { price: 2, set: sets.facialHair }, + 2: { price: 2, set: sets.facialHair }, }); diff --git a/website/common/script/content/appearance/hair/top-hair.js b/website/common/script/content/appearance/hair/top-hair.js index 504a020669..6b9dcf0b36 100644 --- a/website/common/script/content/appearance/hair/top-hair.js +++ b/website/common/script/content/appearance/hair/top-hair.js @@ -3,10 +3,10 @@ import sets from '../sets.js'; export default prefill({ 0: {}, - 1: {price: 2, set: sets.topHair}, - 2: {price: 2, set: sets.topHair}, - 3: {price: 2, set: sets.topHair}, - 4: {price: 2, set: sets.topHair}, - 5: {price: 2, set: sets.topHair}, - 6: {price: 2, set: sets.topHair}, + 1: { price: 2, set: sets.topHair }, + 2: { price: 2, set: sets.topHair }, + 3: { price: 2, set: sets.topHair }, + 4: { price: 2, set: sets.topHair }, + 5: { price: 2, set: sets.topHair }, + 6: { price: 2, set: sets.topHair }, }); diff --git a/website/common/script/content/appearance/index.js b/website/common/script/content/appearance/index.js index 7564cbf2fd..d6fd8f9614 100644 --- a/website/common/script/content/appearance/index.js +++ b/website/common/script/content/appearance/index.js @@ -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, diff --git a/website/common/script/content/appearance/prefill.js b/website/common/script/content/appearance/prefill.js index badfaaf295..8823a36fd3 100644 --- a/website/common/script/content/appearance/prefill.js +++ b/website/common/script/content/appearance/prefill.js @@ -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; diff --git a/website/common/script/content/appearance/sets.js b/website/common/script/content/appearance/sets.js index 31ed3261f3..d26769d271 100644 --- a/website/common/script/content/appearance/sets.js +++ b/website/common/script/content/appearance/sets.js @@ -2,22 +2,36 @@ import t from '../translation'; import prefill from './prefill.js'; export default prefill({ - baseHair1: {setPrice: 5, text: t('hairSet1')}, - baseHair2: {setPrice: 5, text: t('hairSet2')}, - baseHair3: {setPrice: 5, text: t('hairSet3')}, - facialHair: {setPrice: 5, text: t('bodyFacialHair')}, - specialShirts: {setPrice: 5, text: t('specialShirts')}, - 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')}, - 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')}, - 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')}, + baseHair1: { setPrice: 5, text: t('hairSet1') }, + baseHair2: { setPrice: 5, text: t('hairSet2') }, + baseHair3: { setPrice: 5, text: t('hairSet3') }, + facialHair: { setPrice: 5, text: t('bodyFacialHair') }, + specialShirts: { setPrice: 5, text: t('specialShirts') }, + 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'), + }, + 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'), + }, + 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'), + }, }); diff --git a/website/common/script/content/appearance/shirt.js b/website/common/script/content/appearance/shirt.js index eac4ce0762..088113fa55 100644 --- a/website/common/script/content/appearance/shirt.js +++ b/website/common/script/content/appearance/shirt.js @@ -9,15 +9,15 @@ export default prefill({ white: {}, yellow: {}, - convict: {price: 2, set: sets.specialShirts}, - cross: {price: 2, set: sets.specialShirts}, - fire: {price: 2, set: sets.specialShirts}, - horizon: {price: 2, set: sets.specialShirts}, - ocean: {price: 2, set: sets.specialShirts}, - purple: {price: 2, set: sets.specialShirts}, - rainbow: {price: 2, set: sets.specialShirts}, - redblue: {price: 2, set: sets.specialShirts}, - thunder: {price: 2, set: sets.specialShirts}, - tropical: {price: 2, set: sets.specialShirts}, - zombie: {price: 2, set: sets.specialShirts}, + convict: { price: 2, set: sets.specialShirts }, + cross: { price: 2, set: sets.specialShirts }, + fire: { price: 2, set: sets.specialShirts }, + horizon: { price: 2, set: sets.specialShirts }, + ocean: { price: 2, set: sets.specialShirts }, + purple: { price: 2, set: sets.specialShirts }, + rainbow: { price: 2, set: sets.specialShirts }, + redblue: { price: 2, set: sets.specialShirts }, + thunder: { price: 2, set: sets.specialShirts }, + tropical: { price: 2, set: sets.specialShirts }, + zombie: { price: 2, set: sets.specialShirts }, }); diff --git a/website/common/script/content/appearance/skin.js b/website/common/script/content/appearance/skin.js index 4e7a8521af..8a9ca9dfe2 100644 --- a/website/common/script/content/appearance/skin.js +++ b/website/common/script/content/appearance/skin.js @@ -12,66 +12,66 @@ export default prefill({ 'c3e1dc': {}, '6bd049': {}, - 'eb052b': {price: 2, set: sets.rainbowSkins}, - 'f69922': {price: 2, set: sets.rainbowSkins}, - 'f5d70f': {price: 2, set: sets.rainbowSkins}, - '0ff591': {price: 2, set: sets.rainbowSkins}, - '2b43f6': {price: 2, set: sets.rainbowSkins}, - 'd7a9f7': {price: 2, set: sets.rainbowSkins}, - '800ed0': {price: 2, set: sets.rainbowSkins}, - 'rainbow': {price: 2, set: sets.rainbowSkins}, + 'eb052b': { price: 2, set: sets.rainbowSkins }, + 'f69922': { price: 2, set: sets.rainbowSkins }, + 'f5d70f': { price: 2, set: sets.rainbowSkins }, + '0ff591': { price: 2, set: sets.rainbowSkins }, + '2b43f6': { price: 2, set: sets.rainbowSkins }, + 'd7a9f7': { price: 2, set: sets.rainbowSkins }, + '800ed0': { price: 2, set: sets.rainbowSkins }, + 'rainbow': { price: 2, set: sets.rainbowSkins }, - 'bear': {price: 2, set: sets.animalSkins}, - 'cactus': {price: 2, set: sets.animalSkins}, - 'fox': {price: 2, set: sets.animalSkins}, - 'lion': {price: 2, set: sets.animalSkins}, - 'panda': {price: 2, set: sets.animalSkins}, - 'pig': {price: 2, set: sets.animalSkins}, - 'tiger': {price: 2, set: sets.animalSkins}, - 'wolf': {price: 2, set: sets.animalSkins}, + 'bear': { price: 2, set: sets.animalSkins }, + 'cactus': { price: 2, set: sets.animalSkins }, + 'fox': { price: 2, set: sets.animalSkins }, + 'lion': { price: 2, set: sets.animalSkins }, + 'panda': { price: 2, set: sets.animalSkins }, + 'pig': { price: 2, set: sets.animalSkins }, + 'tiger': { price: 2, set: sets.animalSkins }, + 'wolf': { price: 2, set: sets.animalSkins }, - 'pastelPink': {price: 2, set: sets.pastelSkins}, - 'pastelOrange': {price: 2, set: sets.pastelSkins}, - 'pastelYellow': {price: 2, set: sets.pastelSkins}, - 'pastelGreen': {price: 2, set: sets.pastelSkins}, - 'pastelBlue': {price: 2, set: sets.pastelSkins}, - 'pastelPurple': {price: 2, set: sets.pastelSkins}, - 'pastelRainbowChevron': {price: 2, set: sets.pastelSkins}, - 'pastelRainbowDiagonal': {price: 2, set: sets.pastelSkins}, + 'pastelPink': { price: 2, set: sets.pastelSkins }, + 'pastelOrange': { price: 2, set: sets.pastelSkins }, + 'pastelYellow': { price: 2, set: sets.pastelSkins }, + 'pastelGreen': { price: 2, set: sets.pastelSkins }, + 'pastelBlue': { price: 2, set: sets.pastelSkins }, + 'pastelPurple': { price: 2, set: sets.pastelSkins }, + 'pastelRainbowChevron': { price: 2, set: sets.pastelSkins }, + 'pastelRainbowDiagonal': { price: 2, set: sets.pastelSkins }, - 'monster': {price: 2, set: sets.spookySkins}, - 'pumpkin': {price: 2, set: sets.spookySkins}, - 'skeleton': {price: 2, set: sets.spookySkins}, - 'zombie': {price: 2, set: sets.spookySkins}, - 'ghost': {price: 2, set: sets.spookySkins}, - 'shadow': {price: 2, set: sets.spookySkins}, + 'monster': { price: 2, set: sets.spookySkins }, + 'pumpkin': { price: 2, set: sets.spookySkins }, + 'skeleton': { price: 2, set: sets.spookySkins }, + 'zombie': { price: 2, set: sets.spookySkins }, + 'ghost': { price: 2, set: sets.spookySkins }, + 'shadow': { price: 2, set: sets.spookySkins }, - 'candycorn': {price: 2, set: sets.supernaturalSkins}, - 'ogre': {price: 2, set: sets.supernaturalSkins}, - 'pumpkin2': {price: 2, set: sets.supernaturalSkins}, - 'reptile': {price: 2, set: sets.supernaturalSkins}, - 'shadow2': {price: 2, set: sets.supernaturalSkins}, - 'skeleton2': {price: 2, set: sets.supernaturalSkins}, - 'transparent': {price: 2, set: sets.supernaturalSkins}, - 'zombie2': {price: 2, set: sets.supernaturalSkins}, + 'candycorn': { price: 2, set: sets.supernaturalSkins }, + 'ogre': { price: 2, set: sets.supernaturalSkins }, + 'pumpkin2': { price: 2, set: sets.supernaturalSkins }, + 'reptile': { price: 2, set: sets.supernaturalSkins }, + 'shadow2': { price: 2, set: sets.supernaturalSkins }, + 'skeleton2': { price: 2, set: sets.supernaturalSkins }, + 'transparent': { price: 2, set: sets.supernaturalSkins }, + 'zombie2': { price: 2, set: sets.supernaturalSkins }, - 'clownfish': {price: 2, set: sets.splashySkins}, - 'deepocean': {price: 2, set: sets.splashySkins}, - 'merblue': {price: 2, set: sets.splashySkins}, - 'mergold': {price: 2, set: sets.splashySkins}, - 'mergreen': {price: 2, set: sets.splashySkins}, - 'merruby': {price: 2, set: sets.splashySkins}, - 'shark': {price: 2, set: sets.splashySkins}, - 'tropicalwater': {price: 2, set: sets.splashySkins}, + 'clownfish': { price: 2, set: sets.splashySkins }, + 'deepocean': { price: 2, set: sets.splashySkins }, + 'merblue': { price: 2, set: sets.splashySkins }, + 'mergold': { price: 2, set: sets.splashySkins }, + 'mergreen': { price: 2, set: sets.splashySkins }, + 'merruby': { price: 2, set: sets.splashySkins }, + 'shark': { price: 2, set: sets.splashySkins }, + 'tropicalwater': { price: 2, set: sets.splashySkins }, - 'aurora': {price: 2, set: sets.winterySkins}, - 'dapper': {price: 2, set: sets.winterySkins}, - 'festive': {price: 2, set: sets.winterySkins}, - 'holly': {price: 2, set: sets.winterySkins}, - 'polar': {price: 2, set: sets.winterySkins}, - 'sugar': {price: 2, set: sets.winterySkins}, - 'snowy': {price: 2, set: sets.winterySkins}, - 'winterstar': {price: 2, set: sets.winterySkins}, + 'aurora': { price: 2, set: sets.winterySkins }, + 'dapper': { price: 2, set: sets.winterySkins }, + 'festive': { price: 2, set: sets.winterySkins }, + 'holly': { price: 2, set: sets.winterySkins }, + 'polar': { price: 2, set: sets.winterySkins }, + 'sugar': { price: 2, set: sets.winterySkins }, + 'snowy': { price: 2, set: sets.winterySkins }, + 'winterstar': { price: 2, set: sets.winterySkins }, /* eslint-enable quote-props */ }); diff --git a/website/common/script/content/constants.js b/website/common/script/content/constants.js index 5cc052e1b7..5ea01a931d 100644 --- a/website/common/script/content/constants.js +++ b/website/common/script/content/constants.js @@ -203,19 +203,19 @@ export const GEAR_TYPES = [ ]; export const ITEM_LIST = { - weapon: { localeKey: 'weapon', isEquipment: true }, - armor: { localeKey: 'armor', isEquipment: true }, - head: { localeKey: 'headgear', isEquipment: true }, - shield: { localeKey: 'offhand', isEquipment: true }, - back: { localeKey: 'back', isEquipment: true }, - body: { localeKey: 'body', isEquipment: true }, - headAccessory: { localeKey: 'headAccessory', isEquipment: true }, - eyewear: { localeKey: 'eyewear', isEquipment: true }, + weapon: { localeKey: 'weapon', isEquipment: true }, + armor: { localeKey: 'armor', isEquipment: true }, + head: { localeKey: 'headgear', isEquipment: true }, + shield: { localeKey: 'offhand', isEquipment: true }, + back: { localeKey: 'back', isEquipment: true }, + body: { localeKey: 'body', isEquipment: true }, + headAccessory: { localeKey: 'headAccessory', isEquipment: true }, + eyewear: { localeKey: 'eyewear', isEquipment: true }, hatchingPotions: { localeKey: 'hatchingPotion', isEquipment: false }, premiumHatchingPotions: { localeKey: 'hatchingPotion', isEquipment: false }, - eggs: { localeKey: 'eggSingular', isEquipment: false }, - quests: { localeKey: 'quest', isEquipment: false }, - food: { localeKey: 'foodTextThe', isEquipment: false }, + eggs: { localeKey: 'eggSingular', isEquipment: false }, + quests: { localeKey: 'quest', isEquipment: false }, + food: { localeKey: 'foodTextThe', isEquipment: false }, Saddle: { localeKey: 'foodSaddleText', isEquipment: false }, bundles: { localeKey: 'discountBundle', isEquipment: false }, }; @@ -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', + }, ]; diff --git a/website/common/script/content/eggs.js b/website/common/script/content/eggs.js index 9b0820b8e1..77ddd4a209 100644 --- a/website/common/script/content/eggs.js +++ b/website/common/script/content/eggs.js @@ -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, diff --git a/website/common/script/content/faq.js b/website/common/script/content/faq.js index c1cb26bd2c..d63954e2d3 100644 --- a/website/common/script/content/faq.js +++ b/website/common/script/content/faq.js @@ -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}`), diff --git a/website/common/script/content/gear/armor.js b/website/common/script/content/gear/armor.js index 53a0a1c7bc..a090c56364 100644 --- a/website/common/script/content/gear/armor.js +++ b/website/common/script/content/gear/armor.js @@ -1,15 +1,15 @@ -import {armor as baseArmor} from './sets/base'; +import { armor as baseArmor } from './sets/base'; -import {armor as warriorArmor} from './sets/warrior'; -import {armor as rogueArmor} from './sets/rogue'; -import {armor as healerArmor} from './sets/healer'; -import {armor as wizardArmor} from './sets/wizard'; +import { armor as warriorArmor } from './sets/warrior'; +import { armor as rogueArmor } from './sets/rogue'; +import { armor as healerArmor } from './sets/healer'; +import { armor as wizardArmor } from './sets/wizard'; -import {armor as specialArmor} from './sets/special'; -import {armor as mysteryArmor} from './sets/mystery'; -import {armor as armoireArmor} from './sets/armoire'; +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, diff --git a/website/common/script/content/gear/back.js b/website/common/script/content/gear/back.js index 7e0e6cf1bd..0cfe855b70 100644 --- a/website/common/script/content/gear/back.js +++ b/website/common/script/content/gear/back.js @@ -1,13 +1,12 @@ -import {back as baseBack} from './sets/base'; +import { back as baseBack } from './sets/base'; -import {back as mysteryBack} from './sets/mystery'; -import {back as specialBack} from './sets/special'; +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; - diff --git a/website/common/script/content/gear/body.js b/website/common/script/content/gear/body.js index b0ce7eff0a..19349eb2a2 100644 --- a/website/common/script/content/gear/body.js +++ b/website/common/script/content/gear/body.js @@ -1,10 +1,10 @@ -import {body as baseBody} from './sets/base'; +import { body as baseBody } from './sets/base'; -import {body as mysteryBody} from './sets/mystery'; -import {body as specialBody} from './sets/special'; -import {body as armoireBody} from './sets/armoire'; +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, diff --git a/website/common/script/content/gear/eyewear.js b/website/common/script/content/gear/eyewear.js index 073b12ca41..2fdf54e079 100644 --- a/website/common/script/content/gear/eyewear.js +++ b/website/common/script/content/gear/eyewear.js @@ -1,10 +1,10 @@ -import {eyewear as baseEyewear} from './sets/base'; +import { eyewear as baseEyewear } from './sets/base'; -import {eyewear as armoireEyewear} from './sets/armoire'; -import {eyewear as mysteryEyewear} from './sets/mystery'; -import {eyewear as specialEyewear} from './sets/special'; +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, diff --git a/website/common/script/content/gear/gear-helper.js b/website/common/script/content/gear/gear-helper.js index 5319e1eed6..8acfad9297 100644 --- a/website/common/script/content/gear/gear-helper.js +++ b/website/common/script/content/gear/gear-helper.js @@ -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]); } diff --git a/website/common/script/content/gear/head-accessory.js b/website/common/script/content/gear/head-accessory.js index c820a95e9d..146c0e77b8 100644 --- a/website/common/script/content/gear/head-accessory.js +++ b/website/common/script/content/gear/head-accessory.js @@ -1,10 +1,10 @@ -import {headAccessory as baseHeadAccessory} from './sets/base'; +import { headAccessory as baseHeadAccessory } from './sets/base'; -import {headAccessory as specialHeadAccessory} from './sets/special'; -import {headAccessory as mysteryHeadAccessory} from './sets/mystery'; -import {headAccessory as armoireHeadAccessory} from './sets/armoire'; +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; - diff --git a/website/common/script/content/gear/head.js b/website/common/script/content/gear/head.js index a5b550f8cc..6eee326efb 100644 --- a/website/common/script/content/gear/head.js +++ b/website/common/script/content/gear/head.js @@ -1,15 +1,15 @@ -import {head as baseHead} from './sets/base'; +import { head as baseHead } from './sets/base'; -import {head as healerHead} from './sets/healer'; -import {head as rogueHead} from './sets/rogue'; -import {head as warriorHead} from './sets/warrior'; -import {head as wizardHead} from './sets/wizard'; +import { head as healerHead } from './sets/healer'; +import { head as rogueHead } from './sets/rogue'; +import { head as warriorHead } from './sets/warrior'; +import { head as wizardHead } from './sets/wizard'; -import {head as armoireHead} from './sets/armoire'; -import {head as mysteryHead} from './sets/mystery'; -import {head as specialHead} from './sets/special'; +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, diff --git a/website/common/script/content/gear/index.js b/website/common/script/content/gear/index.js index dc4c0e9f6a..2dc039b1c2 100644 --- a/website/common/script/content/gear/index.js +++ b/website/common/script/content/gear/index.js @@ -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; }; diff --git a/website/common/script/content/gear/sets/armoire.js b/website/common/script/content/gear/sets/armoire.js index 31c735f731..a6c761c711 100644 --- a/website/common/script/content/gear/sets/armoire.js +++ b/website/common/script/content/gear/sets/armoire.js @@ -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 }), @@ -1755,4 +1755,4 @@ export { headAccessory, shield, weapon, -}; \ No newline at end of file +}; diff --git a/website/common/script/content/gear/sets/base.js b/website/common/script/content/gear/sets/base.js index a041667df1..f87562012a 100644 --- a/website/common/script/content/gear/sets/base.js +++ b/website/common/script/content/gear/sets/base.js @@ -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'), @@ -75,4 +75,4 @@ export { headAccessory, shield, weapon, -}; \ No newline at end of file +}; diff --git a/website/common/script/content/gear/sets/healer.js b/website/common/script/content/gear/sets/healer.js index 7eeda40422..04af4c2855 100644 --- a/website/common/script/content/gear/sets/healer.js +++ b/website/common/script/content/gear/sets/healer.js @@ -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'), @@ -153,4 +153,4 @@ export { head, shield, weapon, -}; \ No newline at end of file +}; diff --git a/website/common/script/content/gear/sets/mystery.js b/website/common/script/content/gear/sets/mystery.js index 38ee8696fe..5833564e2f 100644 --- a/website/common/script/content/gear/sets/mystery.js +++ b/website/common/script/content/gear/sets/mystery.js @@ -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'), @@ -951,4 +951,4 @@ export { headAccessory, shield, weapon, -}; \ No newline at end of file +}; diff --git a/website/common/script/content/gear/sets/rogue.js b/website/common/script/content/gear/sets/rogue.js index efb070467e..9c8c45a607 100644 --- a/website/common/script/content/gear/sets/rogue.js +++ b/website/common/script/content/gear/sets/rogue.js @@ -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'), @@ -165,4 +165,4 @@ export { head, shield, weapon, -}; \ No newline at end of file +}; diff --git a/website/common/script/content/gear/sets/special/index.js b/website/common/script/content/gear/sets/special/index.js index 9651f39766..e505116e53 100644 --- a/website/common/script/content/gear/sets/special/index.js +++ b/website/common/script/content/gear/sets/special/index.js @@ -10,7 +10,7 @@ import t from '../../../translation'; const CURRENT_SEASON = 'fall'; -let armor = { +const armor = { 0: backerGear.armorSpecial0, 1: contributorGear.armorSpecial1, 2: backerGear.armorSpecial2, @@ -114,9 +114,7 @@ let armor = { notes: t('armorSpecialYetiNotes', { con: 9 }), con: 9, value: 90, - canBuy: () => { - return CURRENT_SEASON === 'winter'; - }, + canBuy: () => CURRENT_SEASON === 'winter', }, ski: { event: EVENTS.winter, @@ -126,9 +124,7 @@ let armor = { notes: t('armorSpecialSkiNotes', { per: 15 }), per: 15, value: 90, - canBuy: () => { - return CURRENT_SEASON === 'winter'; - }, + canBuy: () => CURRENT_SEASON === 'winter', }, candycane: { event: EVENTS.winter, @@ -138,9 +134,7 @@ let armor = { notes: t('armorSpecialCandycaneNotes', { int: 9 }), int: 9, value: 90, - canBuy: () => { - return CURRENT_SEASON === 'winter'; - }, + canBuy: () => CURRENT_SEASON === 'winter', }, snowflake: { event: EVENTS.winter, @@ -150,14 +144,13 @@ let armor = { notes: t('armorSpecialSnowflakeNotes', { con: 15 }), con: 15, value: 90, - canBuy: () => { - return CURRENT_SEASON === 'winter'; - }, + canBuy: () => CURRENT_SEASON === 'winter', }, birthday: { event: EVENTS.birthday, text: t('armorSpecialBirthdayText'), - notes: t('armorSpecialBirthdayNotes'), value: 0, + notes: t('armorSpecialBirthdayNotes'), + value: 0, }, springRogue: { event: EVENTS.spring, @@ -167,9 +160,7 @@ let armor = { notes: t('armorSpecialSpringRogueNotes', { per: 15 }), value: 90, per: 15, - canBuy: () => { - return CURRENT_SEASON === 'spring'; - }, + canBuy: () => CURRENT_SEASON === 'spring', }, springWarrior: { event: EVENTS.spring, @@ -179,9 +170,7 @@ let armor = { notes: t('armorSpecialSpringWarriorNotes', { con: 9 }), value: 90, con: 9, - canBuy: () => { - return CURRENT_SEASON === 'spring'; - }, + canBuy: () => CURRENT_SEASON === 'spring', }, springMage: { event: EVENTS.spring, @@ -191,9 +180,7 @@ let armor = { notes: t('armorSpecialSpringMageNotes', { int: 9 }), value: 90, int: 9, - canBuy: () => { - return CURRENT_SEASON === 'spring'; - }, + canBuy: () => CURRENT_SEASON === 'spring', }, springHealer: { event: EVENTS.spring, @@ -203,9 +190,7 @@ let armor = { notes: t('armorSpecialSpringHealerNotes', { con: 15 }), value: 90, con: 15, - canBuy: () => { - return CURRENT_SEASON === 'spring'; - }, + canBuy: () => CURRENT_SEASON === 'spring', }, summerRogue: { event: EVENTS.summer, @@ -215,9 +200,7 @@ let armor = { notes: t('armorSpecialSummerRogueNotes', { per: 15 }), value: 90, per: 15, - canBuy: () => { - return CURRENT_SEASON === 'summer'; - }, + canBuy: () => CURRENT_SEASON === 'summer', }, summerWarrior: { event: EVENTS.summer, @@ -227,9 +210,7 @@ let armor = { notes: t('armorSpecialSummerWarriorNotes', { con: 9 }), value: 90, con: 9, - canBuy: () => { - return CURRENT_SEASON === 'summer'; - }, + canBuy: () => CURRENT_SEASON === 'summer', }, summerMage: { event: EVENTS.summer, @@ -239,9 +220,7 @@ let armor = { notes: t('armorSpecialSummerMageNotes', { int: 9 }), value: 90, int: 9, - canBuy: () => { - return CURRENT_SEASON === 'summer'; - }, + canBuy: () => CURRENT_SEASON === 'summer', }, summerHealer: { event: EVENTS.summer, @@ -251,9 +230,7 @@ let armor = { notes: t('armorSpecialSummerHealerNotes', { con: 15 }), value: 90, con: 15, - canBuy: () => { - return CURRENT_SEASON === 'summer'; - }, + canBuy: () => CURRENT_SEASON === 'summer', }, fallRogue: { event: EVENTS.fall, @@ -263,9 +240,7 @@ let armor = { notes: t('armorSpecialFallRogueNotes', { per: 15 }), value: 90, per: 15, - canBuy: () => { - return CURRENT_SEASON === 'fall'; - }, + canBuy: () => CURRENT_SEASON === 'fall', }, fallWarrior: { event: EVENTS.fall, @@ -275,9 +250,7 @@ let armor = { notes: t('armorSpecialFallWarriorNotes', { con: 9 }), value: 90, con: 9, - canBuy: () => { - return CURRENT_SEASON === 'fall'; - }, + canBuy: () => CURRENT_SEASON === 'fall', }, fallMage: { event: EVENTS.fall, @@ -287,9 +260,7 @@ let armor = { notes: t('armorSpecialFallMageNotes', { int: 9 }), value: 90, int: 9, - canBuy: () => { - return CURRENT_SEASON === 'fall'; - }, + canBuy: () => CURRENT_SEASON === 'fall', }, fallHealer: { event: EVENTS.fall, @@ -299,9 +270,7 @@ let armor = { notes: t('armorSpecialFallHealerNotes', { con: 15 }), value: 90, con: 15, - canBuy: () => { - return CURRENT_SEASON === 'fall'; - }, + canBuy: () => CURRENT_SEASON === 'fall', }, winter2015Rogue: { event: EVENTS.winter2015, @@ -311,9 +280,7 @@ let armor = { notes: t('armorSpecialWinter2015RogueNotes', { per: 15 }), value: 90, per: 15, - canBuy: () => { - return CURRENT_SEASON === 'winter'; - }, + canBuy: () => CURRENT_SEASON === 'winter', }, winter2015Warrior: { event: EVENTS.winter2015, @@ -323,9 +290,7 @@ let armor = { notes: t('armorSpecialWinter2015WarriorNotes', { con: 9 }), value: 90, con: 9, - canBuy: () => { - return CURRENT_SEASON === 'winter'; - }, + canBuy: () => CURRENT_SEASON === 'winter', }, winter2015Mage: { event: EVENTS.winter2015, @@ -335,9 +300,7 @@ let armor = { notes: t('armorSpecialWinter2015MageNotes', { int: 9 }), value: 90, int: 9, - canBuy: () => { - return CURRENT_SEASON === 'winter'; - }, + canBuy: () => CURRENT_SEASON === 'winter', }, winter2015Healer: { event: EVENTS.winter2015, @@ -347,9 +310,7 @@ let armor = { notes: t('armorSpecialWinter2015HealerNotes', { con: 15 }), value: 90, con: 15, - canBuy: () => { - return CURRENT_SEASON === 'winter'; - }, + canBuy: () => CURRENT_SEASON === 'winter', }, birthday2015: { text: t('armorSpecialBirthday2015Text'), @@ -365,9 +326,7 @@ let armor = { notes: t('armorSpecialSpring2015RogueNotes', { per: 15 }), value: 90, per: 15, - canBuy: () => { - return CURRENT_SEASON === 'spring'; - }, + canBuy: () => CURRENT_SEASON === 'spring', }, spring2015Warrior: { event: EVENTS.spring2015, @@ -377,9 +336,7 @@ let armor = { notes: t('armorSpecialSpring2015WarriorNotes', { con: 9 }), value: 90, con: 9, - canBuy: () => { - return CURRENT_SEASON === 'spring'; - }, + canBuy: () => CURRENT_SEASON === 'spring', }, spring2015Mage: { event: EVENTS.spring2015, @@ -389,9 +346,7 @@ let armor = { notes: t('armorSpecialSpring2015MageNotes', { int: 9 }), value: 90, int: 9, - canBuy: () => { - return CURRENT_SEASON === 'spring'; - }, + canBuy: () => CURRENT_SEASON === 'spring', }, spring2015Healer: { event: EVENTS.spring2015, @@ -401,9 +356,7 @@ let armor = { notes: t('armorSpecialSpring2015HealerNotes', { con: 15 }), value: 90, con: 15, - canBuy: () => { - return CURRENT_SEASON === 'spring'; - }, + canBuy: () => CURRENT_SEASON === 'spring', }, summer2015Rogue: { event: EVENTS.summer2015, @@ -413,9 +366,7 @@ let armor = { notes: t('armorSpecialSummer2015RogueNotes', { per: 15 }), value: 90, per: 15, - canBuy: () => { - return CURRENT_SEASON === 'summer'; - }, + canBuy: () => CURRENT_SEASON === 'summer', }, summer2015Warrior: { event: EVENTS.summer2015, @@ -425,9 +376,7 @@ let armor = { notes: t('armorSpecialSummer2015WarriorNotes', { con: 9 }), value: 90, con: 9, - canBuy: () => { - return CURRENT_SEASON === 'summer'; - }, + canBuy: () => CURRENT_SEASON === 'summer', }, summer2015Mage: { event: EVENTS.summer2015, @@ -437,9 +386,7 @@ let armor = { notes: t('armorSpecialSummer2015MageNotes', { int: 9 }), value: 90, int: 9, - canBuy: () => { - return CURRENT_SEASON === 'summer'; - }, + canBuy: () => CURRENT_SEASON === 'summer', }, summer2015Healer: { event: EVENTS.summer2015, @@ -449,9 +396,7 @@ let armor = { notes: t('armorSpecialSummer2015HealerNotes', { con: 15 }), value: 90, con: 15, - canBuy: () => { - return CURRENT_SEASON === 'summer'; - }, + canBuy: () => CURRENT_SEASON === 'summer', }, fall2015Rogue: { event: EVENTS.fall2015, @@ -461,9 +406,7 @@ let armor = { notes: t('armorSpecialFall2015RogueNotes', { per: 15 }), value: 90, per: 15, - canBuy: () => { - return CURRENT_SEASON === 'fall'; - }, + canBuy: () => CURRENT_SEASON === 'fall', }, fall2015Warrior: { event: EVENTS.fall2015, @@ -473,9 +416,7 @@ let armor = { notes: t('armorSpecialFall2015WarriorNotes', { con: 9 }), value: 90, con: 9, - canBuy: () => { - return CURRENT_SEASON === 'fall'; - }, + canBuy: () => CURRENT_SEASON === 'fall', }, fall2015Mage: { event: EVENTS.fall2015, @@ -485,9 +426,7 @@ let armor = { notes: t('armorSpecialFall2015MageNotes', { int: 9 }), value: 90, int: 9, - canBuy: () => { - return CURRENT_SEASON === 'fall'; - }, + canBuy: () => CURRENT_SEASON === 'fall', }, fall2015Healer: { event: EVENTS.fall2015, @@ -497,9 +436,7 @@ let armor = { notes: t('armorSpecialFall2015HealerNotes', { con: 15 }), value: 90, con: 15, - canBuy: () => { - return CURRENT_SEASON === 'fall'; - }, + canBuy: () => CURRENT_SEASON === 'fall', }, gaymerx: { event: EVENTS.gaymerx, @@ -515,9 +452,7 @@ let armor = { notes: t('armorSpecialWinter2016RogueNotes', { per: 15 }), value: 90, per: 15, - canBuy: () => { - return CURRENT_SEASON === 'winter'; - }, + canBuy: () => CURRENT_SEASON === 'winter', }, winter2016Warrior: { event: EVENTS.winter2016, @@ -527,9 +462,7 @@ let armor = { notes: t('armorSpecialWinter2016WarriorNotes', { con: 9 }), value: 90, con: 9, - canBuy: () => { - return CURRENT_SEASON === 'winter'; - }, + canBuy: () => CURRENT_SEASON === 'winter', }, winter2016Mage: { event: EVENTS.winter2016, @@ -539,9 +472,7 @@ let armor = { notes: t('armorSpecialWinter2016MageNotes', { int: 9 }), value: 90, int: 9, - canBuy: () => { - return CURRENT_SEASON === 'winter'; - }, + canBuy: () => CURRENT_SEASON === 'winter', }, winter2016Healer: { event: EVENTS.winter2016, @@ -551,9 +482,7 @@ let armor = { notes: t('armorSpecialWinter2016HealerNotes', { con: 15 }), value: 90, con: 15, - canBuy: () => { - return CURRENT_SEASON === 'winter'; - }, + canBuy: () => CURRENT_SEASON === 'winter', }, birthday2016: { text: t('armorSpecialBirthday2016Text'), @@ -569,9 +498,7 @@ let armor = { notes: t('armorSpecialSpring2016RogueNotes', { per: 15 }), value: 90, per: 15, - canBuy: () => { - return CURRENT_SEASON === 'spring'; - }, + canBuy: () => CURRENT_SEASON === 'spring', }, spring2016Warrior: { event: EVENTS.spring2016, @@ -581,9 +508,7 @@ let armor = { notes: t('armorSpecialSpring2016WarriorNotes', { con: 9 }), value: 90, con: 9, - canBuy: () => { - return CURRENT_SEASON === 'spring'; - }, + canBuy: () => CURRENT_SEASON === 'spring', }, spring2016Mage: { event: EVENTS.spring2016, @@ -593,9 +518,7 @@ let armor = { notes: t('armorSpecialSpring2016MageNotes', { int: 9 }), value: 90, int: 9, - canBuy: () => { - return CURRENT_SEASON === 'spring'; - }, + canBuy: () => CURRENT_SEASON === 'spring', }, spring2016Healer: { event: EVENTS.spring2016, @@ -605,9 +528,7 @@ let armor = { notes: t('armorSpecialSpring2016HealerNotes', { con: 15 }), value: 90, con: 15, - canBuy: () => { - return CURRENT_SEASON === 'spring'; - }, + canBuy: () => CURRENT_SEASON === 'spring', }, summer2016Rogue: { event: EVENTS.summer2016, @@ -617,9 +538,7 @@ let armor = { notes: t('armorSpecialSummer2016RogueNotes', { per: 15 }), value: 90, per: 15, - canBuy: () => { - return CURRENT_SEASON === 'summer'; - }, + canBuy: () => CURRENT_SEASON === 'summer', }, summer2016Warrior: { event: EVENTS.summer2016, @@ -629,9 +548,7 @@ let armor = { notes: t('armorSpecialSummer2016WarriorNotes', { con: 9 }), value: 90, con: 9, - canBuy: () => { - return CURRENT_SEASON === 'summer'; - }, + canBuy: () => CURRENT_SEASON === 'summer', }, summer2016Mage: { event: EVENTS.summer2016, @@ -641,9 +558,7 @@ let armor = { notes: t('armorSpecialSummer2016MageNotes', { int: 9 }), value: 90, int: 9, - canBuy: () => { - return CURRENT_SEASON === 'summer'; - }, + canBuy: () => CURRENT_SEASON === 'summer', }, summer2016Healer: { event: EVENTS.summer2016, @@ -653,9 +568,7 @@ let armor = { notes: t('armorSpecialSummer2016HealerNotes', { con: 15 }), value: 90, con: 15, - canBuy: () => { - return CURRENT_SEASON === 'summer'; - }, + canBuy: () => CURRENT_SEASON === 'summer', }, fall2016Rogue: { event: EVENTS.fall2016, @@ -665,9 +578,7 @@ let armor = { notes: t('armorSpecialFall2016RogueNotes', { per: 15 }), value: 90, per: 15, - canBuy: () => { - return CURRENT_SEASON === 'fall'; - }, + canBuy: () => CURRENT_SEASON === 'fall', }, fall2016Warrior: { event: EVENTS.fall2016, @@ -677,9 +588,7 @@ let armor = { notes: t('armorSpecialFall2016WarriorNotes', { con: 9 }), value: 90, con: 9, - canBuy: () => { - return CURRENT_SEASON === 'fall'; - }, + canBuy: () => CURRENT_SEASON === 'fall', }, fall2016Mage: { event: EVENTS.fall2016, @@ -689,9 +598,7 @@ let armor = { notes: t('armorSpecialFall2016MageNotes', { int: 9 }), value: 90, int: 9, - canBuy: () => { - return CURRENT_SEASON === 'fall'; - }, + canBuy: () => CURRENT_SEASON === 'fall', }, fall2016Healer: { event: EVENTS.fall2016, @@ -701,9 +608,7 @@ let armor = { notes: t('armorSpecialFall2016HealerNotes', { con: 15 }), value: 90, con: 15, - canBuy: () => { - return CURRENT_SEASON === 'fall'; - }, + canBuy: () => CURRENT_SEASON === 'fall', }, winter2017Rogue: { event: EVENTS.winter2017, @@ -713,9 +618,7 @@ let armor = { notes: t('armorSpecialWinter2017RogueNotes', { per: 15 }), value: 90, per: 15, - canBuy: () => { - return CURRENT_SEASON === 'winter'; - }, + canBuy: () => CURRENT_SEASON === 'winter', }, winter2017Warrior: { event: EVENTS.winter2017, @@ -725,9 +628,7 @@ let armor = { notes: t('armorSpecialWinter2017WarriorNotes', { con: 9 }), value: 90, con: 9, - canBuy: () => { - return CURRENT_SEASON === 'winter'; - }, + canBuy: () => CURRENT_SEASON === 'winter', }, winter2017Mage: { event: EVENTS.winter2017, @@ -737,9 +638,7 @@ let armor = { notes: t('armorSpecialWinter2017MageNotes', { int: 9 }), value: 90, int: 9, - canBuy: () => { - return CURRENT_SEASON === 'winter'; - }, + canBuy: () => CURRENT_SEASON === 'winter', }, winter2017Healer: { event: EVENTS.winter2017, @@ -749,9 +648,7 @@ let armor = { notes: t('armorSpecialWinter2017HealerNotes', { con: 15 }), value: 90, con: 15, - canBuy: () => { - return CURRENT_SEASON === 'winter'; - }, + canBuy: () => CURRENT_SEASON === 'winter', }, birthday2017: { text: t('armorSpecialBirthday2017Text'), @@ -767,9 +664,7 @@ let armor = { notes: t('armorSpecialSpring2017RogueNotes', { per: 15 }), value: 90, per: 15, - canBuy: () => { - return CURRENT_SEASON === 'spring'; - }, + canBuy: () => CURRENT_SEASON === 'spring', }, spring2017Warrior: { event: EVENTS.spring2017, @@ -779,9 +674,7 @@ let armor = { notes: t('armorSpecialSpring2017WarriorNotes', { con: 9 }), value: 90, con: 9, - canBuy: () => { - return CURRENT_SEASON === 'spring'; - }, + canBuy: () => CURRENT_SEASON === 'spring', }, spring2017Mage: { event: EVENTS.spring2017, @@ -791,9 +684,7 @@ let armor = { notes: t('armorSpecialSpring2017MageNotes', { int: 9 }), value: 90, int: 9, - canBuy: () => { - return CURRENT_SEASON === 'spring'; - }, + canBuy: () => CURRENT_SEASON === 'spring', }, spring2017Healer: { event: EVENTS.spring2017, @@ -803,9 +694,7 @@ let armor = { notes: t('armorSpecialSpring2017HealerNotes', { con: 15 }), value: 90, con: 15, - canBuy: () => { - return CURRENT_SEASON === 'spring'; - }, + canBuy: () => CURRENT_SEASON === 'spring', }, summer2017Rogue: { event: EVENTS.summer2017, @@ -815,9 +704,7 @@ let armor = { notes: t('armorSpecialSummer2017RogueNotes', { per: 15 }), value: 90, per: 15, - canBuy: () => { - return CURRENT_SEASON === 'summer'; - }, + canBuy: () => CURRENT_SEASON === 'summer', }, summer2017Warrior: { event: EVENTS.summer2017, @@ -827,9 +714,7 @@ let armor = { notes: t('armorSpecialSummer2017WarriorNotes', { con: 9 }), value: 90, con: 9, - canBuy: () => { - return CURRENT_SEASON === 'summer'; - }, + canBuy: () => CURRENT_SEASON === 'summer', }, summer2017Mage: { event: EVENTS.summer2017, @@ -839,9 +724,7 @@ let armor = { notes: t('armorSpecialSummer2017MageNotes', { int: 9 }), value: 90, int: 9, - canBuy: () => { - return CURRENT_SEASON === 'summer'; - }, + canBuy: () => CURRENT_SEASON === 'summer', }, summer2017Healer: { event: EVENTS.summer2017, @@ -851,9 +734,7 @@ let armor = { notes: t('armorSpecialSummer2017HealerNotes', { con: 15 }), value: 90, con: 15, - canBuy: () => { - return CURRENT_SEASON === 'summer'; - }, + canBuy: () => CURRENT_SEASON === 'summer', }, fall2017Rogue: { event: EVENTS.fall2017, @@ -863,9 +744,7 @@ let armor = { notes: t('armorSpecialFall2017RogueNotes', { per: 15 }), value: 90, per: 15, - canBuy: () => { - return CURRENT_SEASON === 'fall'; - }, + canBuy: () => CURRENT_SEASON === 'fall', }, fall2017Warrior: { event: EVENTS.fall2017, @@ -875,9 +754,7 @@ let armor = { notes: t('armorSpecialFall2017WarriorNotes', { con: 9 }), value: 90, con: 9, - canBuy: () => { - return CURRENT_SEASON === 'fall'; - }, + canBuy: () => CURRENT_SEASON === 'fall', }, fall2017Mage: { event: EVENTS.fall2017, @@ -887,9 +764,7 @@ let armor = { notes: t('armorSpecialFall2017MageNotes', { int: 9 }), value: 90, int: 9, - canBuy: () => { - return CURRENT_SEASON === 'fall'; - }, + canBuy: () => CURRENT_SEASON === 'fall', }, fall2017Healer: { event: EVENTS.fall2017, @@ -899,9 +774,7 @@ let armor = { notes: t('armorSpecialFall2017HealerNotes', { con: 15 }), value: 90, con: 15, - canBuy: () => { - return CURRENT_SEASON === 'fall'; - }, + canBuy: () => CURRENT_SEASON === 'fall', }, winter2018Rogue: { event: EVENTS.winter2018, @@ -911,9 +784,7 @@ let armor = { notes: t('armorSpecialWinter2018RogueNotes', { per: 15 }), value: 90, per: 15, - canBuy: () => { - return CURRENT_SEASON === 'winter'; - }, + canBuy: () => CURRENT_SEASON === 'winter', }, winter2018Warrior: { event: EVENTS.winter2018, @@ -923,9 +794,7 @@ let armor = { notes: t('armorSpecialWinter2018WarriorNotes', { con: 9 }), value: 90, con: 9, - canBuy: () => { - return CURRENT_SEASON === 'winter'; - }, + canBuy: () => CURRENT_SEASON === 'winter', }, winter2018Mage: { event: EVENTS.winter2018, @@ -935,9 +804,7 @@ let armor = { notes: t('armorSpecialWinter2018MageNotes', { int: 9 }), value: 90, int: 9, - canBuy: () => { - return CURRENT_SEASON === 'winter'; - }, + canBuy: () => CURRENT_SEASON === 'winter', }, winter2018Healer: { event: EVENTS.winter2018, @@ -947,9 +814,7 @@ let armor = { notes: t('armorSpecialWinter2018HealerNotes', { con: 15 }), value: 90, con: 15, - canBuy: () => { - return CURRENT_SEASON === 'winter'; - }, + canBuy: () => CURRENT_SEASON === 'winter', }, birthday2018: { text: t('armorSpecialBirthday2018Text'), @@ -965,9 +830,7 @@ let armor = { notes: t('armorSpecialSpring2018RogueNotes', { per: 15 }), value: 90, per: 15, - canBuy: () => { - return CURRENT_SEASON === 'spring'; - }, + canBuy: () => CURRENT_SEASON === 'spring', }, spring2018Warrior: { event: EVENTS.spring2018, @@ -977,9 +840,7 @@ let armor = { notes: t('armorSpecialSpring2018WarriorNotes', { con: 9 }), value: 90, con: 9, - canBuy: () => { - return CURRENT_SEASON === 'spring'; - }, + canBuy: () => CURRENT_SEASON === 'spring', }, spring2018Mage: { event: EVENTS.spring2018, @@ -989,9 +850,7 @@ let armor = { notes: t('armorSpecialSpring2018MageNotes', { int: 9 }), value: 90, int: 9, - canBuy: () => { - return CURRENT_SEASON === 'spring'; - }, + canBuy: () => CURRENT_SEASON === 'spring', }, spring2018Healer: { event: EVENTS.spring2018, @@ -1001,9 +860,7 @@ let armor = { notes: t('armorSpecialSpring2018HealerNotes', { con: 15 }), value: 90, con: 15, - canBuy: () => { - return CURRENT_SEASON === 'spring'; - }, + canBuy: () => CURRENT_SEASON === 'spring', }, summer2018Rogue: { event: EVENTS.summer2018, @@ -1013,9 +870,7 @@ let armor = { notes: t('armorSpecialSummer2018RogueNotes', { per: 15 }), value: 90, per: 15, - canBuy: () => { - return CURRENT_SEASON === 'summer'; - }, + canBuy: () => CURRENT_SEASON === 'summer', }, summer2018Warrior: { event: EVENTS.summer2018, @@ -1025,9 +880,7 @@ let armor = { notes: t('armorSpecialSummer2018WarriorNotes', { con: 9 }), value: 90, con: 9, - canBuy: () => { - return CURRENT_SEASON === 'summer'; - }, + canBuy: () => CURRENT_SEASON === 'summer', }, summer2018Mage: { event: EVENTS.summer2018, @@ -1037,9 +890,7 @@ let armor = { notes: t('armorSpecialSummer2018MageNotes', { int: 9 }), value: 90, int: 9, - canBuy: () => { - return CURRENT_SEASON === 'summer'; - }, + canBuy: () => CURRENT_SEASON === 'summer', }, summer2018Healer: { event: EVENTS.summer2018, @@ -1049,9 +900,7 @@ let armor = { notes: t('armorSpecialSummer2018HealerNotes', { con: 15 }), value: 90, con: 15, - canBuy: () => { - return CURRENT_SEASON === 'summer'; - }, + canBuy: () => CURRENT_SEASON === 'summer', }, fall2018Rogue: { event: EVENTS.fall2018, @@ -1061,9 +910,7 @@ let armor = { notes: t('armorSpecialFall2018RogueNotes', { per: 15 }), value: 90, per: 15, - canBuy: () => { - return CURRENT_SEASON === 'fall'; - }, + canBuy: () => CURRENT_SEASON === 'fall', }, fall2018Warrior: { event: EVENTS.fall2018, @@ -1073,9 +920,7 @@ let armor = { notes: t('armorSpecialFall2018WarriorNotes', { con: 9 }), value: 90, con: 9, - canBuy: () => { - return CURRENT_SEASON === 'fall'; - }, + canBuy: () => CURRENT_SEASON === 'fall', }, fall2018Mage: { event: EVENTS.fall2018, @@ -1085,9 +930,7 @@ let armor = { notes: t('armorSpecialFall2018MageNotes', { int: 9 }), value: 90, int: 9, - canBuy: () => { - return CURRENT_SEASON === 'fall'; - }, + canBuy: () => CURRENT_SEASON === 'fall', }, fall2018Healer: { event: EVENTS.fall2018, @@ -1097,9 +940,7 @@ let armor = { notes: t('armorSpecialFall2018HealerNotes', { con: 15 }), value: 90, con: 15, - canBuy: () => { - return CURRENT_SEASON === 'fall'; - }, + canBuy: () => CURRENT_SEASON === 'fall', }, turkeyArmorGilded: { text: t('armorSpecialTurkeyArmorGildedText'), @@ -1266,9 +1107,9 @@ let armor = { }, }; -let back = { - wondercon_red: wonderconGear.backSpecialWonderconRed, // eslint-disable-line camelcase - wondercon_black: wonderconGear.backSpecialWonderconBlack, // eslint-disable-line camelcase +const back = { + wondercon_red: wonderconGear.backSpecialWonderconRed, // eslint-disable-line camelcase + wondercon_black: wonderconGear.backSpecialWonderconBlack, // eslint-disable-line camelcase takeThis: takeThisGear.backSpecialTakeThis, snowdriftVeil: { text: t('backSpecialSnowdriftVeilText'), @@ -1294,9 +1135,7 @@ let back = { notes: t('backBearTailNotes'), value: 20, canOwn: ownsItem('back_special_bearTail'), - canBuy: () => { - return true; - }, + canBuy: () => true, }, cactusTail: { gearSet: 'animal', @@ -1304,9 +1143,7 @@ let back = { notes: t('backCactusTailNotes'), value: 20, canOwn: ownsItem('back_special_cactusTail'), - canBuy: () => { - return true; - }, + canBuy: () => true, }, foxTail: { gearSet: 'animal', @@ -1314,9 +1151,7 @@ let back = { notes: t('backFoxTailNotes'), value: 20, canOwn: ownsItem('back_special_foxTail'), - canBuy: () => { - return true; - }, + canBuy: () => true, }, lionTail: { gearSet: 'animal', @@ -1324,9 +1159,7 @@ let back = { notes: t('backLionTailNotes'), value: 20, canOwn: ownsItem('back_special_lionTail'), - canBuy: () => { - return true; - }, + canBuy: () => true, }, pandaTail: { gearSet: 'animal', @@ -1334,9 +1167,7 @@ let back = { notes: t('backPandaTailNotes'), value: 20, canOwn: ownsItem('back_special_pandaTail'), - canBuy: () => { - return true; - }, + canBuy: () => true, }, pigTail: { gearSet: 'animal', @@ -1344,9 +1175,7 @@ let back = { notes: t('backPigTailNotes'), value: 20, canOwn: ownsItem('back_special_pigTail'), - canBuy: () => { - return true; - }, + canBuy: () => true, }, tigerTail: { gearSet: 'animal', @@ -1354,9 +1183,7 @@ let back = { notes: t('backTigerTailNotes'), value: 20, canOwn: ownsItem('back_special_tigerTail'), - canBuy: () => { - return true; - }, + canBuy: () => true, }, wolfTail: { gearSet: 'animal', @@ -1364,9 +1191,7 @@ let back = { notes: t('backWolfTailNotes'), value: 20, canOwn: ownsItem('back_special_wolfTail'), - canBuy: () => { - return true; - }, + canBuy: () => true, }, turkeyTailGilded: { text: t('backSpecialTurkeyTailGildedText'), @@ -1376,10 +1201,10 @@ let back = { }, }; -let body = { - wondercon_red: wonderconGear.bodySpecialWonderconRed, // eslint-disable-line camelcase - wondercon_gold: wonderconGear.bodySpecialWonderconGold, // eslint-disable-line camelcase - wondercon_black: wonderconGear.bodySpecialWonderconBlack, // eslint-disable-line camelcase +const body = { + wondercon_red: wonderconGear.bodySpecialWonderconRed, // eslint-disable-line camelcase + wondercon_gold: wonderconGear.bodySpecialWonderconGold, // eslint-disable-line camelcase + wondercon_black: wonderconGear.bodySpecialWonderconBlack, // eslint-disable-line camelcase takeThis: takeThisGear.bodySpecialTakeThis, summerHealer: { event: EVENTS.summer, @@ -1388,9 +1213,7 @@ let body = { text: t('bodySpecialSummerHealerText'), notes: t('bodySpecialSummerHealerNotes'), value: 20, - canBuy: () => { - return CURRENT_SEASON === 'summer'; - }, + canBuy: () => CURRENT_SEASON === 'summer', }, summerMage: { event: EVENTS.summer, @@ -1399,9 +1222,7 @@ let body = { text: t('bodySpecialSummerMageText'), notes: t('bodySpecialSummerMageNotes'), value: 20, - canBuy: () => { - return CURRENT_SEASON === 'summer'; - }, + canBuy: () => CURRENT_SEASON === 'summer', }, summer2015Healer: { event: EVENTS.summer2015, @@ -1410,9 +1231,7 @@ let body = { text: t('bodySpecialSummer2015HealerText'), notes: t('bodySpecialSummer2015HealerNotes'), value: 20, - canBuy: () => { - return CURRENT_SEASON === 'summer'; - }, + canBuy: () => CURRENT_SEASON === 'summer', }, summer2015Mage: { event: EVENTS.summer2015, @@ -1421,9 +1240,7 @@ let body = { text: t('bodySpecialSummer2015MageText'), notes: t('bodySpecialSummer2015MageNotes'), value: 20, - canBuy: () => { - return CURRENT_SEASON === 'summer'; - }, + canBuy: () => CURRENT_SEASON === 'summer', }, summer2015Rogue: { event: EVENTS.summer2015, @@ -1432,9 +1249,7 @@ let body = { text: t('bodySpecialSummer2015RogueText'), notes: t('bodySpecialSummer2015RogueNotes'), value: 20, - canBuy: () => { - return CURRENT_SEASON === 'summer'; - }, + canBuy: () => CURRENT_SEASON === 'summer', }, summer2015Warrior: { event: EVENTS.summer2015, @@ -1443,9 +1258,7 @@ let body = { text: t('bodySpecialSummer2015WarriorText'), notes: t('bodySpecialSummer2015WarriorNotes'), value: 20, - canBuy: () => { - return CURRENT_SEASON === 'summer'; - }, + canBuy: () => CURRENT_SEASON === 'summer', }, aetherAmulet: { text: t('bodySpecialAetherAmuletText'), @@ -1463,9 +1276,9 @@ let body = { }, }; -let eyewear = { - wondercon_red: wonderconGear.eyewearSpecialWonderconRed, // eslint-disable-line camelcase - wondercon_black: wonderconGear.eyewearSpecialWonderconBlack, // eslint-disable-line camelcase +const eyewear = { + wondercon_red: wonderconGear.eyewearSpecialWonderconRed, // eslint-disable-line camelcase + wondercon_black: wonderconGear.eyewearSpecialWonderconBlack, // eslint-disable-line camelcase summerRogue: { event: EVENTS.summer, specialClass: 'rogue', @@ -1473,9 +1286,7 @@ let eyewear = { text: t('eyewearSpecialSummerRogueText'), notes: t('eyewearSpecialSummerRogueNotes'), value: 20, - canBuy: () => { - return CURRENT_SEASON === 'summer'; - }, + canBuy: () => CURRENT_SEASON === 'summer', }, summerWarrior: { event: EVENTS.summer, @@ -1484,9 +1295,7 @@ let eyewear = { text: t('eyewearSpecialSummerWarriorText'), notes: t('eyewearSpecialSummerWarriorNotes'), value: 20, - canBuy: () => { - return CURRENT_SEASON === 'summer'; - }, + canBuy: () => CURRENT_SEASON === 'summer', }, blackTopFrame: { gearSet: 'glasses', @@ -1617,7 +1426,7 @@ let eyewear = { }, }; -let head = { +const head = { 0: backerGear.headSpecial0, 1: contributorGear.headSpecial1, 2: backerGear.headSpecial2, @@ -1728,9 +1537,7 @@ let head = { notes: t('headSpecialYetiNotes', { str: 9 }), str: 9, value: 60, - canBuy: () => { - return CURRENT_SEASON === 'winter'; - }, + canBuy: () => CURRENT_SEASON === 'winter', }, ski: { event: EVENTS.winter, @@ -1740,9 +1547,7 @@ let head = { notes: t('headSpecialSkiNotes', { per: 9 }), per: 9, value: 60, - canBuy: () => { - return CURRENT_SEASON === 'winter'; - }, + canBuy: () => CURRENT_SEASON === 'winter', }, candycane: { event: EVENTS.winter, @@ -1752,9 +1557,7 @@ let head = { notes: t('headSpecialCandycaneNotes', { per: 7 }), per: 7, value: 60, - canBuy: () => { - return CURRENT_SEASON === 'winter'; - }, + canBuy: () => CURRENT_SEASON === 'winter', }, snowflake: { event: EVENTS.winter, @@ -1764,9 +1567,7 @@ let head = { notes: t('headSpecialSnowflakeNotes', { int: 7 }), int: 7, value: 60, - canBuy: () => { - return CURRENT_SEASON === 'winter'; - }, + canBuy: () => CURRENT_SEASON === 'winter', }, springRogue: { event: EVENTS.spring, @@ -1776,9 +1577,7 @@ let head = { notes: t('headSpecialSpringRogueNotes', { per: 9 }), value: 60, per: 9, - canBuy: () => { - return CURRENT_SEASON === 'spring'; - }, + canBuy: () => CURRENT_SEASON === 'spring', }, springWarrior: { event: EVENTS.spring, @@ -1788,9 +1587,7 @@ let head = { notes: t('headSpecialSpringWarriorNotes', { str: 9 }), value: 60, str: 9, - canBuy: () => { - return CURRENT_SEASON === 'spring'; - }, + canBuy: () => CURRENT_SEASON === 'spring', }, springMage: { event: EVENTS.spring, @@ -1800,9 +1597,7 @@ let head = { notes: t('headSpecialSpringMageNotes', { per: 7 }), value: 60, per: 7, - canBuy: () => { - return CURRENT_SEASON === 'spring'; - }, + canBuy: () => CURRENT_SEASON === 'spring', }, springHealer: { event: EVENTS.spring, @@ -1812,9 +1607,7 @@ let head = { notes: t('headSpecialSpringHealerNotes', { int: 7 }), value: 60, int: 7, - canBuy: () => { - return CURRENT_SEASON === 'spring'; - }, + canBuy: () => CURRENT_SEASON === 'spring', }, summerRogue: { event: EVENTS.summer, @@ -1824,9 +1617,7 @@ let head = { notes: t('headSpecialSummerRogueNotes', { per: 9 }), value: 60, per: 9, - canBuy: () => { - return CURRENT_SEASON === 'summer'; - }, + canBuy: () => CURRENT_SEASON === 'summer', }, summerWarrior: { event: EVENTS.summer, @@ -1836,9 +1627,7 @@ let head = { notes: t('headSpecialSummerWarriorNotes', { str: 9 }), value: 60, str: 9, - canBuy: () => { - return CURRENT_SEASON === 'summer'; - }, + canBuy: () => CURRENT_SEASON === 'summer', }, summerMage: { event: EVENTS.summer, @@ -1848,9 +1637,7 @@ let head = { notes: t('headSpecialSummerMageNotes', { per: 7 }), value: 60, per: 7, - canBuy: () => { - return CURRENT_SEASON === 'summer'; - }, + canBuy: () => CURRENT_SEASON === 'summer', }, summerHealer: { event: EVENTS.summer, @@ -1860,9 +1647,7 @@ let head = { notes: t('headSpecialSummerHealerNotes', { int: 7 }), value: 60, int: 7, - canBuy: () => { - return CURRENT_SEASON === 'summer'; - }, + canBuy: () => CURRENT_SEASON === 'summer', }, fallRogue: { event: EVENTS.fall, @@ -1872,9 +1657,7 @@ let head = { notes: t('headSpecialFallRogueNotes', { per: 9 }), value: 60, per: 9, - canBuy: () => { - return CURRENT_SEASON === 'fall'; - }, + canBuy: () => CURRENT_SEASON === 'fall', }, fallWarrior: { event: EVENTS.fall, @@ -1884,9 +1667,7 @@ let head = { notes: t('headSpecialFallWarriorNotes', { str: 9 }), value: 60, str: 9, - canBuy: () => { - return CURRENT_SEASON === 'fall'; - }, + canBuy: () => CURRENT_SEASON === 'fall', }, fallMage: { event: EVENTS.fall, @@ -1896,9 +1677,7 @@ let head = { notes: t('headSpecialFallMageNotes', { per: 7 }), value: 60, per: 7, - canBuy: () => { - return CURRENT_SEASON === 'fall'; - }, + canBuy: () => CURRENT_SEASON === 'fall', }, fallHealer: { event: EVENTS.fall, @@ -1908,9 +1687,7 @@ let head = { notes: t('headSpecialFallHealerNotes', { int: 7 }), value: 60, int: 7, - canBuy: () => { - return CURRENT_SEASON === 'fall'; - }, + canBuy: () => CURRENT_SEASON === 'fall', }, winter2015Rogue: { event: EVENTS.winter2015, @@ -1920,9 +1697,7 @@ let head = { notes: t('headSpecialWinter2015RogueNotes', { per: 9 }), value: 60, per: 9, - canBuy: () => { - return CURRENT_SEASON === 'winter'; - }, + canBuy: () => CURRENT_SEASON === 'winter', }, winter2015Warrior: { event: EVENTS.winter2015, @@ -1932,9 +1707,7 @@ let head = { notes: t('headSpecialWinter2015WarriorNotes', { str: 9 }), value: 60, str: 9, - canBuy: () => { - return CURRENT_SEASON === 'winter'; - }, + canBuy: () => CURRENT_SEASON === 'winter', }, winter2015Mage: { event: EVENTS.winter2015, @@ -1944,9 +1717,7 @@ let head = { notes: t('headSpecialWinter2015MageNotes', { per: 7 }), value: 60, per: 7, - canBuy: () => { - return CURRENT_SEASON === 'winter'; - }, + canBuy: () => CURRENT_SEASON === 'winter', }, winter2015Healer: { event: EVENTS.winter2015, @@ -1956,9 +1727,7 @@ let head = { notes: t('headSpecialWinter2015HealerNotes', { int: 7 }), value: 60, int: 7, - canBuy: () => { - return CURRENT_SEASON === 'winter'; - }, + canBuy: () => CURRENT_SEASON === 'winter', }, nye2014: { text: t('headSpecialNye2014Text'), @@ -1974,9 +1743,7 @@ let head = { notes: t('headSpecialSpring2015RogueNotes', { per: 9 }), value: 60, per: 9, - canBuy: () => { - return CURRENT_SEASON === 'spring'; - }, + canBuy: () => CURRENT_SEASON === 'spring', }, spring2015Warrior: { event: EVENTS.spring2015, @@ -1986,9 +1753,7 @@ let head = { notes: t('headSpecialSpring2015WarriorNotes', { str: 9 }), value: 60, str: 9, - canBuy: () => { - return CURRENT_SEASON === 'spring'; - }, + canBuy: () => CURRENT_SEASON === 'spring', }, spring2015Mage: { event: EVENTS.spring2015, @@ -1998,9 +1763,7 @@ let head = { notes: t('headSpecialSpring2015MageNotes', { per: 7 }), value: 60, per: 7, - canBuy: () => { - return CURRENT_SEASON === 'spring'; - }, + canBuy: () => CURRENT_SEASON === 'spring', }, spring2015Healer: { event: EVENTS.spring2015, @@ -2010,9 +1773,7 @@ let head = { notes: t('headSpecialSpring2015HealerNotes', { int: 7 }), value: 60, int: 7, - canBuy: () => { - return CURRENT_SEASON === 'spring'; - }, + canBuy: () => CURRENT_SEASON === 'spring', }, summer2015Rogue: { event: EVENTS.summer2015, @@ -2022,9 +1783,7 @@ let head = { notes: t('headSpecialSummer2015RogueNotes', { per: 9 }), value: 60, per: 9, - canBuy: () => { - return CURRENT_SEASON === 'summer'; - }, + canBuy: () => CURRENT_SEASON === 'summer', }, summer2015Warrior: { event: EVENTS.summer2015, @@ -2034,9 +1793,7 @@ let head = { notes: t('headSpecialSummer2015WarriorNotes', { str: 9 }), value: 60, str: 9, - canBuy: () => { - return CURRENT_SEASON === 'summer'; - }, + canBuy: () => CURRENT_SEASON === 'summer', }, summer2015Mage: { event: EVENTS.summer2015, @@ -2046,9 +1803,7 @@ let head = { notes: t('headSpecialSummer2015MageNotes', { per: 7 }), value: 60, per: 7, - canBuy: () => { - return CURRENT_SEASON === 'summer'; - }, + canBuy: () => CURRENT_SEASON === 'summer', }, summer2015Healer: { event: EVENTS.summer2015, @@ -2058,9 +1813,7 @@ let head = { notes: t('headSpecialSummer2015HealerNotes', { int: 7 }), value: 60, int: 7, - canBuy: () => { - return CURRENT_SEASON === 'summer'; - }, + canBuy: () => CURRENT_SEASON === 'summer', }, fall2015Rogue: { event: EVENTS.fall2015, @@ -2070,9 +1823,7 @@ let head = { notes: t('headSpecialFall2015RogueNotes', { per: 9 }), value: 60, per: 9, - canBuy: () => { - return CURRENT_SEASON === 'fall'; - }, + canBuy: () => CURRENT_SEASON === 'fall', }, fall2015Warrior: { event: EVENTS.fall2015, @@ -2082,9 +1833,7 @@ let head = { notes: t('headSpecialFall2015WarriorNotes', { str: 9 }), value: 60, str: 9, - canBuy: () => { - return CURRENT_SEASON === 'fall'; - }, + canBuy: () => CURRENT_SEASON === 'fall', }, fall2015Mage: { event: EVENTS.fall2015, @@ -2094,9 +1843,7 @@ let head = { notes: t('headSpecialFall2015MageNotes', { per: 7 }), value: 60, per: 7, - canBuy: () => { - return CURRENT_SEASON === 'fall'; - }, + canBuy: () => CURRENT_SEASON === 'fall', }, fall2015Healer: { event: EVENTS.fall2015, @@ -2106,9 +1853,7 @@ let head = { notes: t('headSpecialFall2015HealerNotes', { int: 7 }), value: 60, int: 7, - canBuy: () => { - return CURRENT_SEASON === 'fall'; - }, + canBuy: () => CURRENT_SEASON === 'fall', }, gaymerx: { event: EVENTS.gaymerx, @@ -2124,9 +1869,7 @@ let head = { notes: t('headSpecialWinter2016RogueNotes', { per: 9 }), value: 60, per: 9, - canBuy: () => { - return CURRENT_SEASON === 'winter'; - }, + canBuy: () => CURRENT_SEASON === 'winter', }, winter2016Warrior: { event: EVENTS.winter2016, @@ -2136,9 +1879,7 @@ let head = { notes: t('headSpecialWinter2016WarriorNotes', { str: 9 }), value: 60, str: 9, - canBuy: () => { - return CURRENT_SEASON === 'winter'; - }, + canBuy: () => CURRENT_SEASON === 'winter', }, winter2016Mage: { event: EVENTS.winter2016, @@ -2148,9 +1889,7 @@ let head = { notes: t('headSpecialWinter2016MageNotes', { per: 7 }), value: 60, per: 7, - canBuy: () => { - return CURRENT_SEASON === 'winter'; - }, + canBuy: () => CURRENT_SEASON === 'winter', }, winter2016Healer: { event: EVENTS.winter2016, @@ -2160,9 +1899,7 @@ let head = { notes: t('headSpecialWinter2016HealerNotes', { int: 7 }), value: 60, int: 7, - canBuy: () => { - return CURRENT_SEASON === 'winter'; - }, + canBuy: () => CURRENT_SEASON === 'winter', }, nye2015: { text: t('headSpecialNye2015Text'), @@ -2178,9 +1915,7 @@ let head = { notes: t('headSpecialSpring2016RogueNotes', { per: 9 }), value: 60, per: 9, - canBuy: () => { - return CURRENT_SEASON === 'spring'; - }, + canBuy: () => CURRENT_SEASON === 'spring', }, spring2016Warrior: { event: EVENTS.spring2016, @@ -2190,9 +1925,7 @@ let head = { notes: t('headSpecialSpring2016WarriorNotes', { str: 9 }), value: 60, str: 9, - canBuy: () => { - return CURRENT_SEASON === 'spring'; - }, + canBuy: () => CURRENT_SEASON === 'spring', }, spring2016Mage: { event: EVENTS.spring2016, @@ -2202,9 +1935,7 @@ let head = { notes: t('headSpecialSpring2016MageNotes', { per: 7 }), value: 60, per: 7, - canBuy: () => { - return CURRENT_SEASON === 'spring'; - }, + canBuy: () => CURRENT_SEASON === 'spring', }, spring2016Healer: { event: EVENTS.spring2016, @@ -2214,9 +1945,7 @@ let head = { notes: t('headSpecialSpring2016HealerNotes', { int: 7 }), value: 60, int: 7, - canBuy: () => { - return CURRENT_SEASON === 'spring'; - }, + canBuy: () => CURRENT_SEASON === 'spring', }, summer2016Rogue: { event: EVENTS.summer2016, @@ -2226,9 +1955,7 @@ let head = { notes: t('headSpecialSummer2016RogueNotes', { per: 9 }), value: 60, per: 9, - canBuy: () => { - return CURRENT_SEASON === 'summer'; - }, + canBuy: () => CURRENT_SEASON === 'summer', }, summer2016Warrior: { event: EVENTS.summer2016, @@ -2238,9 +1965,7 @@ let head = { notes: t('headSpecialSummer2016WarriorNotes', { str: 9 }), value: 60, str: 9, - canBuy: () => { - return CURRENT_SEASON === 'summer'; - }, + canBuy: () => CURRENT_SEASON === 'summer', }, summer2016Mage: { event: EVENTS.summer2016, @@ -2250,9 +1975,7 @@ let head = { notes: t('headSpecialSummer2016MageNotes', { per: 7 }), value: 60, per: 7, - canBuy: () => { - return CURRENT_SEASON === 'summer'; - }, + canBuy: () => CURRENT_SEASON === 'summer', }, summer2016Healer: { event: EVENTS.summer2016, @@ -2262,9 +1985,7 @@ let head = { notes: t('headSpecialSummer2016HealerNotes', { int: 7 }), value: 60, int: 7, - canBuy: () => { - return CURRENT_SEASON === 'summer'; - }, + canBuy: () => CURRENT_SEASON === 'summer', }, fall2016Rogue: { event: EVENTS.fall2016, @@ -2274,9 +1995,7 @@ let head = { notes: t('headSpecialFall2016RogueNotes', { per: 9 }), value: 60, per: 9, - canBuy: () => { - return CURRENT_SEASON === 'fall'; - }, + canBuy: () => CURRENT_SEASON === 'fall', }, fall2016Warrior: { event: EVENTS.fall2016, @@ -2286,9 +2005,7 @@ let head = { notes: t('headSpecialFall2016WarriorNotes', { str: 9 }), value: 60, str: 9, - canBuy: () => { - return CURRENT_SEASON === 'fall'; - }, + canBuy: () => CURRENT_SEASON === 'fall', }, fall2016Mage: { event: EVENTS.fall2016, @@ -2298,9 +2015,7 @@ let head = { notes: t('headSpecialFall2016MageNotes', { per: 7 }), value: 60, per: 7, - canBuy: () => { - return CURRENT_SEASON === 'fall'; - }, + canBuy: () => CURRENT_SEASON === 'fall', }, fall2016Healer: { event: EVENTS.fall2016, @@ -2310,9 +2025,7 @@ let head = { notes: t('headSpecialFall2016HealerNotes', { int: 7 }), value: 60, int: 7, - canBuy: () => { - return CURRENT_SEASON === 'fall'; - }, + canBuy: () => CURRENT_SEASON === 'fall', }, winter2017Rogue: { event: EVENTS.winter2017, @@ -2322,9 +2035,7 @@ let head = { notes: t('headSpecialWinter2017RogueNotes', { per: 9 }), value: 60, per: 9, - canBuy: () => { - return CURRENT_SEASON === 'winter'; - }, + canBuy: () => CURRENT_SEASON === 'winter', }, winter2017Warrior: { event: EVENTS.winter2017, @@ -2334,9 +2045,7 @@ let head = { notes: t('headSpecialWinter2017WarriorNotes', { str: 9 }), value: 60, str: 9, - canBuy: () => { - return CURRENT_SEASON === 'winter'; - }, + canBuy: () => CURRENT_SEASON === 'winter', }, winter2017Mage: { event: EVENTS.winter2017, @@ -2346,9 +2055,7 @@ let head = { notes: t('headSpecialWinter2017MageNotes', { per: 7 }), value: 60, per: 7, - canBuy: () => { - return CURRENT_SEASON === 'winter'; - }, + canBuy: () => CURRENT_SEASON === 'winter', }, winter2017Healer: { event: EVENTS.winter2017, @@ -2358,9 +2065,7 @@ let head = { notes: t('headSpecialWinter2017HealerNotes', { int: 7 }), value: 60, int: 7, - canBuy: () => { - return CURRENT_SEASON === 'winter'; - }, + canBuy: () => CURRENT_SEASON === 'winter', }, nye2016: { text: t('headSpecialNye2016Text'), @@ -2376,9 +2081,7 @@ let head = { notes: t('headSpecialSpring2017RogueNotes', { per: 9 }), value: 60, per: 9, - canBuy: () => { - return CURRENT_SEASON === 'spring'; - }, + canBuy: () => CURRENT_SEASON === 'spring', }, spring2017Warrior: { event: EVENTS.spring2017, @@ -2388,9 +2091,7 @@ let head = { notes: t('headSpecialSpring2017WarriorNotes', { str: 9 }), value: 60, str: 9, - canBuy: () => { - return CURRENT_SEASON === 'spring'; - }, + canBuy: () => CURRENT_SEASON === 'spring', }, spring2017Mage: { event: EVENTS.spring2017, @@ -2400,9 +2101,7 @@ let head = { notes: t('headSpecialSpring2017MageNotes', { per: 7 }), value: 60, per: 7, - canBuy: () => { - return CURRENT_SEASON === 'spring'; - }, + canBuy: () => CURRENT_SEASON === 'spring', }, spring2017Healer: { event: EVENTS.spring2017, @@ -2412,9 +2111,7 @@ let head = { notes: t('headSpecialSpring2017HealerNotes', { int: 7 }), value: 60, int: 7, - canBuy: () => { - return CURRENT_SEASON === 'spring'; - }, + canBuy: () => CURRENT_SEASON === 'spring', }, summer2017Rogue: { event: EVENTS.summer2017, @@ -2424,9 +2121,7 @@ let head = { notes: t('headSpecialSummer2017RogueNotes', { per: 9 }), value: 60, per: 9, - canBuy: () => { - return CURRENT_SEASON === 'summer'; - }, + canBuy: () => CURRENT_SEASON === 'summer', }, summer2017Warrior: { event: EVENTS.summer2017, @@ -2436,9 +2131,7 @@ let head = { notes: t('headSpecialSummer2017WarriorNotes', { str: 9 }), value: 60, str: 9, - canBuy: () => { - return CURRENT_SEASON === 'summer'; - }, + canBuy: () => CURRENT_SEASON === 'summer', }, summer2017Mage: { event: EVENTS.summer2017, @@ -2448,9 +2141,7 @@ let head = { notes: t('headSpecialSummer2017MageNotes', { per: 7 }), value: 60, per: 7, - canBuy: () => { - return CURRENT_SEASON === 'summer'; - }, + canBuy: () => CURRENT_SEASON === 'summer', }, summer2017Healer: { event: EVENTS.summer2017, @@ -2460,9 +2151,7 @@ let head = { notes: t('headSpecialSummer2017HealerNotes', { int: 7 }), value: 60, int: 7, - canBuy: () => { - return CURRENT_SEASON === 'summer'; - }, + canBuy: () => CURRENT_SEASON === 'summer', }, namingDay2017: { text: t('headSpecialNamingDay2017Text'), @@ -2478,9 +2167,7 @@ let head = { notes: t('headSpecialFall2017RogueNotes', { per: 9 }), value: 60, per: 9, - canBuy: () => { - return CURRENT_SEASON === 'fall'; - }, + canBuy: () => CURRENT_SEASON === 'fall', }, fall2017Warrior: { event: EVENTS.fall2017, @@ -2490,9 +2177,7 @@ let head = { notes: t('headSpecialFall2017WarriorNotes', { str: 9 }), value: 60, str: 9, - canBuy: () => { - return CURRENT_SEASON === 'fall'; - }, + canBuy: () => CURRENT_SEASON === 'fall', }, fall2017Mage: { event: EVENTS.fall2017, @@ -2502,9 +2187,7 @@ let head = { notes: t('headSpecialFall2017MageNotes', { per: 7 }), value: 60, per: 7, - canBuy: () => { - return CURRENT_SEASON === 'fall'; - }, + canBuy: () => CURRENT_SEASON === 'fall', }, fall2017Healer: { event: EVENTS.fall2017, @@ -2514,9 +2197,7 @@ let head = { notes: t('headSpecialFall2017HealerNotes', { int: 7 }), value: 60, int: 7, - canBuy: () => { - return CURRENT_SEASON === 'fall'; - }, + canBuy: () => CURRENT_SEASON === 'fall', }, nye2017: { text: t('headSpecialNye2017Text'), @@ -2532,9 +2213,7 @@ let head = { notes: t('headSpecialWinter2018RogueNotes', { per: 9 }), value: 60, per: 9, - canBuy: () => { - return CURRENT_SEASON === 'winter'; - }, + canBuy: () => CURRENT_SEASON === 'winter', }, winter2018Warrior: { event: EVENTS.winter2018, @@ -2544,9 +2223,7 @@ let head = { notes: t('headSpecialWinter2018WarriorNotes', { str: 9 }), value: 60, str: 9, - canBuy: () => { - return CURRENT_SEASON === 'winter'; - }, + canBuy: () => CURRENT_SEASON === 'winter', }, winter2018Mage: { event: EVENTS.winter2018, @@ -2556,9 +2233,7 @@ let head = { notes: t('headSpecialWinter2018MageNotes', { per: 7 }), value: 60, per: 7, - canBuy: () => { - return CURRENT_SEASON === 'winter'; - }, + canBuy: () => CURRENT_SEASON === 'winter', }, winter2018Healer: { event: EVENTS.winter2018, @@ -2568,9 +2243,7 @@ let head = { notes: t('headSpecialWinter2018HealerNotes', { int: 7 }), value: 60, int: 7, - canBuy: () => { - return CURRENT_SEASON === 'winter'; - }, + canBuy: () => CURRENT_SEASON === 'winter', }, spring2018Rogue: { event: EVENTS.spring2018, @@ -2580,9 +2253,7 @@ let head = { notes: t('headSpecialSpring2018RogueNotes', { per: 9 }), value: 60, per: 9, - canBuy: () => { - return CURRENT_SEASON === 'spring'; - }, + canBuy: () => CURRENT_SEASON === 'spring', }, spring2018Warrior: { event: EVENTS.spring2018, @@ -2592,9 +2263,7 @@ let head = { notes: t('headSpecialSpring2018WarriorNotes', { str: 9 }), value: 60, str: 9, - canBuy: () => { - return CURRENT_SEASON === 'spring'; - }, + canBuy: () => CURRENT_SEASON === 'spring', }, spring2018Mage: { event: EVENTS.spring2018, @@ -2604,9 +2273,7 @@ let head = { notes: t('headSpecialSpring2018MageNotes', { per: 7 }), value: 60, per: 7, - canBuy: () => { - return CURRENT_SEASON === 'spring'; - }, + canBuy: () => CURRENT_SEASON === 'spring', }, spring2018Healer: { event: EVENTS.spring2018, @@ -2616,9 +2283,7 @@ let head = { notes: t('headSpecialSpring2018HealerNotes', { int: 7 }), value: 60, int: 7, - canBuy: () => { - return CURRENT_SEASON === 'spring'; - }, + canBuy: () => CURRENT_SEASON === 'spring', }, summer2018Rogue: { event: EVENTS.summer2018, @@ -2628,9 +2293,7 @@ let head = { notes: t('headSpecialSummer2018RogueNotes', { per: 9 }), value: 60, per: 9, - canBuy: () => { - return CURRENT_SEASON === 'summer'; - }, + canBuy: () => CURRENT_SEASON === 'summer', }, summer2018Warrior: { event: EVENTS.summer2018, @@ -2640,9 +2303,7 @@ let head = { notes: t('headSpecialSummer2018WarriorNotes', { str: 9 }), value: 60, str: 9, - canBuy: () => { - return CURRENT_SEASON === 'summer'; - }, + canBuy: () => CURRENT_SEASON === 'summer', }, summer2018Mage: { event: EVENTS.summer2018, @@ -2652,9 +2313,7 @@ let head = { notes: t('headSpecialSummer2018MageNotes', { per: 7 }), value: 60, per: 7, - canBuy: () => { - return CURRENT_SEASON === 'summer'; - }, + canBuy: () => CURRENT_SEASON === 'summer', }, summer2018Healer: { event: EVENTS.summer2018, @@ -2664,9 +2323,7 @@ let head = { notes: t('headSpecialSummer2018HealerNotes', { int: 7 }), value: 60, int: 7, - canBuy: () => { - return CURRENT_SEASON === 'summer'; - }, + canBuy: () => CURRENT_SEASON === 'summer', }, fall2018Rogue: { event: EVENTS.fall2018, @@ -2676,9 +2333,7 @@ let head = { notes: t('headSpecialFall2018RogueNotes', { per: 9 }), value: 60, per: 9, - canBuy: () => { - return CURRENT_SEASON === 'fall'; - }, + canBuy: () => CURRENT_SEASON === 'fall', }, fall2018Warrior: { event: EVENTS.fall2018, @@ -2688,9 +2343,7 @@ let head = { notes: t('headSpecialFall2018WarriorNotes', { str: 9 }), value: 60, str: 9, - canBuy: () => { - return CURRENT_SEASON === 'fall'; - }, + canBuy: () => CURRENT_SEASON === 'fall', }, fall2018Mage: { event: EVENTS.fall2018, @@ -2700,9 +2353,7 @@ let head = { notes: t('headSpecialFall2018MageNotes', { per: 7 }), value: 60, per: 7, - canBuy: () => { - return CURRENT_SEASON === 'fall'; - }, + canBuy: () => CURRENT_SEASON === 'fall', }, fall2018Healer: { event: EVENTS.fall2018, @@ -2712,9 +2363,7 @@ let head = { notes: t('headSpecialFall2018HealerNotes', { int: 7 }), value: 60, int: 7, - canBuy: () => { - return CURRENT_SEASON === 'fall'; - }, + canBuy: () => CURRENT_SEASON === 'fall', }, turkeyHelmGilded: { text: t('headSpecialTurkeyHelmGildedText'), @@ -2887,7 +2536,7 @@ let head = { }, }; -let headAccessory = { +const headAccessory = { springRogue: { event: EVENTS.spring, specialClass: 'rogue', @@ -2895,9 +2544,7 @@ let headAccessory = { text: t('headAccessorySpecialSpringRogueText'), notes: t('headAccessorySpecialSpringRogueNotes'), value: 20, - canBuy: () => { - return CURRENT_SEASON === 'spring'; - }, + canBuy: () => CURRENT_SEASON === 'spring', }, springWarrior: { event: EVENTS.spring, @@ -2906,9 +2553,7 @@ let headAccessory = { text: t('headAccessorySpecialSpringWarriorText'), notes: t('headAccessorySpecialSpringWarriorNotes'), value: 20, - canBuy: () => { - return CURRENT_SEASON === 'spring'; - }, + canBuy: () => CURRENT_SEASON === 'spring', }, springMage: { event: EVENTS.spring, @@ -2917,9 +2562,7 @@ let headAccessory = { text: t('headAccessorySpecialSpringMageText'), notes: t('headAccessorySpecialSpringMageNotes'), value: 20, - canBuy: () => { - return CURRENT_SEASON === 'spring'; - }, + canBuy: () => CURRENT_SEASON === 'spring', }, springHealer: { event: EVENTS.spring, @@ -2928,9 +2571,7 @@ let headAccessory = { text: t('headAccessorySpecialSpringHealerText'), notes: t('headAccessorySpecialSpringHealerNotes'), value: 20, - canBuy: () => { - return CURRENT_SEASON === 'spring'; - }, + canBuy: () => CURRENT_SEASON === 'spring', }, spring2015Rogue: { event: EVENTS.spring2015, @@ -2939,9 +2580,7 @@ let headAccessory = { text: t('headAccessorySpecialSpring2015RogueText'), notes: t('headAccessorySpecialSpring2015RogueNotes'), value: 20, - canBuy: () => { - return CURRENT_SEASON === 'spring'; - }, + canBuy: () => CURRENT_SEASON === 'spring', }, spring2015Warrior: { event: EVENTS.spring2015, @@ -2950,9 +2589,7 @@ let headAccessory = { text: t('headAccessorySpecialSpring2015WarriorText'), notes: t('headAccessorySpecialSpring2015WarriorNotes'), value: 20, - canBuy: () => { - return CURRENT_SEASON === 'spring'; - }, + canBuy: () => CURRENT_SEASON === 'spring', }, spring2015Mage: { event: EVENTS.spring2015, @@ -2961,9 +2598,7 @@ let headAccessory = { text: t('headAccessorySpecialSpring2015MageText'), notes: t('headAccessorySpecialSpring2015MageNotes'), value: 20, - canBuy: () => { - return CURRENT_SEASON === 'spring'; - }, + canBuy: () => CURRENT_SEASON === 'spring', }, spring2015Healer: { event: EVENTS.spring2015, @@ -2972,9 +2607,7 @@ let headAccessory = { text: t('headAccessorySpecialSpring2015HealerText'), notes: t('headAccessorySpecialSpring2015HealerNotes'), value: 20, - canBuy: () => { - return CURRENT_SEASON === 'spring'; - }, + canBuy: () => CURRENT_SEASON === 'spring', }, bearEars: { gearSet: 'animal', @@ -2982,9 +2615,7 @@ let headAccessory = { notes: t('headAccessoryBearEarsNotes'), value: 20, canOwn: ownsItem('headAccessory_special_bearEars'), - canBuy: () => { - return true; - }, + canBuy: () => true, }, cactusEars: { gearSet: 'animal', @@ -2992,9 +2623,7 @@ let headAccessory = { notes: t('headAccessoryCactusEarsNotes'), value: 20, canOwn: ownsItem('headAccessory_special_cactusEars'), - canBuy: () => { - return true; - }, + canBuy: () => true, }, foxEars: { gearSet: 'animal', @@ -3002,9 +2631,7 @@ let headAccessory = { notes: t('headAccessoryFoxEarsNotes'), value: 20, canOwn: ownsItem('headAccessory_special_foxEars'), - canBuy: () => { - return true; - }, + canBuy: () => true, }, lionEars: { gearSet: 'animal', @@ -3012,9 +2639,7 @@ let headAccessory = { notes: t('headAccessoryLionEarsNotes'), value: 20, canOwn: ownsItem('headAccessory_special_lionEars'), - canBuy: () => { - return true; - }, + canBuy: () => true, }, pandaEars: { gearSet: 'animal', @@ -3022,9 +2647,7 @@ let headAccessory = { notes: t('headAccessoryPandaEarsNotes'), value: 20, canOwn: ownsItem('headAccessory_special_pandaEars'), - canBuy: () => { - return true; - }, + canBuy: () => true, }, pigEars: { gearSet: 'animal', @@ -3032,9 +2655,7 @@ let headAccessory = { notes: t('headAccessoryPigEarsNotes'), value: 20, canOwn: ownsItem('headAccessory_special_pigEars'), - canBuy: () => { - return true; - }, + canBuy: () => true, }, tigerEars: { gearSet: 'animal', @@ -3042,9 +2663,7 @@ let headAccessory = { notes: t('headAccessoryTigerEarsNotes'), value: 20, canOwn: ownsItem('headAccessory_special_tigerEars'), - canBuy: () => { - return true; - }, + canBuy: () => true, }, wolfEars: { gearSet: 'animal', @@ -3052,9 +2671,7 @@ let headAccessory = { notes: t('headAccessoryWolfEarsNotes'), value: 20, canOwn: ownsItem('headAccessory_special_wolfEars'), - canBuy: () => { - return true; - }, + canBuy: () => true, }, spring2016Rogue: { event: EVENTS.spring2016, @@ -3063,9 +2680,7 @@ let headAccessory = { text: t('headAccessorySpecialSpring2016RogueText'), notes: t('headAccessorySpecialSpring2016RogueNotes'), value: 20, - canBuy: () => { - return CURRENT_SEASON === 'spring'; - }, + canBuy: () => CURRENT_SEASON === 'spring', }, spring2016Warrior: { event: EVENTS.spring2016, @@ -3074,9 +2689,7 @@ let headAccessory = { text: t('headAccessorySpecialSpring2016WarriorText'), notes: t('headAccessorySpecialSpring2016WarriorNotes'), value: 20, - canBuy: () => { - return CURRENT_SEASON === 'spring'; - }, + canBuy: () => CURRENT_SEASON === 'spring', }, spring2016Mage: { event: EVENTS.spring2016, @@ -3085,9 +2698,7 @@ let headAccessory = { text: t('headAccessorySpecialSpring2016MageText'), notes: t('headAccessorySpecialSpring2016MageNotes'), value: 20, - canBuy: () => { - return CURRENT_SEASON === 'spring'; - }, + canBuy: () => CURRENT_SEASON === 'spring', }, spring2016Healer: { event: EVENTS.spring2016, @@ -3096,9 +2707,7 @@ let headAccessory = { text: t('headAccessorySpecialSpring2016HealerText'), notes: t('headAccessorySpecialSpring2016HealerNotes'), value: 20, - canBuy: () => { - return CURRENT_SEASON === 'spring'; - }, + canBuy: () => CURRENT_SEASON === 'spring', }, spring2017Rogue: { event: EVENTS.spring2017, @@ -3107,9 +2716,7 @@ let headAccessory = { text: t('headAccessorySpecialSpring2017RogueText'), notes: t('headAccessorySpecialSpring2017RogueNotes'), value: 20, - canBuy: () => { - return CURRENT_SEASON === 'spring'; - }, + canBuy: () => CURRENT_SEASON === 'spring', }, spring2017Warrior: { event: EVENTS.spring2017, @@ -3118,9 +2725,7 @@ let headAccessory = { text: t('headAccessorySpecialSpring2017WarriorText'), notes: t('headAccessorySpecialSpring2017WarriorNotes'), value: 20, - canBuy: () => { - return CURRENT_SEASON === 'spring'; - }, + canBuy: () => CURRENT_SEASON === 'spring', }, spring2017Mage: { event: EVENTS.spring2017, @@ -3129,9 +2734,7 @@ let headAccessory = { text: t('headAccessorySpecialSpring2017MageText'), notes: t('headAccessorySpecialSpring2017MageNotes'), value: 20, - canBuy: () => { - return CURRENT_SEASON === 'spring'; - }, + canBuy: () => CURRENT_SEASON === 'spring', }, spring2017Healer: { event: EVENTS.spring2017, @@ -3140,9 +2743,7 @@ let headAccessory = { text: t('headAccessorySpecialSpring2017HealerText'), notes: t('headAccessorySpecialSpring2017HealerNotes'), value: 20, - canBuy: () => { - return CURRENT_SEASON === 'spring'; - }, + canBuy: () => CURRENT_SEASON === 'spring', }, blackHeadband: { gearSet: 'headband', @@ -3195,7 +2796,7 @@ let headAccessory = { }, }; -let shield = { +const shield = { 0: backerGear.shieldSpecial0, 1: contributorGear.shieldSpecial1, takeThis: takeThisGear.shieldSpecialTakeThis, @@ -3264,9 +2865,7 @@ let shield = { notes: t('shieldSpecialYetiNotes', { con: 7 }), con: 7, value: 70, - canBuy: () => { - return CURRENT_SEASON === 'winter'; - }, + canBuy: () => CURRENT_SEASON === 'winter', }, ski: { event: EVENTS.winter, @@ -3276,9 +2875,7 @@ let shield = { notes: t('weaponSpecialSkiNotes', { str: 8 }), str: 8, value: 90, - canBuy: () => { - return CURRENT_SEASON === 'winter'; - }, + canBuy: () => CURRENT_SEASON === 'winter', }, snowflake: { event: EVENTS.winter, @@ -3288,9 +2885,7 @@ let shield = { notes: t('shieldSpecialSnowflakeNotes', { con: 9 }), con: 9, value: 70, - canBuy: () => { - return CURRENT_SEASON === 'winter'; - }, + canBuy: () => CURRENT_SEASON === 'winter', }, springRogue: { event: EVENTS.spring, @@ -3300,9 +2895,7 @@ let shield = { notes: t('shieldSpecialSpringRogueNotes', { str: 8 }), value: 80, str: 8, - canBuy: () => { - return CURRENT_SEASON === 'spring'; - }, + canBuy: () => CURRENT_SEASON === 'spring', }, springWarrior: { event: EVENTS.spring, @@ -3312,9 +2905,7 @@ let shield = { notes: t('shieldSpecialSpringWarriorNotes', { con: 7 }), value: 70, con: 7, - canBuy: () => { - return CURRENT_SEASON === 'spring'; - }, + canBuy: () => CURRENT_SEASON === 'spring', }, springHealer: { event: EVENTS.spring, @@ -3324,9 +2915,7 @@ let shield = { notes: t('shieldSpecialSpringHealerNotes', { con: 9 }), value: 70, con: 9, - canBuy: () => { - return CURRENT_SEASON === 'spring'; - }, + canBuy: () => CURRENT_SEASON === 'spring', }, summerRogue: { event: EVENTS.summer, @@ -3336,9 +2925,7 @@ let shield = { notes: t('shieldSpecialSummerRogueNotes', { str: 8 }), value: 80, str: 8, - canBuy: () => { - return CURRENT_SEASON === 'summer'; - }, + canBuy: () => CURRENT_SEASON === 'summer', }, summerWarrior: { event: EVENTS.summer, @@ -3348,9 +2935,7 @@ let shield = { notes: t('shieldSpecialSummerWarriorNotes', { con: 7 }), value: 70, con: 7, - canBuy: () => { - return CURRENT_SEASON === 'summer'; - }, + canBuy: () => CURRENT_SEASON === 'summer', }, summerHealer: { event: EVENTS.summer, @@ -3360,9 +2945,7 @@ let shield = { notes: t('shieldSpecialSummerHealerNotes', { con: 9 }), value: 70, con: 9, - canBuy: () => { - return CURRENT_SEASON === 'summer'; - }, + canBuy: () => CURRENT_SEASON === 'summer', }, fallRogue: { event: EVENTS.fall, @@ -3372,9 +2955,7 @@ let shield = { notes: t('shieldSpecialFallRogueNotes', { str: 8 }), value: 80, str: 8, - canBuy: () => { - return CURRENT_SEASON === 'fall'; - }, + canBuy: () => CURRENT_SEASON === 'fall', }, fallWarrior: { event: EVENTS.fall, @@ -3384,9 +2965,7 @@ let shield = { notes: t('shieldSpecialFallWarriorNotes', { con: 7 }), value: 70, con: 7, - canBuy: () => { - return CURRENT_SEASON === 'fall'; - }, + canBuy: () => CURRENT_SEASON === 'fall', }, fallHealer: { event: EVENTS.fall, @@ -3396,9 +2975,7 @@ let shield = { notes: t('shieldSpecialFallHealerNotes', { con: 9 }), value: 70, con: 9, - canBuy: () => { - return CURRENT_SEASON === 'fall'; - }, + canBuy: () => CURRENT_SEASON === 'fall', }, winter2015Rogue: { event: EVENTS.winter2015, @@ -3408,9 +2985,7 @@ let shield = { notes: t('shieldSpecialWinter2015RogueNotes', { str: 8 }), value: 80, str: 8, - canBuy: () => { - return CURRENT_SEASON === 'winter'; - }, + canBuy: () => CURRENT_SEASON === 'winter', }, winter2015Warrior: { event: EVENTS.winter2015, @@ -3420,9 +2995,7 @@ let shield = { notes: t('shieldSpecialWinter2015WarriorNotes', { con: 7 }), value: 70, con: 7, - canBuy: () => { - return CURRENT_SEASON === 'winter'; - }, + canBuy: () => CURRENT_SEASON === 'winter', }, winter2015Healer: { event: EVENTS.winter2015, @@ -3432,9 +3005,7 @@ let shield = { notes: t('shieldSpecialWinter2015HealerNotes', { con: 9 }), value: 70, con: 9, - canBuy: () => { - return CURRENT_SEASON === 'winter'; - }, + canBuy: () => CURRENT_SEASON === 'winter', }, spring2015Rogue: { event: EVENTS.spring2015, @@ -3444,9 +3015,7 @@ let shield = { notes: t('shieldSpecialSpring2015RogueNotes', { str: 8 }), value: 80, str: 8, - canBuy: () => { - return CURRENT_SEASON === 'spring'; - }, + canBuy: () => CURRENT_SEASON === 'spring', }, spring2015Warrior: { event: EVENTS.spring2015, @@ -3456,9 +3025,7 @@ let shield = { notes: t('shieldSpecialSpring2015WarriorNotes', { con: 7 }), value: 70, con: 7, - canBuy: () => { - return CURRENT_SEASON === 'spring'; - }, + canBuy: () => CURRENT_SEASON === 'spring', }, spring2015Healer: { event: EVENTS.spring2015, @@ -3468,9 +3035,7 @@ let shield = { notes: t('shieldSpecialSpring2015HealerNotes', { con: 9 }), value: 70, con: 9, - canBuy: () => { - return CURRENT_SEASON === 'spring'; - }, + canBuy: () => CURRENT_SEASON === 'spring', }, summer2015Rogue: { event: EVENTS.summer2015, @@ -3480,9 +3045,7 @@ let shield = { notes: t('shieldSpecialSummer2015RogueNotes', { str: 8 }), value: 80, str: 8, - canBuy: () => { - return CURRENT_SEASON === 'summer'; - }, + canBuy: () => CURRENT_SEASON === 'summer', }, summer2015Warrior: { event: EVENTS.summer2015, @@ -3492,9 +3055,7 @@ let shield = { notes: t('shieldSpecialSummer2015WarriorNotes', { con: 7 }), value: 70, con: 7, - canBuy: () => { - return CURRENT_SEASON === 'summer'; - }, + canBuy: () => CURRENT_SEASON === 'summer', }, summer2015Healer: { event: EVENTS.summer2015, @@ -3504,9 +3065,7 @@ let shield = { notes: t('shieldSpecialSummer2015HealerNotes', { con: 9 }), value: 70, con: 9, - canBuy: () => { - return CURRENT_SEASON === 'summer'; - }, + canBuy: () => CURRENT_SEASON === 'summer', }, fall2015Rogue: { event: EVENTS.fall2015, @@ -3516,9 +3075,7 @@ let shield = { notes: t('shieldSpecialFall2015RogueNotes', { str: 8 }), value: 80, str: 8, - canBuy: () => { - return CURRENT_SEASON === 'fall'; - }, + canBuy: () => CURRENT_SEASON === 'fall', }, fall2015Warrior: { event: EVENTS.fall2015, @@ -3528,9 +3085,7 @@ let shield = { notes: t('shieldSpecialFall2015WarriorNotes', { con: 7 }), value: 70, con: 7, - canBuy: () => { - return CURRENT_SEASON === 'fall'; - }, + canBuy: () => CURRENT_SEASON === 'fall', }, fall2015Healer: { event: EVENTS.fall2015, @@ -3540,9 +3095,7 @@ let shield = { notes: t('shieldSpecialFall2015HealerNotes', { con: 9 }), value: 70, con: 9, - canBuy: () => { - return CURRENT_SEASON === 'fall'; - }, + canBuy: () => CURRENT_SEASON === 'fall', }, winter2016Rogue: { event: EVENTS.winter2016, @@ -3552,9 +3105,7 @@ let shield = { notes: t('shieldSpecialWinter2016RogueNotes', { str: 8 }), value: 80, str: 8, - canBuy: () => { - return CURRENT_SEASON === 'winter'; - }, + canBuy: () => CURRENT_SEASON === 'winter', }, winter2016Warrior: { event: EVENTS.winter2016, @@ -3564,9 +3115,7 @@ let shield = { notes: t('shieldSpecialWinter2016WarriorNotes', { con: 7 }), value: 70, con: 7, - canBuy: () => { - return CURRENT_SEASON === 'winter'; - }, + canBuy: () => CURRENT_SEASON === 'winter', }, winter2016Healer: { event: EVENTS.winter2016, @@ -3576,9 +3125,7 @@ let shield = { notes: t('shieldSpecialWinter2016HealerNotes', { con: 9 }), value: 70, con: 9, - canBuy: () => { - return CURRENT_SEASON === 'winter'; - }, + canBuy: () => CURRENT_SEASON === 'winter', }, spring2016Rogue: { event: EVENTS.spring2016, @@ -3588,9 +3135,7 @@ let shield = { notes: t('shieldSpecialSpring2016RogueNotes', { str: 8 }), value: 80, str: 8, - canBuy: () => { - return CURRENT_SEASON === 'spring'; - }, + canBuy: () => CURRENT_SEASON === 'spring', }, spring2016Warrior: { event: EVENTS.spring2016, @@ -3600,9 +3145,7 @@ let shield = { notes: t('shieldSpecialSpring2016WarriorNotes', { con: 7 }), value: 70, con: 7, - canBuy: () => { - return CURRENT_SEASON === 'spring'; - }, + canBuy: () => CURRENT_SEASON === 'spring', }, spring2016Healer: { event: EVENTS.spring2016, @@ -3612,9 +3155,7 @@ let shield = { notes: t('shieldSpecialSpring2016HealerNotes', { con: 9 }), value: 70, con: 9, - canBuy: () => { - return CURRENT_SEASON === 'spring'; - }, + canBuy: () => CURRENT_SEASON === 'spring', }, summer2016Rogue: { event: EVENTS.summer2016, @@ -3624,9 +3165,7 @@ let shield = { notes: t('shieldSpecialSummer2016RogueNotes', { str: 8 }), value: 80, str: 8, - canBuy: () => { - return CURRENT_SEASON === 'summer'; - }, + canBuy: () => CURRENT_SEASON === 'summer', }, summer2016Warrior: { event: EVENTS.summer2016, @@ -3636,9 +3175,7 @@ let shield = { notes: t('shieldSpecialSummer2016WarriorNotes', { con: 7 }), value: 70, con: 7, - canBuy: () => { - return CURRENT_SEASON === 'summer'; - }, + canBuy: () => CURRENT_SEASON === 'summer', }, summer2016Healer: { event: EVENTS.summer2016, @@ -3648,9 +3185,7 @@ let shield = { notes: t('shieldSpecialSummer2016HealerNotes', { con: 9 }), value: 70, con: 9, - canBuy: () => { - return CURRENT_SEASON === 'summer'; - }, + canBuy: () => CURRENT_SEASON === 'summer', }, fall2016Rogue: { event: EVENTS.fall2016, @@ -3660,9 +3195,7 @@ let shield = { notes: t('shieldSpecialFall2016RogueNotes', { str: 8 }), value: 80, str: 8, - canBuy: () => { - return CURRENT_SEASON === 'fall'; - }, + canBuy: () => CURRENT_SEASON === 'fall', }, fall2016Warrior: { event: EVENTS.fall2016, @@ -3672,9 +3205,7 @@ let shield = { notes: t('shieldSpecialFall2016WarriorNotes', { con: 7 }), value: 70, con: 7, - canBuy: () => { - return CURRENT_SEASON === 'fall'; - }, + canBuy: () => CURRENT_SEASON === 'fall', }, fall2016Healer: { event: EVENTS.fall2016, @@ -3684,9 +3215,7 @@ let shield = { notes: t('shieldSpecialFall2016HealerNotes', { con: 9 }), value: 70, con: 9, - canBuy: () => { - return CURRENT_SEASON === 'fall'; - }, + canBuy: () => CURRENT_SEASON === 'fall', }, winter2017Rogue: { event: EVENTS.winter2017, @@ -3696,9 +3225,7 @@ let shield = { notes: t('shieldSpecialWinter2017RogueNotes', { str: 8 }), value: 80, str: 8, - canBuy: () => { - return CURRENT_SEASON === 'winter'; - }, + canBuy: () => CURRENT_SEASON === 'winter', }, winter2017Warrior: { event: EVENTS.winter2017, @@ -3708,9 +3235,7 @@ let shield = { notes: t('shieldSpecialWinter2017WarriorNotes', { con: 7 }), value: 70, con: 7, - canBuy: () => { - return CURRENT_SEASON === 'winter'; - }, + canBuy: () => CURRENT_SEASON === 'winter', }, winter2017Healer: { event: EVENTS.winter2017, @@ -3720,9 +3245,7 @@ let shield = { notes: t('shieldSpecialWinter2017HealerNotes', { con: 9 }), value: 70, con: 9, - canBuy: () => { - return CURRENT_SEASON === 'winter'; - }, + canBuy: () => CURRENT_SEASON === 'winter', }, spring2017Rogue: { event: EVENTS.spring2017, @@ -3732,9 +3255,7 @@ let shield = { notes: t('shieldSpecialSpring2017RogueNotes', { str: 8 }), value: 80, str: 8, - canBuy: () => { - return CURRENT_SEASON === 'spring'; - }, + canBuy: () => CURRENT_SEASON === 'spring', }, spring2017Warrior: { event: EVENTS.spring2017, @@ -3744,9 +3265,7 @@ let shield = { notes: t('shieldSpecialSpring2017WarriorNotes', { con: 7 }), value: 70, con: 7, - canBuy: () => { - return CURRENT_SEASON === 'spring'; - }, + canBuy: () => CURRENT_SEASON === 'spring', }, spring2017Healer: { event: EVENTS.spring2017, @@ -3756,9 +3275,7 @@ let shield = { notes: t('shieldSpecialSpring2017HealerNotes', { con: 9 }), value: 70, con: 9, - canBuy: () => { - return CURRENT_SEASON === 'spring'; - }, + canBuy: () => CURRENT_SEASON === 'spring', }, summer2017Rogue: { event: EVENTS.summer2017, @@ -3768,9 +3285,7 @@ let shield = { notes: t('shieldSpecialSummer2017RogueNotes', { str: 8 }), value: 80, str: 8, - canBuy: () => { - return CURRENT_SEASON === 'summer'; - }, + canBuy: () => CURRENT_SEASON === 'summer', }, summer2017Warrior: { event: EVENTS.summer2017, @@ -3780,9 +3295,7 @@ let shield = { notes: t('shieldSpecialSummer2017WarriorNotes', { con: 7 }), value: 70, con: 7, - canBuy: () => { - return CURRENT_SEASON === 'summer'; - }, + canBuy: () => CURRENT_SEASON === 'summer', }, summer2017Healer: { event: EVENTS.summer2017, @@ -3792,9 +3305,7 @@ let shield = { notes: t('shieldSpecialSummer2017HealerNotes', { con: 9 }), value: 70, con: 9, - canBuy: () => { - return CURRENT_SEASON === 'summer'; - }, + canBuy: () => CURRENT_SEASON === 'summer', }, fall2017Rogue: { event: EVENTS.fall2017, @@ -3804,9 +3315,7 @@ let shield = { notes: t('shieldSpecialFall2017RogueNotes', { str: 8 }), value: 80, str: 8, - canBuy: () => { - return CURRENT_SEASON === 'fall'; - }, + canBuy: () => CURRENT_SEASON === 'fall', }, fall2017Warrior: { event: EVENTS.fall2017, @@ -3816,9 +3325,7 @@ let shield = { notes: t('shieldSpecialFall2017WarriorNotes', { con: 7 }), value: 70, con: 7, - canBuy: () => { - return CURRENT_SEASON === 'fall'; - }, + canBuy: () => CURRENT_SEASON === 'fall', }, fall2017Healer: { event: EVENTS.fall2017, @@ -3828,9 +3335,7 @@ let shield = { notes: t('shieldSpecialFall2017HealerNotes', { con: 9 }), value: 70, con: 9, - canBuy: () => { - return CURRENT_SEASON === 'fall'; - }, + canBuy: () => CURRENT_SEASON === 'fall', }, winter2018Rogue: { event: EVENTS.winter2018, @@ -3840,9 +3345,7 @@ let shield = { notes: t('shieldSpecialWinter2018RogueNotes', { str: 8 }), value: 80, str: 8, - canBuy: () => { - return CURRENT_SEASON === 'winter'; - }, + canBuy: () => CURRENT_SEASON === 'winter', }, winter2018Warrior: { event: EVENTS.winter2018, @@ -3852,9 +3355,7 @@ let shield = { notes: t('shieldSpecialWinter2018WarriorNotes', { con: 7 }), value: 70, con: 7, - canBuy: () => { - return CURRENT_SEASON === 'winter'; - }, + canBuy: () => CURRENT_SEASON === 'winter', }, winter2018Healer: { event: EVENTS.winter2018, @@ -3864,9 +3365,7 @@ let shield = { notes: t('shieldSpecialWinter2018HealerNotes', { con: 9 }), value: 70, con: 9, - canBuy: () => { - return CURRENT_SEASON === 'winter'; - }, + canBuy: () => CURRENT_SEASON === 'winter', }, spring2018Rogue: { event: EVENTS.spring2018, @@ -3876,9 +3375,7 @@ let shield = { notes: t('weaponSpecialSpring2018RogueNotes', { str: 8 }), value: 80, str: 8, - canBuy: () => { - return CURRENT_SEASON === 'spring'; - }, + canBuy: () => CURRENT_SEASON === 'spring', }, spring2018Warrior: { event: EVENTS.spring2018, @@ -3888,9 +3385,7 @@ let shield = { notes: t('shieldSpecialSpring2018WarriorNotes', { con: 7 }), value: 70, con: 7, - canBuy: () => { - return CURRENT_SEASON === 'spring'; - }, + canBuy: () => CURRENT_SEASON === 'spring', }, spring2018Healer: { event: EVENTS.spring2018, @@ -3900,9 +3395,7 @@ let shield = { notes: t('shieldSpecialSpring2018HealerNotes', { con: 9 }), value: 70, con: 9, - canBuy: () => { - return CURRENT_SEASON === 'spring'; - }, + canBuy: () => CURRENT_SEASON === 'spring', }, summer2018Rogue: { event: EVENTS.summer2018, @@ -3912,9 +3405,7 @@ let shield = { notes: t('weaponSpecialSummer2018RogueNotes', { str: 8 }), value: 80, str: 8, - canBuy: () => { - return CURRENT_SEASON === 'summer'; - }, + canBuy: () => CURRENT_SEASON === 'summer', }, summer2018Warrior: { event: EVENTS.summer2018, @@ -3924,9 +3415,7 @@ let shield = { notes: t('shieldSpecialSummer2018WarriorNotes', { con: 7 }), value: 70, con: 7, - canBuy: () => { - return CURRENT_SEASON === 'summer'; - }, + canBuy: () => CURRENT_SEASON === 'summer', }, summer2018Healer: { event: EVENTS.summer2018, @@ -3936,9 +3425,7 @@ let shield = { notes: t('shieldSpecialSummer2018HealerNotes', { con: 9 }), value: 70, con: 9, - canBuy: () => { - return CURRENT_SEASON === 'summer'; - }, + canBuy: () => CURRENT_SEASON === 'summer', }, fall2018Rogue: { event: EVENTS.fall2018, @@ -3948,9 +3435,7 @@ let shield = { notes: t('shieldSpecialFall2018RogueNotes', { str: 8 }), value: 80, str: 8, - canBuy: () => { - return CURRENT_SEASON === 'fall'; - }, + canBuy: () => CURRENT_SEASON === 'fall', }, fall2018Warrior: { event: EVENTS.fall2018, @@ -3960,9 +3445,7 @@ let shield = { notes: t('shieldSpecialFall2018WarriorNotes', { con: 7 }), value: 70, con: 7, - canBuy: () => { - return CURRENT_SEASON === 'fall'; - }, + canBuy: () => CURRENT_SEASON === 'fall', }, fall2018Healer: { event: EVENTS.fall2018, @@ -3972,9 +3455,7 @@ let shield = { notes: t('shieldSpecialFall2018HealerNotes', { con: 9 }), value: 70, con: 9, - canBuy: () => { - return CURRENT_SEASON === 'fall'; - }, + canBuy: () => CURRENT_SEASON === 'fall', }, winter2019Rogue: { event: EVENTS.winter2019, @@ -4108,7 +3589,7 @@ let shield = { }, }; -let weapon = { +const weapon = { 0: backerGear.weaponSpecial0, 1: contributorGear.weaponSpecial1, 2: backerGear.weaponSpecial2, @@ -4217,9 +3698,7 @@ let weapon = { notes: t('weaponSpecialYetiNotes', { str: 15 }), str: 15, value: 90, - canBuy: () => { - return CURRENT_SEASON === 'winter'; - }, + canBuy: () => CURRENT_SEASON === 'winter', }, ski: { event: EVENTS.winter, @@ -4229,9 +3708,7 @@ let weapon = { notes: t('weaponSpecialSkiNotes', { str: 8 }), str: 8, value: 90, - canBuy: () => { - return CURRENT_SEASON === 'winter'; - }, + canBuy: () => CURRENT_SEASON === 'winter', }, candycane: { event: EVENTS.winter, @@ -4243,9 +3720,7 @@ let weapon = { int: 15, per: 7, value: 160, - canBuy: () => { - return CURRENT_SEASON === 'winter'; - }, + canBuy: () => CURRENT_SEASON === 'winter', }, snowflake: { event: EVENTS.winter, @@ -4255,9 +3730,7 @@ let weapon = { notes: t('weaponSpecialSnowflakeNotes', { int: 9 }), int: 9, value: 90, - canBuy: () => { - return CURRENT_SEASON === 'winter'; - }, + canBuy: () => CURRENT_SEASON === 'winter', }, springRogue: { event: EVENTS.spring, @@ -4267,9 +3740,7 @@ let weapon = { notes: t('weaponSpecialSpringRogueNotes', { str: 8 }), value: 80, str: 8, - canBuy: () => { - return CURRENT_SEASON === 'spring'; - }, + canBuy: () => CURRENT_SEASON === 'spring', }, springWarrior: { event: EVENTS.spring, @@ -4279,9 +3750,7 @@ let weapon = { notes: t('weaponSpecialSpringWarriorNotes', { str: 15 }), value: 90, str: 15, - canBuy: () => { - return CURRENT_SEASON === 'spring'; - }, + canBuy: () => CURRENT_SEASON === 'spring', }, springMage: { event: EVENTS.spring, @@ -4293,9 +3762,7 @@ let weapon = { value: 160, int: 15, per: 7, - canBuy: () => { - return CURRENT_SEASON === 'spring'; - }, + canBuy: () => CURRENT_SEASON === 'spring', }, springHealer: { event: EVENTS.spring, @@ -4305,9 +3772,7 @@ let weapon = { notes: t('weaponSpecialSpringHealerNotes', { int: 9 }), value: 90, int: 9, - canBuy: () => { - return CURRENT_SEASON === 'spring'; - }, + canBuy: () => CURRENT_SEASON === 'spring', }, summerRogue: { event: EVENTS.summer, @@ -4317,9 +3782,7 @@ let weapon = { notes: t('weaponSpecialSummerRogueNotes', { str: 8 }), value: 80, str: 8, - canBuy: () => { - return CURRENT_SEASON === 'summer'; - }, + canBuy: () => CURRENT_SEASON === 'summer', }, summerWarrior: { event: EVENTS.summer, @@ -4329,9 +3792,7 @@ let weapon = { notes: t('weaponSpecialSummerWarriorNotes', { str: 15 }), value: 90, str: 15, - canBuy: () => { - return CURRENT_SEASON === 'summer'; - }, + canBuy: () => CURRENT_SEASON === 'summer', }, summerMage: { event: EVENTS.summer, @@ -4343,9 +3804,7 @@ let weapon = { value: 160, int: 15, per: 7, - canBuy: () => { - return CURRENT_SEASON === 'summer'; - }, + canBuy: () => CURRENT_SEASON === 'summer', }, summerHealer: { event: EVENTS.summer, @@ -4355,9 +3814,7 @@ let weapon = { notes: t('weaponSpecialSummerHealerNotes', { int: 9 }), value: 90, int: 9, - canBuy: () => { - return CURRENT_SEASON === 'summer'; - }, + canBuy: () => CURRENT_SEASON === 'summer', }, fallRogue: { event: EVENTS.fall, @@ -4367,9 +3824,7 @@ let weapon = { notes: t('weaponSpecialFallRogueNotes', { str: 8 }), value: 80, str: 8, - canBuy: () => { - return CURRENT_SEASON === 'fall'; - }, + canBuy: () => CURRENT_SEASON === 'fall', }, fallWarrior: { event: EVENTS.fall, @@ -4379,9 +3834,7 @@ let weapon = { notes: t('weaponSpecialFallWarriorNotes', { str: 15 }), value: 90, str: 15, - canBuy: () => { - return CURRENT_SEASON === 'fall'; - }, + canBuy: () => CURRENT_SEASON === 'fall', }, fallMage: { event: EVENTS.fall, @@ -4393,9 +3846,7 @@ let weapon = { value: 160, int: 15, per: 7, - canBuy: () => { - return CURRENT_SEASON === 'fall'; - }, + canBuy: () => CURRENT_SEASON === 'fall', }, fallHealer: { event: EVENTS.fall, @@ -4405,9 +3856,7 @@ let weapon = { notes: t('weaponSpecialFallHealerNotes', { int: 9 }), value: 90, int: 9, - canBuy: () => { - return CURRENT_SEASON === 'fall'; - }, + canBuy: () => CURRENT_SEASON === 'fall', }, winter2015Rogue: { event: EVENTS.winter2015, @@ -4417,9 +3866,7 @@ let weapon = { notes: t('weaponSpecialWinter2015RogueNotes', { str: 8 }), value: 80, str: 8, - canBuy: () => { - return CURRENT_SEASON === 'winter'; - }, + canBuy: () => CURRENT_SEASON === 'winter', }, winter2015Warrior: { event: EVENTS.winter2015, @@ -4429,9 +3876,7 @@ let weapon = { notes: t('weaponSpecialWinter2015WarriorNotes', { str: 15 }), value: 90, str: 15, - canBuy: () => { - return CURRENT_SEASON === 'winter'; - }, + canBuy: () => CURRENT_SEASON === 'winter', }, winter2015Mage: { event: EVENTS.winter2015, @@ -4443,9 +3888,7 @@ let weapon = { value: 160, int: 15, per: 7, - canBuy: () => { - return CURRENT_SEASON === 'winter'; - }, + canBuy: () => CURRENT_SEASON === 'winter', }, winter2015Healer: { event: EVENTS.winter2015, @@ -4455,9 +3898,7 @@ let weapon = { notes: t('weaponSpecialWinter2015HealerNotes', { int: 9 }), value: 90, int: 9, - canBuy: () => { - return CURRENT_SEASON === 'winter'; - }, + canBuy: () => CURRENT_SEASON === 'winter', }, spring2015Rogue: { event: EVENTS.spring2015, @@ -4467,9 +3908,7 @@ let weapon = { notes: t('weaponSpecialSpring2015RogueNotes', { str: 8 }), value: 80, str: 8, - canBuy: () => { - return CURRENT_SEASON === 'spring'; - }, + canBuy: () => CURRENT_SEASON === 'spring', }, spring2015Warrior: { event: EVENTS.spring2015, @@ -4479,9 +3918,7 @@ let weapon = { notes: t('weaponSpecialSpring2015WarriorNotes', { str: 15 }), value: 90, str: 15, - canBuy: () => { - return CURRENT_SEASON === 'spring'; - }, + canBuy: () => CURRENT_SEASON === 'spring', }, spring2015Mage: { event: EVENTS.spring2015, @@ -4493,9 +3930,7 @@ let weapon = { value: 160, int: 15, per: 7, - canBuy: () => { - return CURRENT_SEASON === 'spring'; - }, + canBuy: () => CURRENT_SEASON === 'spring', }, spring2015Healer: { event: EVENTS.spring2015, @@ -4505,9 +3940,7 @@ let weapon = { notes: t('weaponSpecialSpring2015HealerNotes', { int: 9 }), value: 90, int: 9, - canBuy: () => { - return CURRENT_SEASON === 'spring'; - }, + canBuy: () => CURRENT_SEASON === 'spring', }, summer2015Rogue: { event: EVENTS.summer2015, @@ -4517,9 +3950,7 @@ let weapon = { notes: t('weaponSpecialSummer2015RogueNotes', { str: 8 }), value: 80, str: 8, - canBuy: () => { - return CURRENT_SEASON === 'summer'; - }, + canBuy: () => CURRENT_SEASON === 'summer', }, summer2015Warrior: { event: EVENTS.summer2015, @@ -4529,9 +3960,7 @@ let weapon = { notes: t('weaponSpecialSummer2015WarriorNotes', { str: 15 }), value: 90, str: 15, - canBuy: () => { - return CURRENT_SEASON === 'summer'; - }, + canBuy: () => CURRENT_SEASON === 'summer', }, summer2015Mage: { event: EVENTS.summer2015, @@ -4543,9 +3972,7 @@ let weapon = { value: 160, int: 15, per: 7, - canBuy: () => { - return CURRENT_SEASON === 'summer'; - }, + canBuy: () => CURRENT_SEASON === 'summer', }, summer2015Healer: { event: EVENTS.summer2015, @@ -4555,9 +3982,7 @@ let weapon = { notes: t('weaponSpecialSummer2015HealerNotes', { int: 9 }), value: 90, int: 9, - canBuy: () => { - return CURRENT_SEASON === 'summer'; - }, + canBuy: () => CURRENT_SEASON === 'summer', }, fall2015Rogue: { event: EVENTS.fall2015, @@ -4567,9 +3992,7 @@ let weapon = { notes: t('weaponSpecialFall2015RogueNotes', { str: 8 }), value: 80, str: 8, - canBuy: () => { - return CURRENT_SEASON === 'fall'; - }, + canBuy: () => CURRENT_SEASON === 'fall', }, fall2015Warrior: { event: EVENTS.fall2015, @@ -4579,9 +4002,7 @@ let weapon = { notes: t('weaponSpecialFall2015WarriorNotes', { str: 15 }), value: 90, str: 15, - canBuy: () => { - return CURRENT_SEASON === 'fall'; - }, + canBuy: () => CURRENT_SEASON === 'fall', }, fall2015Mage: { event: EVENTS.fall2015, @@ -4593,9 +4014,7 @@ let weapon = { value: 160, int: 15, per: 7, - canBuy: () => { - return CURRENT_SEASON === 'fall'; - }, + canBuy: () => CURRENT_SEASON === 'fall', }, fall2015Healer: { event: EVENTS.fall2015, @@ -4605,9 +4024,7 @@ let weapon = { notes: t('weaponSpecialFall2015HealerNotes', { int: 9 }), value: 90, int: 9, - canBuy: () => { - return CURRENT_SEASON === 'fall'; - }, + canBuy: () => CURRENT_SEASON === 'fall', }, winter2016Rogue: { event: EVENTS.winter2016, @@ -4617,9 +4034,7 @@ let weapon = { notes: t('weaponSpecialWinter2016RogueNotes', { str: 8 }), value: 80, str: 8, - canBuy: () => { - return CURRENT_SEASON === 'winter'; - }, + canBuy: () => CURRENT_SEASON === 'winter', }, winter2016Warrior: { event: EVENTS.winter2016, @@ -4629,9 +4044,7 @@ let weapon = { notes: t('weaponSpecialWinter2016WarriorNotes', { str: 15 }), value: 90, str: 15, - canBuy: () => { - return CURRENT_SEASON === 'winter'; - }, + canBuy: () => CURRENT_SEASON === 'winter', }, winter2016Mage: { event: EVENTS.winter2016, @@ -4643,9 +4056,7 @@ let weapon = { value: 160, int: 15, per: 7, - canBuy: () => { - return CURRENT_SEASON === 'winter'; - }, + canBuy: () => CURRENT_SEASON === 'winter', }, winter2016Healer: { event: EVENTS.winter2016, @@ -4655,9 +4066,7 @@ let weapon = { notes: t('weaponSpecialWinter2016HealerNotes', { int: 9 }), value: 90, int: 9, - canBuy: () => { - return CURRENT_SEASON === 'winter'; - }, + canBuy: () => CURRENT_SEASON === 'winter', }, spring2016Rogue: { event: EVENTS.spring2016, @@ -4667,9 +4076,7 @@ let weapon = { notes: t('weaponSpecialSpring2016RogueNotes', { str: 8 }), value: 80, str: 8, - canBuy: () => { - return CURRENT_SEASON === 'spring'; - }, + canBuy: () => CURRENT_SEASON === 'spring', }, spring2016Warrior: { event: EVENTS.spring2016, @@ -4679,9 +4086,7 @@ let weapon = { notes: t('weaponSpecialSpring2016WarriorNotes', { str: 15 }), value: 90, str: 15, - canBuy: () => { - return CURRENT_SEASON === 'spring'; - }, + canBuy: () => CURRENT_SEASON === 'spring', }, spring2016Mage: { event: EVENTS.spring2016, @@ -4693,9 +4098,7 @@ let weapon = { value: 160, int: 15, per: 7, - canBuy: () => { - return CURRENT_SEASON === 'spring'; - }, + canBuy: () => CURRENT_SEASON === 'spring', }, spring2016Healer: { event: EVENTS.spring2016, @@ -4705,9 +4108,7 @@ let weapon = { notes: t('weaponSpecialSpring2016HealerNotes', { int: 9 }), value: 90, int: 9, - canBuy: () => { - return CURRENT_SEASON === 'spring'; - }, + canBuy: () => CURRENT_SEASON === 'spring', }, summer2016Rogue: { event: EVENTS.summer2016, @@ -4717,9 +4118,7 @@ let weapon = { notes: t('weaponSpecialSummer2016RogueNotes', { str: 8 }), value: 80, str: 8, - canBuy: () => { - return CURRENT_SEASON === 'summer'; - }, + canBuy: () => CURRENT_SEASON === 'summer', }, summer2016Warrior: { event: EVENTS.summer2016, @@ -4729,9 +4128,7 @@ let weapon = { notes: t('weaponSpecialSummer2016WarriorNotes', { str: 15 }), value: 90, str: 15, - canBuy: () => { - return CURRENT_SEASON === 'summer'; - }, + canBuy: () => CURRENT_SEASON === 'summer', }, summer2016Mage: { event: EVENTS.summer2016, @@ -4743,9 +4140,7 @@ let weapon = { value: 160, int: 15, per: 7, - canBuy: () => { - return CURRENT_SEASON === 'summer'; - }, + canBuy: () => CURRENT_SEASON === 'summer', }, summer2016Healer: { event: EVENTS.summer2016, @@ -4755,9 +4150,7 @@ let weapon = { notes: t('weaponSpecialSummer2016HealerNotes', { int: 9 }), value: 90, int: 9, - canBuy: () => { - return CURRENT_SEASON === 'summer'; - }, + canBuy: () => CURRENT_SEASON === 'summer', }, fall2016Rogue: { event: EVENTS.fall2016, @@ -4767,9 +4160,7 @@ let weapon = { notes: t('weaponSpecialFall2016RogueNotes', { str: 8 }), value: 80, str: 8, - canBuy: () => { - return CURRENT_SEASON === 'fall'; - }, + canBuy: () => CURRENT_SEASON === 'fall', }, fall2016Warrior: { event: EVENTS.fall2016, @@ -4779,9 +4170,7 @@ let weapon = { notes: t('weaponSpecialFall2016WarriorNotes', { str: 15 }), value: 90, str: 15, - canBuy: () => { - return CURRENT_SEASON === 'fall'; - }, + canBuy: () => CURRENT_SEASON === 'fall', }, fall2016Mage: { event: EVENTS.fall2016, @@ -4793,9 +4182,7 @@ let weapon = { value: 160, int: 15, per: 7, - canBuy: () => { - return CURRENT_SEASON === 'fall'; - }, + canBuy: () => CURRENT_SEASON === 'fall', }, fall2016Healer: { event: EVENTS.fall2016, @@ -4805,9 +4192,7 @@ let weapon = { notes: t('weaponSpecialFall2016HealerNotes', { int: 9 }), value: 90, int: 9, - canBuy: () => { - return CURRENT_SEASON === 'fall'; - }, + canBuy: () => CURRENT_SEASON === 'fall', }, winter2017Rogue: { event: EVENTS.winter2017, @@ -4817,9 +4202,7 @@ let weapon = { notes: t('weaponSpecialWinter2017RogueNotes', { str: 8 }), value: 80, str: 8, - canBuy: () => { - return CURRENT_SEASON === 'winter'; - }, + canBuy: () => CURRENT_SEASON === 'winter', }, winter2017Warrior: { event: EVENTS.winter2017, @@ -4829,9 +4212,7 @@ let weapon = { notes: t('weaponSpecialWinter2017WarriorNotes', { str: 15 }), value: 90, str: 15, - canBuy: () => { - return CURRENT_SEASON === 'winter'; - }, + canBuy: () => CURRENT_SEASON === 'winter', }, winter2017Mage: { event: EVENTS.winter2017, @@ -4843,9 +4224,7 @@ let weapon = { value: 170, int: 15, per: 7, - canBuy: () => { - return CURRENT_SEASON === 'winter'; - }, + canBuy: () => CURRENT_SEASON === 'winter', }, winter2017Healer: { event: EVENTS.winter2017, @@ -4855,9 +4234,7 @@ let weapon = { notes: t('weaponSpecialWinter2017HealerNotes', { int: 9 }), value: 90, int: 9, - canBuy: () => { - return CURRENT_SEASON === 'winter'; - }, + canBuy: () => CURRENT_SEASON === 'winter', }, spring2017Rogue: { event: EVENTS.spring2017, @@ -4867,9 +4244,7 @@ let weapon = { notes: t('weaponSpecialSpring2017RogueNotes', { str: 8 }), value: 80, str: 8, - canBuy: () => { - return CURRENT_SEASON === 'spring'; - }, + canBuy: () => CURRENT_SEASON === 'spring', }, spring2017Warrior: { event: EVENTS.spring2017, @@ -4879,9 +4254,7 @@ let weapon = { notes: t('weaponSpecialSpring2017WarriorNotes', { str: 15 }), value: 90, str: 15, - canBuy: () => { - return CURRENT_SEASON === 'spring'; - }, + canBuy: () => CURRENT_SEASON === 'spring', }, spring2017Mage: { event: EVENTS.spring2017, @@ -4893,9 +4266,7 @@ let weapon = { value: 160, int: 15, per: 7, - canBuy: () => { - return CURRENT_SEASON === 'spring'; - }, + canBuy: () => CURRENT_SEASON === 'spring', }, spring2017Healer: { event: EVENTS.spring2017, @@ -4905,9 +4276,7 @@ let weapon = { notes: t('weaponSpecialSpring2017HealerNotes', { int: 9 }), value: 90, int: 9, - canBuy: () => { - return CURRENT_SEASON === 'spring'; - }, + canBuy: () => CURRENT_SEASON === 'spring', }, summer2017Rogue: { event: EVENTS.summer2017, @@ -4917,9 +4286,7 @@ let weapon = { notes: t('weaponSpecialSummer2017RogueNotes', { str: 8 }), value: 80, str: 8, - canBuy: () => { - return CURRENT_SEASON === 'summer'; - }, + canBuy: () => CURRENT_SEASON === 'summer', }, summer2017Warrior: { event: EVENTS.summer2017, @@ -4929,9 +4296,7 @@ let weapon = { notes: t('weaponSpecialSummer2017WarriorNotes', { str: 15 }), value: 90, str: 15, - canBuy: () => { - return CURRENT_SEASON === 'summer'; - }, + canBuy: () => CURRENT_SEASON === 'summer', }, summer2017Mage: { event: EVENTS.summer2017, @@ -4943,9 +4308,7 @@ let weapon = { value: 160, int: 15, per: 7, - canBuy: () => { - return CURRENT_SEASON === 'summer'; - }, + canBuy: () => CURRENT_SEASON === 'summer', }, summer2017Healer: { event: EVENTS.summer2017, @@ -4955,9 +4318,7 @@ let weapon = { notes: t('weaponSpecialSummer2017HealerNotes', { int: 9 }), value: 90, int: 9, - canBuy: () => { - return CURRENT_SEASON === 'summer'; - }, + canBuy: () => CURRENT_SEASON === 'summer', }, fall2017Rogue: { event: EVENTS.fall2017, @@ -4967,9 +4328,7 @@ let weapon = { notes: t('weaponSpecialFall2017RogueNotes', { str: 8 }), value: 80, str: 8, - canBuy: () => { - return CURRENT_SEASON === 'fall'; - }, + canBuy: () => CURRENT_SEASON === 'fall', }, fall2017Warrior: { event: EVENTS.fall2017, @@ -4979,9 +4338,7 @@ let weapon = { notes: t('weaponSpecialFall2017WarriorNotes', { str: 15 }), value: 90, str: 15, - canBuy: () => { - return CURRENT_SEASON === 'fall'; - }, + canBuy: () => CURRENT_SEASON === 'fall', }, fall2017Mage: { event: EVENTS.fall2017, @@ -4993,9 +4350,7 @@ let weapon = { value: 160, int: 15, per: 7, - canBuy: () => { - return CURRENT_SEASON === 'fall'; - }, + canBuy: () => CURRENT_SEASON === 'fall', }, fall2017Healer: { event: EVENTS.fall2017, @@ -5005,9 +4360,7 @@ let weapon = { notes: t('weaponSpecialFall2017HealerNotes', { int: 9 }), value: 90, int: 9, - canBuy: () => { - return CURRENT_SEASON === 'fall'; - }, + canBuy: () => CURRENT_SEASON === 'fall', }, winter2018Rogue: { event: EVENTS.winter2018, @@ -5017,9 +4370,7 @@ let weapon = { notes: t('weaponSpecialWinter2018RogueNotes', { str: 8 }), value: 80, str: 8, - canBuy: () => { - return CURRENT_SEASON === 'winter'; - }, + canBuy: () => CURRENT_SEASON === 'winter', }, winter2018Warrior: { event: EVENTS.winter2018, @@ -5029,9 +4380,7 @@ let weapon = { notes: t('weaponSpecialWinter2018WarriorNotes', { str: 15 }), value: 90, str: 15, - canBuy: () => { - return CURRENT_SEASON === 'winter'; - }, + canBuy: () => CURRENT_SEASON === 'winter', }, winter2018Mage: { event: EVENTS.winter2018, @@ -5043,9 +4392,7 @@ let weapon = { value: 170, int: 15, per: 7, - canBuy: () => { - return CURRENT_SEASON === 'winter'; - }, + canBuy: () => CURRENT_SEASON === 'winter', }, winter2018Healer: { event: EVENTS.winter2018, @@ -5055,9 +4402,7 @@ let weapon = { notes: t('weaponSpecialWinter2018HealerNotes', { int: 9 }), value: 90, int: 9, - canBuy: () => { - return CURRENT_SEASON === 'winter'; - }, + canBuy: () => CURRENT_SEASON === 'winter', }, spring2018Rogue: { event: EVENTS.spring2018, @@ -5067,9 +4412,7 @@ let weapon = { notes: t('weaponSpecialSpring2018RogueNotes', { str: 8 }), value: 80, str: 8, - canBuy: () => { - return CURRENT_SEASON === 'spring'; - }, + canBuy: () => CURRENT_SEASON === 'spring', }, spring2018Warrior: { event: EVENTS.spring2018, @@ -5079,9 +4422,7 @@ let weapon = { notes: t('weaponSpecialSpring2018WarriorNotes', { str: 15 }), value: 90, str: 15, - canBuy: () => { - return CURRENT_SEASON === 'spring'; - }, + canBuy: () => CURRENT_SEASON === 'spring', }, spring2018Mage: { event: EVENTS.spring2018, @@ -5093,9 +4434,7 @@ let weapon = { value: 160, int: 15, per: 7, - canBuy: () => { - return CURRENT_SEASON === 'spring'; - }, + canBuy: () => CURRENT_SEASON === 'spring', }, spring2018Healer: { event: EVENTS.spring2018, @@ -5105,9 +4444,7 @@ let weapon = { notes: t('weaponSpecialSpring2018HealerNotes', { int: 9 }), value: 90, int: 9, - canBuy: () => { - return CURRENT_SEASON === 'spring'; - }, + canBuy: () => CURRENT_SEASON === 'spring', }, summer2018Rogue: { event: EVENTS.summer2018, @@ -5117,9 +4454,7 @@ let weapon = { notes: t('weaponSpecialSummer2018RogueNotes', { str: 8 }), value: 80, str: 8, - canBuy: () => { - return CURRENT_SEASON === 'summer'; - }, + canBuy: () => CURRENT_SEASON === 'summer', }, summer2018Warrior: { event: EVENTS.summer2018, @@ -5129,9 +4464,7 @@ let weapon = { notes: t('weaponSpecialSummer2018WarriorNotes', { str: 15 }), value: 90, str: 15, - canBuy: () => { - return CURRENT_SEASON === 'summer'; - }, + canBuy: () => CURRENT_SEASON === 'summer', }, summer2018Mage: { event: EVENTS.summer2018, @@ -5143,9 +4476,7 @@ let weapon = { value: 160, int: 15, per: 7, - canBuy: () => { - return CURRENT_SEASON === 'summer'; - }, + canBuy: () => CURRENT_SEASON === 'summer', }, summer2018Healer: { event: EVENTS.summer2018, @@ -5155,9 +4486,7 @@ let weapon = { notes: t('weaponSpecialSummer2018HealerNotes', { int: 9 }), value: 90, int: 9, - canBuy: () => { - return CURRENT_SEASON === 'summer'; - }, + canBuy: () => CURRENT_SEASON === 'summer', }, fall2018Rogue: { event: EVENTS.fall2018, @@ -5167,9 +4496,7 @@ let weapon = { notes: t('weaponSpecialFall2018RogueNotes', { str: 8 }), value: 80, str: 8, - canBuy: () => { - return CURRENT_SEASON === 'fall'; - }, + canBuy: () => CURRENT_SEASON === 'fall', }, fall2018Warrior: { event: EVENTS.fall2018, @@ -5179,9 +4506,7 @@ let weapon = { notes: t('weaponSpecialFall2018WarriorNotes', { str: 15 }), value: 90, str: 15, - canBuy: () => { - return CURRENT_SEASON === 'fall'; - }, + canBuy: () => CURRENT_SEASON === 'fall', }, fall2018Mage: { event: EVENTS.fall2018, @@ -5193,9 +4518,7 @@ let weapon = { value: 160, int: 15, per: 7, - canBuy: () => { - return CURRENT_SEASON === 'fall'; - }, + canBuy: () => CURRENT_SEASON === 'fall', }, fall2018Healer: { event: EVENTS.fall2018, @@ -5205,9 +4528,7 @@ let weapon = { notes: t('weaponSpecialFall2018HealerNotes', { int: 9 }), value: 90, int: 9, - canBuy: () => { - return CURRENT_SEASON === 'fall'; - }, + canBuy: () => CURRENT_SEASON === 'fall', }, winter2019Rogue: { event: EVENTS.winter2019, @@ -5377,4 +4698,4 @@ export { headAccessory, shield, weapon, -}; \ No newline at end of file +}; diff --git a/website/common/script/content/gear/sets/special/special-backer.js b/website/common/script/content/gear/sets/special/special-backer.js index d4b7a4e6f3..599009fce6 100644 --- a/website/common/script/content/gear/sets/special/special-backer.js +++ b/website/common/script/content/gear/sets/special/special-backer.js @@ -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); - }; + 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, @@ -88,4 +86,4 @@ export { weaponSpecial0, weaponSpecial2, weaponSpecial3, -}; \ No newline at end of file +}; diff --git a/website/common/script/content/gear/sets/special/special-contributor.js b/website/common/script/content/gear/sets/special/special-contributor.js index 478d3ff5cb..c5de25b1c6 100644 --- a/website/common/script/content/gear/sets/special/special-contributor.js +++ b/website/common/script/content/gear/sets/special/special-contributor.js @@ -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); - }; + 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; }, @@ -74,4 +72,4 @@ export { shieldSpecial1, weaponSpecial1, weaponSpecialCritical, -}; \ No newline at end of file +}; diff --git a/website/common/script/content/gear/sets/special/special-takeThis.js b/website/common/script/content/gear/sets/special/special-takeThis.js index efd21f1d53..2bab7ec50c 100644 --- a/website/common/script/content/gear/sets/special/special-takeThis.js +++ b/website/common/script/content/gear/sets/special/special-takeThis.js @@ -1,8 +1,8 @@ import t from '../../../translation'; -let armorSpecialTakeThis = { +const armorSpecialTakeThis = { text: t('armorSpecialTakeThisText'), - notes: t('armorSpecialTakeThisNotes', {attrs: 5}), + notes: t('armorSpecialTakeThisNotes', { attrs: 5 }), value: 0, con: 5, int: 5, @@ -10,9 +10,9 @@ let armorSpecialTakeThis = { str: 5, }; -let backSpecialTakeThis = { +const backSpecialTakeThis = { text: t('backSpecialTakeThisText'), - notes: t('backSpecialTakeThisNotes', {attrs: 1}), + notes: t('backSpecialTakeThisNotes', { attrs: 1 }), value: 0, con: 1, int: 1, @@ -20,9 +20,9 @@ let backSpecialTakeThis = { str: 1, }; -let bodySpecialTakeThis = { +const bodySpecialTakeThis = { text: t('bodySpecialTakeThisText'), - notes: t('bodySpecialTakeThisNotes', {attrs: 1}), + notes: t('bodySpecialTakeThisNotes', { attrs: 1 }), value: 0, con: 1, int: 1, @@ -30,9 +30,9 @@ let bodySpecialTakeThis = { str: 1, }; -let headSpecialTakeThis = { +const headSpecialTakeThis = { text: t('headSpecialTakeThisText'), - notes: t('headSpecialTakeThisNotes', {attrs: 5}), + notes: t('headSpecialTakeThisNotes', { attrs: 5 }), value: 0, con: 5, int: 5, @@ -40,9 +40,9 @@ let headSpecialTakeThis = { str: 5, }; -let shieldSpecialTakeThis = { +const shieldSpecialTakeThis = { text: t('shieldSpecialTakeThisText'), - notes: t('shieldSpecialTakeThisNotes', {attrs: 5}), + notes: t('shieldSpecialTakeThisNotes', { attrs: 5 }), value: 0, con: 5, int: 5, @@ -50,9 +50,9 @@ let shieldSpecialTakeThis = { str: 5, }; -let weaponSpecialTakeThis = { +const weaponSpecialTakeThis = { text: t('weaponSpecialTakeThisText'), - notes: t('weaponSpecialTakeThisNotes', {attrs: 5}), + notes: t('weaponSpecialTakeThisNotes', { attrs: 5 }), value: 0, con: 5, int: 5, @@ -67,4 +67,4 @@ export { headSpecialTakeThis, shieldSpecialTakeThis, weaponSpecialTakeThis, -}; \ No newline at end of file +}; diff --git a/website/common/script/content/gear/sets/special/special-wondercon.js b/website/common/script/content/gear/sets/special/special-wondercon.js index e4862d9c3b..13cf36b55d 100644 --- a/website/common/script/content/gear/sets/special/special-wondercon.js +++ b/website/common/script/content/gear/sets/special/special-wondercon.js @@ -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, @@ -57,4 +57,4 @@ export { bodySpecialWonderconBlack, eyewearSpecialWonderconRed, eyewearSpecialWonderconBlack, -}; \ No newline at end of file +}; diff --git a/website/common/script/content/gear/sets/warrior.js b/website/common/script/content/gear/sets/warrior.js index 689ad716fc..2a479d6caa 100644 --- a/website/common/script/content/gear/sets/warrior.js +++ b/website/common/script/content/gear/sets/warrior.js @@ -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 }), @@ -150,4 +152,4 @@ export { head, shield, weapon, -}; \ No newline at end of file +}; diff --git a/website/common/script/content/gear/sets/wizard.js b/website/common/script/content/gear/sets/wizard.js index f3f34e9156..db1178714c 100644 --- a/website/common/script/content/gear/sets/wizard.js +++ b/website/common/script/content/gear/sets/wizard.js @@ -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'), @@ -136,4 +138,4 @@ export { head, shield, weapon, -}; \ No newline at end of file +}; diff --git a/website/common/script/content/gear/shield.js b/website/common/script/content/gear/shield.js index b04af0f52a..46afefd3bb 100644 --- a/website/common/script/content/gear/shield.js +++ b/website/common/script/content/gear/shield.js @@ -1,19 +1,19 @@ import cloneDeep from 'lodash/cloneDeep'; -import {shield as baseShield} from './sets/base'; +import { shield as baseShield } from './sets/base'; -import {shield as healerShield} from './sets/healer'; -import {weapon as rogueWeapon} from './sets/rogue'; -import {shield as warriorShield} from './sets/warrior'; -import {shield as wizardShield} from './sets/wizard'; +import { shield as healerShield } from './sets/healer'; +import { weapon as rogueWeapon } from './sets/rogue'; +import { shield as warriorShield } from './sets/warrior'; +import { shield as wizardShield } from './sets/wizard'; -import {shield as armoireShield} from './sets/armoire'; -import {shield as mysteryShield} from './sets/mystery'; -import {shield as specialShield} from './sets/special'; +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, diff --git a/website/common/script/content/gear/weapon.js b/website/common/script/content/gear/weapon.js index ca1a0527b0..98ce8e5829 100644 --- a/website/common/script/content/gear/weapon.js +++ b/website/common/script/content/gear/weapon.js @@ -1,17 +1,17 @@ import t from '../translation'; -import {weapon as baseWeapon} from './sets/base'; +import { weapon as baseWeapon } from './sets/base'; -import {weapon as healerWeapon} from './sets/healer'; -import {weapon as rogueWeapon} from './sets/rogue'; -import {weapon as warriorWeapon} from './sets/warrior'; -import {weapon as wizardWeapon} from './sets/wizard'; +import { weapon as healerWeapon } from './sets/healer'; +import { weapon as rogueWeapon } from './sets/rogue'; +import { weapon as warriorWeapon } from './sets/warrior'; +import { weapon as wizardWeapon } from './sets/wizard'; -import {weapon as armoireWeapon} from './sets/armoire'; -import {weapon as mysteryWeapon} from './sets/mystery'; -import {weapon as specialWeapon} from './sets/special'; +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, @@ -27,31 +27,31 @@ let weapon = { // Add Two Handed message to all weapons const rtlLanguages = [ 'ae', /* Avestan */ - 'ar', /* 'العربية', Arabic */ - 'arc', /* Aramaic */ - 'bcc', /* 'بلوچی مکرانی', Southern Balochi */ - 'bqi', /* 'بختياري', Bakthiari */ - 'ckb', /* 'Soranî / کوردی', Sorani */ - 'dv', /* Dhivehi */ - 'fa', /* 'فارسی', Persian */ - 'glk', /* 'گیلکی', Gilaki */ - 'he', /* 'עברית', Hebrew */ - 'ku', /* 'Kurdî / كوردی', Kurdish */ - 'mzn', /* 'مازِرونی', Mazanderani */ - 'nqo', /* N'Ko */ - 'pnb', /* 'پنجابی', Western Punjabi */ - 'ps', /* 'پښتو', Pashto, */ - 'sd', /* 'سنڌي', Sindhi */ - 'ug', /* 'Uyghurche / ئۇيغۇرچە', Uyghur */ - 'ur', /* 'اردو', Urdu */ - 'yi', /* 'ייִדיש', Yiddish */ + 'ar', /* 'العربية', Arabic */ + 'arc', /* Aramaic */ + 'bcc', /* 'بلوچی مکرانی', Southern Balochi */ + 'bqi', /* 'بختياري', Bakthiari */ + 'ckb', /* 'Soranî / کوردی', Sorani */ + 'dv', /* Dhivehi */ + 'fa', /* 'فارسی', Persian */ + 'glk', /* 'گیلکی', Gilaki */ + 'he', /* 'עברית', Hebrew */ + 'ku', /* 'Kurdî / كوردی', Kurdish */ + 'mzn', /* 'مازِرونی', Mazanderani */ + 'nqo', /* N'Ko */ + 'pnb', /* 'پنجابی', Western Punjabi */ + 'ps', /* 'پښتو', Pashto, */ + 'sd', /* 'سنڌي', Sindhi */ + 'ug', /* 'Uyghurche / ئۇيغۇرچە', Uyghur */ + '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) { diff --git a/website/common/script/content/hatching-potions.js b/website/common/script/content/hatching-potions.js index b2001593d0..8a77355f3a 100644 --- a/website/common/script/content/hatching-potions.js +++ b/website/common/script/content/hatching-potions.js @@ -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, diff --git a/website/common/script/content/index.js b/website/common/script/content/index.js index f0daf5e527..b020eb10d0 100644 --- a/website/common/script/content/index.js +++ b/website/common/script/content/index.js @@ -2,7 +2,7 @@ import defaults from 'lodash/defaults'; import each from 'lodash/each'; import moment from 'moment'; import t from './translation'; -import {tasksByCategory} from './tasks'; +import { tasksByCategory } from './tasks'; import { CLASSES, @@ -12,8 +12,6 @@ import { ANIMAL_COLOR_ACHIEVEMENTS, } from './constants'; -const api = {}; - import achievements from './achievements'; import * as eggs from './eggs'; @@ -27,7 +25,7 @@ import { } from './quests'; import appearances from './appearance'; -import {backgroundsTree, backgroundsFlat} from './appearance/backgrounds'; +import { backgroundsTree, backgroundsFlat } from './appearance/backgrounds'; import spells from './spells'; import subscriptionBlocks from './subscriptionBlocks'; import faq from './faq'; @@ -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,17 +810,15 @@ api.food = { /* eslint-enable camelcase */ }; -each(api.food, (food, key) => { - return defaults(food, { - value: 1, - key, - notes: t('foodNotes'), - canBuy () { - return false; - }, - canDrop: false, - }); -}); +each(api.food, (food, key) => defaults(food, { + value: 1, + key, + notes: t('foodNotes'), + canBuy () { + return false; + }, + canDrop: false, +})); api.appearances = appearances; @@ -837,9 +835,9 @@ api.userDefaults = { down: false, attribute: 'per', tags: [ - t('defaultTag1'), // Work - t('defaultTag4'), // School - t('defaultTag6'), // Chores + t('defaultTag1'), // Work + t('defaultTag4'), // School + t('defaultTag6'), // Chores ], }, { type: 'habit', @@ -849,7 +847,7 @@ api.userDefaults = { down: true, attribute: 'str', tags: [ - t('defaultTag3'), // Health + Wellness + t('defaultTag3'), // Health + Wellness ], }, { type: 'habit', @@ -859,8 +857,8 @@ api.userDefaults = { down: true, attribute: 'str', tags: [ - t('defaultTag2'), // Exercise - t('defaultTag3'), // Health + Wellness + t('defaultTag2'), // Exercise + t('defaultTag3'), // Health + Wellness ], }, ], diff --git a/website/common/script/content/loginIncentives.js b/website/common/script/content/loginIncentives.js index 691d3d929d..c4d1363b4f 100644 --- a/website/common/script/content/loginIncentives.js +++ b/website/common/script/content/loginIncentives.js @@ -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; }); diff --git a/website/common/script/content/mystery-sets.js b/website/common/script/content/mystery-sets.js index d4223f3406..560e26ebf0 100644 --- a/website/common/script/content/mystery-sets.js +++ b/website/common/script/content/mystery-sets.js @@ -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', diff --git a/website/common/script/content/quests.js b/website/common/script/content/quests.js index 8fb2c90afc..be1795c4da 100644 --- a/website/common/script/content/quests.js +++ b/website/common/script/content/quests.js @@ -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'), @@ -2261,7 +2261,7 @@ let quests = { unlockCondition: { condition: 'party invite', incentiveThreshold: 7, - text: t('loginReward', {count: 7}), + text: t('loginReward', { count: 7 }), }, collect: { shard: { @@ -2292,7 +2292,7 @@ let quests = { unlockCondition: { condition: 'party invite', incentiveThreshold: 22, - text: t('loginReward', {count: 22}), + text: t('loginReward', { count: 22 }), }, boss: { name: t('questMoon2Boss'), @@ -2322,7 +2322,7 @@ let quests = { unlockCondition: { condition: 'party invite', incentiveThreshold: 40, - text: t('loginReward', {count: 40}), + text: t('loginReward', { count: 40 }), }, boss: { name: t('questMoon3Boss'), @@ -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, diff --git a/website/common/script/content/spells.js b/website/common/script/content/spells.js index 657294fe26..809f4a6e8d 100644 --- a/website/common/script/content/spells.js +++ b/website/common/script/content/spells.js @@ -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', { - card: 'nye', - from: { - id: user._id, - name: senderName, - }, - }); + 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', { - card: 'valentine', - from: { - id: user._id, - name: senderName, - }, - }); + 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', { - card: 'greeting', - from: { - id: user._id, - name: senderName, - }, - }); + 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', { - card: 'thankyou', - from: { - id: user._id, - name: senderName, - }, - }); + 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', { - card: 'birthday', - from: { - id: user._id, - name: senderName, - }, - }); + 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', { - card: 'congrats', - from: { - id: user._id, - name: senderName, - }, - }); + 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', { - card: 'getwell', - from: { - id: user._id, - name: senderName, - }, - }); + 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', { - card: 'goodluck', - from: { - id: user._id, - name: senderName, - }, - }); + 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; diff --git a/website/common/script/content/stable.js b/website/common/script/content/stable.js index 016611e72f..387633d220 100644 --- a/website/common/script/content/stable.js +++ b/website/common/script/content/stable.js @@ -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', diff --git a/website/common/script/content/subscriptionBlocks.js b/website/common/script/content/subscriptionBlocks.js index 69beedc6db..4de82ea711 100644 --- a/website/common/script/content/subscriptionBlocks.js +++ b/website/common/script/content/subscriptionBlocks.js @@ -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; diff --git a/website/common/script/content/time-travelers.js b/website/common/script/content/time-travelers.js index 7a6b2a9ae3..eb18d340dc 100644 --- a/website/common/script/content/time-travelers.js +++ b/website/common/script/content/time-travelers.js @@ -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, { - mystery: k, - }); -}); +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) => { @@ -34,4 +32,4 @@ let timeTravelerStore = (user) => { export default { timeTravelerStore, mystery, -}; \ No newline at end of file +}; diff --git a/website/common/script/count.js b/website/common/script/count.js index 846b8efee5..6a15df8c8c 100644 --- a/website/common/script/count.js +++ b/website/common/script/count.js @@ -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; -} \ No newline at end of file +} diff --git a/website/common/script/cron.js b/website/common/script/cron.js index b93df4b80e..49ccbe86a5 100644 --- a/website/common/script/cron.js +++ b/website/common/script/cron.js @@ -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; diff --git a/website/common/script/fns/autoAllocate.js b/website/common/script/fns/autoAllocate.js index 7fa344d78e..a7244b7613 100644 --- a/website/common/script/fns/autoAllocate.js +++ b/website/common/script/fns/autoAllocate.js @@ -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]++; } diff --git a/website/common/script/fns/crit.js b/website/common/script/fns/crit.js index a0109ebe11..230b0c9b73 100644 --- a/website/common/script/fns/crit.js +++ b/website/common/script/fns/crit.js @@ -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 }; diff --git a/website/common/script/fns/handleTwoHanded.js b/website/common/script/fns/handleTwoHanded.js index 8e3911ccbd..d793e0a9d6 100644 --- a/website/common/script/fns/handleTwoHanded.js +++ b/website/common/script/fns/handleTwoHanded.js @@ -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; diff --git a/website/common/script/fns/predictableRandom.js b/website/common/script/fns/predictableRandom.js index 9d449d1b85..9407339da3 100644 --- a/website/common/script/fns/predictableRandom.js +++ b/website/common/script/fns/predictableRandom.js @@ -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); } diff --git a/website/common/script/fns/randomDrop.js b/website/common/script/fns/randomDrop.js index 11e808354e..86ef28643f 100644 --- a/website/common/script/fns/randomDrop.js +++ b/website/common/script/fns/randomDrop.js @@ -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]++; diff --git a/website/common/script/fns/resetGear.js b/website/common/script/fns/resetGear.js index 91a9b12f6d..008b1a13b9 100644 --- a/website/common/script/fns/resetGear.js +++ b/website/common/script/fns/resetGear.js @@ -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; } diff --git a/website/common/script/fns/ultimateGear.js b/website/common/script/fns/ultimateGear.js index ffd135ccbf..18cce620f7 100644 --- a/website/common/script/fns/ultimateGear.js +++ b/website/common/script/fns/ultimateGear.js @@ -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; } diff --git a/website/common/script/i18n.js b/website/common/script/i18n.js index b144c3d87f..a66cf878be 100644 --- a/website/common/script/i18n.js +++ b/website/common/script/i18n.js @@ -19,7 +19,7 @@ function t (stringName) { locale = arguments[2]; } - let i18nNotSetup = !i18n.strings && !i18n.translations[locale]; + const i18nNotSetup = !i18n.strings && !i18n.translations[locale]; if (!locale || i18nNotSetup) { locale = 'en'; @@ -33,7 +33,7 @@ function t (stringName) { string = i18n.translations[locale] && i18n.translations[locale][stringName]; } - let clonedVars = clone(vars) || {}; + const clonedVars = clone(vars) || {}; clonedVars.locale = locale; diff --git a/website/common/script/index.js b/website/common/script/index.js index e70fe94f74..eb02863df8 100644 --- a/website/common/script/index.js +++ b/website/common/script/index.js @@ -1,20 +1,12 @@ // When using a common module from the website or the server NEVER import the module directly // but access it through `api` (the main common) module, otherwise you would require the non transpiled version of the file in production. -const api = {}; - import content from './content/index'; -api.content = content; import * as errors from './libs/errors'; -api.errors = errors; import i18n from './i18n'; -api.i18n = i18n; // TODO under api.libs.cron? import { shouldDo, daysSince, DAY_MAPPING } from './cron'; -api.shouldDo = shouldDo; -api.daysSince = daysSince; -api.DAY_MAPPING = DAY_MAPPING; import { MAX_HEALTH, @@ -34,90 +26,48 @@ import { CHAT_FLAG_FROM_SHADOW_MUTE, } from './constants'; -api.constants = { - MAX_INCENTIVES, - LARGE_GROUP_COUNT_MESSAGE_CUTOFF, - MAX_SUMMARY_SIZE_FOR_GUILDS, - MAX_SUMMARY_SIZE_FOR_CHALLENGES, - MIN_SHORTNAME_SIZE_FOR_CHALLENGES, - SUPPORTED_SOCIAL_NETWORKS, - GUILDS_PER_PAGE, - PARTY_LIMIT_MEMBERS, - CHAT_FLAG_LIMIT_FOR_HIDING, - CHAT_FLAG_FROM_MOD, - CHAT_FLAG_FROM_SHADOW_MUTE, -}; -// TODO Move these under api.constants -api.maxLevel = MAX_LEVEL; -api.maxHealth = MAX_HEALTH; -api.maxStatPoints = MAX_STAT_POINTS; -api.TAVERN_ID = TAVERN_ID; - // TODO under api.libs.statHelpers? import * as statHelpers from './statHelpers'; -api.capByLevel = statHelpers.capByLevel; -api.tnl = statHelpers.toNextLevel; -api.diminishingReturns = statHelpers.diminishingReturns; import splitWhitespace from './libs/splitWhitespace'; -api.$w = splitWhitespace; import refPush from './libs/refPush'; -api.refPush = refPush; import planGemLimits from './libs/planGemLimits'; -api.planGemLimits = planGemLimits; import preenTodos from './libs/preenTodos'; -api.preenTodos = preenTodos; import updateStore from './libs/updateStore'; -api.updateStore = updateStore; import inAppRewards from './libs/inAppRewards'; -api.inAppRewards = inAppRewards; import uuid from './libs/uuid'; -api.uuid = uuid; import taskDefaults from './libs/taskDefaults'; -api.taskDefaults = taskDefaults; import percent from './libs/percent'; -api.percent = percent; import gold from './libs/gold'; -api.gold = gold; import silver from './libs/silver'; -api.silver = silver; import noTags from './libs/noTags'; -api.noTags = noTags; import appliedTags from './libs/appliedTags'; -api.appliedTags = appliedTags; import pickDeep from './libs/pickDeep'; -api.pickDeep = pickDeep; import * as count from './count'; -api.count = count; import statsComputed from './libs/statsComputed'; -api.statsComputed = statsComputed; import shops from './libs/shops'; -api.shops = shops; import achievements from './libs/achievements'; -api.achievements = achievements; import randomVal from './libs/randomVal'; -api.randomVal = randomVal; import hasClass from './libs/hasClass'; -api.hasClass = hasClass; import autoAllocate from './fns/autoAllocate'; import crit from './fns/crit'; @@ -128,17 +78,6 @@ import resetGear from './fns/resetGear'; import ultimateGear from './fns/ultimateGear'; import updateStats from './fns/updateStats'; -api.fns = { - autoAllocate, - crit, - handleTwoHanded, - predictableRandom, - randomDrop, - resetGear, - ultimateGear, - updateStats, -}; - import scoreTask from './ops/scoreTask'; import sleep from './ops/sleep'; import allocateNow from './ops/stats/allocateNow'; @@ -166,6 +105,67 @@ import reset from './ops/reset'; import markPmsRead from './ops/markPMSRead'; import * as pinnedGearUtils from './ops/pinnedGearUtils'; +const api = {}; +api.content = content; +api.errors = errors; +api.i18n = i18n; +api.shouldDo = shouldDo; +api.daysSince = daysSince; +api.DAY_MAPPING = DAY_MAPPING; + +api.constants = { + MAX_INCENTIVES, + LARGE_GROUP_COUNT_MESSAGE_CUTOFF, + MAX_SUMMARY_SIZE_FOR_GUILDS, + MAX_SUMMARY_SIZE_FOR_CHALLENGES, + MIN_SHORTNAME_SIZE_FOR_CHALLENGES, + SUPPORTED_SOCIAL_NETWORKS, + GUILDS_PER_PAGE, + PARTY_LIMIT_MEMBERS, + CHAT_FLAG_LIMIT_FOR_HIDING, + CHAT_FLAG_FROM_MOD, + CHAT_FLAG_FROM_SHADOW_MUTE, +}; +// TODO Move these under api.constants +api.maxLevel = MAX_LEVEL; +api.maxHealth = MAX_HEALTH; +api.maxStatPoints = MAX_STAT_POINTS; +api.TAVERN_ID = TAVERN_ID; +api.capByLevel = statHelpers.capByLevel; +api.tnl = statHelpers.toNextLevel; +api.diminishingReturns = statHelpers.diminishingReturns; +api.$w = splitWhitespace; +api.refPush = refPush; +api.planGemLimits = planGemLimits; +api.preenTodos = preenTodos; +api.updateStore = updateStore; +api.inAppRewards = inAppRewards; +api.uuid = uuid; +api.taskDefaults = taskDefaults; +api.percent = percent; +api.gold = gold; +api.silver = silver; +api.noTags = noTags; +api.appliedTags = appliedTags; +api.pickDeep = pickDeep; +api.count = count; +api.statsComputed = statsComputed; +api.shops = shops; +api.achievements = achievements; +api.randomVal = randomVal; +api.hasClass = hasClass; + +api.fns = { + autoAllocate, + crit, + handleTwoHanded, + predictableRandom, + randomDrop, + resetGear, + ultimateGear, + updateStats, +}; + api.ops = { scoreTask, sleep, diff --git a/website/common/script/libs/achievements.js b/website/common/script/libs/achievements.js index 6e3f85c1ad..10b0020b0f 100644 --- a/website/common/script/libs/achievements.js +++ b/website/common/script/libs/achievements.js @@ -1,15 +1,15 @@ +import get from 'lodash/get'; import content from '../content/index'; import i18n from '../i18n'; -import get from 'lodash/get'; -let achievs = {}; -let achievsContent = content.achievements; +const achievs = {}; +const achievsContent = content.achievements; let index = 0; function contribText (contrib, backer, language) { if (!contrib && !backer) return; if (backer && backer.npc) return backer.npc; - let lvl = contrib && contrib.level; + const lvl = contrib && contrib.level; if (lvl && lvl > 0) { let contribTitle = ''; @@ -44,11 +44,11 @@ function _add (result, data) { } function _addSimpleWithCustomPath (result, user, data) { - let value = get(user, data.path); - let thisContent = achievsContent[data.key]; + const value = get(user, data.path); + const thisContent = achievsContent[data.key]; _add(result, { - title: i18n.t(thisContent.titleKey, {key: value}, data.language), + title: i18n.t(thisContent.titleKey, { key: value }, data.language), text: i18n.t(thisContent.textKey, data.language), icon: thisContent.icon, key: data.key, @@ -64,10 +64,10 @@ function _addQuest (result, user, data) { } function _addSimple (result, user, data) { - let value = user.achievements[data.path]; + const value = user.achievements[data.path]; - let key = data.key || data.path; - let thisContent = achievsContent[key]; + const key = data.key || data.path; + const thisContent = achievsContent[key]; _add(result, { title: i18n.t(thisContent.titleKey, data.language), @@ -80,14 +80,14 @@ function _addSimple (result, user, data) { } function _addSimpleWithMasterCount (result, user, data) { - let language = data.language; - let value = user.achievements[`${data.path}Count`] || 0; + const { language } = data; + const value = user.achievements[`${data.path}Count`] || 0; - let thisContent = achievsContent[data.path]; + const thisContent = achievsContent[data.path]; let text = i18n.t(thisContent.textKey, language); if (value > 0) { - text += i18n.t(thisContent.text2Key, {count: value}, language); + text += i18n.t(thisContent.text2Key, { count: value }, language); } _add(result, { @@ -102,14 +102,14 @@ function _addSimpleWithMasterCount (result, user, data) { } function _addSimpleWithCount (result, user, data) { - let value = user.achievements[data.path] || 0; + const value = user.achievements[data.path] || 0; - let key = data.key || data.path; - let thisContent = achievsContent[key]; + const key = data.key || data.path; + const thisContent = achievsContent[key]; _add(result, { title: i18n.t(thisContent.titleKey, data.language), - text: i18n.t(thisContent.textKey, {count: value}, data.language), + text: i18n.t(thisContent.textKey, { count: value }, data.language), icon: thisContent.icon, key, value, @@ -119,10 +119,10 @@ function _addSimpleWithCount (result, user, data) { } function _addPlural (result, user, data) { - let value = user.achievements[data.path] || 0; + const value = user.achievements[data.path] || 0; - let key = data.key || data.path; - let thisContent = achievsContent[key]; + const key = data.key || data.path; + const thisContent = achievsContent[key]; let titleKey; let textKey; @@ -137,8 +137,8 @@ function _addPlural (result, user, data) { } _add(result, { - title: i18n.t(titleKey, {count: value}, data.language), - text: i18n.t(textKey, {count: value}, data.language), + title: i18n.t(titleKey, { count: value }, data.language), + text: i18n.t(textKey, { count: value }, data.language), icon: thisContent.icon, key, value, @@ -152,14 +152,14 @@ function _addUltimateGear (result, user, data) { data.altPath = data.path; } - let value = user.achievements.ultimateGearSets[data.altPath]; + const value = user.achievements.ultimateGearSets[data.altPath]; - let key = `${data.path}UltimateGear`; - let thisContent = achievsContent[key]; + const key = `${data.path}UltimateGear`; + const thisContent = achievsContent[key]; - let localizedClass = i18n.t(data.path, data.language); - let title = i18n.t(thisContent.titleKey, {ultClass: localizedClass}, data.language); - let text = i18n.t(thisContent.textKey, {ultClass: localizedClass}, data.language); + const localizedClass = i18n.t(data.path, data.language); + const title = i18n.t(thisContent.titleKey, { ultClass: localizedClass }, data.language); + const text = i18n.t(thisContent.textKey, { ultClass: localizedClass }, data.language); _add(result, { title, @@ -172,44 +172,44 @@ function _addUltimateGear (result, user, data) { } function _getBasicAchievements (user, language) { - let result = {}; + const result = {}; - _addPlural(result, user, {path: 'streak', language}); - _addPlural(result, user, {path: 'perfect', language}); + _addPlural(result, user, { path: 'streak', language }); + _addPlural(result, user, { path: 'perfect', language }); - _addSimple(result, user, {path: 'partyUp', language}); - _addSimple(result, user, {path: 'partyOn', language}); - _addSimple(result, user, {path: 'joinedGuild', language}); - _addSimple(result, user, {path: 'royallyLoyal', language}); - _addSimple(result, user, {path: 'joinedChallenge', language}); - _addSimple(result, user, {path: 'invitedFriend', language}); - _addSimple(result, user, {path: 'lostMasterclasser', language}); - _addSimple(result, user, {path: 'mindOverMatter', language}); - _addSimple(result, user, {path: 'justAddWater', language}); - _addSimple(result, user, {path: 'backToBasics', language}); - _addSimple(result, user, {path: 'allYourBase', language}); - _addSimple(result, user, {path: 'dustDevil', language}); - _addSimple(result, user, {path: 'aridAuthority', language}); + _addSimple(result, user, { path: 'partyUp', language }); + _addSimple(result, user, { path: 'partyOn', language }); + _addSimple(result, user, { path: 'joinedGuild', language }); + _addSimple(result, user, { path: 'royallyLoyal', language }); + _addSimple(result, user, { path: 'joinedChallenge', language }); + _addSimple(result, user, { path: 'invitedFriend', language }); + _addSimple(result, user, { path: 'lostMasterclasser', language }); + _addSimple(result, user, { path: 'mindOverMatter', language }); + _addSimple(result, user, { path: 'justAddWater', language }); + _addSimple(result, user, { path: 'backToBasics', language }); + _addSimple(result, user, { path: 'allYourBase', language }); + _addSimple(result, user, { path: 'dustDevil', language }); + _addSimple(result, user, { path: 'aridAuthority', language }); - _addSimpleWithMasterCount(result, user, {path: 'beastMaster', language}); - _addSimpleWithMasterCount(result, user, {path: 'mountMaster', language}); - _addSimpleWithMasterCount(result, user, {path: 'triadBingo', language}); + _addSimpleWithMasterCount(result, user, { path: 'beastMaster', language }); + _addSimpleWithMasterCount(result, user, { path: 'mountMaster', language }); + _addSimpleWithMasterCount(result, user, { path: 'triadBingo', language }); - _addUltimateGear(result, user, {path: 'healer', language}); - _addUltimateGear(result, user, {path: 'rogue', language}); - _addUltimateGear(result, user, {path: 'warrior', language}); - _addUltimateGear(result, user, {path: 'mage', altPath: 'wizard', language}); + _addUltimateGear(result, user, { path: 'healer', language }); + _addUltimateGear(result, user, { path: 'rogue', language }); + _addUltimateGear(result, user, { path: 'warrior', language }); + _addUltimateGear(result, user, { path: 'mage', altPath: 'wizard', language }); - let cardAchievements = ['greeting', 'thankyou', 'birthday', 'congrats', 'getwell', 'goodluck']; + const cardAchievements = ['greeting', 'thankyou', 'birthday', 'congrats', 'getwell', 'goodluck']; cardAchievements.forEach(path => { - _addSimpleWithCount(result, user, {path, key: `${path}Cards`, language}); + _addSimpleWithCount(result, user, { path, key: `${path}Cards`, language }); }); let rebirthTitle; let rebirthText; if (user.achievements.rebirths > 1) { - rebirthTitle = i18n.t('rebirthText', {rebirths: user.achievements.rebirths}, language); + rebirthTitle = i18n.t('rebirthText', { rebirths: user.achievements.rebirths }, language); } else { rebirthTitle = i18n.t('rebirthBegan', language); } @@ -217,7 +217,7 @@ function _getBasicAchievements (user, language) { if (!user.achievements.rebirthLevel) { rebirthText = i18n.t('rebirthOrbNoLevel', language); } else if (user.achievements.rebirthLevel < 100) { - rebirthText = i18n.t('rebirthOrb', {level: user.achievements.rebirthLevel}, language); + rebirthText = i18n.t('rebirthOrb', { level: user.achievements.rebirthLevel }, language); } else { rebirthText = i18n.t('rebirthOrb100', language); } @@ -235,41 +235,41 @@ function _getBasicAchievements (user, language) { } function _getSeasonalAchievements (user, language) { - let result = {}; + const result = {}; - _addPlural(result, user, {path: 'habiticaDays', language}); - _addPlural(result, user, {path: 'habitBirthdays', language}); + _addPlural(result, user, { path: 'habiticaDays', language }); + _addPlural(result, user, { path: 'habitBirthdays', language }); - let spellAchievements = ['snowball', 'spookySparkles', 'shinySeed', 'seafoam']; + const spellAchievements = ['snowball', 'spookySparkles', 'shinySeed', 'seafoam']; spellAchievements.forEach(path => { - _addSimpleWithCount(result, user, {path, language}); + _addSimpleWithCount(result, user, { path, language }); }); - let questAchievements = ['dilatory', 'stressbeast', 'burnout', 'bewilder', 'dysheartener']; + const questAchievements = ['dilatory', 'stressbeast', 'burnout', 'bewilder', 'dysheartener']; questAchievements.forEach(path => { if (user.achievements.quests[path]) { - _addQuest(result, user, {path, language}); + _addQuest(result, user, { path, language }); } }); - _addPlural(result, user, {path: 'costumeContests', language}); + _addPlural(result, user, { path: 'costumeContests', language }); - let cardAchievements = ['nye', 'valentine']; + const cardAchievements = ['nye', 'valentine']; cardAchievements.forEach(path => { - _addSimpleWithCount(result, user, {path, key: `${path}Cards`, language}); + _addSimpleWithCount(result, user, { path, key: `${path}Cards`, language }); }); return result; } function _getSpecialAchievements (user, language) { - let result = {}; + const result = {}; - _addPlural(result, user, {path: 'habitSurveys', language}); + _addPlural(result, user, { path: 'habitSurveys', language }); - let contribKey = 'contributor'; - let contribContent = achievsContent[contribKey]; - let contributorAchiev = { + const contribKey = 'contributor'; + const contribContent = achievsContent[contribKey]; + const contributorAchiev = { key: contribKey, text: i18n.t(contribContent.textKey, language), icon: contribContent.icon, @@ -285,23 +285,23 @@ function _getSpecialAchievements (user, language) { _add(result, contributorAchiev); if (user.backer && user.backer.npc) { - _addSimpleWithCustomPath(result, user, {key: 'npc', path: 'backer.npc', language}); + _addSimpleWithCustomPath(result, user, { key: 'npc', path: 'backer.npc', language }); } if (user.backer && user.backer.tier) { - _addSimpleWithCustomPath(result, user, {key: 'kickstarter', path: 'backer.tier', language}); + _addSimpleWithCustomPath(result, user, { key: 'kickstarter', path: 'backer.tier', language }); } if (user.achievements.veteran) { - _addSimple(result, user, {path: 'veteran', language}); + _addSimple(result, user, { path: 'veteran', language }); } if (user.achievements.originalUser) { - _addSimple(result, user, {path: 'originalUser', language}); + _addSimple(result, user, { path: 'originalUser', language }); } if (user.achievements.kickstarter2019) { - _addSimple(result, user, {path: 'kickstarter2019', language}); + _addSimple(result, user, { path: 'kickstarter2019', language }); } return result; @@ -309,7 +309,7 @@ function _getSpecialAchievements (user, language) { // Build and return the given user's achievement data. achievs.getAchievementsForProfile = function getAchievementsForProfile (user, language) { - let result = { + const result = { basic: { label: 'Basic', achievements: _getBasicAchievements(user, language), diff --git a/website/common/script/libs/appliedTags.js b/website/common/script/libs/appliedTags.js index 14a0493a7e..cfbb8da2cc 100644 --- a/website/common/script/libs/appliedTags.js +++ b/website/common/script/libs/appliedTags.js @@ -5,10 +5,6 @@ Are there tags applied? // TODO move to client export default function appliedTags (userTags, taskTags = []) { - let arr = userTags.filter(tag => { - return taskTags.indexOf(tag.id) !== -1; - }).map(tag => { - return tag.name; - }); + const arr = userTags.filter(tag => taskTags.indexOf(tag.id) !== -1).map(tag => tag.name); return arr.join(', '); } diff --git a/website/common/script/libs/errorMessage.js b/website/common/script/libs/errorMessage.js index d083e6cdfa..bbd8aae20c 100644 --- a/website/common/script/libs/errorMessage.js +++ b/website/common/script/libs/errorMessage.js @@ -6,10 +6,10 @@ import _template from 'lodash/template'; import messages from '../../errors/commonErrorMessages'; export default function (msgKey, vars = {}) { - let message = messages[msgKey]; + const message = messages[msgKey]; if (!message) throw new Error(`Error processing the common message "${msgKey}".`); - let clonedVars = vars ? _clone(vars) : {}; + const clonedVars = vars ? _clone(vars) : {}; // TODO cache the result of template() ? More memory usage, faster output return _template(message)(clonedVars); diff --git a/website/common/script/libs/getItemByPathAndType.js b/website/common/script/libs/getItemByPathAndType.js index e921a2193e..039593e5b0 100644 --- a/website/common/script/libs/getItemByPathAndType.js +++ b/website/common/script/libs/getItemByPathAndType.js @@ -1,11 +1,11 @@ -import content from '../content/index'; import get from 'lodash/get'; +import content from '../content/index'; export default function getItemByPathAndType (type, path) { let item = get(content, path); if (type === 'timeTravelersStable') { - let [, animalType, key] = path.split('.'); + const [, animalType, key] = path.split('.'); item = { key, diff --git a/website/common/script/libs/getItemInfo.js b/website/common/script/libs/getItemInfo.js index f1b787c2a5..ced86dc0e9 100644 --- a/website/common/script/libs/getItemInfo.js +++ b/website/common/script/libs/getItemInfo.js @@ -1,3 +1,4 @@ +import _mapValues from 'lodash/mapValues'; import i18n from '../i18n'; import content from '../content/index'; import { BadRequest } from './errors'; @@ -7,7 +8,6 @@ import isPinned from './isPinned'; import isFreeRebirth from './isFreeRebirth'; import getOfficialPinnedItems from './getOfficialPinnedItems'; -import _mapValues from 'lodash/mapValues'; function lockQuest (quest, user) { if (quest.key === 'lostMasterclasser1') return !(user.achievements.quests.dilatoryDistress3 && user.achievements.quests.mayhemMistiflying3 && user.achievements.quests.stoikalmCalamity3 && user.achievements.quests.taskwoodsTerror3); @@ -20,9 +20,7 @@ function lockQuest (quest, user) { } function isItemSuggested (officialPinnedItems, itemInfo) { - return officialPinnedItems.findIndex(officialItem => { - return officialItem.type === itemInfo.pinType && officialItem.path === itemInfo.path; - }) > -1; + return officialPinnedItems.findIndex(officialItem => officialItem.type === itemInfo.pinType && officialItem.path === itemInfo.path) > -1; } function getDefaultGearProps (item, language) { @@ -57,7 +55,7 @@ export default function getItemInfo (user, type, item, officialPinnedItems, lang case 'eggs': itemInfo = { key: item.key, - text: i18n.t('egg', {eggType: item.text(language)}, language), + text: i18n.t('egg', { eggType: item.text(language) }, language), notes: item.notes(language), value: item.value, class: `Pet_Egg_${item.key}`, @@ -71,7 +69,7 @@ export default function getItemInfo (user, type, item, officialPinnedItems, lang case 'hatchingPotions': itemInfo = { key: item.key, - text: i18n.t('potion', {potionType: item.text(language)}), + text: i18n.t('potion', { potionType: item.text(language) }), notes: item.notes(language), class: `Pet_HatchingPotion_${item.key}`, value: item.value, @@ -85,7 +83,7 @@ export default function getItemInfo (user, type, item, officialPinnedItems, lang case 'premiumHatchingPotion': itemInfo = { key: item.key, - text: i18n.t('potion', {potionType: item.text(language)}), + text: i18n.t('potion', { potionType: item.text(language) }), notes: `${item.notes(language)} ${item._addlNotes(language)}`, class: `Pet_HatchingPotion_${item.key}`, value: item.value, @@ -137,12 +135,10 @@ export default function getItemInfo (user, type, item, officialPinnedItems, lang unlockCondition: item.unlockCondition, drop: item.drop, boss: item.boss, - collect: item.collect ? _mapValues(item.collect, (o) => { - return { - count: o.count, - text: o.text(), - }; - }) : undefined, + collect: item.collect ? _mapValues(item.collect, o => ({ + count: o.count, + text: o.text(), + })) : undefined, lvl: item.lvl, class: locked ? `inventory_quest_scroll_${item.key}_locked` : `inventory_quest_scroll_${item.key}`, purchaseType: 'quests', @@ -264,7 +260,7 @@ export default function getItemInfo (user, type, item, officialPinnedItems, lang }; break; case 'card': { - let spellInfo = content.spells.special[item.key]; + const spellInfo = content.spells.special[item.key]; itemInfo = { key: item.key, @@ -347,7 +343,7 @@ export default function getItemInfo (user, type, item, officialPinnedItems, lang itemInfo.isSuggested = isItemSuggested(officialPinnedItems, itemInfo); itemInfo.pinned = isPinned(user, itemInfo, officialPinnedItems); } else { - throw new BadRequest(i18n.t('wrongItemType', {type}, language)); + throw new BadRequest(i18n.t('wrongItemType', { type }, language)); } return itemInfo; diff --git a/website/common/script/libs/getOfficialPinnedItems.js b/website/common/script/libs/getOfficialPinnedItems.js index 53e2501f3b..82ca9ba866 100644 --- a/website/common/script/libs/getOfficialPinnedItems.js +++ b/website/common/script/libs/getOfficialPinnedItems.js @@ -1,22 +1,20 @@ -import content from '../content/index'; -import SeasonalShopConfig from '../libs/shops-seasonal.config'; import toArray from 'lodash/toArray'; +import content from '../content/index'; +import SeasonalShopConfig from './shops-seasonal.config'; -const officialPinnedItems = content.officialPinnedItems; +const { officialPinnedItems } = content; -let flatGearArray = toArray(content.gear.flat); +const flatGearArray = toArray(content.gear.flat); export default function getOfficialPinnedItems (user) { - let officialItemsArray = [...officialPinnedItems]; + const officialItemsArray = [...officialPinnedItems]; if (SeasonalShopConfig.pinnedSets && Boolean(user) && user.stats.class) { - let setToAdd = SeasonalShopConfig.pinnedSets[user.stats.class]; + const setToAdd = SeasonalShopConfig.pinnedSets[user.stats.class]; // pinnedSets == current seasonal class set are always gold purchaseable - flatGearArray.filter((gear) => { - return user.items.gear.owned[gear.key] === undefined && gear.set === setToAdd; - }).map((gear) => { + flatGearArray.filter(gear => user.items.gear.owned[gear.key] === undefined && gear.set === setToAdd).map(gear => { officialItemsArray.push({ type: 'marketGear', path: `gear.flat.${gear.key}`, diff --git a/website/common/script/libs/gold.js b/website/common/script/libs/gold.js index f55e125d91..0553035d25 100644 --- a/website/common/script/libs/gold.js +++ b/website/common/script/libs/gold.js @@ -3,7 +3,6 @@ export default function gold (num) { if (num) { return Math.floor(num); - } else { - return '0'; } + return '0'; } diff --git a/website/common/script/libs/hasClass.js b/website/common/script/libs/hasClass.js index 6db1607acb..9f0b84e2d3 100644 --- a/website/common/script/libs/hasClass.js +++ b/website/common/script/libs/hasClass.js @@ -1,8 +1,8 @@ // Check if user has Class system enabled export default function hasClass (member) { return ( - member.stats.lvl >= 10 && - !member.preferences.disableClasses && - member.flags.classSelected + member.stats.lvl >= 10 + && !member.preferences.disableClasses + && member.flags.classSelected ); } diff --git a/website/common/script/libs/inAppRewards.js b/website/common/script/libs/inAppRewards.js index 907c49e4c2..034fbb43e9 100644 --- a/website/common/script/libs/inAppRewards.js +++ b/website/common/script/libs/inAppRewards.js @@ -1,10 +1,10 @@ +import compactArray from 'lodash/compact'; import getItemInfo from './getItemInfo'; import shops from './shops'; import getOfficialPinnedItems from './getOfficialPinnedItems'; -import compactArray from 'lodash/compact'; import getItemByPathAndType from './getItemByPathAndType'; -import {checkPinnedAreasForNullEntries} from '../ops/pinnedGearUtils'; +import { checkPinnedAreasForNullEntries } from '../ops/pinnedGearUtils'; /** * Orders the pinned items so we always get our inAppRewards in the order @@ -15,12 +15,12 @@ import {checkPinnedAreasForNullEntries} from '../ops/pinnedGearUtils'; * @return items of ordered inAppRewards */ function sortInAppRewards (user, items) { - let pinnedItemsOrder = user.pinnedItemsOrder; + const { pinnedItemsOrder } = user; let orderedItems = []; - let unorderedItems = []; // what we want to add later + const unorderedItems = []; // what we want to add later items.forEach((item, index) => { - let i = pinnedItemsOrder[index] === item.path ? index : pinnedItemsOrder.indexOf(item.path); + const i = pinnedItemsOrder[index] === item.path ? index : pinnedItemsOrder.indexOf(item.path); if (i === -1) { unorderedItems.push(item); } else { @@ -35,7 +35,7 @@ function sortInAppRewards (user, items) { export default function getPinnedItems (user) { checkPinnedAreasForNullEntries(user); - let officialPinnedItems = getOfficialPinnedItems(user); + const officialPinnedItems = getOfficialPinnedItems(user); const officialPinnedItemsNotUnpinned = officialPinnedItems.filter(officialPin => { const isUnpinned = user.unpinnedItems.findIndex(unpinned => unpinned.path === officialPin.path) > -1; @@ -44,15 +44,15 @@ export default function getPinnedItems (user) { const pinnedItems = officialPinnedItemsNotUnpinned.concat(user.pinnedItems); - let items = pinnedItems - .map(({type, path}) => { - let item = getItemByPathAndType(type, path); + const items = pinnedItems + .map(({ type, path }) => { + const item = getItemByPathAndType(type, path); return getItemInfo(user, type, item, officialPinnedItems); }); shops.checkMarketGearLocked(user, items); - let orderedItems = sortInAppRewards(user, items); + const orderedItems = sortInAppRewards(user, items); return orderedItems; } diff --git a/website/common/script/libs/isPinned.js b/website/common/script/libs/isPinned.js index 4025c008cf..01dc35bbff 100644 --- a/website/common/script/libs/isPinned.js +++ b/website/common/script/libs/isPinned.js @@ -1,13 +1,11 @@ export default function isPinned (user, item, checkOfficialPinnedItems /* getOfficialPinnedItems */) { - if (user === null) - return false; + if (user === null) return false; const isPinnedOfficial = checkOfficialPinnedItems !== undefined && checkOfficialPinnedItems.findIndex(pinned => pinned.path === item.path) > -1; const isItemUnpinned = user.unpinnedItems !== undefined && user.unpinnedItems.findIndex(unpinned => unpinned.path === item.path) > -1; const isItemPinned = user.pinnedItems !== undefined && user.pinnedItems.findIndex(pinned => pinned.path === item.path) > -1; - if (isPinnedOfficial && !isItemUnpinned) - return true; + if (isPinnedOfficial && !isItemUnpinned) return true; return isItemPinned; } diff --git a/website/common/script/libs/noTags.js b/website/common/script/libs/noTags.js index 15c11d5589..aff2d45b8f 100644 --- a/website/common/script/libs/noTags.js +++ b/website/common/script/libs/noTags.js @@ -8,7 +8,5 @@ are any tags active? // TODO move to client export default function noTags (tags) { - return isEmpty(tags) || isEmpty(filter(tags, (t) => { - return t; - })); + return isEmpty(tags) || isEmpty(filter(tags, t => t)); } diff --git a/website/common/script/libs/pickDeep.js b/website/common/script/libs/pickDeep.js index 48330c3000..24eaf07275 100644 --- a/website/common/script/libs/pickDeep.js +++ b/website/common/script/libs/pickDeep.js @@ -8,8 +8,8 @@ import get from 'lodash/get'; export default function pickDeep (obj, properties) { if (!Array.isArray(properties)) throw new Error('"properties" must be an array'); - let result = {}; - each(properties, (prop) => set(result, prop, get(obj, prop))); + const result = {}; + each(properties, prop => set(result, prop, get(obj, prop))); return result; } diff --git a/website/common/script/libs/preenTodos.js b/website/common/script/libs/preenTodos.js index 1853b2fed9..9d3c44ab96 100644 --- a/website/common/script/libs/preenTodos.js +++ b/website/common/script/libs/preenTodos.js @@ -4,9 +4,7 @@ import filter from 'lodash/filter'; // TODO used only in v2 export default function preenTodos (tasks) { - return filter(tasks, (t) => { - return !t.completed || t.challenge && t.challenge.id || moment(t.dateCompleted).isAfter(moment().subtract({ - days: 3, - })); - }); + return filter(tasks, t => !t.completed || t.challenge && t.challenge.id || moment(t.dateCompleted).isAfter(moment().subtract({ + days: 3, + }))); } diff --git a/website/common/script/libs/randomVal.js b/website/common/script/libs/randomVal.js index dfbcc43a2c..acd13ebb59 100644 --- a/website/common/script/libs/randomVal.js +++ b/website/common/script/libs/randomVal.js @@ -8,12 +8,12 @@ export function trueRandom () { // Get a random property from an object // returns random property (the value) export default function randomVal (obj, options = {}) { - let array = options.key ? keys(obj) : values(obj); - let random = options.predictableRandom || trueRandom(); + const array = options.key ? keys(obj) : values(obj); + const random = options.predictableRandom || trueRandom(); array.sort(); - let randomIndex = Math.floor(random * array.length); + const randomIndex = Math.floor(random * array.length); return array[randomIndex]; -} \ No newline at end of file +} diff --git a/website/common/script/libs/shops.js b/website/common/script/libs/shops.js index efd1eb3713..33e32805d0 100644 --- a/website/common/script/libs/shops.js +++ b/website/common/script/libs/shops.js @@ -17,7 +17,7 @@ import featuredItems from '../content/shop-featuredItems'; import getOfficialPinnedItems from './getOfficialPinnedItems'; -let shops = {}; +const shops = {}; /* Market */ @@ -30,18 +30,16 @@ shops.getMarketShop = function getMarketShop (user, language) { categories: shops.getMarketCategories(user, language), featured: { text: i18n.t('featuredItems'), - items: featuredItems.market.map(i => { - return getItemInfo(user, i.type, get(content, i.path)); - }), + items: featuredItems.market.map(i => getItemInfo(user, i.type, get(content, i.path))), }, }; }; shops.getMarketCategories = function getMarket (user, language) { - let officialPinnedItems = getOfficialPinnedItems(user); + const officialPinnedItems = getOfficialPinnedItems(user); - let categories = []; - let eggsCategory = { + const categories = []; + const eggsCategory = { identifier: 'eggs', text: i18n.t('eggs', language), notes: i18n.t('dropsExplanationEggs', language), @@ -50,47 +48,39 @@ shops.getMarketCategories = function getMarket (user, language) { eggsCategory.items = sortBy(values(content.questEggs) .filter(egg => egg.canBuy(user)) .concat(values(content.dropEggs)) - .map(egg => { - return getItemInfo(user, 'eggs', egg, officialPinnedItems, language); - }), 'key'); + .map(egg => getItemInfo(user, 'eggs', egg, officialPinnedItems, language)), 'key'); categories.push(eggsCategory); - let hatchingPotionsCategory = { + const hatchingPotionsCategory = { identifier: 'hatchingPotions', text: i18n.t('hatchingPotions', language), notes: i18n.t('dropsExplanation', language), }; hatchingPotionsCategory.items = sortBy(values(content.hatchingPotions) .filter(hp => !hp.limited) - .map(hatchingPotion => { - return getItemInfo(user, 'hatchingPotions', hatchingPotion, officialPinnedItems, language); - }), 'key'); + .map(hatchingPotion => getItemInfo(user, 'hatchingPotions', hatchingPotion, officialPinnedItems, language)), 'key'); categories.push(hatchingPotionsCategory); - let premiumHatchingPotionsCategory = { + const premiumHatchingPotionsCategory = { identifier: 'premiumHatchingPotions', text: i18n.t('magicHatchingPotions', language), notes: i18n.t('premiumPotionNoDropExplanation', language), }; premiumHatchingPotionsCategory.items = sortBy(values(content.hatchingPotions) .filter(hp => hp.limited && hp.canBuy(user)) - .map(premiumHatchingPotion => { - return getItemInfo(user, 'premiumHatchingPotion', premiumHatchingPotion, officialPinnedItems, language); - }), 'key'); + .map(premiumHatchingPotion => getItemInfo(user, 'premiumHatchingPotion', premiumHatchingPotion, officialPinnedItems, language)), 'key'); if (premiumHatchingPotionsCategory.items.length > 0) { categories.push(premiumHatchingPotionsCategory); } - let foodCategory = { + const foodCategory = { identifier: 'food', text: i18n.t('food', language), notes: i18n.t('dropsExplanation', language), }; foodCategory.items = sortBy(values(content.food) .filter(food => food.canDrop || food.key === 'Saddle') - .map(foodItem => { - return getItemInfo(user, 'food', foodItem, officialPinnedItems, language); - }), 'key'); + .map(foodItem => getItemInfo(user, 'food', foodItem, officialPinnedItems, language)), 'key'); categories.push(foodCategory); return categories; @@ -99,27 +89,26 @@ shops.getMarketCategories = function getMarket (user, language) { function getClassName (classType, language) { if (classType === 'wizard') { return i18n.t('mage', language); - } else { - return i18n.t(classType, language); } + return i18n.t(classType, language); } // TODO Refactor the `.locked` logic shops.checkMarketGearLocked = function checkMarketGearLocked (user, items) { - let result = filter(items, ['pinType', 'marketGear']); + const result = filter(items, ['pinType', 'marketGear']); const officialPinnedItems = getOfficialPinnedItems(user); - let availableGear = map(updateStore(user), (item) => getItemInfo(user, 'marketGear', item, officialPinnedItems).path); - for (let gear of result) { + const availableGear = map(updateStore(user), item => getItemInfo(user, 'marketGear', item, officialPinnedItems).path); + for (const gear of result) { if (gear.klass !== user.stats.class) { gear.locked = true; } - if (!gear.locked && !availableGear.includes(gear.path)) { + if (!gear.locked && !availableGear.includes(gear.path)) { gear.locked = true; } if (Boolean(gear.specialClass) && Boolean(gear.set)) { - let currentSet = gear.set === seasonalShopConfig.pinnedSets[gear.specialClass]; + const currentSet = gear.set === seasonalShopConfig.pinnedSets[gear.specialClass]; gear.locked = currentSet && user.stats.class !== gear.specialClass; } @@ -128,7 +117,7 @@ shops.checkMarketGearLocked = function checkMarketGearLocked (user, items) { gear.locked = !gear.canOwn(user); } - let itemOwned = user.items.gear.owned[gear.key]; + const itemOwned = user.items.gear.owned[gear.key]; if (itemOwned === false && !availableGear.includes(gear.path)) { gear.locked = true; @@ -145,18 +134,18 @@ shops.checkMarketGearLocked = function checkMarketGearLocked (user, items) { }; shops.getMarketGearCategories = function getMarketGear (user, language) { - let categories = []; - let officialPinnedItems = getOfficialPinnedItems(user); + const categories = []; + const officialPinnedItems = getOfficialPinnedItems(user); - for (let classType of content.classes) { - let category = { + for (const classType of content.classes) { + const category = { identifier: classType, text: getClassName(classType, language), }; - let result = filter(content.gear.flat, function findClassGear (gearItem) { + const result = filter(content.gear.flat, gearItem => { if (gearItem.klass === classType) return true; - let classShift = { + const classShift = { items: user.items, stats: { class: classType, @@ -165,17 +154,13 @@ shops.getMarketGearCategories = function getMarketGear (user, language) { if (gearItem.specialClass === classType && user.items.gear.owned[gearItem.key] !== false) return gearItem.canOwn(classShift); }); - category.items = map(result, (e) => { - return getItemInfo(user, 'marketGear', e, officialPinnedItems); - }); + category.items = map(result, e => getItemInfo(user, 'marketGear', e, officialPinnedItems)); - let specialGear = filter(content.gear.flat, (gear) => { - return user.items.gear.owned[gear.key] === false && - gear.specialClass === classType && - gear.klass === 'special'; - }); + const specialGear = filter(content.gear.flat, gear => user.items.gear.owned[gear.key] === false + && gear.specialClass === classType + && gear.klass === 'special'); - each(specialGear, (gear) => { + each(specialGear, gear => { category.items.push(getItemInfo(user, 'marketGear', gear)); }); @@ -183,21 +168,17 @@ shops.getMarketGearCategories = function getMarketGear (user, language) { categories.push(category); } - let nonClassCategory = { + const nonClassCategory = { identifier: 'none', text: i18n.t('none', language), }; - let specialNonClassGear = filter(content.gear.flat, (gear) => { - return !user.items.gear.owned[gear.key] && - content.classes.indexOf(gear.klass) === -1 && - content.classes.indexOf(gear.specialClass) === -1 && - (gear.canOwn && gear.canOwn(user)); - }); + const specialNonClassGear = filter(content.gear.flat, gear => !user.items.gear.owned[gear.key] + && content.classes.indexOf(gear.klass) === -1 + && content.classes.indexOf(gear.specialClass) === -1 + && (gear.canOwn && gear.canOwn(user))); - nonClassCategory.items = map(specialNonClassGear, (e) => { - return getItemInfo(user, 'marketGear', e); - }); + nonClassCategory.items = map(specialNonClassGear, e => getItemInfo(user, 'marketGear', e)); shops.checkMarketGearLocked(user, nonClassCategory.items); categories.push(nonClassCategory); @@ -215,16 +196,14 @@ shops.getQuestShop = function getQuestShop (user, language) { categories: shops.getQuestShopCategories(user, language), featured: { text: i18n.t('featuredQuests'), - items: featuredItems.quests.map(i => { - return getItemInfo(user, i.type, get(content, i.path)); - }), + items: featuredItems.quests.map(i => getItemInfo(user, i.type, get(content, i.path))), }, }; }; shops.getQuestShopCategories = function getQuestShopCategories (user, language) { - let categories = []; - let officialPinnedItems = getOfficialPinnedItems(user); + const categories = []; + const officialPinnedItems = getOfficialPinnedItems(user); /* * --------------------------------------------------------------- @@ -280,32 +259,28 @@ shops.getQuestShopCategories = function getQuestShopCategories (user, language) * */ - let bundleCategory = { + const bundleCategory = { identifier: 'bundle', text: i18n.t('questBundles', language), }; bundleCategory.items = sortBy(values(content.bundles) .filter(bundle => bundle.type === 'quests' && bundle.canBuy()) - .map(bundle => { - return getItemInfo(user, 'bundles', bundle, officialPinnedItems, language); - })); + .map(bundle => getItemInfo(user, 'bundles', bundle, officialPinnedItems, language))); if (bundleCategory.items.length > 0) { categories.push(bundleCategory); } each(content.userCanOwnQuestCategories, type => { - let category = { + const category = { identifier: type, text: i18n.t(`${type}Quests`, language), }; category.items = content.questsByLevel .filter(quest => quest.canBuy(user) && quest.category === type) - .map(quest => { - return getItemInfo(user, 'quests', quest, officialPinnedItems, language); - }); + .map(quest => getItemInfo(user, 'quests', quest, officialPinnedItems, language)); categories.push(category); }); @@ -316,7 +291,7 @@ shops.getQuestShopCategories = function getQuestShopCategories (user, language) /* Time Travelers */ shops.getTimeTravelersShop = function getTimeTravelersShop (user, language) { - let hasTrinkets = user.purchased.plan.consecutive.trinkets > 0; + const hasTrinkets = user.purchased.plan.consecutive.trinkets > 0; return { identifier: 'timeTravelersShop', @@ -329,36 +304,36 @@ shops.getTimeTravelersShop = function getTimeTravelersShop (user, language) { }; shops.getTimeTravelersCategories = function getTimeTravelersCategories (user, language) { - let categories = []; - let stable = {pets: 'Pet-', mounts: 'Mount_Icon_'}; + const categories = []; + const stable = { pets: 'Pet-', mounts: 'Mount_Icon_' }; - let officialPinnedItems = getOfficialPinnedItems(user); + const officialPinnedItems = getOfficialPinnedItems(user); - let questCategory = { + const questCategory = { identifier: 'quests', text: i18n.t('quests', language), items: [], }; - for (let key in content.quests) { + for (const key in content.quests) { if (content.quests[key].category === 'timeTravelers') { - let item = getItemInfo(user, 'quests', content.quests[key], officialPinnedItems, language); + const item = getItemInfo(user, 'quests', content.quests[key], officialPinnedItems, language); questCategory.items.push(item); } } categories.push(questCategory); - for (let type in stable) { + for (const type in stable) { if (stable.hasOwnProperty(type)) { - let category = { + const category = { identifier: type, text: i18n.t(type, language), items: [], }; - for (let key in content.timeTravelStable[type]) { + for (const key in content.timeTravelStable[type]) { if (content.timeTravelStable[type].hasOwnProperty(key)) { if (!user.items[type][key]) { - let item = getItemInfo(user, 'timeTravelersStable', { + const item = getItemInfo(user, 'timeTravelersStable', { key, type, }, officialPinnedItems, language); @@ -372,11 +347,11 @@ shops.getTimeTravelersCategories = function getTimeTravelersCategories (user, la } } - let sets = content.timeTravelerStore(user); - for (let setKey in sets) { + const sets = content.timeTravelerStore(user); + for (const setKey in sets) { if (sets.hasOwnProperty(setKey)) { - let set = sets[setKey]; - let category = { + const set = sets[setKey]; + const category = { identifier: set.key, text: set.text(language), path: `mystery.${set.key}`, @@ -384,20 +359,18 @@ shops.getTimeTravelersCategories = function getTimeTravelersCategories (user, la purchaseAll: true, }; - category.items = map(set.items, item => { - return { - key: item.key, - text: item.text(language), - notes: item.notes(language), - type: item.type, - purchaseType: 'gear', - value: 1, - locked: false, - currency: 'hourglasses', - class: `shop_${item.key}`, - pinKey: `timeTravelers!gear.flat.${item.key}`, - }; - }); + category.items = map(set.items, item => ({ + key: item.key, + text: item.text(language), + notes: item.notes(language), + type: item.type, + purchaseType: 'gear', + value: 1, + locked: false, + currency: 'hourglasses', + class: `shop_${item.key}`, + pinKey: `timeTravelers!gear.flat.${item.key}`, + })); if (category.items.length > 0) { categories.push(category); } @@ -410,19 +383,18 @@ shops.getTimeTravelersCategories = function getTimeTravelersCategories (user, la /* Seasonal */ -let flatGearArray = toArray(content.gear.flat); +const flatGearArray = toArray(content.gear.flat); shops.getSeasonalGearBySet = function getSeasonalGearBySet (user, set, officialPinnedItems, language, ignoreAlreadyOwned = false) { - return flatGearArray.filter((gear) => { - if (!ignoreAlreadyOwned && user.items.gear.owned[gear.key] !== undefined) - return false; + return flatGearArray.filter(gear => { + if (!ignoreAlreadyOwned && user.items.gear.owned[gear.key] !== undefined) return false; return gear.set === set; }).map(gear => { - let currentSet = gear.set === seasonalShopConfig.pinnedSets[gear.specialClass]; + const currentSet = gear.set === seasonalShopConfig.pinnedSets[gear.specialClass]; // only the current season set can be purchased by gold - let itemInfo = getItemInfo(null, currentSet ? 'marketGear' : 'gear', gear, officialPinnedItems, language); + const itemInfo = getItemInfo(null, currentSet ? 'marketGear' : 'gear', gear, officialPinnedItems, language); itemInfo.locked = currentSet && user.stats.class !== gear.specialClass; return itemInfo; @@ -430,9 +402,9 @@ shops.getSeasonalGearBySet = function getSeasonalGearBySet (user, set, officialP }; shops.getSeasonalShop = function getSeasonalShop (user, language) { - let officialPinnedItems = getOfficialPinnedItems(user); + const officialPinnedItems = getOfficialPinnedItems(user); - let resObject = { + const resObject = { identifier: 'seasonalShop', text: i18n.t('seasonalShop'), notes: i18n.t(`seasonalShop${seasonalShopConfig.currentSeason}Text`), @@ -453,7 +425,7 @@ shops.getSeasonalShop = function getSeasonalShop (user, language) { // setKey: i18n.t('setTranslationString', language), // }; shops.getSeasonalShopCategories = function getSeasonalShopCategories (user, language) { - let officialPinnedItems = getOfficialPinnedItems(user); + const officialPinnedItems = getOfficialPinnedItems(user); const AVAILABLE_SPELLS = [ ...seasonalShopConfig.availableSpells, @@ -463,44 +435,36 @@ shops.getSeasonalShopCategories = function getSeasonalShopCategories (user, lang ...seasonalShopConfig.availableQuests, ]; - let categories = []; + const categories = []; - let spells = pickBy(content.spells.special, (spell, key) => { - return AVAILABLE_SPELLS.indexOf(key) !== -1; - }); + const spells = pickBy(content.spells.special, (spell, key) => AVAILABLE_SPELLS.indexOf(key) !== -1); if (keys(spells).length > 0) { - let category = { + const category = { identifier: 'spells', text: i18n.t('seasonalItems', language), }; - category.items = map(spells, (spell) => { - return getItemInfo(user, 'seasonalSpell', spell, officialPinnedItems, language); - }); + category.items = map(spells, spell => getItemInfo(user, 'seasonalSpell', spell, officialPinnedItems, language)); categories.push(category); } - let quests = pickBy(content.quests, (quest, key) => { - return AVAILABLE_QUESTS.indexOf(key) !== -1; - }); + const quests = pickBy(content.quests, (quest, key) => AVAILABLE_QUESTS.indexOf(key) !== -1); if (keys(quests).length > 0) { - let category = { + const category = { identifier: 'quests', text: i18n.t('quests', language), }; - category.items = map(quests, (quest) => { - return getItemInfo(user, 'seasonalQuest', quest, officialPinnedItems, language); - }); + category.items = map(quests, quest => getItemInfo(user, 'seasonalQuest', quest, officialPinnedItems, language)); categories.push(category); } - for (let set of seasonalShopConfig.availableSets) { - let category = { + for (const set of seasonalShopConfig.availableSets) { + const category = { identifier: set, text: i18n.t(set), }; @@ -508,7 +472,7 @@ shops.getSeasonalShopCategories = function getSeasonalShopCategories (user, lang category.items = shops.getSeasonalGearBySet(user, set, officialPinnedItems, language, false); if (category.items.length > 0) { - let item = category.items[0]; + const item = category.items[0]; category.specialClass = item.specialClass; category.event = item.event; @@ -520,18 +484,16 @@ shops.getSeasonalShopCategories = function getSeasonalShopCategories (user, lang }; shops.getBackgroundShopSets = function getBackgroundShopSets (language) { - let sets = []; - let officialPinnedItems = getOfficialPinnedItems(); + const sets = []; + const officialPinnedItems = getOfficialPinnedItems(); eachRight(content.backgrounds, (group, key) => { - let set = { + const set = { identifier: key, text: i18n.t(key, language), }; - set.items = map(group, (background) => { - return getItemInfo(null, 'background', background, officialPinnedItems, language); - }); + set.items = map(group, background => getItemInfo(null, 'background', background, officialPinnedItems, language)); sets.push(set); }); diff --git a/website/common/script/libs/silver.js b/website/common/script/libs/silver.js index 286a81343e..96ec97531a 100644 --- a/website/common/script/libs/silver.js +++ b/website/common/script/libs/silver.js @@ -6,9 +6,8 @@ Silver amount from their money export default function silver (num) { if (num) { - let centCount = Math.floor((num - Math.floor(num)) * 100); + const centCount = Math.floor((num - Math.floor(num)) * 100); return `0${centCount}`.slice(-2); - } else { - return '00'; } + return '00'; } diff --git a/website/common/script/libs/statsComputed.js b/website/common/script/libs/statsComputed.js index 07c2b74242..34b2066d24 100644 --- a/website/common/script/libs/statsComputed.js +++ b/website/common/script/libs/statsComputed.js @@ -5,23 +5,23 @@ import content from '../content/index'; import * as statHelpers from '../statHelpers'; function equipmentStatBonusComputed (stat, user) { - let gear = content.gear.flat; + const gear = content.gear.flat; let gearBonus = 0; let classBonus = 0; // toObject is required here due to lodash values not working well with mongoose doc objects. // if toObject doesn't exist, we can assume the object is already plain JSON // see http://stackoverflow.com/questions/25767334/underscore-js-keys-and-omit-not-working-as-expected - let equipped = user.items.gear.equipped; - let equippedKeys = values(!equipped.toObject ? equipped : equipped.toObject()); + const { equipped } = user.items.gear; + const equippedKeys = values(!equipped.toObject ? equipped : equipped.toObject()); - each(equippedKeys, (equippedItem) => { - let item = gear[equippedItem]; + each(equippedKeys, equippedItem => { + const item = gear[equippedItem]; if (item) { - let equipmentStat = item[stat]; - let classBonusMultiplier = item.klass === user.stats.class || - item.specialClass === user.stats.class ? 0.5 : 0; + const equipmentStat = item[stat]; + const classBonusMultiplier = item.klass === user.stats.class + || item.specialClass === user.stats.class ? 0.5 : 0; gearBonus += equipmentStat; classBonus += equipmentStat * classBonusMultiplier; } @@ -34,17 +34,17 @@ function equipmentStatBonusComputed (stat, user) { } export default function statsComputed (user) { - let statBreakdown = { + const statBreakdown = { gearBonus: {}, classBonus: {}, baseStat: {}, buff: {}, levelBonus: {}, }; - each(['per', 'con', 'str', 'int'], (stat) => { - let baseStat = get(user, 'stats')[stat]; - let buff = get(user, 'stats.buffs')[stat]; - let equipmentBonus = equipmentStatBonusComputed(stat, user); + each(['per', 'con', 'str', 'int'], stat => { + const baseStat = get(user, 'stats')[stat]; + const buff = get(user, 'stats.buffs')[stat]; + const equipmentBonus = equipmentStatBonusComputed(stat, user); statBreakdown[stat] = equipmentBonus.gearBonus + equipmentBonus.classBonus + baseStat + buff; statBreakdown[stat] += Math.floor(statHelpers.capByLevel(user.stats.lvl) / 2); diff --git a/website/common/script/libs/taskDefaults.js b/website/common/script/libs/taskDefaults.js index 2714041cb2..c8691077a8 100644 --- a/website/common/script/libs/taskDefaults.js +++ b/website/common/script/libs/taskDefaults.js @@ -14,8 +14,8 @@ export default function taskDefaults (task, user) { task.type = 'habit'; } - let defaultId = uuid(); - let defaultTaskObj = { + const defaultId = uuid(); + const defaultTaskObj = { _id: defaultId, text: task._id || defaultId, notes: '', @@ -65,9 +65,9 @@ export default function taskDefaults (task, user) { } if (task.type === 'daily') { - let now = moment().zone(user.preferences.timezoneOffset); - let startOfDay = now.clone().startOf('day'); - let startOfDayWithCDSTime = startOfDay + const now = moment().zone(user.preferences.timezoneOffset); + const startOfDay = now.clone().startOf('day'); + const startOfDayWithCDSTime = startOfDay .clone() .add({ hours: user.preferences.dayStart, @@ -85,9 +85,9 @@ export default function taskDefaults (task, user) { su: true, }, // If cron will happen today, start the daily yesterday - startDate: startOfDayWithCDSTime.isAfter(now) ? - startOfDay.clone().subtract(1, 'day').toDate() : - startOfDay.toDate(), + startDate: startOfDayWithCDSTime.isAfter(now) + ? startOfDay.clone().subtract(1, 'day').toDate() + : startOfDay.toDate(), everyX: 1, frequency: 'weekly', daysOfMonth: [], diff --git a/website/common/script/libs/updateStore.js b/website/common/script/libs/updateStore.js index a5b68f506d..b475689739 100644 --- a/website/common/script/libs/updateStore.js +++ b/website/common/script/libs/updateStore.js @@ -8,7 +8,7 @@ import content from '../content/index'; // Return the list of gear items available for purchase // TODO: Remove updateStore once the new client is live -let sortOrder = reduce(content.gearTypes, (accumulator, val, key) => { +const sortOrder = reduce(content.gearTypes, (accumulator, val, key) => { accumulator[val] = key; return accumulator; }, {}); @@ -16,21 +16,18 @@ let sortOrder = reduce(content.gearTypes, (accumulator, val, key) => { export default function updateStore (user) { let changes = []; - each(content.gearTypes, (type) => { - let found = lodashFind(content.gear.tree[type][user.stats.class], (item) => { - return !user.items.gear.owned[item.key]; - }); + each(content.gearTypes, type => { + const found = lodashFind(content.gear.tree[type][user.stats.class], item => !user.items.gear.owned[item.key]); if (found) changes.push(found); }); - changes = changes.concat(filter(content.gear.flat, (val) => { + changes = changes.concat(filter(content.gear.flat, val => { if (['special', 'mystery', 'armoire'].indexOf(val.klass) !== -1 && !user.items.gear.owned[val.key] && (val.canOwn ? val.canOwn(user) : false)) { return true; - } else { - return false; } + return false; })); - return sortBy(changes, (change) => sortOrder[change.type]); + return sortBy(changes, change => sortOrder[change.type]); } diff --git a/website/common/script/ops/addTag.js b/website/common/script/ops/addTag.js index 18961c5923..0e9db409e2 100644 --- a/website/common/script/ops/addTag.js +++ b/website/common/script/ops/addTag.js @@ -1,5 +1,5 @@ -import uuid from '../libs/uuid'; import get from 'lodash/get'; +import uuid from '../libs/uuid'; // TODO used only in client, move there? diff --git a/website/common/script/ops/addTask.js b/website/common/script/ops/addTask.js index 11bc1c2004..e89485bb3c 100644 --- a/website/common/script/ops/addTask.js +++ b/website/common/script/ops/addTask.js @@ -1,10 +1,10 @@ -import taskDefaults from '../libs/taskDefaults'; import clone from 'lodash/clone'; +import taskDefaults from '../libs/taskDefaults'; // TODO move to client since it's only used there? -export default function addTask (user, req = {body: {}}) { - let task = taskDefaults(req.body, user); +export default function addTask (user, req = { body: {} }) { + const task = taskDefaults(req.body, user); user.tasksOrder[`${task.type}s`].unshift(task._id); user[`${task.type}s`].unshift(task); diff --git a/website/common/script/ops/blockUser.js b/website/common/script/ops/blockUser.js index 90f3fe0d8f..9e9f58f675 100644 --- a/website/common/script/ops/blockUser.js +++ b/website/common/script/ops/blockUser.js @@ -8,7 +8,7 @@ export default function blockUser (user, req = {}) { if (!validator.isUUID(req.params.uuid)) throw new BadRequest(i18n.t('invalidUUID', req.language)); if (req.params.uuid === user._id) throw new BadRequest(i18n.t('blockYourself', req.language)); - let i = user.inbox.blocks.indexOf(req.params.uuid); + const i = user.inbox.blocks.indexOf(req.params.uuid); if (i === -1) { user.inbox.blocks.push(req.params.uuid); } else { diff --git a/website/common/script/ops/buy/abstractBuyOperation.js b/website/common/script/ops/buy/abstractBuyOperation.js index 3f87f08694..38d81517b5 100644 --- a/website/common/script/ops/buy/abstractBuyOperation.js +++ b/website/common/script/ops/buy/abstractBuyOperation.js @@ -1,11 +1,11 @@ +import _merge from 'lodash/merge'; +import _get from 'lodash/get'; import i18n from '../../i18n'; import { NotAuthorized, NotImplementedError, BadRequest, } from '../../libs/errors'; -import _merge from 'lodash/merge'; -import _get from 'lodash/get'; export class AbstractBuyOperation { /** @@ -18,7 +18,7 @@ export class AbstractBuyOperation { this.req = req || {}; this.analytics = analytics; - let quantity = _get(req, 'quantity'); + const quantity = _get(req, 'quantity'); this.quantity = quantity ? Number(quantity) : 1; if (this.quantity < 1 || !Number.isInteger(this.quantity)) throw new BadRequest(this.i18n('invalidQuantity')); @@ -48,8 +48,7 @@ export class AbstractBuyOperation { * @returns {String} */ getItemType (item) { - if (!item.type) - throw new NotImplementedError('item doesn\'t have a type property'); + if (!item.type) throw new NotImplementedError('item doesn\'t have a type property'); return item.type; } @@ -95,7 +94,7 @@ export class AbstractBuyOperation { this.extractAndValidateParams(this.user, this.req); - let resultObj = this.executeChanges(this.user, this.item, this.req); + const resultObj = this.executeChanges(this.user, this.item, this.req); if (this.analytics) { this.sendToAnalytics(this.analyticsData()); @@ -110,7 +109,7 @@ export class AbstractBuyOperation { sendToAnalytics (additionalData = {}) { // spread-operator produces an "unexpected token" error - let analyticsData = _merge(additionalData, { + const analyticsData = _merge(additionalData, { // ...additionalData, uuid: this.user._id, category: 'behavior', @@ -132,9 +131,9 @@ export class AbstractGoldItemOperation extends AbstractBuyOperation { canUserPurchase (user, item) { this.item = item; - let itemValue = this.getItemValue(item); + const itemValue = this.getItemValue(item); - let userGold = user.stats.gp; + const userGold = user.stats.gp; if (userGold < itemValue * this.quantity) { throw new NotAuthorized(this.i18n('messageNotEnoughGold')); @@ -146,7 +145,7 @@ export class AbstractGoldItemOperation extends AbstractBuyOperation { } subtractCurrency (user, item) { - let itemValue = this.getItemValue(item); + const itemValue = this.getItemValue(item); user.stats.gp -= itemValue * this.quantity; } @@ -168,7 +167,7 @@ export class AbstractGemItemOperation extends AbstractBuyOperation { canUserPurchase (user, item) { this.item = item; - let itemValue = this.getItemValue(item); + const itemValue = this.getItemValue(item); if (!item.canBuy(user)) { throw new NotAuthorized(this.i18n('messageNotAvailable')); @@ -180,7 +179,7 @@ export class AbstractGemItemOperation extends AbstractBuyOperation { } subtractCurrency (user, item) { - let itemValue = this.getItemValue(item); + const itemValue = this.getItemValue(item); user.balance -= itemValue * this.quantity; } diff --git a/website/common/script/ops/buy/buy.js b/website/common/script/ops/buy/buy.js index ee7d5a7768..50837375ed 100644 --- a/website/common/script/ops/buy/buy.js +++ b/website/common/script/ops/buy/buy.js @@ -2,28 +2,28 @@ import get from 'lodash/get'; import { BadRequest, } from '../../libs/errors'; -import {BuyArmoireOperation} from './buyArmoire'; -import {BuyHealthPotionOperation} from './buyHealthPotion'; -import {BuyMarketGearOperation} from './buyMarketGear'; +import { BuyArmoireOperation } from './buyArmoire'; +import { BuyHealthPotionOperation } from './buyHealthPotion'; +import { BuyMarketGearOperation } from './buyMarketGear'; import buyMysterySet from './buyMysterySet'; -import {BuyQuestWithGoldOperation} from './buyQuestGold'; -import {BuySpellOperation} from './buySpell'; +import { BuyQuestWithGoldOperation } from './buyQuestGold'; +import { BuySpellOperation } from './buySpell'; import purchaseOp from './purchase'; import hourglassPurchase from './hourglassPurchase'; import errorMessage from '../../libs/errorMessage'; -import {BuyGemOperation} from './buyGem'; -import {BuyQuestWithGemOperation} from './buyQuestGem'; -import {BuyHourglassMountOperation} from './buyMount'; +import { BuyGemOperation } from './buyGem'; +import { BuyQuestWithGemOperation } from './buyQuestGem'; +import { BuyHourglassMountOperation } from './buyMount'; // @TODO: remove the req option style. Dependency on express structure is an anti-pattern // We should either have more params or a set structure validated by a Type checker // @TODO: when we are sure buy is the only function used, let's move the buy files to a folder -export default function buy (user, req = {}, analytics, options = {quantity: 1, hourglass: false}) { - let key = get(req, 'params.key'); - const hourglass = options.hourglass; - const quantity = options.quantity; +export default function buy (user, req = {}, analytics, options = { quantity: 1, hourglass: false }) { + const key = get(req, 'params.key'); + const { hourglass } = options; + const { quantity } = options; if (!key) throw new BadRequest(errorMessage('missingKeyParam')); // @TODO: Slowly remove the need for key and use type instead diff --git a/website/common/script/ops/buy/buyArmoire.js b/website/common/script/ops/buy/buyArmoire.js index 985fcd023e..8852bde107 100644 --- a/website/common/script/ops/buy/buyArmoire.js +++ b/website/common/script/ops/buy/buyArmoire.js @@ -1,15 +1,15 @@ -import content from '../../content/index'; import filter from 'lodash/filter'; import isEmpty from 'lodash/isEmpty'; import pick from 'lodash/pick'; +import content from '../../content/index'; import * as count from '../../count'; import splitWhitespace from '../../libs/splitWhitespace'; import { NotAuthorized, } from '../../libs/errors'; import randomVal, * as randomValFns from '../../libs/randomVal'; -import {removeItemByPath} from '../pinnedGearUtils'; -import {AbstractGoldItemOperation} from './abstractBuyOperation'; +import { removeItemByPath } from '../pinnedGearUtils'; +import { AbstractGoldItemOperation } from './abstractBuyOperation'; // TODO this is only used on the server // move out of common? @@ -27,7 +27,7 @@ export class BuyArmoireOperation extends AbstractGoldItemOperation { } extractAndValidateParams (user) { - let item = content.armoire; + const item = content.armoire; this.canUserPurchase(user, item); } @@ -35,11 +35,9 @@ export class BuyArmoireOperation extends AbstractGoldItemOperation { executeChanges (user, item) { let result = {}; - let armoireResult = randomValFns.trueRandom(); - let eligibleEquipment = filter(content.gear.flat, (eligible) => { - return eligible.klass === 'armoire' && !user.items.gear.owned[eligible.key]; - }); - let armoireHasEquipment = !isEmpty(eligibleEquipment); + const armoireResult = randomValFns.trueRandom(); + const eligibleEquipment = filter(content.gear.flat, eligible => eligible.klass === 'armoire' && !user.items.gear.owned[eligible.key]); + const armoireHasEquipment = !isEmpty(eligibleEquipment); if (armoireHasEquipment && (armoireResult < YIELD_EQUIPMENT_THRESHOLD || !user.flags.armoireOpened)) { result = this._gearResult(user, eligibleEquipment); @@ -51,7 +49,7 @@ export class BuyArmoireOperation extends AbstractGoldItemOperation { this.subtractCurrency(user, item); - let {message, armoireResp} = result; + let { message, armoireResp } = result; if (!message) { message = this.i18n('messageBought', { @@ -59,7 +57,7 @@ export class BuyArmoireOperation extends AbstractGoldItemOperation { }); } - let resData = pick(user, splitWhitespace('items flags')); + const resData = pick(user, splitWhitespace('items flags')); if (armoireResp) resData.armoire = armoireResp; return [ @@ -83,7 +81,7 @@ export class BuyArmoireOperation extends AbstractGoldItemOperation { _gearResult (user, eligibleEquipment) { eligibleEquipment.sort(); - let drop = randomVal(eligibleEquipment); + const drop = randomVal(eligibleEquipment); if (user.items.gear.owned[drop.key]) { throw new NotAuthorized(this.i18n('equipmentAlreadyOwned')); @@ -93,7 +91,7 @@ export class BuyArmoireOperation extends AbstractGoldItemOperation { if (user.markModified) user.markModified('items.gear.owned'); user.flags.armoireOpened = true; - let message = this.i18n('armoireEquipment', { + const message = this.i18n('armoireEquipment', { image: ``, dropText: drop.text(this.req.language), }); @@ -108,7 +106,7 @@ export class BuyArmoireOperation extends AbstractGoldItemOperation { this._trackDropAnalytics(user._id, drop.key); } - let armoireResp = { + const armoireResp = { type: 'gear', dropKey: drop.key, dropText: drop.text(this.req.language), @@ -121,7 +119,7 @@ export class BuyArmoireOperation extends AbstractGoldItemOperation { } _foodResult (user) { - let drop = randomVal(filter(content.food, { + const drop = randomVal(filter(content.food, { canDrop: true, })); @@ -147,7 +145,7 @@ export class BuyArmoireOperation extends AbstractGoldItemOperation { } _experienceResult (user) { - let armoireExp = Math.floor(randomValFns.trueRandom() * 40 + 10); + const armoireExp = Math.floor(randomValFns.trueRandom() * 40 + 10); user.stats.exp += armoireExp; return { diff --git a/website/common/script/ops/buy/buyGem.js b/website/common/script/ops/buy/buyGem.js index b2ea03046e..9ef30ae786 100644 --- a/website/common/script/ops/buy/buyGem.js +++ b/website/common/script/ops/buy/buyGem.js @@ -1,11 +1,11 @@ import pick from 'lodash/pick'; +import get from 'lodash/get'; import splitWhitespace from '../../libs/splitWhitespace'; import { BadRequest, NotAuthorized, } from '../../libs/errors'; -import {AbstractGoldItemOperation} from './abstractBuyOperation'; -import get from 'lodash/get'; +import { AbstractGoldItemOperation } from './abstractBuyOperation'; import planGemLimits from '../../libs/planGemLimits'; export class BuyGemOperation extends AbstractGoldItemOperation { @@ -30,10 +30,10 @@ export class BuyGemOperation extends AbstractGoldItemOperation { } extractAndValidateParams (user, req) { - let key = this.key = get(req, 'params.key'); + const key = this.key = get(req, 'params.key'); if (!key) throw new BadRequest(this.i18n('missingKeyParam')); - let convCap = planGemLimits.convCap; + let { convCap } = planGemLimits; convCap += user.purchased.plan.consecutive.gemCapExtra; // todo better name? @@ -50,7 +50,7 @@ export class BuyGemOperation extends AbstractGoldItemOperation { super.canUserPurchase(user, item); if (user.purchased.plan.gemsBought >= this.convCap) { - throw new NotAuthorized(this.i18n('reachedGoldToGemCap', {convCap: this.convCap})); + throw new NotAuthorized(this.i18n('reachedGoldToGemCap', { convCap: this.convCap })); } if (user.purchased.plan.gemsBought + this.quantity > this.convCap) { @@ -69,7 +69,7 @@ export class BuyGemOperation extends AbstractGoldItemOperation { return [ pick(user, splitWhitespace('stats balance')), - this.i18n('plusGem', {count: this.quantity}), + this.i18n('plusGem', { count: this.quantity }), ]; } diff --git a/website/common/script/ops/buy/buyHealthPotion.js b/website/common/script/ops/buy/buyHealthPotion.js index e3d6c1062a..bc0f5ef5f3 100644 --- a/website/common/script/ops/buy/buyHealthPotion.js +++ b/website/common/script/ops/buy/buyHealthPotion.js @@ -3,7 +3,7 @@ import { NotAuthorized, } from '../../libs/errors'; -import { AbstractGoldItemOperation} from './abstractBuyOperation'; +import { AbstractGoldItemOperation } from './abstractBuyOperation'; export class BuyHealthPotionOperation extends AbstractGoldItemOperation { constructor (user, req, analytics) { @@ -15,8 +15,8 @@ export class BuyHealthPotionOperation extends AbstractGoldItemOperation { } extractAndValidateParams (user) { - let item = content.potion; - let userHp = user.stats.hp; + const item = content.potion; + const userHp = user.stats.hp; super.canUserPurchase(user, item); @@ -37,7 +37,7 @@ export class BuyHealthPotionOperation extends AbstractGoldItemOperation { this.subtractCurrency(user, item, this.quantity); - let message = this.i18n('messageBought', { + const message = this.i18n('messageBought', { itemText: this.item.text(this.req.language), }); diff --git a/website/common/script/ops/buy/buyMarketGear.js b/website/common/script/ops/buy/buyMarketGear.js index 5f8728bf53..293b9bd5ec 100644 --- a/website/common/script/ops/buy/buyMarketGear.js +++ b/website/common/script/ops/buy/buyMarketGear.js @@ -1,6 +1,6 @@ -import content from '../../content/index'; import get from 'lodash/get'; import pick from 'lodash/pick'; +import content from '../../content/index'; import splitWhitespace from '../../libs/splitWhitespace'; import { BadRequest, @@ -10,7 +10,7 @@ import { import handleTwoHanded from '../../fns/handleTwoHanded'; import ultimateGear from '../../fns/ultimateGear'; -import {removePinnedGearAddPossibleNewOnes} from '../pinnedGearUtils'; +import { removePinnedGearAddPossibleNewOnes } from '../pinnedGearUtils'; import { AbstractGoldItemOperation } from './abstractBuyOperation'; import errorMessage from '../../libs/errorMessage'; @@ -24,7 +24,7 @@ export class BuyMarketGearOperation extends AbstractGoldItemOperation { return false; } - canUserPurchase (user, item) { + canUserPurchase (user, item) { super.canUserPurchase(user, item); const checkKlass = item.klass && !['special', 'armoire', user.stats.class].includes(item.klass); @@ -37,11 +37,11 @@ export class BuyMarketGearOperation extends AbstractGoldItemOperation { } extractAndValidateParams (user, req) { - let key = this.key = get(req, 'params.key'); + const key = this.key = get(req, 'params.key'); if (!key) throw new BadRequest(errorMessage('missingKeyParam')); - let item = content.gear.flat[key]; - if (!item) throw new NotFound(errorMessage('itemNotFound', {key})); + const item = content.gear.flat[key]; + if (!item) throw new NotFound(errorMessage('itemNotFound', { key })); this.canUserPurchase(user, item); @@ -49,12 +49,12 @@ export class BuyMarketGearOperation extends AbstractGoldItemOperation { throw new NotAuthorized(this.i18n('equipmentAlreadyOwned')); } - let itemIndex = Number(item.index); + const itemIndex = Number(item.index); if (Number.isInteger(itemIndex) && content.classes.includes(item.klass)) { - let previousLevelGear = key.replace(/[0-9]/, itemIndex - 1); - let hasPreviousLevelGear = user.items.gear.owned[previousLevelGear]; - let checkIndexToType = itemIndex > (item.type === 'weapon' || item.type === 'shield' && item.klass === 'rogue' ? 0 : 1); + const previousLevelGear = key.replace(/[0-9]/, itemIndex - 1); + const hasPreviousLevelGear = user.items.gear.owned[previousLevelGear]; + const checkIndexToType = itemIndex > (item.type === 'weapon' || item.type === 'shield' && item.klass === 'rogue' ? 0 : 1); if (checkIndexToType && !hasPreviousLevelGear) { throw new NotAuthorized(this.i18n('previousGearNotOwned')); diff --git a/website/common/script/ops/buy/buyMount.js b/website/common/script/ops/buy/buyMount.js index ced5cddfc8..50fde36ce7 100644 --- a/website/common/script/ops/buy/buyMount.js +++ b/website/common/script/ops/buy/buyMount.js @@ -1,13 +1,13 @@ +import get from 'lodash/get'; +import includes from 'lodash/includes'; +import keys from 'lodash/keys'; import content from '../../content/index'; import { BadRequest, NotAuthorized, } from '../../libs/errors'; -import {AbstractHourglassItemOperation} from './abstractBuyOperation'; -import get from 'lodash/get'; -import includes from 'lodash/includes'; -import keys from 'lodash/keys'; +import { AbstractHourglassItemOperation } from './abstractBuyOperation'; export class BuyHourglassMountOperation extends AbstractHourglassItemOperation { constructor (user, req, analytics) { @@ -19,7 +19,7 @@ export class BuyHourglassMountOperation extends AbstractHourglassItemOperation { } extractAndValidateParams (user, req) { - let key = this.key = get(req, 'params.key'); + const key = this.key = get(req, 'params.key'); if (!key) throw new BadRequest(this.i18n('missingKeyParam')); @@ -43,7 +43,7 @@ export class BuyHourglassMountOperation extends AbstractHourglassItemOperation { this.subtractCurrency(user); - let message = this.i18n('hourglassPurchase'); + const message = this.i18n('hourglassPurchase'); return [ { items: user.items, purchasedPlanConsecutive: user.purchased.plan.consecutive }, @@ -52,7 +52,7 @@ export class BuyHourglassMountOperation extends AbstractHourglassItemOperation { } analyticsData () { - let data = super.analyticsData(); + const data = super.analyticsData(); data.itemType = 'mounts'; return data; } diff --git a/website/common/script/ops/buy/buyMysterySet.js b/website/common/script/ops/buy/buyMysterySet.js index 6b2aeab148..570f297959 100644 --- a/website/common/script/ops/buy/buyMysterySet.js +++ b/website/common/script/ops/buy/buyMysterySet.js @@ -1,7 +1,7 @@ -import i18n from '../../i18n'; -import content from '../../content/index'; import get from 'lodash/get'; import each from 'lodash/each'; +import i18n from '../../i18n'; +import content from '../../content/index'; import { BadRequest, NotAuthorized, @@ -10,15 +10,15 @@ import { import errorMessage from '../../libs/errorMessage'; export default function buyMysterySet (user, req = {}, analytics) { - let key = get(req, 'params.key'); + const key = get(req, 'params.key'); if (!key) throw new BadRequest(errorMessage('missingKeyParam')); if (!(user.purchased.plan.consecutive.trinkets > 0)) { throw new NotAuthorized(i18n.t('notEnoughHourglasses', req.language)); } - let ref = content.timeTravelerStore(user); - let mysterySet = ref ? ref[key] : undefined; + const ref = content.timeTravelerStore(user); + const mysterySet = ref ? ref[key] : undefined; if (!mysterySet) { throw new NotFound(i18n.t('mysterySetNotFound', req.language)); diff --git a/website/common/script/ops/buy/buyQuestGem.js b/website/common/script/ops/buy/buyQuestGem.js index 63ba528ce3..893062e398 100644 --- a/website/common/script/ops/buy/buyQuestGem.js +++ b/website/common/script/ops/buy/buyQuestGem.js @@ -1,13 +1,13 @@ +import get from 'lodash/get'; import { BadRequest, NotAuthorized, NotFound, } from '../../libs/errors'; import content from '../../content/index'; -import get from 'lodash/get'; import errorMessage from '../../libs/errorMessage'; -import {AbstractGemItemOperation} from './abstractBuyOperation'; +import { AbstractGemItemOperation } from './abstractBuyOperation'; export class BuyQuestWithGemOperation extends AbstractGemItemOperation { constructor (user, req, analytics) { @@ -31,15 +31,15 @@ export class BuyQuestWithGemOperation extends AbstractGemItemOperation { } extractAndValidateParams (user, req) { - let key = this.key = get(req, 'params.key'); + const key = this.key = get(req, 'params.key'); if (!key) throw new BadRequest(errorMessage('missingKeyParam')); - let item = content.quests[key]; + const item = content.quests[key]; - if (!item) throw new NotFound(errorMessage('questNotFound', {key})); + if (!item) throw new NotFound(errorMessage('questNotFound', { key })); if (item.category === 'gold') { - throw new NotAuthorized(this.i18n('questNotGemPurchasable', {key})); + throw new NotAuthorized(this.i18n('questNotGemPurchasable', { key })); } this.canUserPurchase(user, item); diff --git a/website/common/script/ops/buy/buyQuestGold.js b/website/common/script/ops/buy/buyQuestGold.js index 09f04dcb59..89a0be0edd 100644 --- a/website/common/script/ops/buy/buyQuestGold.js +++ b/website/common/script/ops/buy/buyQuestGold.js @@ -1,12 +1,12 @@ +import get from 'lodash/get'; import { BadRequest, NotAuthorized, NotFound, } from '../../libs/errors'; import content from '../../content/index'; -import get from 'lodash/get'; -import {AbstractGoldItemOperation} from './abstractBuyOperation'; +import { AbstractGoldItemOperation } from './abstractBuyOperation'; import errorMessage from '../../libs/errorMessage'; export class BuyQuestWithGoldOperation extends AbstractGoldItemOperation { @@ -19,10 +19,10 @@ export class BuyQuestWithGoldOperation extends AbstractGoldItemOperation { } userAbleToStartMasterClasser (user) { - return user.achievements.quests.dilatoryDistress3 && - user.achievements.quests.mayhemMistiflying3 && - user.achievements.quests.stoikalmCalamity3 && - user.achievements.quests.taskwoodsTerror3; + return user.achievements.quests.dilatoryDistress3 + && user.achievements.quests.mayhemMistiflying3 + && user.achievements.quests.stoikalmCalamity3 + && user.achievements.quests.taskwoodsTerror3; } getItemKey () { @@ -38,15 +38,15 @@ export class BuyQuestWithGoldOperation extends AbstractGoldItemOperation { } extractAndValidateParams (user, req) { - let key = this.key = get(req, 'params.key'); + const key = this.key = get(req, 'params.key'); if (!key) throw new BadRequest(errorMessage('missingKeyParam')); - let item = content.quests[key]; + const item = content.quests[key]; - if (!item) throw new NotFound(errorMessage('questNotFound', {key})); + if (!item) throw new NotFound(errorMessage('questNotFound', { key })); if (!(item.category === 'gold' && item.goldValue)) { - throw new NotAuthorized(this.i18n('questNotGoldPurchasable', {key})); + throw new NotAuthorized(this.i18n('questNotGoldPurchasable', { key })); } this.checkPrerequisites(user, key); @@ -61,7 +61,7 @@ export class BuyQuestWithGoldOperation extends AbstractGoldItemOperation { } if (item && item.previous && !user.achievements.quests[item.previous]) { - throw new NotAuthorized(this.i18n('mustComplete', {quest: item.previous})); + throw new NotAuthorized(this.i18n('mustComplete', { quest: item.previous })); } } diff --git a/website/common/script/ops/buy/buySpell.js b/website/common/script/ops/buy/buySpell.js index 46e73a5d81..123455d6c7 100644 --- a/website/common/script/ops/buy/buySpell.js +++ b/website/common/script/ops/buy/buySpell.js @@ -1,12 +1,12 @@ -import content from '../../content/index'; import get from 'lodash/get'; import pick from 'lodash/pick'; +import content from '../../content/index'; import splitWhitespace from '../../libs/splitWhitespace'; import { BadRequest, NotFound, } from '../../libs/errors'; -import {AbstractGoldItemOperation} from './abstractBuyOperation'; +import { AbstractGoldItemOperation } from './abstractBuyOperation'; import errorMessage from '../../libs/errorMessage'; export class BuySpellOperation extends AbstractGoldItemOperation { @@ -27,11 +27,11 @@ export class BuySpellOperation extends AbstractGoldItemOperation { } extractAndValidateParams (user, req) { - let key = this.key = get(req, 'params.key'); + const key = this.key = get(req, 'params.key'); if (!key) throw new BadRequest(errorMessage('missingKeyParam')); - let item = content.special[key]; - if (!item) throw new NotFound(errorMessage('spellNotFound', {spellId: key})); + const item = content.special[key]; + if (!item) throw new NotFound(errorMessage('spellNotFound', { spellId: key })); this.canUserPurchase(user, item); } diff --git a/website/common/script/ops/buy/hourglassPurchase.js b/website/common/script/ops/buy/hourglassPurchase.js index fbea9d2541..dba5b93c30 100644 --- a/website/common/script/ops/buy/hourglassPurchase.js +++ b/website/common/script/ops/buy/hourglassPurchase.js @@ -1,8 +1,8 @@ -import content from '../../content/index'; -import i18n from '../../i18n'; import get from 'lodash/get'; import includes from 'lodash/includes'; import keys from 'lodash/keys'; +import i18n from '../../i18n'; +import content from '../../content/index'; import { BadRequest, NotAuthorized, @@ -10,10 +10,10 @@ import { import errorMessage from '../../libs/errorMessage'; export default function purchaseHourglass (user, req = {}, analytics, quantity = 1) { - let key = get(req, 'params.key'); + const key = get(req, 'params.key'); if (!key) throw new BadRequest(errorMessage('missingKeyParam')); - let type = get(req, 'params.type'); + const type = get(req, 'params.type'); if (!type) throw new BadRequest(errorMessage('missingTypeParam')); if (type === 'quests') { @@ -29,7 +29,7 @@ export default function purchaseHourglass (user, req = {}, analytics, quantity = if (user.markModified) user.markModified('items.quests'); } else { if (!content.timeTravelStable[type]) { - throw new NotAuthorized(i18n.t('typeNotAllowedHourglass', {allowedTypes: keys(content.timeTravelStable).toString()}, req.language)); + throw new NotAuthorized(i18n.t('typeNotAllowedHourglass', { allowedTypes: keys(content.timeTravelStable).toString() }, req.language)); } if (!includes(keys(content.timeTravelStable[type]), key)) { diff --git a/website/common/script/ops/buy/purchase.js b/website/common/script/ops/buy/purchase.js index 8b6bd1b017..e69fcfaed5 100644 --- a/website/common/script/ops/buy/purchase.js +++ b/website/common/script/ops/buy/purchase.js @@ -1,8 +1,8 @@ -import content from '../../content/index'; -import i18n from '../../i18n'; import get from 'lodash/get'; import pick from 'lodash/pick'; import forEach from 'lodash/forEach'; +import i18n from '../../i18n'; +import content from '../../content/index'; import splitWhitespace from '../../libs/splitWhitespace'; import { NotFound, @@ -21,7 +21,7 @@ function getItemAndPrice (user, type, key, req) { item = content.gear.flat[key]; if (!item) { - throw new NotFound(i18n.t('contentKeyNotFound', {type}, req.language)); + throw new NotFound(i18n.t('contentKeyNotFound', { type }, req.language)); } if (user.items.gear.owned[key]) { @@ -33,13 +33,13 @@ function getItemAndPrice (user, type, key, req) { item = content[type][key]; if (!item) { - throw new NotFound(i18n.t('contentKeyNotFound', {type}, req.language)); + throw new NotFound(i18n.t('contentKeyNotFound', { type }, req.language)); } price = item.value / 4; } - return {item, price}; + return { item, price }; } function purchaseItem (user, item, price, type, key) { @@ -49,8 +49,8 @@ function purchaseItem (user, item, price, type, key) { user.items.gear.owned[key] = true; if (user.markModified) user.markModified('items.gear.owned'); } else if (type === 'bundles') { - let subType = item.type; - forEach(item.bundleKeys, function addBundledItems (bundledKey) { + const subType = item.type; + forEach(item.bundleKeys, bundledKey => { if (!user.items[subType][bundledKey] || user.items[subType][key] < 0) { user.items[subType][bundledKey] = 0; } @@ -69,10 +69,10 @@ function purchaseItem (user, item, price, type, key) { const acceptedTypes = ['eggs', 'hatchingPotions', 'food', 'gear', 'bundles']; const singlePurchaseTypes = ['gear']; export default function purchase (user, req = {}, analytics) { - let type = get(req.params, 'type'); - let key = get(req.params, 'key'); + const type = get(req.params, 'type'); + const key = get(req.params, 'key'); - let quantity = req.quantity ? Number(req.quantity) : 1; + const quantity = req.quantity ? Number(req.quantity) : 1; if (quantity < 1 || !Number.isInteger(quantity)) throw new BadRequest(i18n.t('invalidQuantity', req.language)); if (!type) { @@ -87,7 +87,7 @@ export default function purchase (user, req = {}, analytics) { throw new NotFound(i18n.t('notAccteptedType', req.language)); } - let {price, item} = getItemAndPrice(user, type, key, req); + const { price, item } = getItemAndPrice(user, type, key, req); if (!item.canBuy(user)) { throw new NotAuthorized(i18n.t('messageNotAvailable', req.language)); @@ -98,7 +98,7 @@ export default function purchase (user, req = {}, analytics) { } if (singlePurchaseTypes.includes(type)) { - let itemInfo = getItemInfo(user, type, item); + const itemInfo = getItemInfo(user, type, item); removeItemByPath(user, itemInfo.path); } diff --git a/website/common/script/ops/changeClass.js b/website/common/script/ops/changeClass.js index fe76572e7e..c15d652248 100644 --- a/website/common/script/ops/changeClass.js +++ b/website/common/script/ops/changeClass.js @@ -1,6 +1,6 @@ -import i18n from '../i18n'; import get from 'lodash/get'; import pick from 'lodash/pick'; +import i18n from '../i18n'; import splitWhitespace from '../libs/splitWhitespace'; import { capByLevel } from '../statHelpers'; import { @@ -34,7 +34,7 @@ function resetClass (user, req = {}) { } export default function changeClass (user, req = {}, analytics) { - let klass = get(req, 'query.class'); + const klass = get(req, 'query.class'); let balanceRemoved = 0; // user.flags.classSelected is set to false after the user paid the 3 gems if (user.stats.lvl < 10) { diff --git a/website/common/script/ops/deleteTag.js b/website/common/script/ops/deleteTag.js index d9e3da8643..70249c3a5b 100644 --- a/website/common/script/ops/deleteTag.js +++ b/website/common/script/ops/deleteTag.js @@ -1,15 +1,15 @@ -import i18n from '../i18n'; import get from 'lodash/get'; import findIndex from 'lodash/findIndex'; import each from 'lodash/each'; +import i18n from '../i18n'; import { NotFound } from '../libs/errors'; // TODO used only in client, move there? export default function deleteTag (user, req = {}) { - let tid = get(req, 'params.id'); + const tid = get(req, 'params.id'); - let index = findIndex(user.tags, { + const index = findIndex(user.tags, { id: tid, }); @@ -17,16 +17,14 @@ export default function deleteTag (user, req = {}) { throw new NotFound(i18n.t('messageTagNotFound', req.language)); } - let tag = user.tags[index]; + const tag = user.tags[index]; delete user.filters[tag.id]; user.tags.splice(index, 1); - each(user.tasks, (task) => { - return delete task.tags[tag.id]; - }); + each(user.tasks, task => delete task.tags[tag.id]); - each(['habits', 'dailys', 'todos', 'rewards'], (type) => { + each(['habits', 'dailys', 'todos', 'rewards'], type => { if (user.markModified) user.markModified(type); }); diff --git a/website/common/script/ops/deleteTask.js b/website/common/script/ops/deleteTask.js index 376dfb932e..6a9cff9a6b 100644 --- a/website/common/script/ops/deleteTask.js +++ b/website/common/script/ops/deleteTask.js @@ -1,17 +1,15 @@ -import i18n from '../i18n'; -import { NotFound } from '../libs/errors'; import get from 'lodash/get'; import findIndex from 'lodash/findIndex'; +import i18n from '../i18n'; +import { NotFound } from '../libs/errors'; // TODO used only in client, move there? export default function deleteTask (user, req = {}) { - let tid = get(req, 'params.id'); - let taskType = get(req, 'params.taskType'); + const tid = get(req, 'params.id'); + const taskType = get(req, 'params.taskType'); - let index = findIndex(user[`${taskType}s`], function findById (task) { - return task._id === tid; - }); + const index = findIndex(user[`${taskType}s`], task => task._id === tid); if (index === -1) { throw new NotFound(i18n.t('messageTaskNotFound', req.language)); diff --git a/website/common/script/ops/disableClasses.js b/website/common/script/ops/disableClasses.js index 7ef15802b1..b499b84b9b 100644 --- a/website/common/script/ops/disableClasses.js +++ b/website/common/script/ops/disableClasses.js @@ -1,6 +1,6 @@ +import pick from 'lodash/pick'; import splitWhitespace from '../libs/splitWhitespace'; import { capByLevel } from '../statHelpers'; -import pick from 'lodash/pick'; export default function disableClasses (user) { user.stats.class = 'warrior'; diff --git a/website/common/script/ops/equip.js b/website/common/script/ops/equip.js index d12e25043e..2d55a6cb6f 100644 --- a/website/common/script/ops/equip.js +++ b/website/common/script/ops/equip.js @@ -1,3 +1,4 @@ +import get from 'lodash/get'; import content from '../content/index'; import i18n from '../i18n'; import handleTwoHanded from '../fns/handleTwoHanded'; @@ -5,14 +6,13 @@ import { NotFound, BadRequest, } from '../libs/errors'; -import get from 'lodash/get'; import errorMessage from '../libs/errorMessage'; export default function equip (user, req = {}) { // Being type a parameter followed by another parameter // when using the API it must be passes specifically in the URL, it's won't default to equipped - let type = get(req, 'params.type', 'equipped'); - let key = get(req, 'params.key'); + const type = get(req, 'params.type', 'equipped'); + const key = get(req, 'params.key'); if (!key || !type) throw new BadRequest(errorMessage('missingTypeKeyEquip')); if (['mount', 'pet', 'costume', 'equipped'].indexOf(type) === -1) { @@ -44,25 +44,25 @@ export default function equip (user, req = {}) { throw new NotFound(i18n.t('gearNotOwned', req.language)); } - let item = content.gear.flat[key]; + const item = content.gear.flat[key]; if (user.items.gear[type][item.type] === key) { - user.items.gear[type] = Object.assign( - {}, - user.items.gear[type].toObject ? user.items.gear[type].toObject() : user.items.gear[type], - {[item.type]: `${item.type}_base_0`} - ); + user.items.gear[type] = { + + ...(user.items.gear[type].toObject ? user.items.gear[type].toObject() : user.items.gear[type]), + [item.type]: `${item.type}_base_0`, + }; if (user.markModified && type === 'owned') user.markModified('items.gear.owned'); message = i18n.t('messageUnEquipped', { itemText: item.text(req.language), }, req.language); } else { - user.items.gear[type] = Object.assign( - {}, - user.items.gear[type].toObject ? user.items.gear[type].toObject() : user.items.gear[type], - {[item.type]: item.key} - ); + user.items.gear[type] = { + + ...(user.items.gear[type].toObject ? user.items.gear[type].toObject() : user.items.gear[type]), + [item.type]: item.key, + }; if (user.markModified && type === 'owned') user.markModified('items.gear.owned'); message = handleTwoHanded(user, item, type, req); @@ -71,7 +71,7 @@ export default function equip (user, req = {}) { } } - let res = [user.items]; + const res = [user.items]; if (message) res.push(message); return res; } diff --git a/website/common/script/ops/feed.js b/website/common/script/ops/feed.js index 1087212cba..bd7c4fcb29 100644 --- a/website/common/script/ops/feed.js +++ b/website/common/script/ops/feed.js @@ -1,10 +1,10 @@ -import content from '../content/index'; -import i18n from '../i18n'; import forEach from 'lodash/forEach'; import findIndex from 'lodash/findIndex'; import get from 'lodash/get'; import keys from 'lodash/keys'; import upperFirst from 'lodash/upperFirst'; +import i18n from '../i18n'; +import content from '../content/index'; import { BadRequest, NotAuthorized, @@ -32,7 +32,7 @@ function evolve (user, pet, req) { export default function feed (user, req = {}) { let pet = get(req, 'params.pet'); - let foodK = get(req, 'params.food'); + const foodK = get(req, 'params.food'); if (!pet || !foodK) throw new BadRequest(errorMessage('missingPetFoodFeed')); @@ -42,12 +42,12 @@ export default function feed (user, req = {}) { throw new BadRequest(errorMessage('invalidPetName')); } - let food = content.food[foodK]; + const food = content.food[foodK]; if (!food) { throw new NotFound(errorMessage('invalidFoodName', req.language)); } - let userPets = user.items.pets; + const userPets = user.items.pets; if (!userPets[pet.key]) { throw new NotFound(i18n.t('messagePetNotFound', req.language)); @@ -70,7 +70,7 @@ export default function feed (user, req = {}) { if (food.key === 'Saddle') { message = evolve(user, pet, req); } else { - let messageParams = { + const messageParams = { egg: pet.text(req.language), foodText: food.textThe(req.language), }; @@ -93,11 +93,9 @@ export default function feed (user, req = {}) { user.items.food[food.key]--; if (user.markModified) user.markModified('items.food'); - forEach(content.animalColorAchievements, (achievement) => { + forEach(content.animalColorAchievements, achievement => { if (!user.achievements[achievement.mountAchievement]) { - const mountIndex = findIndex(keys(content.dropEggs), (animal) => { - return !user.items.mounts[`${animal}-${achievement.color}`]; - }); + const mountIndex = findIndex(keys(content.dropEggs), animal => !user.items.mounts[`${animal}-${achievement.color}`]); if (mountIndex === -1) { user.achievements[achievement.mountAchievement] = true; if (user.addNotification) { diff --git a/website/common/script/ops/hatch.js b/website/common/script/ops/hatch.js index e867b69395..2401c52d0c 100644 --- a/website/common/script/ops/hatch.js +++ b/website/common/script/ops/hatch.js @@ -1,10 +1,10 @@ -import content from '../content/index'; -import i18n from '../i18n'; import findIndex from 'lodash/findIndex'; import forEach from 'lodash/forEach'; import get from 'lodash/get'; import keys from 'lodash/keys'; import upperFirst from 'lodash/upperFirst'; +import i18n from '../i18n'; +import content from '../content/index'; import { BadRequest, NotAuthorized, @@ -13,8 +13,8 @@ import { import errorMessage from '../libs/errorMessage'; export default function hatch (user, req = {}) { - let egg = get(req, 'params.egg'); - let hatchingPotion = get(req, 'params.hatchingPotion'); + const egg = get(req, 'params.egg'); + const hatchingPotion = get(req, 'params.hatchingPotion'); if (!(egg && hatchingPotion)) { throw new BadRequest(errorMessage('missingEggHatchingPotion')); @@ -28,7 +28,7 @@ export default function hatch (user, req = {}) { throw new BadRequest(i18n.t('messageInvalidEggPotionCombo', req.language)); } - let pet = `${egg}-${hatchingPotion}`; + const pet = `${egg}-${hatchingPotion}`; if (user.items.pets[pet] && user.items.pets[pet] > 0) { throw new NotAuthorized(i18n.t('messageAlreadyPet', req.language)); @@ -43,11 +43,9 @@ export default function hatch (user, req = {}) { user.markModified('items.hatchingPotions'); } - forEach(content.animalColorAchievements, (achievement) => { + forEach(content.animalColorAchievements, achievement => { if (!user.achievements[achievement.petAchievement]) { - const petIndex = findIndex(keys(content.dropEggs), (animal) => { - return isNaN(user.items.pets[`${animal}-${achievement.color}`]) || user.items.pets[`${animal}-${achievement.color}`] <= 0; - }); + const petIndex = findIndex(keys(content.dropEggs), animal => isNaN(user.items.pets[`${animal}-${achievement.color}`]) || user.items.pets[`${animal}-${achievement.color}`] <= 0); if (petIndex === -1) { user.achievements[achievement.petAchievement] = true; if (user.addNotification) { diff --git a/website/common/script/ops/openMysteryItem.js b/website/common/script/ops/openMysteryItem.js index 5b72720667..0ab7926c40 100644 --- a/website/common/script/ops/openMysteryItem.js +++ b/website/common/script/ops/openMysteryItem.js @@ -1,20 +1,18 @@ +import cloneDeep from 'lodash/cloneDeep'; import content from '../content/index'; import i18n from '../i18n'; import { BadRequest, } from '../libs/errors'; -import cloneDeep from 'lodash/cloneDeep'; function markNotificationAsRead (user) { - const index = user.notifications.findIndex(notification => { - return notification && notification.type === 'NEW_MYSTERY_ITEMS'; - }); + const index = user.notifications.findIndex(notification => notification && notification.type === 'NEW_MYSTERY_ITEMS'); if (index !== -1) user.notifications.splice(index, 1); } export default function openMysteryItem (user, req = {}, analytics) { - const mysteryItems = user.purchased.plan.mysteryItems; + const { mysteryItems } = user.purchased.plan; let item = mysteryItems.shift(); if (!item) { diff --git a/website/common/script/ops/pinnedGearUtils.js b/website/common/script/ops/pinnedGearUtils.js index 0afcfa1898..fea7994b35 100644 --- a/website/common/script/ops/pinnedGearUtils.js +++ b/website/common/script/ops/pinnedGearUtils.js @@ -1,3 +1,7 @@ +import each from 'lodash/each'; +import sortBy from 'lodash/sortBy'; +import lodashFind from 'lodash/find'; +import reduce from 'lodash/reduce'; import content from '../content/index'; import getItemInfo from '../libs/getItemInfo'; import { BadRequest } from '../libs/errors'; @@ -5,12 +9,8 @@ import i18n from '../i18n'; import getItemByPathAndType from '../libs/getItemByPathAndType'; import getOfficialPinnedItems from '../libs/getOfficialPinnedItems'; -import each from 'lodash/each'; -import sortBy from 'lodash/sortBy'; -import lodashFind from 'lodash/find'; -import reduce from 'lodash/reduce'; -let sortOrder = reduce(content.gearTypes, (accumulator, val, key) => { +const sortOrder = reduce(content.gearTypes, (accumulator, val, key) => { accumulator[val] = key; return accumulator; }, {}); @@ -21,9 +21,7 @@ let sortOrder = reduce(content.gearTypes, (accumulator, val, key) => { * @param String path */ function pathExistsInArray (array, path) { - return array.findIndex(item => { - return item.path === path; - }); + return array.findIndex(item => item.path === path); } function checkForNullEntries (array) { @@ -36,17 +34,15 @@ export function checkPinnedAreasForNullEntries (user) { } export function selectGearToPin (user) { - let changes = []; + const changes = []; - each(content.gearTypes, (type) => { - let found = lodashFind(content.gear.tree[type][user.stats.class], (item) => { - return !user.items.gear.owned[item.key]; - }); + each(content.gearTypes, type => { + const found = lodashFind(content.gear.tree[type][user.stats.class], item => !user.items.gear.owned[item.key]); if (found) changes.push(found); }); - return sortBy(changes, (change) => sortOrder[change.type]); + return sortBy(changes, change => sortOrder[change.type]); } export function addPinnedGear (user, type, path) { @@ -61,10 +57,10 @@ export function addPinnedGear (user, type, path) { } export function addPinnedGearByClass (user) { - let newPinnedItems = selectGearToPin(user); + const newPinnedItems = selectGearToPin(user); - for (let item of newPinnedItems) { - let itemInfo = getItemInfo(user, 'marketGear', item); + for (const item of newPinnedItems) { + const itemInfo = getItemInfo(user, 'marketGear', item); addPinnedGear(user, itemInfo.pinType, itemInfo.path); } @@ -82,10 +78,10 @@ export function removeItemByPath (user, path) { } export function removePinnedGearByClass (user) { - let currentPinnedItems = selectGearToPin(user); + const currentPinnedItems = selectGearToPin(user); - for (let item of currentPinnedItems) { - let itemInfo = getItemInfo(user, 'marketGear', item); + for (const item of currentPinnedItems) { + const itemInfo = getItemInfo(user, 'marketGear', item); removeItemByPath(user, itemInfo.path); } @@ -124,9 +120,9 @@ const PATHS_WITHOUT_ITEM = ['special.gems', 'special.rebirth_orb', 'special.fort /** * @returns {boolean} TRUE added the item / FALSE removed it */ -export function togglePinnedItem (user, {item, type, path}, req = {}) { +export function togglePinnedItem (user, { item, type, path }, req = {}) { let arrayToChange; - let officialPinnedItems = getOfficialPinnedItems(user); + const officialPinnedItems = getOfficialPinnedItems(user); if (!path) { // If path isn't passed it means an item was passed @@ -137,7 +133,7 @@ export function togglePinnedItem (user, {item, type, path}, req = {}) { if (!item && PATHS_WITHOUT_ITEM.indexOf(path) === -1) { // path not exists in our content structure - throw new BadRequest(i18n.t('wrongItemPath', {path}, req.language)); + throw new BadRequest(i18n.t('wrongItemPath', { path }, req.language)); } // check if item exists & valid to be pinned @@ -171,10 +167,9 @@ export function togglePinnedItem (user, {item, type, path}, req = {}) { if (foundIndex >= 0) { arrayToChange.splice(foundIndex, 1); return isOfficialPinned; - } else { - arrayToChange.push({path, type}); - return !isOfficialPinned; } + arrayToChange.push({ path, type }); + return !isOfficialPinned; } export { default as isPinned } from '../libs/isPinned'; diff --git a/website/common/script/ops/readCard.js b/website/common/script/ops/readCard.js index 8602016c1c..c3be9a1d7e 100644 --- a/website/common/script/ops/readCard.js +++ b/website/common/script/ops/readCard.js @@ -11,10 +11,10 @@ import content from '../content/index'; function markNotificationAsRead (user, cardType) { const indexToRemove = user.notifications.findIndex(notification => { if ( - notification && - notification.type === 'CARD_RECEIVED' && - notification.data && - notification.data.card === cardType + notification + && notification.type === 'CARD_RECEIVED' + && notification.data + && notification.data.card === cardType ) return true; }); @@ -23,7 +23,7 @@ function markNotificationAsRead (user, cardType) { export default function readCard (user, req = {}) { - let cardType = get(req.params, 'cardType'); + const cardType = get(req.params, 'cardType'); if (!cardType) { throw new BadRequest(i18n.t('cardTypeRequired', req.language)); @@ -40,6 +40,6 @@ export default function readCard (user, req = {}) { return [ { specialItems: user.items.special, cardReceived: user.flags.cardReceived }, - i18n.t('readCard', {cardType}, req.language), + i18n.t('readCard', { cardType }, req.language), ]; } diff --git a/website/common/script/ops/rebirth.js b/website/common/script/ops/rebirth.js index d56904634a..09cd63db5a 100644 --- a/website/common/script/ops/rebirth.js +++ b/website/common/script/ops/rebirth.js @@ -1,5 +1,5 @@ -import i18n from '../i18n'; import each from 'lodash/each'; +import i18n from '../i18n'; import { capByLevel } from '../statHelpers'; import { MAX_LEVEL } from '../constants'; import { @@ -18,7 +18,7 @@ export default function rebirth (user, tasks = [], req = {}, analytics) { throw new NotAuthorized(i18n.t('notEnoughGems', req.language)); } - let analyticsData = { + const analyticsData = { uuid: user._id, category: 'behavior', }; @@ -37,9 +37,9 @@ export default function rebirth (user, tasks = [], req = {}, analytics) { analytics.track('Rebirth', analyticsData); } - let lvl = capByLevel(user.stats.lvl); + const lvl = capByLevel(user.stats.lvl); - each(tasks, function resetTasks (task) { + each(tasks, task => { if (!task.challenge || !task.challenge.id || task.challenge.broken) { if (task.type !== 'reward') { task.value = 0; @@ -56,7 +56,7 @@ export default function rebirth (user, tasks = [], req = {}, analytics) { removePinnedGearByClass(user); - let stats = user.stats; + const { stats } = user; stats.buffs = {}; stats.hp = 50; stats.lvl = 1; @@ -64,7 +64,7 @@ export default function rebirth (user, tasks = [], req = {}, analytics) { user.preferences.automaticAllocation = false; - each(USERSTATSLIST, function resetStats (value) { + each(USERSTATSLIST, value => { stats[value] = 0; }); @@ -86,7 +86,7 @@ export default function rebirth (user, tasks = [], req = {}, analytics) { }); } - let flags = user.flags; + const { flags } = user; flags.itemsEnabled = false; flags.dropsEnabled = false; flags.classSelected = false; @@ -110,7 +110,7 @@ export default function rebirth (user, tasks = [], req = {}, analytics) { user.stats.buffs = {}; return [ - {user, tasks}, + { user, tasks }, i18n.t('rebirthComplete'), ]; } diff --git a/website/common/script/ops/releaseBoth.js b/website/common/script/ops/releaseBoth.js index 1948f93033..669c330fcd 100644 --- a/website/common/script/ops/releaseBoth.js +++ b/website/common/script/ops/releaseBoth.js @@ -1,11 +1,11 @@ +import pick from 'lodash/pick'; import content from '../content/index'; -import {beastMasterProgress, mountMasterProgress} from '../count'; +import { beastMasterProgress, mountMasterProgress } from '../count'; import i18n from '../i18n'; import { NotAuthorized, } from '../libs/errors'; import splitWhitespace from '../libs/splitWhitespace'; -import pick from 'lodash/pick'; export default function releaseBoth (user, req = {}) { let animal; @@ -37,13 +37,13 @@ export default function releaseBoth (user, req = {}) { // user.balance -= 1.5; // } - let mountInfo = content.mountInfo[user.items.currentMount]; + const mountInfo = content.mountInfo[user.items.currentMount]; if (mountInfo && mountInfo.type === 'drop') { user.items.currentMount = ''; } - let petInfo = content.petInfo[user.items.currentPet]; + const petInfo = content.petInfo[user.items.currentPet]; if (petInfo && petInfo.type === 'drop') { user.items.currentPet = ''; diff --git a/website/common/script/ops/releaseMounts.js b/website/common/script/ops/releaseMounts.js index f3733e3e05..06247e6d9e 100644 --- a/website/common/script/ops/releaseMounts.js +++ b/website/common/script/ops/releaseMounts.js @@ -1,5 +1,5 @@ import content from '../content/index'; -import {mountMasterProgress} from '../count'; +import { mountMasterProgress } from '../count'; import i18n from '../i18n'; import { NotAuthorized, @@ -18,13 +18,13 @@ export default function releaseMounts (user, req = {}, analytics) { let giveMountMasterAchievement = true; - let mountInfo = content.mountInfo[user.items.currentMount]; + const mountInfo = content.mountInfo[user.items.currentMount]; if (mountInfo && mountInfo.type === 'drop') { user.items.currentMount = ''; } - for (let mount in content.pets) { + for (const mount in content.pets) { if (user.items.mounts[mount] === null || user.items.mounts[mount] === undefined) { giveMountMasterAchievement = false; } diff --git a/website/common/script/ops/releasePets.js b/website/common/script/ops/releasePets.js index 7d2ea051d8..436f205d3a 100644 --- a/website/common/script/ops/releasePets.js +++ b/website/common/script/ops/releasePets.js @@ -1,5 +1,5 @@ import content from '../content/index'; -import {beastMasterProgress} from '../count'; +import { beastMasterProgress } from '../count'; import i18n from '../i18n'; import { NotAuthorized, @@ -18,13 +18,13 @@ export default function releasePets (user, req = {}, analytics) { let giveBeastMasterAchievement = true; - let petInfo = content.petInfo[user.items.currentPet]; + const petInfo = content.petInfo[user.items.currentPet]; if (petInfo && petInfo.type === 'drop') { user.items.currentPet = ''; } - for (let pet in content.pets) { + for (const pet in content.pets) { if (!user.items.pets[pet]) { giveBeastMasterAchievement = false; } diff --git a/website/common/script/ops/reroll.js b/website/common/script/ops/reroll.js index 35add88e42..c5d8d2c82d 100644 --- a/website/common/script/ops/reroll.js +++ b/website/common/script/ops/reroll.js @@ -1,5 +1,5 @@ -import i18n from '../i18n'; import each from 'lodash/each'; +import i18n from '../i18n'; import { NotAuthorized, } from '../libs/errors'; @@ -12,7 +12,7 @@ export default function reroll (user, tasks = [], req = {}, analytics) { user.balance--; user.stats.hp = 50; - each(tasks, function resetTaskValues (task) { + each(tasks, task => { if (!task.challenge || !task.challenge.id || task.challenge.broken) { if (task.type !== 'reward') { task.value = 0; @@ -31,7 +31,7 @@ export default function reroll (user, tasks = [], req = {}, analytics) { } return [ - {user, tasks}, + { user, tasks }, i18n.t('fortifyComplete'), ]; } diff --git a/website/common/script/ops/reset.js b/website/common/script/ops/reset.js index 23f466a528..1964afb0fd 100644 --- a/website/common/script/ops/reset.js +++ b/website/common/script/ops/reset.js @@ -7,14 +7,14 @@ export default function reset (user, tasks = []) { user.stats.gp = 0; user.stats.exp = 0; - let tasksToRemove = []; + const tasksToRemove = []; tasks.forEach(task => { - let isNotChallengeTask = !task.challenge || !task.challenge.id || task.challenge.broken; - let isNotGroupTask = !task.group || !task.group.id || task.group.broken; + const isNotChallengeTask = !task.challenge || !task.challenge.id || task.challenge.broken; + const isNotGroupTask = !task.group || !task.group.id || task.group.broken; if (isNotChallengeTask && isNotGroupTask) { tasksToRemove.push(task._id); - let i = user.tasksOrder[`${task.type}s`].indexOf(task._id); + const i = user.tasksOrder[`${task.type}s`].indexOf(task._id); if (i !== -1) user.tasksOrder[`${task.type}s`].splice(i, 1); } }); @@ -24,7 +24,7 @@ export default function reset (user, tasks = []) { user.preferences.automaticAllocation = false; return [ - {user, tasksToRemove}, + { user, tasksToRemove }, i18n.t('resetComplete'), ]; } diff --git a/website/common/script/ops/revive.js b/website/common/script/ops/revive.js index d87b71b77b..5436520d12 100644 --- a/website/common/script/ops/revive.js +++ b/website/common/script/ops/revive.js @@ -1,8 +1,8 @@ -import content from '../content/index'; -import i18n from '../i18n'; import merge from 'lodash/merge'; import reduce from 'lodash/reduce'; import each from 'lodash/each'; +import i18n from '../i18n'; +import content from '../content/index'; import { NotAuthorized, } from '../libs/errors'; @@ -27,7 +27,7 @@ export default function revive (user, req = {}, analytics) { user.stats.lvl--; } - let lostStat = randomVal(reduce(['str', 'con', 'per', 'int'], function findRandomStat (m, k) { + const lostStat = randomVal(reduce(['str', 'con', 'per', 'int'], (m, k) => { if (user.stats[k]) { m[k] = k; } @@ -40,7 +40,7 @@ export default function revive (user, req = {}, analytics) { user.stats[lostStat]--; } - let base = user.items.gear.owned; + const base = user.items.gear.owned; let gearOwned; if (typeof base.toObject === 'function') { @@ -49,24 +49,24 @@ export default function revive (user, req = {}, analytics) { gearOwned = user.items.gear.owned; } - let losableItems = {}; - let userClass = user.stats.class; + const losableItems = {}; + const userClass = user.stats.class; - each(gearOwned, function findLosableItems (value, key) { + each(gearOwned, (value, key) => { let itm; if (value) { itm = content.gear.flat[key]; if (itm) { - let itemHasValueOrWarrior0 = itm.value > 0 || key === 'weapon_warrior_0'; + const itemHasValueOrWarrior0 = itm.value > 0 || key === 'weapon_warrior_0'; - let itemClassEqualsUserClass = itm.klass === userClass; + const itemClassEqualsUserClass = itm.klass === userClass; - let itemClassSpecial = itm.klass === 'special'; - let itemNotSpecialOrUserClassIsSpecial = !itm.specialClass || itm.specialClass === userClass; - let itemIsSpecial = itemNotSpecialOrUserClassIsSpecial && itemClassSpecial; + const itemClassSpecial = itm.klass === 'special'; + const itemNotSpecialOrUserClassIsSpecial = !itm.specialClass || itm.specialClass === userClass; + const itemIsSpecial = itemNotSpecialOrUserClassIsSpecial && itemClassSpecial; - let itemIsArmoire = itm.klass === 'armoire'; + const itemIsArmoire = itm.klass === 'armoire'; if (itemHasValueOrWarrior0 && (itemClassEqualsUserClass || itemIsSpecial || itemIsArmoire)) { losableItems[key] = key; @@ -76,12 +76,12 @@ export default function revive (user, req = {}, analytics) { } }); - let lostItem = randomVal(losableItems, { + const lostItem = randomVal(losableItems, { predictableRandom: predictableRandom(user), }); let message = ''; - let item = content.gear.flat[lostItem]; + const item = content.gear.flat[lostItem]; if (item) { removePinnedGearByClass(user); @@ -91,18 +91,18 @@ export default function revive (user, req = {}, analytics) { addPinnedGearByClass(user); - let itemInfo = getItemInfo(user, 'marketGear', item); + const itemInfo = getItemInfo(user, 'marketGear', item); addPinnedGear(user, itemInfo.pinType, itemInfo.path); if (user.items.gear.equipped[item.type] === lostItem) { - user.items.gear.equipped[item.type] = `${item.type}_base_0`; + user.items.gear.equipped[item.type] = `${item.type}_base_0`; } if (user.items.gear.costume[item.type] === lostItem) { user.items.gear.costume[item.type] = `${item.type}_base_0`; } - message = i18n.t('messageLostItem', { itemText: item.text(req.language)}, req.language); + message = i18n.t('messageLostItem', { itemText: item.text(req.language) }, req.language); } if (analytics) { diff --git a/website/common/script/ops/scoreTask.js b/website/common/script/ops/scoreTask.js index 6b6d85c889..3a7da608db 100644 --- a/website/common/script/ops/scoreTask.js +++ b/website/common/script/ops/scoreTask.js @@ -17,18 +17,17 @@ const CLOSE_ENOUGH = 0.00001; function _getTaskValue (taskValue) { if (taskValue < MIN_TASK_VALUE) { return MIN_TASK_VALUE; - } else if (taskValue > MAX_TASK_VALUE) { + } if (taskValue > MAX_TASK_VALUE) { return MAX_TASK_VALUE; - } else { - return taskValue; } + return taskValue; } // Calculates the next task.value based on direction // Uses a capped inverse log y=.95^x, y>= -5 function _calculateDelta (task, direction, cron) { // Min/max on task redness - let currVal = _getTaskValue(task.value); + const currVal = _getTaskValue(task.value); let nextDelta = Math.pow(0.9747, currVal) * (direction === 'down' ? -1 : 1); // Checklists @@ -52,15 +51,15 @@ function _calculateDelta (task, direction, cron) { // First, calculate the value using the normal way for our first guess although // it will be a bit off function _calculateReverseDelta (task, direction) { - let currVal = _getTaskValue(task.value); + const currVal = _getTaskValue(task.value); let testVal = currVal + Math.pow(0.9747, currVal) * (direction === 'down' ? -1 : 1); // Now keep moving closer to the original value until we get "close enough" // Check how close we are to the original value by computing the delta off our guess // and looking at the difference between that and our current value. while (true) { // eslint-disable-line no-constant-condition - let calc = testVal + Math.pow(0.9747, testVal); - let diff = currVal - calc; + const calc = testVal + Math.pow(0.9747, testVal); + const diff = currVal - calc; if (Math.abs(diff) < CLOSE_ENOUGH) break; @@ -101,30 +100,30 @@ function _subtractPoints (user, task, stats, delta) { let conBonus = 1 - statsComputed(user).con / 250; if (conBonus < 0.1) conBonus = 0.1; - let hpMod = delta * conBonus * task.priority * 2; // constant 2 multiplier for better results + const hpMod = delta * conBonus * task.priority * 2; // constant 2 multiplier for better results stats.hp += Math.round(hpMod * 10) / 10; // round to 1dp return stats.hp; } function _addPoints (user, task, stats, direction, delta) { - let _crit = user._tmp.crit || 1; + const _crit = user._tmp.crit || 1; // Exp Modifier // ===== Intelligence ===== // TODO Increases Experience gain by .2% per point. - let intBonus = 1 + statsComputed(user).int * 0.025; + const intBonus = 1 + statsComputed(user).int * 0.025; stats.exp += Math.round(delta * intBonus * task.priority * _crit * 6); // GP modifier // ===== PERCEPTION ===== // TODO Increases Gold gained from tasks by .3% per point. - let perBonus = 1 + statsComputed(user).per * 0.02; - let gpMod = delta * task.priority * _crit * perBonus; + const perBonus = 1 + statsComputed(user).per * 0.02; + const gpMod = delta * task.priority * _crit * perBonus; if (task.streak) { - let currStreak = direction === 'down' ? task.streak - 1 : task.streak; - let streakBonus = currStreak / 100 + 1; // eg, 1-day streak is 1.01, 2-day is 1.02, etc - let afterStreak = gpMod * streakBonus; + const currStreak = direction === 'down' ? task.streak - 1 : task.streak; + const streakBonus = currStreak / 100 + 1; // eg, 1-day streak is 1.01, 2-day is 1.02, etc + const afterStreak = gpMod * streakBonus; if (currStreak > 0 && gpMod > 0) { user._tmp.streakBonus = afterStreak - gpMod; // keep this on-hand for later, so we can notify streak-bonus } @@ -140,14 +139,14 @@ function _changeTaskValue (user, task, direction, times, cron) { // ===== CRITICAL HITS ===== // allow critical hit only when checking off a task, not when unchecking it: - let _crit = direction === 'up' ? crit.crit(user) : 1; + const _crit = direction === 'up' ? crit.crit(user) : 1; // if there was a crit, alert the user via notification if (_crit > 1) user._tmp.crit = _crit; // If multiple days have passed, multiply times days missed timesLodash(times, () => { // Each iteration calculate the nextDelta, which is then accumulated in the total delta. - let nextDelta = !cron && direction === 'down' ? _calculateReverseDelta(task, direction) : _calculateDelta(task, direction, cron); + const nextDelta = !cron && direction === 'down' ? _calculateReverseDelta(task, direction) : _calculateDelta(task, direction, cron); if (task.type !== 'reward') { if (user.preferences.automaticAllocation === true && user.preferences.allocationMode === 'taskbased' && !(task.type === 'todo' && direction === 'down')) { @@ -156,7 +155,7 @@ function _changeTaskValue (user, task, direction, times, cron) { if (direction === 'up') { // Make progress on quest based on STR user.party.quest.progress.up = user.party.quest.progress.up || 0; - let prevProgress = user.party.quest.progress.up; + const prevProgress = user.party.quest.progress.up; if (task.type === 'todo' || task.type === 'daily') { user.party.quest.progress.up += nextDelta * _crit * (1 + statsComputed(user).str / 200); @@ -185,9 +184,11 @@ function _updateCounter (task, direction, times) { } export default function scoreTask (options = {}, req = {}) { - let {user, task, direction, times = 1, cron = false} = options; + const { + user, task, direction, times = 1, cron = false, + } = options; let delta = 0; - let stats = { + const stats = { gp: user.stats.gp, hp: user.stats.hp, exp: user.stats.exp, @@ -215,8 +216,8 @@ export default function scoreTask (options = {}, req = {}) { // Save history entry for habit task.history = task.history || []; - const timezoneOffset = user.preferences.timezoneOffset; - const dayStart = user.preferences.dayStart; + const { timezoneOffset } = user.preferences; + const { dayStart } = user.preferences; const historyLength = task.history.length; const lastHistoryEntry = task.history[historyLength - 1]; @@ -229,8 +230,8 @@ export default function scoreTask (options = {}, req = {}) { } if ( - lastHistoryEntryDate && - moment().zone(timezoneOffset).isSame(lastHistoryEntryDate, 'day') + lastHistoryEntryDate + && moment().zone(timezoneOffset).isSame(lastHistoryEntryDate, 'day') ) { lastHistoryEntry.value = task.value; lastHistoryEntry.date = Number(new Date()); @@ -278,7 +279,7 @@ export default function scoreTask (options = {}, req = {}) { // Save history entry for daily task.history = task.history || []; - let historyEntry = { + const historyEntry = { date: Number(new Date()), value: task.value, }; @@ -312,7 +313,7 @@ export default function scoreTask (options = {}, req = {}) { _addPoints(user, task, stats, direction, delta); // MP++ per checklist item in ToDo, bonus per CLI - let multiplier = max([reduce(task.checklist, (m, i) => m + (i.completed ? 1 : 0), 1), 1]); + const multiplier = max([reduce(task.checklist, (m, i) => m + (i.completed ? 1 : 0), 1), 1]); _gainMP(user, max([multiplier, 0.01 * statsComputed(user).maxMP * multiplier]) * (direction === 'down' ? -1 : 1)); } } else if (task.type === 'reward') { diff --git a/website/common/script/ops/sell.js b/website/common/script/ops/sell.js index 2eb5aa9b99..23f14cd851 100644 --- a/website/common/script/ops/sell.js +++ b/website/common/script/ops/sell.js @@ -1,7 +1,7 @@ -import content from '../content/index'; -import i18n from '../i18n'; import get from 'lodash/get'; import pick from 'lodash/pick'; +import content from '../content/index'; +import i18n from '../i18n'; import splitWhitespace from '../libs/splitWhitespace'; import { NotFound, @@ -13,9 +13,9 @@ import { const ACCEPTEDTYPES = ['eggs', 'hatchingPotions', 'food']; export default function sell (user, req = {}) { - let key = get(req.params, 'key'); - let type = get(req.params, 'type'); - let amount = get(req.query, 'amount', 1); + const key = get(req.params, 'key'); + const type = get(req.params, 'type'); + const amount = get(req.query, 'amount', 1); if (amount < 0) { throw new BadRequest(i18n.t('positiveAmountRequired', req.language)); @@ -30,17 +30,17 @@ export default function sell (user, req = {}) { } if (ACCEPTEDTYPES.indexOf(type) === -1) { - throw new NotAuthorized(i18n.t('typeNotSellable', {acceptedTypes: ACCEPTEDTYPES.join(', ')}, req.language)); + throw new NotAuthorized(i18n.t('typeNotSellable', { acceptedTypes: ACCEPTEDTYPES.join(', ') }, req.language)); } if (!user.items[type][key]) { - throw new NotFound(i18n.t('userItemsKeyNotFound', {type}, req.language)); + throw new NotFound(i18n.t('userItemsKeyNotFound', { type }, req.language)); } - let currentAmount = user.items[type][key]; + const currentAmount = user.items[type][key]; if (amount > currentAmount) { - throw new NotFound(i18n.t('userItemsNotEnough', {type}, req.language)); + throw new NotFound(i18n.t('userItemsNotEnough', { type }, req.language)); } if (type === 'food' && key === 'Saddle') { diff --git a/website/common/script/ops/sortTag.js b/website/common/script/ops/sortTag.js index 65d7dbf530..11dffeae4c 100644 --- a/website/common/script/ops/sortTag.js +++ b/website/common/script/ops/sortTag.js @@ -1,14 +1,14 @@ -import { BadRequest } from '../libs/errors'; import get from 'lodash/get'; +import { BadRequest } from '../libs/errors'; // TODO used only in client, move there? export default function sortTag (user, req = {}) { - let to = get(req, 'query.to'); - let fromParam = get(req, 'query.from'); + const to = get(req, 'query.to'); + const fromParam = get(req, 'query.from'); - let invalidTo = !to && to !== 0; - let invalidFrom = !fromParam && fromParam !== 0; + const invalidTo = !to && to !== 0; + const invalidFrom = !fromParam && fromParam !== 0; if (invalidTo || invalidFrom) { throw new BadRequest('?to=__&from=__ are required'); diff --git a/website/common/script/ops/sortTask.js b/website/common/script/ops/sortTask.js index 996976dd26..0e461f5a88 100644 --- a/website/common/script/ops/sortTask.js +++ b/website/common/script/ops/sortTask.js @@ -1,23 +1,21 @@ +import get from 'lodash/get'; +import findIndex from 'lodash/findIndex'; import i18n from '../i18n'; import preenTodos from '../libs/preenTodos'; import { NotFound, BadRequest, } from '../libs/errors'; -import get from 'lodash/get'; -import findIndex from 'lodash/findIndex'; // TODO used only in client, move there? export default function sortTask (user, req = {}) { - let id = get(req, 'params.id'); + const id = get(req, 'params.id'); let to = get(req, 'query.to'); let fromParam = get(req, 'query.from'); - let taskType = get(req, 'params.taskType'); + const taskType = get(req, 'params.taskType'); - let index = findIndex(user[`${taskType}s`], function findById (task) { - return task._id === id; - }); + const index = findIndex(user[`${taskType}s`], task => task._id === id); if (index === -1) { throw new NotFound(i18n.t('messageTaskNotFound', req.language)); @@ -26,10 +24,10 @@ export default function sortTask (user, req = {}) { throw new BadRequest('?to=__&from=__ are required'); } - let tasks = user[`${taskType}s`]; + const tasks = user[`${taskType}s`]; if (taskType === 'todo') { - let preenedTasks = preenTodos(tasks); + const preenedTasks = preenTodos(tasks); if (to !== -1) { to = tasks.indexOf(preenedTasks[to]); @@ -38,7 +36,7 @@ export default function sortTask (user, req = {}) { fromParam = tasks.indexOf(preenedTasks[fromParam]); } - let movedTask = tasks.splice(fromParam, 1)[0]; + const movedTask = tasks.splice(fromParam, 1)[0]; if (to === -1) { tasks.push(movedTask); diff --git a/website/common/script/ops/stats/allocate.js b/website/common/script/ops/stats/allocate.js index e1350571e6..28b76695f3 100644 --- a/website/common/script/ops/stats/allocate.js +++ b/website/common/script/ops/stats/allocate.js @@ -11,10 +11,10 @@ import errorMessage from '../../libs/errorMessage'; import hasClass from '../../libs/hasClass'; export default function allocate (user, req = {}) { - let stat = get(req, 'query.stat', 'str'); + const stat = get(req, 'query.stat', 'str'); if (ATTRIBUTES.indexOf(stat) === -1) { - throw new BadRequest(errorMessage('invalidAttribute', {attr: stat})); + throw new BadRequest(errorMessage('invalidAttribute', { attr: stat })); } if (!hasClass(user)) { diff --git a/website/common/script/ops/stats/allocateBulk.js b/website/common/script/ops/stats/allocateBulk.js index f5ae89949d..e532525d89 100644 --- a/website/common/script/ops/stats/allocateBulk.js +++ b/website/common/script/ops/stats/allocateBulk.js @@ -15,11 +15,9 @@ export default function allocateBulk (user, req = {}) { if (!stats) throw new BadRequest(errorMessage('statsObjectRequired')); const statKeys = Object.keys(stats); - const invalidStats = statKeys.filter(statKey => { - return ATTRIBUTES.indexOf(statKey) === -1; - }); + const invalidStats = statKeys.filter(statKey => ATTRIBUTES.indexOf(statKey) === -1); if (invalidStats.length > 0) { - throw new BadRequest(errorMessage('invalidAttribute', {attr: invalidStats.join(',')})); + throw new BadRequest(errorMessage('invalidAttribute', { attr: invalidStats.join(',') })); } if (!hasClass(user)) { @@ -31,14 +29,12 @@ export default function allocateBulk (user, req = {}) { } const newStatValues = Object.values(stats); - const totalPointsToAllocate = newStatValues.reduce((sum, value) => { - return sum + value; - }, 0); + const totalPointsToAllocate = newStatValues.reduce((sum, value) => sum + value, 0); if (user.stats.points < totalPointsToAllocate) { throw new NotAuthorized(i18n.t('notEnoughAttrPoints', req.language)); } - for (let [stat, value] of Object.entries(stats)) { + for (const [stat, value] of Object.entries(stats)) { user.stats[stat] += value; user.stats.points -= value; if (stat === 'int') user.stats.mp += value; diff --git a/website/common/script/ops/unlock.js b/website/common/script/ops/unlock.js index 891eeb946c..b72fab6fbb 100644 --- a/website/common/script/ops/unlock.js +++ b/website/common/script/ops/unlock.js @@ -1,8 +1,8 @@ -import i18n from '../i18n'; import get from 'lodash/get'; import each from 'lodash/each'; import pick from 'lodash/pick'; import setWith from 'lodash/setWith'; +import i18n from '../i18n'; import splitWhitespace from '../libs/splitWhitespace'; import { NotAuthorized, @@ -16,14 +16,14 @@ import content from '../content/index'; // If item is already purchased -> equip it // Otherwise unlock it export default function unlock (user, req = {}, analytics) { - let path = get(req.query, 'path'); + const path = get(req.query, 'path'); if (!path) { throw new BadRequest(i18n.t('pathRequired', req.language)); } - let isFullSet = path.indexOf(',') !== -1; - let isBackground = path.indexOf('background.') !== -1; + const isFullSet = path.indexOf(',') !== -1; + const isBackground = path.indexOf('background.') !== -1; let cost; if (isBackground && isFullSet) { @@ -69,11 +69,11 @@ export default function unlock (user, req = {}, analytics) { } if (isFullSet) { - each(setPaths, function markItemsAsPurchased (pathPart) { + each(setPaths, pathPart => { if (path.indexOf('gear.') !== -1) { // Using Object so path[1] won't create an array but an object {path: {1: value}} setWith(user, pathPart, true, Object); - let itemName = pathPart.split('.').pop(); + const itemName = pathPart.split('.').pop(); removeItemByPath(user, `gear.flat.${itemName}`); if (user.markModified && path.indexOf('gear.owned') !== -1) user.markModified('items.gear.owned'); } @@ -82,9 +82,9 @@ export default function unlock (user, req = {}, analytics) { setWith(user, `purchased.${pathPart}`, true, Object); }); } else { - let split = path.split('.'); + const split = path.split('.'); let value = split.pop(); - let key = split.join('.'); + const key = split.join('.'); if (alreadyOwns) { // eslint-disable-line no-lonely-if if (key === 'background' && value === user.preferences.background) { @@ -104,8 +104,8 @@ export default function unlock (user, req = {}, analytics) { // @TODO: Test and check test coverage if (isBackground) { - let backgroundContent = content.backgroundsFlat[value]; - let itemInfo = getItemInfo(user, 'background', backgroundContent); + const backgroundContent = content.backgroundsFlat[value]; + const itemInfo = getItemInfo(user, 'background', backgroundContent); removeItemByPath(user, itemInfo.path); } } @@ -131,7 +131,7 @@ export default function unlock (user, req = {}, analytics) { } } - let response = [ + const response = [ pick(user, splitWhitespace('purchased preferences items')), ]; diff --git a/website/common/script/ops/updateTag.js b/website/common/script/ops/updateTag.js index ca4264d130..a939e24cc2 100644 --- a/website/common/script/ops/updateTag.js +++ b/website/common/script/ops/updateTag.js @@ -1,14 +1,14 @@ -import i18n from '../i18n'; import get from 'lodash/get'; import findIndex from 'lodash/findIndex'; +import i18n from '../i18n'; import { NotFound } from '../libs/errors'; // TODO used only in client, move there? export default function updateTag (user, req = {}) { - let tid = get(req, 'params.id'); + const tid = get(req, 'params.id'); - let index = findIndex(user.tags, { + const index = findIndex(user.tags, { id: tid, }); diff --git a/website/common/script/ops/updateTask.js b/website/common/script/ops/updateTask.js index e504184f45..dcca31c529 100644 --- a/website/common/script/ops/updateTask.js +++ b/website/common/script/ops/updateTask.js @@ -3,7 +3,7 @@ import omit from 'lodash/omit'; // From server pass task.toObject() not the task document directly export default function updateTask (task, req = {}) { - let body = req.body || {}; + const body = req.body || {}; // If reminders are updated -> replace the original ones if (body.reminders) { diff --git a/website/common/script/statHelpers.js b/website/common/script/statHelpers.js index b678f08ef1..81e4cc2fc7 100644 --- a/website/common/script/statHelpers.js +++ b/website/common/script/statHelpers.js @@ -11,9 +11,8 @@ import { export function capByLevel (lvl) { if (lvl > MAX_LEVEL) { return MAX_LEVEL; - } else { - return lvl; } + return lvl; } /* @@ -25,7 +24,7 @@ export function capByLevel (lvl) { export function toNextLevel (lvl) { if (lvl < 5) { return 25 * lvl; - } else if (lvl === 5) { + } if (lvl === 5) { return 150; } return Math.round((Math.pow(lvl, 2) * 0.25 + 10 * lvl + 139.75) / 10) * 10; diff --git a/website/server/.eslintrc b/website/server/.eslintrc index 7b3c05adf0..b62d7f2160 100644 --- a/website/server/.eslintrc +++ b/website/server/.eslintrc @@ -1,6 +1,5 @@ { "extends": [ - "habitrpg/server", - "habitrpg/esnext" + "habitrpg/lib/node", ] } \ No newline at end of file diff --git a/website/server/api-doc.js b/website/server/api-doc.js index 14d136ef30..83b417afed 100644 --- a/website/server/api-doc.js +++ b/website/server/api-doc.js @@ -1,4 +1,3 @@ -'use strict'; // This file defines some globals for use in the API Doc comments diff --git a/website/server/controllers/api-v3/auth.js b/website/server/controllers/api-v3/auth.js index 782e52c5ba..588a6b7273 100644 --- a/website/server/controllers/api-v3/auth.js +++ b/website/server/controllers/api-v3/auth.js @@ -12,7 +12,7 @@ import { } from '../../libs/errors'; import * as passwordUtils from '../../libs/password'; import { sendTxn as sendTxnEmail } from '../../libs/email'; -import { validatePasswordResetCodeAndFindUser, convertToBcrypt} from '../../libs/password'; +import { validatePasswordResetCodeAndFindUser, convertToBcrypt } from '../../libs/password'; import { encrypt } from '../../libs/encryption'; import { loginRes, @@ -20,12 +20,12 @@ import { loginSocial, registerLocal, } from '../../libs/auth'; -import {verifyUsername} from '../../libs/user/validation'; +import { verifyUsername } from '../../libs/user/validation'; const BASE_URL = nconf.get('BASE_URL'); const TECH_ASSISTANCE_EMAIL = nconf.get('EMAILS_TECH_ASSISTANCE_EMAIL'); -let api = {}; +const api = {}; /** * @api {post} /api/v3/user/auth/local/register Register @@ -79,24 +79,24 @@ api.loginLocal = { errorMessage: res.t('missingPassword'), }, }); - let validationErrors = req.validationErrors(); + const validationErrors = req.validationErrors(); if (validationErrors) throw validationErrors; req.sanitizeBody('username').trim(); req.sanitizeBody('password').trim(); let login; - let username = req.body.username; - let password = req.body.password; + const { username } = req.body; + const { password } = req.body; if (validator.isEmail(String(username))) { - login = {'auth.local.email': username.toLowerCase()}; // Emails are stored lowercase + login = { 'auth.local.email': username.toLowerCase() }; // Emails are stored lowercase } else { - login = {'auth.local.username': username}; + login = { 'auth.local.username': username }; } // load the entire user because we may have to save it to convert the password to bcrypt - let user = await User.findOne(login).exec(); + const user = await User.findOne(login).exec(); // if user is using social login, then user will not have a hashed_password stored if (!user || !user.auth.local.hashed_password) throw new NotAuthorized(res.t('invalidLoginCredentialsLong')); @@ -150,17 +150,17 @@ api.loginSocial = { * @apiParam (Body) {String} username The new username * @apiSuccess {String} data.username The new username - **/ + * */ api.updateUsername = { method: 'PUT', middlewares: [authWithHeaders()], url: '/user/auth/update-username', async handler (req, res) { - const user = res.locals.user; + const { user } = res.locals; req.checkBody({ username: { - notEmpty: {errorMessage: res.t('missingUsername')}, + notEmpty: { errorMessage: res.t('missingUsername') }, }, }); @@ -172,13 +172,13 @@ api.updateUsername = { const issues = verifyUsername(newUsername, res); if (issues.length > 0) throw new BadRequest(issues.join(' ')); - const password = req.body.password; + const { password } = req.body; if (password !== undefined) { - let isValidPassword = await passwordUtils.compare(user, password); + const isValidPassword = await passwordUtils.compare(user, password); if (!isValidPassword) throw new NotAuthorized(res.t('wrongPassword')); } - const existingUser = await User.findOne({ 'auth.local.lowerCaseUsername': newUsername.toLowerCase() }, {auth: 1}).exec(); + const existingUser = await User.findOne({ 'auth.local.lowerCaseUsername': newUsername.toLowerCase() }, { auth: 1 }).exec(); if (existingUser !== undefined && existingUser !== null && existingUser._id !== user._id) { throw new BadRequest(res.t('usernameTaken')); } @@ -224,39 +224,39 @@ api.updateUsername = { * @apiParam (Body) {String} confirmPassword New password confirmation * * @apiSuccess {Object} data An empty object - **/ + * */ api.updatePassword = { method: 'PUT', middlewares: [authWithHeaders()], url: '/user/auth/update-password', async handler (req, res) { - let user = res.locals.user; + const { user } = res.locals; if (!user.auth.local.hashed_password) throw new BadRequest(res.t('userHasNoLocalRegistration')); req.checkBody({ password: { - notEmpty: {errorMessage: res.t('missingPassword')}, + notEmpty: { errorMessage: res.t('missingPassword') }, }, newPassword: { - notEmpty: {errorMessage: res.t('missingNewPassword')}, + notEmpty: { errorMessage: res.t('missingNewPassword') }, }, confirmPassword: { - notEmpty: {errorMessage: res.t('missingNewPassword')}, + notEmpty: { errorMessage: res.t('missingNewPassword') }, }, }); - let validationErrors = req.validationErrors(); + const validationErrors = req.validationErrors(); if (validationErrors) { throw validationErrors; } - let oldPassword = req.body.password; - let isValidPassword = await passwordUtils.compare(user, oldPassword); + const oldPassword = req.body.password; + const isValidPassword = await passwordUtils.compare(user, oldPassword); if (!isValidPassword) throw new NotAuthorized(res.t('wrongPassword')); - let newPassword = req.body.newPassword; + const { newPassword } = req.body; if (newPassword !== req.body.confirmPassword) throw new NotAuthorized(res.t('passwordConfirmationMatch')); // set new password and make sure it's using bcrypt for hashing @@ -276,7 +276,7 @@ api.updatePassword = { * @apiParam (Body) {String} email The email address of the user * * @apiSuccess {String} message The localized success message - **/ + * */ api.resetPassword = { method: 'POST', middlewares: [], @@ -284,14 +284,14 @@ api.resetPassword = { async handler (req, res) { req.checkBody({ email: { - notEmpty: {errorMessage: res.t('missingEmail')}, + notEmpty: { errorMessage: res.t('missingEmail') }, }, }); - let validationErrors = req.validationErrors(); + const validationErrors = req.validationErrors(); if (validationErrors) throw validationErrors; - let email = req.body.email.toLowerCase(); - let user = await User.findOne({ 'auth.local.email': email }).exec(); + const email = req.body.email.toLowerCase(); + const user = await User.findOne({ 'auth.local.email': email }).exec(); if (user) { // create an encrypted link to be used to reset the password @@ -299,12 +299,12 @@ api.resetPassword = { userId: user._id, expiresAt: moment().add({ hours: 24 }), })); - let link = `${BASE_URL}/static/user/auth/local/reset-password-set-new-one?code=${passwordResetCode}`; + const link = `${BASE_URL}/static/user/auth/local/reset-password-set-new-one?code=${passwordResetCode}`; user.auth.local.passwordResetCode = passwordResetCode; sendTxnEmail(user, 'reset-password', [ - {name: 'PASSWORD_RESET_LINK', content: link}, + { name: 'PASSWORD_RESET_LINK', content: link }, ]); await user.save(); @@ -330,23 +330,23 @@ api.updateEmail = { middlewares: [authWithHeaders()], url: '/user/auth/update-email', async handler (req, res) { - let user = res.locals.user; + const { user } = res.locals; if (!user.auth.local.email) throw new BadRequest(res.t('userHasNoLocalRegistration')); req.checkBody('newEmail', res.t('newEmailRequired')).notEmpty().isEmail(); req.checkBody('password', res.t('missingPassword')).notEmpty(); - let validationErrors = req.validationErrors(); + const validationErrors = req.validationErrors(); if (validationErrors) throw validationErrors; - let emailAlreadyInUse = await User.findOne({ + const emailAlreadyInUse = await User.findOne({ 'auth.local.email': req.body.newEmail.toLowerCase(), - }).select({_id: 1}).lean().exec(); + }).select({ _id: 1 }).lean().exec(); if (emailAlreadyInUse) throw new NotAuthorized(res.t('cannotFulfillReq', { techAssistanceEmail: TECH_ASSISTANCE_EMAIL })); - let password = req.body.password; - let isValidPassword = await passwordUtils.compare(user, password); + const { password } = req.body; + const isValidPassword = await passwordUtils.compare(user, password); if (!isValidPassword) throw new NotAuthorized(res.t('wrongPassword')); // if password is using old sha1 encryption, change it @@ -377,18 +377,18 @@ api.resetPasswordSetNewOne = { method: 'POST', url: '/user/auth/reset-password-set-new-one', async handler (req, res) { - let user = await validatePasswordResetCodeAndFindUser(req.body.code); - let isValidCode = Boolean(user); + const user = await validatePasswordResetCodeAndFindUser(req.body.code); + const isValidCode = Boolean(user); if (!isValidCode) throw new NotAuthorized(res.t('invalidPasswordResetCode')); req.checkBody('newPassword', res.t('missingNewPassword')).notEmpty(); req.checkBody('confirmPassword', res.t('missingNewPassword')).notEmpty(); - let validationErrors = req.validationErrors(); + const validationErrors = req.validationErrors(); if (validationErrors) throw validationErrors; - let newPassword = req.body.newPassword; - let confirmPassword = req.body.confirmPassword; + const { newPassword } = req.body; + const { confirmPassword } = req.body; if (newPassword !== confirmPassword) { throw new BadRequest(res.t('passwordConfirmationMatch')); @@ -416,17 +416,15 @@ api.deleteSocial = { url: '/user/auth/social/:network', middlewares: [authWithHeaders()], async handler (req, res) { - let user = res.locals.user; - let network = req.params.network; - let isSupportedNetwork = common.constants.SUPPORTED_SOCIAL_NETWORKS.find(supportedNetwork => { - return supportedNetwork.key === network; - }); + const { user } = res.locals; + const { network } = req.params; + const isSupportedNetwork = common.constants.SUPPORTED_SOCIAL_NETWORKS.find(supportedNetwork => supportedNetwork.key === network); if (!isSupportedNetwork) throw new BadRequest(res.t('unsupportedNetwork')); if (!hasBackupAuth(user, network)) throw new NotAuthorized(res.t('cantDetachSocial')); - let unset = { + const unset = { [`auth.${network}`]: 1, }; - await User.update({_id: user._id}, {$unset: unset}).exec(); + await User.update({ _id: user._id }, { $unset: unset }).exec(); res.respond(200, {}); }, diff --git a/website/server/controllers/api-v3/challenges.js b/website/server/controllers/api-v3/challenges.js index 655bd4585b..aa0aa316bd 100644 --- a/website/server/controllers/api-v3/challenges.js +++ b/website/server/controllers/api-v3/challenges.js @@ -1,6 +1,6 @@ -import { authWithHeaders, authWithSession } from '../../middlewares/auth'; import _ from 'lodash'; import cloneDeep from 'lodash/cloneDeep'; +import { authWithHeaders, authWithSession } from '../../middlewares/auth'; import { model as Challenge } from '../../models/challenge'; import { model as Group, @@ -29,7 +29,7 @@ import { } from '../../libs/challenges'; import apiError from '../../libs/apiError'; -let api = {}; +const api = {}; /** * @apiDefine ChallengeLeader Challenge Leader @@ -186,19 +186,19 @@ api.createChallenge = { url: '/challenges', middlewares: [authWithHeaders()], async handler (req, res) { - let user = res.locals.user; + const { user } = res.locals; req.checkBody('group', apiError('groupIdRequired')).notEmpty(); const validationErrors = req.validationErrors(); if (validationErrors) throw validationErrors; - const {savedChal, group} = await createChallenge(user, req, res); + const { savedChal, group } = await createChallenge(user, req, res); - let response = savedChal.toJSON(); + const response = savedChal.toJSON(); response.leader = { // the leader is the authenticated user _id: user._id, - profile: {name: user.profile.name}, + profile: { name: user.profile.name }, }; response.group = getChallengeGroupResponse(group); @@ -235,18 +235,20 @@ api.joinChallenge = { url: '/challenges/:challengeId/join', middlewares: [authWithHeaders()], async handler (req, res) { - let user = res.locals.user; + const { user } = res.locals; req.checkParams('challengeId', res.t('challengeIdRequired')).notEmpty().isUUID(); - let validationErrors = req.validationErrors(); + const validationErrors = req.validationErrors(); if (validationErrors) throw validationErrors; - let challenge = await Challenge.findOne({ _id: req.params.challengeId }).exec(); + const challenge = await Challenge.findOne({ _id: req.params.challengeId }).exec(); if (!challenge) throw new NotFound(res.t('challengeNotFound')); if (challenge.isMember(user)) throw new NotAuthorized(res.t('userAlreadyInChallenge')); - let group = await Group.getGroup({user, groupId: challenge.group, fields: basicGroupFields, optionalMembership: true}); + const group = await Group.getGroup({ + user, groupId: challenge.group, fields: basicGroupFields, optionalMembership: true, + }); if (!group || !challenge.canJoin(user, group)) throw new NotFound(res.t('challengeNotFound')); challenge.memberCount += 1; @@ -254,12 +256,12 @@ api.joinChallenge = { addUserJoinChallengeNotification(user); // Add all challenge's tasks to user's tasks and save the challenge - let results = await Promise.all([challenge.syncToUser(user), challenge.save()]); + const results = await Promise.all([challenge.syncToUser(user), challenge.save()]); - let response = results[1].toJSON(); + const response = results[1].toJSON(); response.group = getChallengeGroupResponse(group); - let chalLeader = await User.findById(response.leader).select(nameFields).exec(); - response.leader = chalLeader ? chalLeader.toJSON({minimize: true}) : null; + const chalLeader = await User.findById(response.leader).select(nameFields).exec(); + response.leader = chalLeader ? chalLeader.toJSON({ minimize: true }) : null; res.analytics.track('challenge join', { uuid: user._id, @@ -292,15 +294,15 @@ api.leaveChallenge = { url: '/challenges/:challengeId/leave', middlewares: [authWithHeaders()], async handler (req, res) { - let user = res.locals.user; - let keep = req.body.keep === 'remove-all' ? 'remove-all' : 'keep-all'; + const { user } = res.locals; + const keep = req.body.keep === 'remove-all' ? 'remove-all' : 'keep-all'; req.checkParams('challengeId', res.t('challengeIdRequired')).notEmpty().isUUID(); - let validationErrors = req.validationErrors(); + const validationErrors = req.validationErrors(); if (validationErrors) throw validationErrors; - let challenge = await Challenge.findOne({ _id: req.params.challengeId }).exec(); + const challenge = await Challenge.findOne({ _id: req.params.challengeId }).exec(); if (!challenge) throw new NotFound(res.t('challengeNotFound')); if (!challenge.isMember(user)) throw new NotAuthorized(res.t('challengeMemberNotFound')); @@ -342,50 +344,50 @@ api.getUserChallenges = { middlewares: [authWithHeaders()], async handler (req, res) { const CHALLENGES_PER_PAGE = 10; - const page = req.query.page; + const { page } = req.query; - const user = res.locals.user; - let orOptions = [ - {_id: {$in: user.challenges}}, // Challenges where the user is participating + const { user } = res.locals; + const orOptions = [ + { _id: { $in: user.challenges } }, // Challenges where the user is participating ]; - const owned = req.query.owned; - if (!owned) { - orOptions.push({leader: user._id}); + const { owned } = req.query; + if (!owned) { + orOptions.push({ leader: user._id }); } if (!req.query.member) { orOptions.push({ - group: {$in: user.getGroups()}, + group: { $in: user.getGroups() }, }); // Challenges in groups where I'm a member } - let query = { - $and: [{$or: orOptions}], + const query = { + $and: [{ $or: orOptions }], }; if (owned) { if (owned === 'not_owned') { - query.$and.push({leader: {$ne: user._id}}); + query.$and.push({ leader: { $ne: user._id } }); } if (owned === 'owned') { - query.$and.push({leader: user._id}); + query.$and.push({ leader: user._id }); } } if (req.query.search) { - const searchOr = {$or: []}; + const searchOr = { $or: [] }; const searchWords = _.escapeRegExp(req.query.search).split(' ').join('|'); const searchQuery = { $regex: new RegExp(`${searchWords}`, 'i') }; - searchOr.$or.push({name: searchQuery}); - searchOr.$or.push({description: searchQuery}); + searchOr.$or.push({ name: searchQuery }); + searchOr.$or.push({ description: searchQuery }); query.$and.push(searchOr); } if (req.query.categories) { - let categorySlugs = req.query.categories.split(','); - query.categories = { $elemMatch: { slug: {$in: categorySlugs} } }; + const categorySlugs = req.query.categories.split(','); + query.categories = { $elemMatch: { slug: { $in: categorySlugs } } }; } let mongoQuery = Challenge.find(query) @@ -404,20 +406,16 @@ api.getUserChallenges = { let resChals = challenges.map(challenge => challenge.toJSON()); - resChals = _.orderBy(resChals, [challenge => { - return challenge.categories.map(category => category.slug).includes('habitica_official'); - }], ['desc']); + resChals = _.orderBy(resChals, [challenge => challenge.categories.map(category => category.slug).includes('habitica_official')], ['desc']); // Instead of populate we make a find call manually because of https://github.com/Automattic/mongoose/issues/3833 - await Promise.all(resChals.map((chal, index) => { - return Promise.all([ - User.findById(chal.leader).select(`${nameFields} backer contributor`).exec(), - Group.findById(chal.group).select(basicGroupFields).exec(), - ]).then(populatedData => { - resChals[index].leader = populatedData[0] ? populatedData[0].toJSON({minimize: true}) : null; - resChals[index].group = populatedData[1] ? populatedData[1].toJSON({minimize: true}) : null; - }); - })); + await Promise.all(resChals.map((chal, index) => Promise.all([ + User.findById(chal.leader).select(`${nameFields} backer contributor`).exec(), + Group.findById(chal.group).select(basicGroupFields).exec(), + ]).then(populatedData => { + resChals[index].leader = populatedData[0] ? populatedData[0].toJSON({ minimize: true }) : null; + resChals[index].group = populatedData[1] ? populatedData[1].toJSON({ minimize: true }) : null; + }))); res.respond(200, resChals); }, @@ -446,12 +444,12 @@ api.getGroupChallenges = { userFieldsToInclude: ['party', 'guilds'], // Some fields are always loaded (see middlewares/auth) })], async handler (req, res) { - let user = res.locals.user; - let groupId = req.params.groupId; + const { user } = res.locals; + let { groupId } = req.params; req.checkParams('groupId', apiError('groupIdRequired')).notEmpty(); - let validationErrors = req.validationErrors(); + const validationErrors = req.validationErrors(); if (validationErrors) throw validationErrors; if (groupId === 'party') groupId = user.party._id; @@ -467,20 +465,16 @@ api.getGroupChallenges = { let resChals = challenges.map(challenge => challenge.toJSON()); - resChals = _.orderBy(resChals, [challenge => { - return challenge.categories.map(category => category.slug).includes('habitica_official'); - }], ['desc']); + resChals = _.orderBy(resChals, [challenge => challenge.categories.map(category => category.slug).includes('habitica_official')], ['desc']); // Instead of populate we make a find call manually because of https://github.com/Automattic/mongoose/issues/3833 - await Promise.all(resChals.map((chal, index) => { - return User - .findById(chal.leader) - .select(nameFields) - .exec() - .then(populatedLeader => { - resChals[index].leader = populatedLeader ? populatedLeader.toJSON({minimize: true}) : null; - }); - })); + await Promise.all(resChals.map((chal, index) => User + .findById(chal.leader) + .select(nameFields) + .exec() + .then(populatedLeader => { + resChals[index].leader = populatedLeader ? populatedLeader.toJSON({ minimize: true }) : null; + }))); res.respond(200, resChals); }, @@ -506,27 +500,29 @@ api.getChallenge = { async handler (req, res) { req.checkParams('challengeId', res.t('challengeIdRequired')).notEmpty().isUUID(); - let validationErrors = req.validationErrors(); + const validationErrors = req.validationErrors(); if (validationErrors) throw validationErrors; - let user = res.locals.user; - let challengeId = req.params.challengeId; + const { user } = res.locals; + const { challengeId } = req.params; // Don't populate the group as we'll fetch it manually later // .populate('leader', nameFields) - let challenge = await Challenge.findById(challengeId).exec(); + const challenge = await Challenge.findById(challengeId).exec(); if (!challenge) throw new NotFound(res.t('challengeNotFound')); // Fetching basic group data - let group = await Group.getGroup({user, groupId: challenge.group, fields: basicGroupFields, optionalMembership: true}); + const group = await Group.getGroup({ + user, groupId: challenge.group, fields: basicGroupFields, optionalMembership: true, + }); if (!group || !challenge.canView(user, group)) throw new NotFound(res.t('challengeNotFound')); - let chalRes = challenge.toJSON(); - chalRes.group = group.toJSON({minimize: true}); + const chalRes = challenge.toJSON(); + chalRes.group = group.toJSON({ minimize: true }); // Instead of populate we make a find call manually because of https://github.com/Automattic/mongoose/issues/3833 - let chalLeader = await User.findById(chalRes.leader).select(nameFields).exec(); - chalRes.leader = chalLeader ? chalLeader.toJSON({minimize: true}) : null; + const chalLeader = await User.findById(chalRes.leader).select(nameFields).exec(); + chalRes.leader = chalLeader ? chalLeader.toJSON({ minimize: true }) : null; res.respond(200, chalRes); }, @@ -550,33 +546,36 @@ api.exportChallengeCsv = { async handler (req, res) { req.checkParams('challengeId', res.t('challengeIdRequired')).notEmpty().isUUID(); - let validationErrors = req.validationErrors(); + const validationErrors = req.validationErrors(); if (validationErrors) throw validationErrors; - let user = res.locals.user; - let challengeId = req.params.challengeId; + const { user } = res.locals; + const { challengeId } = req.params; - let challenge = await Challenge.findById(challengeId).select('_id group leader tasksOrder').exec(); + const challenge = await Challenge.findById(challengeId).select('_id group leader tasksOrder').exec(); if (!challenge) throw new NotFound(res.t('challengeNotFound')); - let group = await Group.getGroup({user, groupId: challenge.group, fields: '_id type privacy', optionalMembership: true}); + const group = await Group.getGroup({ + user, groupId: challenge.group, fields: '_id type privacy', optionalMembership: true, + }); if (!group || !challenge.canView(user, group)) throw new NotFound(res.t('challengeNotFound')); // In v2 this used the aggregation framework to run some computation on MongoDB but then iterated through all // results on the server so the perf difference isn't that big (hopefully) - let [members, tasks] = await Promise.all([ - User.find({challenges: challengeId}) + const [members, tasks] = await Promise.all([ + User.find({ challenges: challengeId }) .select(nameFields) - .sort({_id: 1}) + .sort({ _id: 1 }) .lean() // so we don't involve mongoose .exec(), Tasks.Task.find({ 'challenge.id': challengeId, - userId: {$exists: true}, - }).sort({userId: 1, text: 1}) + userId: { $exists: true }, + }).sort({ userId: 1, text: 1 }) .select('userId type text value notes streak') - .lean().exec(), + .lean() + .exec(), ]); let resArray = members.map(member => [member._id, member.profile.name, member.auth.local.username]); @@ -605,15 +604,13 @@ api.exportChallengeCsv = { }); // The first row is going to be UUID name Task Value Notes repeated n times for the n challenge tasks - let challengeTasks = _.reduce(challenge.tasksOrder.toObject(), (result, array) => { - return result.concat(array); - }, []).sort(); + const challengeTasks = _.reduce(challenge.tasksOrder.toObject(), (result, array) => result.concat(array), []).sort(); resArray.unshift(['UUID', 'Display Name', 'Username']); _.times(challengeTasks.length, () => resArray[0].push('Task', 'Value', 'Notes', 'Streak')); // Remove lines for users without tasks info - resArray = resArray.filter((line) => { + resArray = resArray.filter(line => { if (line.length === 2) { // only user data ([id, profile name]), no task data return false; } @@ -626,7 +623,7 @@ api.exportChallengeCsv = { 'Content-disposition': `attachment; filename=${challengeId}.csv`, }); - let csvRes = await csvStringify(resArray); + const csvRes = await csvStringify(resArray); res.status(200).send(csvRes); }, }; @@ -660,26 +657,28 @@ api.updateChallenge = { async handler (req, res) { req.checkParams('challengeId', res.t('challengeIdRequired')).notEmpty().isUUID(); - let validationErrors = req.validationErrors(); + const validationErrors = req.validationErrors(); if (validationErrors) throw validationErrors; - let user = res.locals.user; - let challengeId = req.params.challengeId; + const { user } = res.locals; + const { challengeId } = req.params; - let challenge = await Challenge.findById(challengeId).exec(); + const challenge = await Challenge.findById(challengeId).exec(); if (!challenge) throw new NotFound(res.t('challengeNotFound')); - let group = await Group.getGroup({user, groupId: challenge.group, fields: basicGroupFields, optionalMembership: true}); + const group = await Group.getGroup({ + user, groupId: challenge.group, fields: basicGroupFields, optionalMembership: true, + }); if (!group || !challenge.canView(user, group)) throw new NotFound(res.t('challengeNotFound')); if (!challenge.canModify(user)) throw new NotAuthorized(res.t('onlyLeaderUpdateChal')); _.merge(challenge, Challenge.sanitizeUpdate(req.body)); - let savedChal = await challenge.save(); - let response = savedChal.toJSON(); + const savedChal = await challenge.save(); + const response = savedChal.toJSON(); response.group = getChallengeGroupResponse(group); - let chalLeader = await User.findById(response.leader).select(nameFields).exec(); - response.leader = chalLeader ? chalLeader.toJSON({minimize: true}) : null; + const chalLeader = await User.findById(response.leader).select(nameFields).exec(); + response.leader = chalLeader ? chalLeader.toJSON({ minimize: true }) : null; res.respond(200, response); }, }; @@ -700,19 +699,19 @@ api.deleteChallenge = { url: '/challenges/:challengeId', middlewares: [authWithHeaders()], async handler (req, res) { - let user = res.locals.user; + const { user } = res.locals; req.checkParams('challengeId', res.t('challengeIdRequired')).notEmpty().isUUID(); - let validationErrors = req.validationErrors(); + const validationErrors = req.validationErrors(); if (validationErrors) throw validationErrors; - let challenge = await Challenge.findOne({_id: req.params.challengeId}).exec(); + const challenge = await Challenge.findOne({ _id: req.params.challengeId }).exec(); if (!challenge) throw new NotFound(res.t('challengeNotFound')); if (!challenge.canModify(user)) throw new NotAuthorized(res.t('onlyLeaderDeleteChal')); // Close channel in background, some ops are run in the background without `await`ing - await challenge.closeChal({broken: 'CHALLENGE_DELETED'}); + await challenge.closeChal({ broken: 'CHALLENGE_DELETED' }); res.analytics.track('challenge delete', { uuid: user._id, @@ -745,23 +744,23 @@ api.selectChallengeWinner = { url: '/challenges/:challengeId/selectWinner/:winnerId', middlewares: [authWithHeaders()], async handler (req, res) { - let user = res.locals.user; + const { user } = res.locals; req.checkParams('challengeId', res.t('challengeIdRequired')).notEmpty().isUUID(); req.checkParams('winnerId', res.t('winnerIdRequired')).notEmpty().isUUID(); - let validationErrors = req.validationErrors(); + const validationErrors = req.validationErrors(); if (validationErrors) throw validationErrors; - let challenge = await Challenge.findOne({_id: req.params.challengeId}).exec(); + const challenge = await Challenge.findOne({ _id: req.params.challengeId }).exec(); if (!challenge) throw new NotFound(res.t('challengeNotFound')); if (!challenge.canModify(user)) throw new NotAuthorized(res.t('onlyLeaderDeleteChal')); - let winner = await User.findOne({_id: req.params.winnerId}).exec(); - if (!winner || winner.challenges.indexOf(challenge._id) === -1) throw new NotFound(res.t('winnerNotFound', {userId: req.params.winnerId})); + const winner = await User.findOne({ _id: req.params.winnerId }).exec(); + if (!winner || winner.challenges.indexOf(challenge._id) === -1) throw new NotFound(res.t('winnerNotFound', { userId: req.params.winnerId })); // Close channel in background, some ops are run in the background without `await`ing - await challenge.closeChal({broken: 'CHALLENGE_CLOSED', winner}); + await challenge.closeChal({ broken: 'CHALLENGE_CLOSED', winner }); res.analytics.track('challenge close', { uuid: user._id, @@ -794,26 +793,26 @@ api.cloneChallenge = { url: '/challenges/:challengeId/clone', middlewares: [authWithHeaders()], async handler (req, res) { - let user = res.locals.user; + const { user } = res.locals; req.checkParams('challengeId', res.t('challengeIdRequired')).notEmpty().isUUID(); - let validationErrors = req.validationErrors(); + const validationErrors = req.validationErrors(); if (validationErrors) throw validationErrors; - const challengeToClone = await Challenge.findOne({_id: req.params.challengeId}).exec(); + const challengeToClone = await Challenge.findOne({ _id: req.params.challengeId }).exec(); if (!challengeToClone) throw new NotFound(res.t('challengeNotFound')); - const {savedChal} = await createChallenge(user, req, res); + const { savedChal } = await createChallenge(user, req, res); const challengeTasks = await Tasks.Task.find({ 'challenge.id': challengeToClone._id, - userId: {$exists: false}, + userId: { $exists: false }, }).exec(); const tasksToClone = challengeTasks.map(task => { - let clonedTask = cloneDeep(task.toObject()); - let omittedTask = cleanUpTask(clonedTask); + const clonedTask = cloneDeep(task.toObject()); + const omittedTask = cleanUpTask(clonedTask); return omittedTask; }); @@ -821,9 +820,9 @@ api.cloneChallenge = { body: tasksToClone, }; - const clonedTasks = await createTasks(taskRequest, res, {user, challenge: savedChal}); + const clonedTasks = await createTasks(taskRequest, res, { user, challenge: savedChal }); - res.respond(200, {clonedTasks, clonedChallenge: savedChal}); + res.respond(200, { clonedTasks, clonedChallenge: savedChal }); }, }; diff --git a/website/server/controllers/api-v3/chat.js b/website/server/controllers/api-v3/chat.js index 1d4a9d7b7d..67ca3eca60 100644 --- a/website/server/controllers/api-v3/chat.js +++ b/website/server/controllers/api-v3/chat.js @@ -1,3 +1,4 @@ +import nconf from 'nconf'; import { authWithHeaders } from '../../middlewares/auth'; import { model as Group } from '../../models/group'; import { model as User } from '../../models/user'; @@ -12,17 +13,14 @@ import { removeFromArray } from '../../libs/collectionManipulators'; import { getUserInfo, getGroupUrl, sendTxn } from '../../libs/email'; import * as slack from '../../libs/slack'; import { chatReporterFactory } from '../../libs/chatReporting/chatReporterFactory'; -import { getAuthorEmailFromMessage} from '../../libs/chat'; -import nconf from 'nconf'; +import { getAuthorEmailFromMessage } from '../../libs/chat'; import bannedWords from '../../libs/bannedWords'; import guildsAllowingBannedWords from '../../libs/guildsAllowingBannedWords'; import { getMatchesByWordArray } from '../../libs/stringUtils'; import bannedSlurs from '../../libs/bannedSlurs'; import apiError from '../../libs/apiError'; -const FLAG_REPORT_EMAILS = nconf.get('FLAG_REPORT_EMAIL').split(',').map((email) => { - return { email, canSend: true }; -}); +const FLAG_REPORT_EMAILS = nconf.get('FLAG_REPORT_EMAIL').split(',').map(email => ({ email, canSend: true })); /** * @apiDefine MessageNotFound @@ -44,10 +42,10 @@ const FLAG_REPORT_EMAILS = nconf.get('FLAG_REPORT_EMAIL').split(',').map((email) * @apiError (400) {badRequest} messageIdRequired A message ID is required */ -let api = {}; +const api = {}; function textContainsBannedSlur (message) { - let bannedSlursMatched = getMatchesByWordArray(message, bannedSlurs); + const bannedSlursMatched = getMatchesByWordArray(message, bannedSlurs); return bannedSlursMatched.length > 0; } @@ -69,15 +67,15 @@ api.getChat = { url: '/groups/:groupId/chat', middlewares: [authWithHeaders()], async handler (req, res) { - let user = res.locals.user; + const { user } = res.locals; req.checkParams('groupId', apiError('groupIdRequired')).notEmpty(); - let validationErrors = req.validationErrors(); + const validationErrors = req.validationErrors(); if (validationErrors) throw validationErrors; - const groupId = req.params.groupId; - let group = await Group.getGroup({user, groupId, fields: 'chat'}); + const { groupId } = req.params; + const group = await Group.getGroup({ user, groupId, fields: 'chat' }); if (!group) throw new NotFound(res.t('groupNotFound')); const groupChat = await Group.toJSONCleanChat(group, user); @@ -110,42 +108,42 @@ api.postChat = { url: '/groups/:groupId/chat', middlewares: [authWithHeaders()], async handler (req, res) { - let user = res.locals.user; - let groupId = req.params.groupId; + const { user } = res.locals; + const { groupId } = req.params; let chatUpdated; req.checkParams('groupId', apiError('groupIdRequired')).notEmpty(); req.sanitize('message').trim(); req.checkBody('message', res.t('messageGroupChatBlankMessage')).notEmpty(); - let validationErrors = req.validationErrors(); + const validationErrors = req.validationErrors(); if (validationErrors) throw validationErrors; - let group = await Group.getGroup({user, groupId}); + const group = await Group.getGroup({ user, groupId }); // Check message for banned slurs if (textContainsBannedSlur(req.body.message)) { - let message = req.body.message; + const { message } = req.body; user.flags.chatRevoked = true; await user.save(); // Email the mods - let authorEmail = getUserInfo(user, ['email']).email; - let groupUrl = getGroupUrl(group); + const authorEmail = getUserInfo(user, ['email']).email; + const groupUrl = getGroupUrl(group); - let report = [ - {name: 'MESSAGE_TIME', content: (new Date()).toString()}, - {name: 'MESSAGE_TEXT', content: message}, + const report = [ + { name: 'MESSAGE_TIME', content: (new Date()).toString() }, + { name: 'MESSAGE_TEXT', content: message }, - {name: 'AUTHOR_USERNAME', content: user.profile.name}, - {name: 'AUTHOR_UUID', content: user._id}, - {name: 'AUTHOR_EMAIL', content: authorEmail}, - {name: 'AUTHOR_MODAL_URL', content: `/profile/${user._id}`}, + { name: 'AUTHOR_USERNAME', content: user.profile.name }, + { name: 'AUTHOR_UUID', content: user._id }, + { name: 'AUTHOR_EMAIL', content: authorEmail }, + { name: 'AUTHOR_MODAL_URL', content: `/profile/${user._id}` }, - {name: 'GROUP_NAME', content: group.name}, - {name: 'GROUP_TYPE', content: group.type}, - {name: 'GROUP_ID', content: group._id}, - {name: 'GROUP_URL', content: groupUrl}, + { name: 'GROUP_NAME', content: group.name }, + { name: 'GROUP_TYPE', content: group.type }, + { name: 'GROUP_ID', content: group._id }, + { name: 'GROUP_URL', content: groupUrl }, ]; sendTxn(FLAG_REPORT_EMAILS, 'slur-report-to-mods', report); @@ -169,15 +167,15 @@ api.postChat = { // prevent banned words being posted, except in private guilds/parties and in certain public guilds with specific topics if (group.privacy === 'public' && !guildsAllowingBannedWords[group._id]) { - let matchedBadWords = getBannedWordsFromText(req.body.message); + const matchedBadWords = getBannedWordsFromText(req.body.message); if (matchedBadWords.length > 0) { - throw new BadRequest(res.t('bannedWordUsed', {swearWordsUsed: matchedBadWords.join(', ')})); + throw new BadRequest(res.t('bannedWordUsed', { swearWordsUsed: matchedBadWords.join(', ') })); } } const chatRes = await Group.toJSONCleanChat(group, user); const lastClientMsg = req.query.previousMsg; - chatUpdated = lastClientMsg && group.chat && group.chat[0] && group.chat[0].id !== lastClientMsg ? true : false; + chatUpdated = !!(lastClientMsg && group.chat && group.chat[0] && group.chat[0].id !== lastClientMsg); if (group.checkChatSpam(user)) { throw new NotAuthorized(res.t('messageGroupChatSpam')); @@ -191,25 +189,25 @@ api.postChat = { let flagCount = 0; if (group.privacy === 'public' && user.flags.chatShadowMuted) { flagCount = common.constants.CHAT_FLAG_FROM_SHADOW_MUTE; - let message = req.body.message; + const { message } = req.body; // Email the mods - let authorEmail = getUserInfo(user, ['email']).email; - let groupUrl = getGroupUrl(group); + const authorEmail = getUserInfo(user, ['email']).email; + const groupUrl = getGroupUrl(group); - let report = [ - {name: 'MESSAGE_TIME', content: (new Date()).toString()}, - {name: 'MESSAGE_TEXT', content: message}, + const report = [ + { name: 'MESSAGE_TIME', content: (new Date()).toString() }, + { name: 'MESSAGE_TEXT', content: message }, - {name: 'AUTHOR_USERNAME', content: user.profile.name}, - {name: 'AUTHOR_UUID', content: user._id}, - {name: 'AUTHOR_EMAIL', content: authorEmail}, - {name: 'AUTHOR_MODAL_URL', content: `/profile/${user._id}`}, + { name: 'AUTHOR_USERNAME', content: user.profile.name }, + { name: 'AUTHOR_UUID', content: user._id }, + { name: 'AUTHOR_EMAIL', content: authorEmail }, + { name: 'AUTHOR_MODAL_URL', content: `/profile/${user._id}` }, - {name: 'GROUP_NAME', content: group.name}, - {name: 'GROUP_TYPE', content: group.type}, - {name: 'GROUP_ID', content: group._id}, - {name: 'GROUP_URL', content: groupUrl}, + { name: 'GROUP_NAME', content: group.name }, + { name: 'GROUP_TYPE', content: group.type }, + { name: 'GROUP_ID', content: group._id }, + { name: 'GROUP_URL', content: groupUrl }, ]; sendTxn(FLAG_REPORT_EMAILS, 'shadow-muted-post-report-to-mods', report); @@ -223,8 +221,10 @@ api.postChat = { }); } - const newChatMessage = group.sendChat({message: req.body.message, user, flagCount, metaData: null, client, translate: res.t}); - let toSave = [newChatMessage.save()]; + const newChatMessage = group.sendChat({ + message: req.body.message, user, flagCount, metaData: null, client, translate: res.t, + }); + const toSave = [newChatMessage.save()]; if (group.type === 'party') { user.party.lastMessageSeen = newChatMessage.id; @@ -233,7 +233,7 @@ api.postChat = { await Promise.all(toSave); - let analyticsObject = { + const analyticsObject = { uuid: user._id, hitType: 'event', category: 'behavior', @@ -255,9 +255,9 @@ api.postChat = { res.analytics.track('group chat', analyticsObject); if (chatUpdated) { - res.respond(200, {chat: chatRes.chat}); + res.respond(200, { chat: chatRes.chat }); } else { - res.respond(200, {message: newChatMessage}); + res.respond(200, { message: newChatMessage }); } }, }; @@ -284,19 +284,19 @@ api.likeChat = { url: '/groups/:groupId/chat/:chatId/like', middlewares: [authWithHeaders()], async handler (req, res) { - let user = res.locals.user; - let groupId = req.params.groupId; + const { user } = res.locals; + const { groupId } = req.params; req.checkParams('groupId', apiError('groupIdRequired')).notEmpty(); req.checkParams('chatId', apiError('chatIdRequired')).notEmpty(); - let validationErrors = req.validationErrors(); + const validationErrors = req.validationErrors(); if (validationErrors) throw validationErrors; - let group = await Group.getGroup({user, groupId}); + const group = await Group.getGroup({ user, groupId }); if (!group) throw new NotFound(res.t('groupNotFound')); - let message = await Chat.findOne({_id: req.params.chatId}).exec(); + const message = await Chat.findOne({ _id: req.params.chatId }).exec(); if (!message) throw new NotFound(res.t('messageGroupChatNotFound')); // @TODO correct this error type if (message.uuid === user._id) throw new NotFound(res.t('messageGroupChatLikeOwnMessage')); @@ -371,55 +371,55 @@ api.clearChatFlags = { url: '/groups/:groupId/chat/:chatId/clearflags', middlewares: [authWithHeaders()], async handler (req, res) { - let user = res.locals.user; - let groupId = req.params.groupId; - let chatId = req.params.chatId; + const { user } = res.locals; + const { groupId } = req.params; + const { chatId } = req.params; req.checkParams('groupId', apiError('groupIdRequired')).notEmpty(); req.checkParams('chatId', apiError('chatIdRequired')).notEmpty(); - let validationErrors = req.validationErrors(); + const validationErrors = req.validationErrors(); if (validationErrors) throw validationErrors; if (!user.contributor.admin) { throw new NotAuthorized(res.t('messageGroupChatAdminClearFlagCount')); } - let group = await Group.getGroup({ + const group = await Group.getGroup({ user, groupId, optionalMembership: user.contributor.admin, }); if (!group) throw new NotFound(res.t('groupNotFound')); - let message = await Chat.findOne({_id: chatId}).exec(); + const message = await Chat.findOne({ _id: chatId }).exec(); if (!message) throw new NotFound(res.t('messageGroupChatNotFound')); message.flagCount = 0; await message.save(); - let adminEmailContent = getUserInfo(user, ['email']).email; - let authorEmail = getAuthorEmailFromMessage(message); - let groupUrl = getGroupUrl(group); + const adminEmailContent = getUserInfo(user, ['email']).email; + const authorEmail = getAuthorEmailFromMessage(message); + const groupUrl = getGroupUrl(group); sendTxn(FLAG_REPORT_EMAILS, 'unflag-report-to-mods', [ - {name: 'MESSAGE_TIME', content: (new Date(message.timestamp)).toString()}, - {name: 'MESSAGE_TEXT', content: message.text}, + { name: 'MESSAGE_TIME', content: (new Date(message.timestamp)).toString() }, + { name: 'MESSAGE_TEXT', content: message.text }, - {name: 'ADMIN_USERNAME', content: user.profile.name}, - {name: 'ADMIN_UUID', content: user._id}, - {name: 'ADMIN_EMAIL', content: adminEmailContent}, - {name: 'ADMIN_MODAL_URL', content: `/profile/${user._id}`}, + { name: 'ADMIN_USERNAME', content: user.profile.name }, + { name: 'ADMIN_UUID', content: user._id }, + { name: 'ADMIN_EMAIL', content: adminEmailContent }, + { name: 'ADMIN_MODAL_URL', content: `/profile/${user._id}` }, - {name: 'AUTHOR_USERNAME', content: message.user}, - {name: 'AUTHOR_UUID', content: message.uuid}, - {name: 'AUTHOR_EMAIL', content: authorEmail}, - {name: 'AUTHOR_MODAL_URL', content: `/profile/${message.uuid}`}, + { name: 'AUTHOR_USERNAME', content: message.user }, + { name: 'AUTHOR_UUID', content: message.uuid }, + { name: 'AUTHOR_EMAIL', content: authorEmail }, + { name: 'AUTHOR_MODAL_URL', content: `/profile/${message.uuid}` }, - {name: 'GROUP_NAME', content: group.name}, - {name: 'GROUP_TYPE', content: group.type}, - {name: 'GROUP_ID', content: group._id}, - {name: 'GROUP_URL', content: groupUrl}, + { name: 'GROUP_NAME', content: group.name }, + { name: 'GROUP_TYPE', content: group.type }, + { name: 'GROUP_ID', content: group._id }, + { name: 'GROUP_URL', content: groupUrl }, ]); res.respond(200, {}); @@ -441,19 +441,19 @@ api.seenChat = { url: '/groups/:groupId/chat/seen', middlewares: [authWithHeaders()], async handler (req, res) { - let user = res.locals.user; - let groupId = req.params.groupId; + const { user } = res.locals; + const { groupId } = req.params; req.checkParams('groupId', apiError('groupIdRequired')).notEmpty(); - let validationErrors = req.validationErrors(); + const validationErrors = req.validationErrors(); if (validationErrors) throw validationErrors; // Do not validate group existence, it doesn't really matter and make it works if the group gets deleted // let group = await Group.getGroup({user, groupId}); // if (!group) throw new NotFound(res.t('groupNotFound')); - let update = { + const update = { $unset: {}, $pull: {}, }; @@ -478,7 +478,7 @@ api.seenChat = { // See https://github.com/HabitRPG/habitica/pull/9321#issuecomment-354187666 for more info user._v++; - await User.update({_id: user._id}, update).exec(); + await User.update({ _id: user._id }, update).exec(); res.respond(200, {}); }, }; @@ -507,20 +507,20 @@ api.deleteChat = { url: '/groups/:groupId/chat/:chatId', middlewares: [authWithHeaders()], async handler (req, res) { - let user = res.locals.user; - let groupId = req.params.groupId; - let chatId = req.params.chatId; + const { user } = res.locals; + const { groupId } = req.params; + const { chatId } = req.params; req.checkParams('groupId', apiError('groupIdRequired')).notEmpty(); req.checkParams('chatId', apiError('chatIdRequired')).notEmpty(); - let validationErrors = req.validationErrors(); + const validationErrors = req.validationErrors(); if (validationErrors) throw validationErrors; - let group = await Group.getGroup({user, groupId, fields: 'chat'}); + const group = await Group.getGroup({ user, groupId, fields: 'chat' }); if (!group) throw new NotFound(res.t('groupNotFound')); - let message = await Chat.findOne({_id: chatId}).exec(); + const message = await Chat.findOne({ _id: chatId }).exec(); if (!message) throw new NotFound(res.t('messageGroupChatNotFound')); if (user._id !== message.uuid && !user.contributor.admin) { @@ -529,12 +529,12 @@ api.deleteChat = { const chatRes = await Group.toJSONCleanChat(group, user); const lastClientMsg = req.query.previousMsg; - const chatUpdated = lastClientMsg && group.chat && group.chat[0] && group.chat[0].id !== lastClientMsg ? true : false; + const chatUpdated = !!(lastClientMsg && group.chat && group.chat[0] && group.chat[0].id !== lastClientMsg); - await Chat.remove({_id: message._id}).exec(); + await Chat.remove({ _id: message._id }).exec(); if (chatUpdated) { - removeFromArray(chatRes.chat, {id: chatId}); + removeFromArray(chatRes.chat, { id: chatId }); res.respond(200, chatRes.chat); } else { res.respond(200, {}); diff --git a/website/server/controllers/api-v3/content.js b/website/server/controllers/api-v3/content.js index f175872033..75bef8096b 100644 --- a/website/server/controllers/api-v3/content.js +++ b/website/server/controllers/api-v3/content.js @@ -1,10 +1,10 @@ -import common from '../../../common'; import _ from 'lodash'; -import { langCodes } from '../../libs/i18n'; import fsCallback from 'fs'; import path from 'path'; -import logger from '../../libs/logger'; import util from 'util'; +import logger from '../../libs/logger'; +import { langCodes } from '../../libs/i18n'; +import common from '../../../common'; // Transform fs methods that accept callbacks in ones that return promises const fs = { @@ -14,7 +14,7 @@ const fs = { mkdir: util.promisify(fsCallback.mkdir).bind(fsCallback), }; -let api = {}; +const api = {}; function walkContent (obj, lang) { _.each(obj, (item, key, source) => { @@ -26,10 +26,10 @@ function walkContent (obj, lang) { // After the getContent route is called the first time for a certain language // the response is saved on disk and subsequentially served directly from there to reduce computation. // Example: if `cachedContentResponses.en` is true it means that the response is cached -let cachedContentResponses = {}; +const cachedContentResponses = {}; // Language key set to true while the cache file is being written -let cacheBeingWritten = {}; +const cacheBeingWritten = {}; _.each(langCodes, code => { cachedContentResponses[code] = false; @@ -52,11 +52,9 @@ async function saveContentToDisk (language, content) { if (err.code === 'ENOENT' && err.syscall === 'stat') { // the directory doesn't exists, create it and retry await fs.mkdir(CONTENT_CACHE_PATH); return saveContentToDisk(language, content); - } else { - cacheBeingWritten[language] = false; - logger.error(err); - return; } + cacheBeingWritten[language] = false; + logger.error(err); } } @@ -104,7 +102,7 @@ api.getContent = { noLanguage: true, async handler (req, res) { let language = 'en'; - let proposedLang = req.query.language && req.query.language.toString(); + const proposedLang = req.query.language && req.query.language.toString(); if (proposedLang in cachedContentResponses) { language = proposedLang; @@ -125,7 +123,7 @@ api.getContent = { 'Content-Type': 'application/json', }); - let jsonResString = `{"success": true, "data": ${content}}`; + const jsonResString = `{"success": true, "data": ${content}}`; res.status(200).send(jsonResString); // save the file in background unless it's already cached or being written right now diff --git a/website/server/controllers/api-v3/coupon.js b/website/server/controllers/api-v3/coupon.js index 38109f51be..efbc7345fa 100644 --- a/website/server/controllers/api-v3/coupon.js +++ b/website/server/controllers/api-v3/coupon.js @@ -1,16 +1,16 @@ +import _ from 'lodash'; +import couponCode from 'coupon-code'; import csvStringify from '../../libs/csvStringify'; import { authWithHeaders, authWithSession, } from '../../middlewares/auth'; import { ensureSudo } from '../../middlewares/ensureAccessRight'; -import _ from 'lodash'; import * as couponsLib from '../../libs/coupons'; -import couponCode from 'coupon-code'; import apiError from '../../libs/apiError'; import { model as Coupon } from '../../models/coupon'; -let api = {}; +const api = {}; /** * @apiDefine Sudo Sudo Users @@ -37,12 +37,10 @@ api.getCoupons = { url: '/coupons', middlewares: [authWithSession, ensureSudo], async handler (req, res) { - let coupons = await Coupon.find().sort('createdAt').lean().exec(); + const coupons = await Coupon.find().sort('createdAt').lean().exec(); - let output = [['code', 'event', 'date', 'user']].concat(_.map(coupons, coupon => { - return [coupon._id, coupon.event, coupon.createdAt, coupon.user]; - })); - let csv = await csvStringify(output); + const output = [['code', 'event', 'date', 'user']].concat(_.map(coupons, coupon => [coupon._id, coupon.event, coupon.createdAt, coupon.user])); + const csv = await csvStringify(output); res.set({ 'Content-Type': 'text/csv', @@ -74,10 +72,10 @@ api.generateCoupons = { req.checkParams('event', apiError('eventRequired')).notEmpty(); req.checkQuery('count', apiError('countRequired')).notEmpty().isNumeric(); - let validationErrors = req.validationErrors(); + const validationErrors = req.validationErrors(); if (validationErrors) throw validationErrors; - let coupons = await Coupon.generate(req.params.event, req.query.count); + const coupons = await Coupon.generate(req.params.event, req.query.count); res.respond(200, coupons); }, }; @@ -98,7 +96,7 @@ api.enterCouponCode = { url: '/coupons/enter/:code', middlewares: [authWithHeaders()], async handler (req, res) { - const user = res.locals.user; + const { user } = res.locals; await couponsLib.enterCode(req, res, user); const userToJSON = await user.toJSONWithInbox(); res.respond(200, userToJSON); @@ -123,17 +121,17 @@ api.validateCoupon = { async handler (req, res) { req.checkParams('code', res.t('couponCodeRequired')).notEmpty(); - let validationErrors = req.validationErrors(); + const validationErrors = req.validationErrors(); if (validationErrors) throw validationErrors; let valid = false; - let code = couponCode.validate(req.params.code); + const code = couponCode.validate(req.params.code); if (code) { - let coupon = await Coupon.findOne({_id: code}).exec(); - valid = coupon ? true : false; + const coupon = await Coupon.findOne({ _id: code }).exec(); + valid = !!coupon; } - res.respond(200, {valid}); + res.respond(200, { valid }); }, }; diff --git a/website/server/controllers/api-v3/cron.js b/website/server/controllers/api-v3/cron.js index ecba00df92..0016650bcf 100644 --- a/website/server/controllers/api-v3/cron.js +++ b/website/server/controllers/api-v3/cron.js @@ -1,7 +1,7 @@ import { authWithHeaders } from '../../middlewares/auth'; import cron from '../../middlewares/cron'; -let api = {}; +const api = {}; /** * @api {post} /api/v3/cron Runs cron diff --git a/website/server/controllers/api-v3/debug.js b/website/server/controllers/api-v3/debug.js index 46297f14ea..65a9487a09 100644 --- a/website/server/controllers/api-v3/debug.js +++ b/website/server/controllers/api-v3/debug.js @@ -1,10 +1,10 @@ +import _ from 'lodash'; import { authWithHeaders } from '../../middlewares/auth'; import ensureDevelpmentMode from '../../middlewares/ensureDevelpmentMode'; import { BadRequest } from '../../libs/errors'; import common from '../../../common'; -import _ from 'lodash'; -const content = common.content; +const { content } = common; /** * @apiDefine Development Development @@ -16,7 +16,7 @@ const content = common.content; * This route only exists when developing Habitica in non-production environment. */ -let api = {}; +const api = {}; /** * @api {post} /api/v3/debug/add-ten-gems Add ten gems to the current user @@ -31,7 +31,7 @@ api.addTenGems = { url: '/debug/add-ten-gems', middlewares: [ensureDevelpmentMode, authWithHeaders()], async handler (req, res) { - let user = res.locals.user; + const { user } = res.locals; user.balance += 2.5; @@ -54,7 +54,7 @@ api.addHourglass = { url: '/debug/add-hourglass', middlewares: [ensureDevelpmentMode, authWithHeaders()], async handler (req, res) { - let user = res.locals.user; + const { user } = res.locals; user.purchased.plan.consecutive.trinkets += 1; @@ -77,8 +77,8 @@ api.setCron = { url: '/debug/set-cron', middlewares: [ensureDevelpmentMode, authWithHeaders()], async handler (req, res) { - let user = res.locals.user; - let cron = req.body.lastCron; + const { user } = res.locals; + const cron = req.body.lastCron; user.lastCron = cron; @@ -101,7 +101,7 @@ api.makeAdmin = { url: '/debug/make-admin', middlewares: [ensureDevelpmentMode, authWithHeaders()], async handler (req, res) { - let user = res.locals.user; + const { user } = res.locals; user.contributor.admin = true; @@ -132,8 +132,8 @@ api.modifyInventory = { url: '/debug/modify-inventory', middlewares: [ensureDevelpmentMode, authWithHeaders()], async handler (req, res) { - let user = res.locals.user; - let { gear } = req.body; + const { user } = res.locals; + const { gear } = req.body; if (gear) { user.items.gear.owned = gear; @@ -148,7 +148,7 @@ api.modifyInventory = { 'hatchingPotions', 'food', 'quests', - ].forEach((type) => { + ].forEach(type => { if (req.body[type]) { user.items[type] = req.body[type]; user.markModified(`items.${type}`); @@ -174,9 +174,9 @@ api.questProgress = { url: '/debug/quest-progress', middlewares: [ensureDevelpmentMode, authWithHeaders()], async handler (req, res) { - let user = res.locals.user; - let key = _.get(user, 'party.quest.key'); - let quest = content.quests[key]; + const { user } = res.locals; + const key = _.get(user, 'party.quest.key'); + const quest = content.quests[key]; if (!quest) { throw new BadRequest('User is not on a valid quest.'); diff --git a/website/server/controllers/api-v3/groups.js b/website/server/controllers/api-v3/groups.js index a5b6039aef..bfd2d17eca 100644 --- a/website/server/controllers/api-v3/groups.js +++ b/website/server/controllers/api-v3/groups.js @@ -1,6 +1,6 @@ -import { authWithHeaders } from '../../middlewares/auth'; import _ from 'lodash'; import nconf from 'nconf'; +import { authWithHeaders } from '../../middlewares/auth'; import { model as Group, basicFields as basicGroupFields, @@ -61,7 +61,7 @@ const TECH_ASSISTANCE_EMAIL = nconf.get('EMAILS_TECH_ASSISTANCE_EMAIL'); * The group leader can use this route. */ -let api = {}; +const api = {}; /** * @api {post} /api/v3/groups Create group @@ -112,8 +112,8 @@ api.createGroup = { url: '/groups', middlewares: [authWithHeaders()], async handler (req, res) { - let user = res.locals.user; - let group = new Group(Group.sanitize(req.body)); + const { user } = res.locals; + const group = new Group(Group.sanitize(req.body)); group.leader = user._id; if (group.type === 'guild') { @@ -135,19 +135,19 @@ api.createGroup = { user.party._id = group._id; } - let results = await Promise.all([user.save(), group.save()]); - let savedGroup = results[1]; + const results = await Promise.all([user.save(), group.save()]); + const savedGroup = results[1]; // Instead of populate we make a find call manually because of https://github.com/Automattic/mongoose/issues/3833 // await Q.ninvoke(savedGroup, 'populate', ['leader', nameFields]); // doc.populate doesn't return a promise - let response = savedGroup.toJSON(); + const response = savedGroup.toJSON(); // the leader is the authenticated user response.leader = { _id: user._id, - profile: {name: user.profile.name}, + profile: { name: user.profile.name }, }; - let analyticsObject = { + const analyticsObject = { uuid: user._id, hitType: 'event', category: 'behavior', @@ -179,12 +179,12 @@ api.createGroupPlan = { url: '/groups/create-plan', middlewares: [authWithHeaders()], async handler (req, res) { - let user = res.locals.user; - let group = new Group(Group.sanitize(req.body.groupToCreate)); + const { user } = res.locals; + const group = new Group(Group.sanitize(req.body.groupToCreate)); req.checkBody('paymentType', res.t('paymentTypeRequired')).notEmpty(); - let validationErrors = req.validationErrors(); + const validationErrors = req.validationErrors(); if (validationErrors) throw validationErrors; // @TODO: Change message @@ -192,11 +192,11 @@ api.createGroupPlan = { group.leader = user._id; user.guilds.push(group._id); - let results = await Promise.all([user.save(), group.save()]); - let savedGroup = results[1]; + const results = await Promise.all([user.save(), group.save()]); + const savedGroup = results[1]; // Analytics - let analyticsObject = { + const analyticsObject = { uuid: user._id, hitType: 'event', category: 'behavior', @@ -208,13 +208,13 @@ api.createGroupPlan = { res.analytics.track('join group', analyticsObject); if (req.body.paymentType === 'Stripe') { - let token = req.body.id; - let gift = req.query.gift ? JSON.parse(req.query.gift) : undefined; - let sub = req.query.sub ? shared.content.subscriptionBlocks[req.query.sub] : false; - let groupId = savedGroup._id; - let email = req.body.email; - let headers = req.headers; - let coupon = req.query.coupon; + const token = req.body.id; + const gift = req.query.gift ? JSON.parse(req.query.gift) : undefined; + const sub = req.query.sub ? shared.content.subscriptionBlocks[req.query.sub] : false; + const groupId = savedGroup._id; + const { email } = req.body; + const { headers } = req; + const { coupon } = req.query; await stripePayments.checkout({ token, @@ -227,11 +227,11 @@ api.createGroupPlan = { coupon, }); } else if (req.body.paymentType === 'Amazon') { - let billingAgreementId = req.body.billingAgreementId; - let sub = req.body.subscription ? shared.content.subscriptionBlocks[req.body.subscription] : false; - let coupon = req.body.coupon; - let groupId = savedGroup._id; - let headers = req.headers; + const { billingAgreementId } = req.body; + const sub = req.body.subscription ? shared.content.subscriptionBlocks[req.body.subscription] : false; + const { coupon } = req.body; + const groupId = savedGroup._id; + const { headers } = req; await amzLib.subscribe({ billingAgreementId, @@ -245,11 +245,11 @@ api.createGroupPlan = { // Instead of populate we make a find call manually because of https://github.com/Automattic/mongoose/issues/3833 // await Q.ninvoke(savedGroup, 'populate', ['leader', nameFields]); // doc.populate doesn't return a promise - let response = savedGroup.toJSON(); + const response = savedGroup.toJSON(); // the leader is the authenticated user response.leader = { _id: user._id, - profile: {name: user.profile.name}, + profile: { name: user.profile.name }, }; res.respond(201, response); // do not remove chat flags data as we've just created the group @@ -288,30 +288,30 @@ api.getGroups = { url: '/groups', middlewares: [authWithHeaders()], async handler (req, res) { - let user = res.locals.user; + const { user } = res.locals; req.checkQuery('type', res.t('groupTypesRequired')).notEmpty(); // pagination options, can only be used with public guilds req.checkQuery('paginate').optional().isIn(['true', 'false'], apiError('guildsPaginateBooleanString')); - req.checkQuery('page').optional().isInt({min: 0}, apiError('queryPageInteger')); + req.checkQuery('page').optional().isInt({ min: 0 }, apiError('queryPageInteger')); - let validationErrors = req.validationErrors(); + const validationErrors = req.validationErrors(); if (validationErrors) throw validationErrors; - let types = req.query.type.split(','); + const types = req.query.type.split(','); - let paginate = req.query.paginate === 'true' ? true : false; + const paginate = req.query.paginate === 'true'; if (paginate && !_.includes(types, 'publicGuilds')) { throw new BadRequest(apiError('guildsOnlyPaginate')); } - let groupFields = basicGroupFields.concat(' description memberCount balance'); - let sort = '-memberCount'; + const groupFields = basicGroupFields.concat(' description memberCount balance'); + const sort = '-memberCount'; - let filters = {}; + const filters = {}; if (req.query.categories) { - let categorySlugs = req.query.categories.split(','); - filters.categories = { $elemMatch: { slug: {$in: categorySlugs} } }; + const categorySlugs = req.query.categories.split(','); + filters.categories = { $elemMatch: { slug: { $in: categorySlugs } } }; } if (req.query.minMemberCount) { @@ -337,13 +337,18 @@ api.getGroups = { filters.$or = []; const searchWords = _.escapeRegExp(req.query.search).split(' ').join('|'); const searchQuery = { $regex: new RegExp(`${searchWords}`, 'i') }; - filters.$or.push({name: searchQuery}); - filters.$or.push({description: searchQuery}); + filters.$or.push({ name: searchQuery }); + filters.$or.push({ description: searchQuery }); } - let results = await Group.getGroups({ - user, types, groupFields, sort, - paginate, page: req.query.page, filters, + const results = await Group.getGroups({ + user, + types, + groupFields, + sort, + paginate, + page: req.query.page, + filters, }); res.respond(200, results); }, @@ -379,28 +384,28 @@ api.getGroup = { userFieldsToInclude: ['party', 'guilds', 'contributor'], })], async handler (req, res) { - let user = res.locals.user; + const { user } = res.locals; req.checkParams('groupId', apiError('groupIdRequired')).notEmpty(); - let validationErrors = req.validationErrors(); + const validationErrors = req.validationErrors(); if (validationErrors) throw validationErrors; - let groupId = req.params.groupId; - let group = await Group.getGroup({user, groupId, populateLeader: false}); + const { groupId } = req.params; + const group = await Group.getGroup({ user, groupId, populateLeader: false }); if (!group) { throw new NotFound(res.t('groupNotFound')); } - let groupJson = await Group.toJSONCleanChat(group, user); + const groupJson = await Group.toJSONCleanChat(group, user); if (groupJson.leader === user._id) { groupJson.purchased.plan = group.purchased.plan.toObject(); } // Instead of populate we make a find call manually because of https://github.com/Automattic/mongoose/issues/3833 - let leader = await User.findById(groupJson.leader).select(nameFields).exec(); - if (leader) groupJson.leader = leader.toJSON({minimize: true}); + const leader = await User.findById(groupJson.leader).select(nameFields).exec(); + if (leader) groupJson.leader = leader.toJSON({ minimize: true }); res.respond(200, groupJson); }, @@ -437,14 +442,14 @@ api.updateGroup = { url: '/groups/:groupId', middlewares: [authWithHeaders()], async handler (req, res) { - let user = res.locals.user; + const { user } = res.locals; req.checkParams('groupId', apiError('groupIdRequired')).notEmpty(); - let validationErrors = req.validationErrors(); + const validationErrors = req.validationErrors(); if (validationErrors) throw validationErrors; - let optionalMembership = Boolean(user.contributor.admin); - let group = await Group.getGroup({user, groupId: req.params.groupId, optionalMembership}); + const optionalMembership = Boolean(user.contributor.admin); + const group = await Group.getGroup({ user, groupId: req.params.groupId, optionalMembership }); if (!group) throw new NotFound(res.t('groupNotFound')); @@ -455,17 +460,17 @@ api.updateGroup = { _.assign(group, _.merge(group.toObject(), Group.sanitizeUpdate(req.body))); - let savedGroup = await group.save(); - let response = await Group.toJSONCleanChat(savedGroup, user); + const savedGroup = await group.save(); + const response = await Group.toJSONCleanChat(savedGroup, user); // If the leader changed fetch new data, otherwise use authenticated user if (response.leader !== user._id) { - let rawLeader = await User.findById(response.leader).select(nameFields).exec(); - response.leader = rawLeader.toJSON({minimize: true}); + const rawLeader = await User.findById(response.leader).select(nameFields).exec(); + response.leader = rawLeader.toJSON({ minimize: true }); } else { response.leader = { _id: user._id, - profile: {name: user.profile.name}, + profile: { name: user.profile.name }, }; } res.respond(200, response); @@ -500,30 +505,30 @@ api.joinGroup = { url: '/groups/:groupId/join', middlewares: [authWithHeaders()], async handler (req, res) { - let user = res.locals.user; + const { user } = res.locals; let inviter; req.checkParams('groupId', apiError('groupIdRequired')).notEmpty(); // .isUUID(); can't be used because it would block 'habitrpg' or 'party' - let validationErrors = req.validationErrors(); + const validationErrors = req.validationErrors(); if (validationErrors) throw validationErrors; // Works even if the user is not yet a member of the group - let group = await Group.getGroup({user, groupId: req.params.groupId, optionalMembership: true}); // Do not fetch chat and work even if the user is not yet a member of the group + const group = await Group.getGroup({ user, groupId: req.params.groupId, optionalMembership: true }); // Do not fetch chat and work even if the user is not yet a member of the group if (!group) throw new NotFound(res.t('groupNotFound')); let isUserInvited = false; if (group.type === 'party') { // Check if was invited to party - let inviterParty = _.find(user.invitations.parties, {id: group._id}); + const inviterParty = _.find(user.invitations.parties, { id: group._id }); if (inviterParty) { inviter = inviterParty.inviter; // If user was in a different party (when partying solo you can be invited to a new party) // make them leave that party before doing anything if (user.party._id) { - let userPreviousParty = await Group.getGroup({user, groupId: user.party._id}); + const userPreviousParty = await Group.getGroup({ user, groupId: user.party._id }); if (userPreviousParty.memberCount === 1 && user.party.quest.key) { throw new NotAuthorized(res.t('messageCannotLeaveWhileQuesting')); @@ -549,13 +554,13 @@ api.joinGroup = { isUserInvited = true; } } else if (group.type === 'guild') { - let hasInvitation = removeFromArray(user.invitations.guilds, { id: group._id }); + const hasInvitation = removeFromArray(user.invitations.guilds, { id: group._id }); if (hasInvitation) { isUserInvited = true; inviter = hasInvitation.inviter; } else { - isUserInvited = group.privacy === 'private' ? false : true; + isUserInvited = group.privacy !== 'private'; } } @@ -581,7 +586,7 @@ api.joinGroup = { if (inviter) { inviter = await User.findById(inviter).exec(); - let data = { + const data = { headerText: common.i18n.t('invitationAcceptedHeader', inviter.preferences.language), bodyText: common.i18n.t('invitationAcceptedBody', { groupName: group.name, @@ -604,32 +609,32 @@ api.joinGroup = { if (group.type === 'party' && inviter) { if (group.memberCount > 1) { promises.push(User.update({ - $or: [{'party._id': group._id}, {_id: user._id}], - 'achievements.partyUp': {$ne: true}, - }, {$set: {'achievements.partyUp': true}}, {multi: true}).exec()); + $or: [{ 'party._id': group._id }, { _id: user._id }], + 'achievements.partyUp': { $ne: true }, + }, { $set: { 'achievements.partyUp': true } }, { multi: true }).exec()); } if (group.memberCount > 3) { promises.push(User.update({ - $or: [{'party._id': group._id}, {_id: user._id}], - 'achievements.partyOn': {$ne: true}, - }, {$set: {'achievements.partyOn': true}}, {multi: true}).exec()); + $or: [{ 'party._id': group._id }, { _id: user._id }], + 'achievements.partyOn': { $ne: true }, + }, { $set: { 'achievements.partyOn': true } }, { multi: true }).exec()); } } promises = await Promise.all(promises); - if (group.hasNotCancelled()) { + if (group.hasNotCancelled()) { await payments.addSubToGroupUser(user, group); await group.updateGroupPlan(); } - let response = await Group.toJSONCleanChat(promises[0], user); - let leader = await User.findById(response.leader).select(nameFields).exec(); + const response = await Group.toJSONCleanChat(promises[0], user); + const leader = await User.findById(response.leader).select(nameFields).exec(); if (leader) { - response.leader = leader.toJSON({minimize: true}); + response.leader = leader.toJSON({ minimize: true }); } - let analyticsObject = { + const analyticsObject = { uuid: user._id, hitType: 'event', category: 'behavior', @@ -669,23 +674,23 @@ api.rejectGroupInvite = { url: '/groups/:groupId/reject-invite', middlewares: [authWithHeaders()], async handler (req, res) { - let user = res.locals.user; + const { user } = res.locals; req.checkParams('groupId', apiError('groupIdRequired')).notEmpty(); // .isUUID(); can't be used because it would block 'habitrpg' or 'party' - let validationErrors = req.validationErrors(); + const validationErrors = req.validationErrors(); if (validationErrors) throw validationErrors; - let groupId = req.params.groupId; + const { groupId } = req.params; let isUserInvited = false; - let hasPartyInvitation = removeFromArray(user.invitations.parties, { id: groupId }); + const hasPartyInvitation = removeFromArray(user.invitations.parties, { id: groupId }); if (hasPartyInvitation) { user.invitations.party = user.invitations.parties.length > 0 ? user.invitations.parties[user.invitations.parties.length - 1] : {}; user.markModified('invitations.party'); isUserInvited = true; } else { - let hasInvitation = removeFromArray(user.invitations.guilds, { id: groupId }); + const hasInvitation = removeFromArray(user.invitations.guilds, { id: groupId }); if (hasInvitation) { isUserInvited = true; @@ -744,17 +749,19 @@ api.leaveGroup = { url: '/groups/:groupId/leave', middlewares: [authWithHeaders()], async handler (req, res) { - let user = res.locals.user; + const { user } = res.locals; req.checkParams('groupId', apiError('groupIdRequired')).notEmpty(); // When removing the user from challenges, should we keep the tasks? req.checkQuery('keep', apiError('keepOrRemoveAll')).optional().isIn(['keep-all', 'remove-all']); req.checkBody('keepChallenges', apiError('groupRemainOrLeaveChallenges')).optional().isIn(['remain-in-challenges', 'leave-challenges']); - let validationErrors = req.validationErrors(); + const validationErrors = req.validationErrors(); if (validationErrors) throw validationErrors; - let groupId = req.params.groupId; - let group = await Group.getGroup({user, groupId, fields: '-chat', requireMembership: true}); + const { groupId } = req.params; + const group = await Group.getGroup({ + user, groupId, fields: '-chat', requireMembership: true, + }); if (!group) { throw new NotFound(res.t('groupNotFound')); } @@ -775,11 +782,11 @@ api.leaveGroup = { await user.save(); if (group.type !== 'party') { - let guildIndex = user.guilds.indexOf(group._id); + const guildIndex = user.guilds.indexOf(group._id); if (guildIndex >= 0) user.guilds.splice(guildIndex, 1); } - let isMemberOfGroupPlan = await user.isMemberOfGroupPlan(); + const isMemberOfGroupPlan = await user.isMemberOfGroupPlan(); if (!isMemberOfGroupPlan) { await payments.cancelGroupSubscriptionForUser(user, group); } @@ -792,12 +799,12 @@ api.leaveGroup = { // Send an email to the removed user with an optional message from the leader function _sendMessageToRemoved (group, removedUser, message, isInGroup) { if (removedUser.preferences.emailNotifications.kickedGroup !== false) { - let subject = isInGroup ? `kicked-from-${group.type}` : `${group.type}-invite-rescinded`; + const subject = isInGroup ? `kicked-from-${group.type}` : `${group.type}-invite-rescinded`; sendTxnEmail(removedUser, subject, [ - {name: 'GROUP_NAME', content: group.name}, - {name: 'MESSAGE', content: message}, - {name: 'GUILDS_LINK', content: '/groups/discovery'}, - {name: 'PARTY_WANTED_GUILD', content: '/groups/guild/f2db2a7f-13c5-454d-b3ee-ea1f5089e601'}, + { name: 'GROUP_NAME', content: group.name }, + { name: 'MESSAGE', content: message }, + { name: 'GUILDS_LINK', content: '/groups/discovery' }, + { name: 'PARTY_WANTED_GUILD', content: '/groups/guild/f2db2a7f-13c5-454d-b3ee-ea1f5089e601' }, ]); } } @@ -831,19 +838,21 @@ api.removeGroupMember = { url: '/groups/:groupId/removeMember/:memberId', middlewares: [authWithHeaders()], async handler (req, res) { - let user = res.locals.user; + const { user } = res.locals; req.checkParams('groupId', apiError('groupIdRequired')).notEmpty(); req.checkParams('memberId', res.t('userIdRequired')).notEmpty().isUUID(); - let validationErrors = req.validationErrors(); + const validationErrors = req.validationErrors(); if (validationErrors) throw validationErrors; - let optionalMembership = Boolean(user.contributor.admin); - let group = await Group.getGroup({user, groupId: req.params.groupId, optionalMembership, fields: '-chat'}); // Do not fetch chat + const optionalMembership = Boolean(user.contributor.admin); + const group = await Group.getGroup({ + user, groupId: req.params.groupId, optionalMembership, fields: '-chat', + }); // Do not fetch chat if (!group) throw new NotFound(res.t('groupNotFound')); - let uuid = req.params.memberId; + const uuid = req.params.memberId; if (group.leader !== user._id && group.type === 'party') throw new NotAuthorized(res.t('onlyLeaderCanRemoveMember')); if (group.leader !== user._id && !user.contributor.admin) throw new NotAuthorized(res.t('onlyLeaderCanRemoveMember')); @@ -852,7 +861,7 @@ api.removeGroupMember = { if (user._id === uuid) throw new NotAuthorized(res.t('memberCannotRemoveYourself')); - let member = await User.findOne({_id: uuid}).exec(); + const member = await User.findOne({ _id: uuid }).exec(); // We're removing the user from a guild or a party? is the user invited only? let isInGroup; @@ -863,9 +872,9 @@ api.removeGroupMember = { } let isInvited; - if (_.find(member.invitations.parties, {id: group._id})) { + if (_.find(member.invitations.parties, { id: group._id })) { isInvited = 'party'; - } else if (_.findIndex(member.invitations.guilds, {id: group._id}) !== -1) { + } else if (_.findIndex(member.invitations.guilds, { id: group._id }) !== -1) { isInvited = 'guild'; } @@ -907,7 +916,7 @@ api.removeGroupMember = { throw new NotFound(res.t('groupMemberNotFound')); } - let message = req.query.message || req.body.message; + const message = req.query.message || req.body.message; _sendMessageToRemoved(group, member, message, isInGroup); await Promise.all([ @@ -915,7 +924,7 @@ api.removeGroupMember = { group.save(), ]); - if (isInGroup && group.hasNotCancelled()) { + if (isInGroup && group.hasNotCancelled()) { await group.updateGroupPlan(true); await payments.cancelGroupSubscriptionForUser(member, group, true); } @@ -1010,7 +1019,7 @@ api.inviteToGroup = { url: '/groups/:groupId/invite', middlewares: [authWithHeaders()], async handler (req, res) { - const user = res.locals.user; + const { user } = res.locals; if (user.flags.chatRevoked) throw new NotAuthorized(res.t('chatPrivilegesRevoked')); @@ -1021,7 +1030,7 @@ api.inviteToGroup = { const validationErrors = req.validationErrors(); if (validationErrors) throw validationErrors; - const group = await Group.getGroup({user, groupId: req.params.groupId, fields: '-chat'}); + const group = await Group.getGroup({ user, groupId: req.params.groupId, fields: '-chat' }); if (!group) throw new NotFound(res.t('groupNotFound')); if (group.purchased && group.purchased.plan.customerId && user._id !== group.leader) throw new NotAuthorized(res.t('onlyGroupLeaderCanInviteToGroupPlan')); @@ -1041,13 +1050,13 @@ api.inviteToGroup = { const results = []; if (uuids) { - const uuidInvites = uuids.map((uuid) => inviteByUUID(uuid, group, user, req, res)); + const uuidInvites = uuids.map(uuid => inviteByUUID(uuid, group, user, req, res)); const uuidResults = await Promise.all(uuidInvites); results.push(...uuidResults); } if (emails) { - const emailInvites = emails.map((invite) => inviteByEmail(invite, group, user, req, res)); + const emailInvites = emails.map(invite => inviteByEmail(invite, group, user, req, res)); user.invitesSent += emails.length; await user.save(); const emailResults = await Promise.all(emailInvites); @@ -1055,12 +1064,12 @@ api.inviteToGroup = { } if (usernames) { - const usernameInvites = usernames.map((username) => inviteByUserName(username, group, user, req, res)); + const usernameInvites = usernames.map(username => inviteByUserName(username, group, user, req, res)); const usernameResults = await Promise.all(usernameInvites); results.push(...usernameResults); } - let analyticsObject = { + const analyticsObject = { uuid: user._id, hitType: 'event', category: 'behavior', @@ -1096,23 +1105,23 @@ api.addGroupManager = { url: '/groups/:groupId/add-manager', middlewares: [authWithHeaders()], async handler (req, res) { - let user = res.locals.user; - let managerId = req.body.managerId; + const { user } = res.locals; + const { managerId } = req.body; req.checkParams('groupId', apiError('groupIdRequired')).notEmpty(); // .isUUID(); can't be used because it would block 'habitrpg' or 'party' req.checkBody('managerId', apiError('managerIdRequired')).notEmpty(); - let validationErrors = req.validationErrors(); + const validationErrors = req.validationErrors(); if (validationErrors) throw validationErrors; - let newManager = await User.findById(managerId, 'guilds party').exec(); - let groupFields = basicGroupFields.concat(' managers'); - let group = await Group.getGroup({user, groupId: req.params.groupId, fields: groupFields}); + const newManager = await User.findById(managerId, 'guilds party').exec(); + const groupFields = basicGroupFields.concat(' managers'); + const group = await Group.getGroup({ user, groupId: req.params.groupId, fields: groupFields }); if (!group) throw new NotFound(res.t('groupNotFound')); if (group.leader !== user._id) throw new NotAuthorized(res.t('messageGroupOnlyLeaderCanUpdate')); - let isMember = group.isMember(newManager); + const isMember = group.isMember(newManager); if (!isMember) throw new NotAuthorized(res.t('userMustBeMember')); group.managers[managerId] = true; @@ -1145,17 +1154,17 @@ api.removeGroupManager = { url: '/groups/:groupId/remove-manager', middlewares: [authWithHeaders()], async handler (req, res) { - let user = res.locals.user; - let managerId = req.body.managerId; + const { user } = res.locals; + const { managerId } = req.body; req.checkParams('groupId', apiError('groupIdRequired')).notEmpty(); // .isUUID(); can't be used because it would block 'habitrpg' or 'party' req.checkBody('managerId', apiError('managerIdRequired')).notEmpty(); - let validationErrors = req.validationErrors(); + const validationErrors = req.validationErrors(); if (validationErrors) throw validationErrors; - let groupFields = basicGroupFields.concat(' managers'); - let group = await Group.getGroup({user, groupId: req.params.groupId, fields: groupFields}); + const groupFields = basicGroupFields.concat(' managers'); + const group = await Group.getGroup({ user, groupId: req.params.groupId, fields: groupFields }); if (!group) throw new NotFound(res.t('groupNotFound')); if (group.leader !== user._id) throw new NotAuthorized(res.t('messageGroupOnlyLeaderCanUpdate')); @@ -1166,8 +1175,8 @@ api.removeGroupManager = { group.markModified('managers'); await group.save(); - let manager = await User.findById(managerId, 'notifications').exec(); - let newNotifications = manager.notifications.filter((notification) => { + const manager = await User.findById(managerId, 'notifications').exec(); + const newNotifications = manager.notifications.filter(notification => { const isGroupTaskNotification = notification && notification.type && notification.type.indexOf('GROUP_TASK_') === 0; return !isGroupTaskNotification; @@ -1198,20 +1207,18 @@ api.getGroupPlans = { url: '/group-plans', middlewares: [authWithHeaders()], async handler (req, res) { - let user = res.locals.user; + const { user } = res.locals; const userGroups = user.getGroups(); const groups = await Group .find({ - _id: {$in: userGroups}, + _id: { $in: userGroups }, }) .select('leaderOnly leader purchased name managers') .exec(); - let groupPlans = groups.filter(group => { - return group.isSubscribed(); - }); + const groupPlans = groups.filter(group => group.isSubscribed()); res.respond(200, groupPlans); }, diff --git a/website/server/controllers/api-v3/hall.js b/website/server/controllers/api-v3/hall.js index 1c81cc25ac..e5ec6c079c 100644 --- a/website/server/controllers/api-v3/hall.js +++ b/website/server/controllers/api-v3/hall.js @@ -1,19 +1,19 @@ +import _ from 'lodash'; +import validator from 'validator'; import { authWithHeaders } from '../../middlewares/auth'; import { ensureAdmin } from '../../middlewares/ensureAccessRight'; import { model as User } from '../../models/user'; import { NotFound, } from '../../libs/errors'; -import _ from 'lodash'; import apiError from '../../libs/apiError'; -import validator from 'validator'; import { validateItemPath, castItemVal, } from '../../libs/items/utils'; -let api = {}; +const api = {}; /** * @api {get} /api/v3/hall/patrons Get all patrons @@ -69,17 +69,17 @@ api.getPatrons = { url: '/hall/patrons', middlewares: [authWithHeaders()], async handler (req, res) { - req.checkQuery('page').optional().isInt({min: 0}, apiError('queryPageInteger')); + req.checkQuery('page').optional().isInt({ min: 0 }, apiError('queryPageInteger')); - let validationErrors = req.validationErrors(); + const validationErrors = req.validationErrors(); if (validationErrors) throw validationErrors; - let page = req.query.page ? Number(req.query.page) : 0; + const page = req.query.page ? Number(req.query.page) : 0; const perPage = 50; - let patrons = await User + const patrons = await User .find({ - 'backer.tier': {$gt: 0}, + 'backer.tier': { $gt: 0 }, }) .select('contributor backer profile.name') .sort('-backer.tier') @@ -129,9 +129,9 @@ api.getHeroes = { url: '/hall/heroes', middlewares: [authWithHeaders()], async handler (req, res) { - let heroes = await User + const heroes = await User .find({ - 'contributor.level': {$gt: 0}, + 'contributor.level': { $gt: 0 }, }) .select('contributor backer profile.name') .sort('-contributor.level') @@ -174,13 +174,13 @@ api.getHero = { validationErrors = req.validationErrors(); if (validationErrors) throw validationErrors; - const heroId = req.params.heroId; + const { heroId } = req.params; let query; if (validator.isUUID(heroId)) { - query = {_id: heroId}; + query = { _id: heroId }; } else { - query = {'auth.local.lowerCaseUsername': heroId.toLowerCase()}; + query = { 'auth.local.lowerCaseUsername': heroId.toLowerCase() }; } const hero = await User @@ -188,8 +188,8 @@ api.getHero = { .select(heroAdminFields) .exec(); - if (!hero) throw new NotFound(res.t('userWithIDNotFound', {userId: heroId})); - let heroRes = hero.toJSON({minimize: true}); + if (!hero) throw new NotFound(res.t('userWithIDNotFound', { userId: heroId })); + const heroRes = hero.toJSON({ minimize: true }); // supply to the possible absence of hero.contributor // if we didn't pass minimize: true it would have returned all fields as empty if (!heroRes.contributor) heroRes.contributor = {}; @@ -198,7 +198,9 @@ api.getHero = { }; // e.g., tier 5 gives 4 gems. Tier 8 = moderator. Tier 9 = staff -const gemsPerTier = {1: 3, 2: 3, 3: 3, 4: 4, 5: 4, 6: 4, 7: 4, 8: 0, 9: 0}; +const gemsPerTier = { + 1: 3, 2: 3, 3: 3, 4: 4, 5: 4, 6: 4, 7: 4, 8: 0, 9: 0, +}; /** * @api {put} /api/v3/hall/heroes/:heroId Update any user ("hero") @@ -240,22 +242,22 @@ api.updateHero = { url: '/hall/heroes/:heroId', middlewares: [authWithHeaders(), ensureAdmin], async handler (req, res) { - let heroId = req.params.heroId; - let updateData = req.body; + const { heroId } = req.params; + const updateData = req.body; req.checkParams('heroId', res.t('heroIdRequired')).notEmpty().isUUID(); - let validationErrors = req.validationErrors(); + const validationErrors = req.validationErrors(); if (validationErrors) throw validationErrors; - let hero = await User.findById(heroId).exec(); - if (!hero) throw new NotFound(res.t('userWithIDNotFound', {userId: heroId})); + const hero = await User.findById(heroId).exec(); + if (!hero) throw new NotFound(res.t('userWithIDNotFound', { userId: heroId })); if (updateData.balance) hero.balance = updateData.balance; // give them gems if they got an higher level let newTier = updateData.contributor && updateData.contributor.level; // tier = level in this context - let oldTier = hero.contributor && hero.contributor.level || 0; + const oldTier = hero.contributor && hero.contributor.level || 0; if (newTier > oldTier) { hero.flags.contributor = true; let tierDiff = newTier - oldTier; // can be 2+ tier increases at once @@ -291,9 +293,9 @@ api.updateHero = { if (updateData.flags && _.isBoolean(updateData.flags.chatRevoked)) hero.flags.chatRevoked = updateData.flags.chatRevoked; if (updateData.flags && _.isBoolean(updateData.flags.chatShadowMuted)) hero.flags.chatShadowMuted = updateData.flags.chatShadowMuted; - let savedHero = await hero.save(); - let heroJSON = savedHero.toJSON(); - let responseHero = {_id: heroJSON._id}; // only respond with important fields + const savedHero = await hero.save(); + const heroJSON = savedHero.toJSON(); + const responseHero = { _id: heroJSON._id }; // only respond with important fields heroAdminFields.split(' ').forEach(field => { _.set(responseHero, field, _.get(heroJSON, field)); }); diff --git a/website/server/controllers/api-v3/i18n.js b/website/server/controllers/api-v3/i18n.js index 63e6e54450..76a7d7ecd1 100644 --- a/website/server/controllers/api-v3/i18n.js +++ b/website/server/controllers/api-v3/i18n.js @@ -1,9 +1,9 @@ +import _ from 'lodash'; import { translations, momentLangs, availableLanguages, } from '../../libs/i18n'; -import _ from 'lodash'; const api = {}; @@ -32,7 +32,7 @@ api.geti18nBrowserScript = { method: 'GET', url: '/i18n/browser-script', async handler (req, res) { - const language = _.find(availableLanguages, {code: req.language}); + const language = _.find(availableLanguages, { code: req.language }); res.set({ 'Content-Type': 'application/javascript', diff --git a/website/server/controllers/api-v3/iap.js b/website/server/controllers/api-v3/iap.js index 0d07063f88..6512bf9dff 100644 --- a/website/server/controllers/api-v3/iap.js +++ b/website/server/controllers/api-v3/iap.js @@ -2,4 +2,5 @@ // to be found at /api/v3/iap instead of /iap. import iap from '../top-level/payments/iap'; + export default iap; diff --git a/website/server/controllers/api-v3/inbox.js b/website/server/controllers/api-v3/inbox.js index a6ad1d1410..0702fd0979 100644 --- a/website/server/controllers/api-v3/inbox.js +++ b/website/server/controllers/api-v3/inbox.js @@ -1,7 +1,7 @@ import { authWithHeaders } from '../../middlewares/auth'; import * as inboxLib from '../../libs/inbox'; -let api = {}; +const api = {}; /* NOTE most inbox routes are either in the user or members controller */ @@ -21,9 +21,9 @@ api.getInboxMessages = { url: '/inbox/messages', middlewares: [authWithHeaders()], async handler (req, res) { - const user = res.locals.user; - const page = req.query.page; - const conversation = req.query.conversation; + const { user } = res.locals; + const { page } = req.query; + const { conversation } = req.query; const userInbox = await inboxLib.getUserInbox(user, { page, conversation, diff --git a/website/server/controllers/api-v3/members.js b/website/server/controllers/api-v3/members.js index 2c90a12a47..d10fd2baa2 100644 --- a/website/server/controllers/api-v3/members.js +++ b/website/server/controllers/api-v3/members.js @@ -19,12 +19,12 @@ import { sendTxn as sendTxnEmail, } from '../../libs/email'; import { sendNotification as sendPushNotification } from '../../libs/pushNotifications'; -import common from '../../../../website/common/'; -import {sentMessage} from '../../libs/inbox'; +import common from '../../../common'; +import { sentMessage } from '../../libs/inbox'; -const achievements = common.achievements; +const { achievements } = common; -let api = {}; +const api = {}; /** * @api {get} /api/v3/members/:memberId Get a member profile @@ -100,22 +100,22 @@ api.getMember = { async handler (req, res) { req.checkParams('memberId', res.t('memberIdRequired')).notEmpty().isUUID(); - let validationErrors = req.validationErrors(); + const validationErrors = req.validationErrors(); if (validationErrors) throw validationErrors; - let memberId = req.params.memberId; + const { memberId } = req.params; - let member = await User + const member = await User .findById(memberId) .select(memberFields) .exec(); - if (!member) throw new NotFound(res.t('userWithIDNotFound', {userId: memberId})); + if (!member) throw new NotFound(res.t('userWithIDNotFound', { userId: memberId })); if (!member.flags.verifiedUsername) member.auth.local.username = null; // manually call toJSON with minimize: true so empty paths aren't returned - let memberToJSON = member.toJSON({minimize: true}); + const memberToJSON = member.toJSON({ minimize: true }); User.addComputedStatsToJSONObj(memberToJSON.stats, member); res.respond(200, memberToJSON); @@ -129,21 +129,21 @@ api.getMemberByUsername = { async handler (req, res) { req.checkParams('username', res.t('invalidReqParams')).notEmpty(); - let validationErrors = req.validationErrors(); + const validationErrors = req.validationErrors(); if (validationErrors) throw validationErrors; let username = req.params.username.toLowerCase(); if (username[0] === '@') username = username.slice(1, username.length); - let member = await User - .findOne({'auth.local.lowerCaseUsername': username, 'flags.verifiedUsername': true}) + const member = await User + .findOne({ 'auth.local.lowerCaseUsername': username, 'flags.verifiedUsername': true }) .select(memberFields) .exec(); if (!member) throw new NotFound(res.t('userNotFound')); // manually call toJSON with minimize: true so empty paths aren't returned - let memberToJSON = member.toJSON({minimize: true}); + const memberToJSON = member.toJSON({ minimize: true }); User.addComputedStatsToJSONObj(memberToJSON.stats, member); res.respond(200, memberToJSON); @@ -239,19 +239,19 @@ api.getMemberAchievements = { async handler (req, res) { req.checkParams('memberId', res.t('memberIdRequired')).notEmpty().isUUID(); - let validationErrors = req.validationErrors(); + const validationErrors = req.validationErrors(); if (validationErrors) throw validationErrors; - let memberId = req.params.memberId; + const { memberId } = req.params; - let member = await User + const member = await User .findById(memberId) .select(memberFields) .exec(); - if (!member) throw new NotFound(res.t('userWithIDNotFound', {userId: memberId})); + if (!member) throw new NotFound(res.t('userWithIDNotFound', { userId: memberId })); - let achievsObject = achievements.getAchievementsForProfile(member, req.language); + const achievsObject = achievements.getAchievementsForProfile(member, req.language); res.respond(200, achievsObject); }, @@ -274,13 +274,13 @@ function _getMembersForItem (type) { } req.checkQuery('lastId').optional().notEmpty().isUUID(); - let validationErrors = req.validationErrors(); + const validationErrors = req.validationErrors(); if (validationErrors) throw validationErrors; - let groupId = req.params.groupId; - let challengeId = req.params.challengeId; - let lastId = req.query.lastId; - let user = res.locals.user; + const { groupId } = req.params; + const { challengeId } = req.params; + const { lastId } = req.query; + const { user } = res.locals; let challenge; let group; @@ -299,11 +299,11 @@ function _getMembersForItem (type) { if (!group || !challenge.canView(user, group)) throw new NotFound(res.t('challengeNotFound')); } else { - group = await Group.getGroup({user, groupId, fields: '_id type'}); + group = await Group.getGroup({ user, groupId, fields: '_id type' }); if (!group) throw new NotFound(res.t('groupNotFound')); } - let query = {}; + const query = {}; let fields = nameFields; let addComputedStats = false; // add computes stats to the member info when items and stats are available @@ -316,7 +316,7 @@ function _getMembersForItem (type) { } if (req.query.search) { - query['profile.name'] = {$regex: req.query.search}; + query['profile.name'] = { $regex: req.query.search }; } } else if (type === 'group-members') { if (group.type === 'guild') { @@ -357,7 +357,7 @@ function _getMembersForItem (type) { } } - if (lastId) query._id = {$gt: lastId}; + if (lastId) query._id = { $gt: lastId }; let limit = 30; @@ -366,9 +366,9 @@ function _getMembersForItem (type) { limit = 0; // no limit } - let members = await User + const members = await User .find(query) - .sort({_id: 1}) + .sort({ _id: 1 }) .limit(limit) .select(fields) .lean() @@ -541,26 +541,28 @@ api.getChallengeMemberProgress = { req.checkParams('challengeId', res.t('challengeIdRequired')).notEmpty().isUUID(); req.checkParams('memberId', res.t('memberIdRequired')).notEmpty().isUUID(); - let validationErrors = req.validationErrors(); + const validationErrors = req.validationErrors(); if (validationErrors) throw validationErrors; - let user = res.locals.user; - let challengeId = req.params.challengeId; - let memberId = req.params.memberId; + const { user } = res.locals; + const { challengeId } = req.params; + const { memberId } = req.params; - let member = await User.findById(memberId).select(`${nameFields} challenges`).exec(); - if (!member) throw new NotFound(res.t('userWithIDNotFound', {userId: memberId})); + const member = await User.findById(memberId).select(`${nameFields} challenges`).exec(); + if (!member) throw new NotFound(res.t('userWithIDNotFound', { userId: memberId })); - let challenge = await Challenge.findById(challengeId).exec(); + const challenge = await Challenge.findById(challengeId).exec(); if (!challenge) throw new NotFound(res.t('challengeNotFound')); // optionalMembership is set to true because even if you're not member of the group you may be able to access the challenge // for example if you've been booted from it, are the leader or a site admin - let group = await Group.getGroup({user, groupId: challenge.group, fields: '_id type privacy', optionalMembership: true}); + const group = await Group.getGroup({ + user, groupId: challenge.group, fields: '_id type privacy', optionalMembership: true, + }); if (!group || !challenge.canView(user, group)) throw new NotFound(res.t('challengeNotFound')); if (!challenge.isMember(member)) throw new NotFound(res.t('challengeMemberNotFound')); - let chalTasks = await Tasks.Task.find({ + const chalTasks = await Tasks.Task.find({ userId: memberId, 'challenge.id': challengeId, }) @@ -568,11 +570,11 @@ api.getChallengeMemberProgress = { .exec(); // manually call toJSON with minimize: true so empty paths aren't returned - let response = member.toJSON({minimize: true}); + const response = member.toJSON({ minimize: true }); delete response.challenges; response.tasks = chalTasks.map(chalTask => { chalTask.checklist = []; // Clear checklists as they are private - return chalTask.toJSON({minimize: true}); + return chalTask.toJSON({ minimize: true }); }); res.respond(200, response); }, @@ -597,15 +599,15 @@ api.getObjectionsToInteraction = { req.checkParams('toUserId', res.t('toUserIDRequired')).notEmpty().isUUID(); req.checkParams('interaction', res.t('interactionRequired')).notEmpty().isIn(KNOWN_INTERACTIONS); - let validationErrors = req.validationErrors(); + const validationErrors = req.validationErrors(); if (validationErrors) throw validationErrors; - let sender = res.locals.user; - let receiver = await User.findById(req.params.toUserId).exec(); - if (!receiver) throw new NotFound(res.t('userWithIDNotFound', {userId: req.params.toUserId})); + const sender = res.locals.user; + const receiver = await User.findById(req.params.toUserId).exec(); + if (!receiver) throw new NotFound(res.t('userWithIDNotFound', { userId: req.params.toUserId })); - let interaction = req.params.interaction; - let response = sender.getObjectionsToInteraction(interaction, receiver); + const { interaction } = req.params; + const response = sender.getObjectionsToInteraction(interaction, receiver); res.respond(200, response.map(res.t)); }, @@ -635,7 +637,7 @@ api.sendPrivateMessage = { if (validationErrors) throw validationErrors; const sender = res.locals.user; - const message = req.body.message; + const { message } = req.body; const receiver = await User.findById(req.body.toUserId).exec(); if (!receiver) throw new NotFound(res.t('userNotFound')); @@ -646,7 +648,7 @@ api.sendPrivateMessage = { const messageSent = await sentMessage(sender, receiver, message, res.t); - res.respond(200, {message: messageSent}); + res.respond(200, { message: messageSent }); }, }; @@ -671,18 +673,18 @@ api.transferGems = { req.checkBody('toUserId', res.t('toUserIDRequired')).notEmpty().isUUID(); req.checkBody('gemAmount', res.t('gemAmountRequired')).notEmpty().isInt(); - let validationErrors = req.validationErrors(); + const validationErrors = req.validationErrors(); if (validationErrors) throw validationErrors; - let sender = res.locals.user; - let receiver = await User.findById(req.body.toUserId).exec(); + const sender = res.locals.user; + const receiver = await User.findById(req.body.toUserId).exec(); if (!receiver) throw new NotFound(res.t('userNotFound')); - let objections = sender.getObjectionsToInteraction('transfer-gems', receiver); + const objections = sender.getObjectionsToInteraction('transfer-gems', receiver); if (objections.length > 0) throw new NotAuthorized(res.t(objections[0])); - let gemAmount = req.body.gemAmount; - let amount = gemAmount / 4; + const { gemAmount } = req.body; + const amount = gemAmount / 4; if (amount <= 0 || sender.balance < amount) { throw new NotAuthorized(res.t('badAmountOfGemsToSend')); @@ -691,13 +693,13 @@ api.transferGems = { receiver.balance += amount; sender.balance -= amount; // @TODO necessary? Also saved when sending the inbox message - let promises = [receiver.save(), sender.save()]; + const promises = [receiver.save(), sender.save()]; await Promise.all(promises); // generate the message in both languages, so both users can understand it - let receiverLang = receiver.preferences.language; - let senderLang = sender.preferences.language; - let [receiverMsg, senderMsg] = [receiverLang, senderLang].map((lang) => { + const receiverLang = receiver.preferences.language; + const senderLang = sender.preferences.language; + const [receiverMsg, senderMsg] = [receiverLang, senderLang].map(lang => { let messageContent = res.t('privateMessageGiftGemsMessage', { receiverName: receiver.profile.name, senderName: sender.profile.name, @@ -716,21 +718,21 @@ api.transferGems = { receiverMsg, }); - let byUsername = getUserInfo(sender, ['name']).name; + const byUsername = getUserInfo(sender, ['name']).name; if (receiver.preferences.emailNotifications.giftedGems !== false) { sendTxnEmail(receiver, 'gifted-gems', [ - {name: 'GIFTER', content: byUsername}, - {name: 'X_GEMS_GIFTED', content: gemAmount}, + { name: 'GIFTER', content: byUsername }, + { name: 'X_GEMS_GIFTED', content: gemAmount }, ]); } if (receiver.preferences.pushNotifications.giftedGems !== false) { sendPushNotification(receiver, { title: res.t('giftedGems', receiverLang), - message: res.t('giftedGemsInfo', {amount: gemAmount, name: byUsername}, receiverLang), + message: res.t('giftedGemsInfo', { amount: gemAmount, name: byUsername }, receiverLang), identifier: 'giftedGems', - payload: {replyTo: sender._id}, + payload: { replyTo: sender._id }, }); } diff --git a/website/server/controllers/api-v3/modelsPaths.js b/website/server/controllers/api-v3/modelsPaths.js index 56ae235986..d98ad7841f 100644 --- a/website/server/controllers/api-v3/modelsPaths.js +++ b/website/server/controllers/api-v3/modelsPaths.js @@ -1,9 +1,9 @@ import mongoose from 'mongoose'; -let api = {}; +const api = {}; -let tasksModels = ['habit', 'daily', 'todo', 'reward']; -let allModels = ['user', 'tag', 'challenge', 'group'].concat(tasksModels); +const tasksModels = ['habit', 'daily', 'todo', 'reward']; +const allModels = ['user', 'tag', 'challenge', 'group'].concat(tasksModels); /** * @api {get} /api/v3/models/:model/paths Get all paths for the specified model @@ -36,10 +36,10 @@ api.getModelPaths = { async handler (req, res) { req.checkParams('model', res.t('modelNotFound')).notEmpty().isIn(allModels); - let validationErrors = req.validationErrors(); + const validationErrors = req.validationErrors(); if (validationErrors) throw validationErrors; - let model = req.params.model; + let { model } = req.params; // tasks models are lowercase, the others have the first letter uppercase (User, Group) if (tasksModels.indexOf(model) === -1) { model = model.charAt(0).toUpperCase() + model.slice(1); diff --git a/website/server/controllers/api-v3/news.js b/website/server/controllers/api-v3/news.js index 09e6c4e5bf..8196d3dac2 100644 --- a/website/server/controllers/api-v3/news.js +++ b/website/server/controllers/api-v3/news.js @@ -1,6 +1,6 @@ import { authWithHeaders } from '../../middlewares/auth'; -let api = {}; +const api = {}; // @TODO export this const, cannot export it from here because only routes are exported from controllers const LAST_ANNOUNCEMENT_TITLE = 'SPOOKY SPARKLES AND COSTUME CHALLENGE!'; @@ -65,13 +65,11 @@ api.tellMeLaterNews = { middlewares: [authWithHeaders()], url: '/news/tell-me-later', async handler (req, res) { - const user = res.locals.user; + const { user } = res.locals; user.flags.newStuff = false; - const existingNotificationIndex = user.notifications.findIndex(n => { - return n && n.type === 'NEW_STUFF'; - }); + const existingNotificationIndex = user.notifications.findIndex(n => n && n.type === 'NEW_STUFF'); if (existingNotificationIndex !== -1) user.notifications.splice(existingNotificationIndex, 1); user.addNotification('NEW_STUFF', { title: LAST_ANNOUNCEMENT_TITLE }, true); // seen by default diff --git a/website/server/controllers/api-v3/notifications.js b/website/server/controllers/api-v3/notifications.js index 45d92d0f77..f188ec66e3 100644 --- a/website/server/controllers/api-v3/notifications.js +++ b/website/server/controllers/api-v3/notifications.js @@ -9,7 +9,7 @@ import { model as UserNotification, } from '../../models/userNotification'; -let api = {}; +const api = {}; /** * @api {post} /api/v3/notifications/:notificationId/read Mark one notification as read @@ -25,16 +25,14 @@ api.readNotification = { url: '/notifications/:notificationId/read', middlewares: [authWithHeaders()], async handler (req, res) { - let user = res.locals.user; + const { user } = res.locals; req.checkParams('notificationId', res.t('notificationIdRequired')).notEmpty(); - let validationErrors = req.validationErrors(); + const validationErrors = req.validationErrors(); if (validationErrors) throw validationErrors; - const index = user.notifications.findIndex(n => { - return n && n.id === req.params.notificationId; - }); + const index = user.notifications.findIndex(n => n && n.id === req.params.notificationId); if (index === -1) { throw new NotificationNotFound(req.language); @@ -67,18 +65,16 @@ api.readNotifications = { url: '/notifications/read', middlewares: [authWithHeaders()], async handler (req, res) { - let user = res.locals.user; + const { user } = res.locals; req.checkBody('notificationIds', res.t('notificationsRequired')).notEmpty(); - let validationErrors = req.validationErrors(); + const validationErrors = req.validationErrors(); if (validationErrors) throw validationErrors; - let notificationsIds = req.body.notificationIds; - for (let notificationId of notificationsIds) { - const index = user.notifications.findIndex(n => { - return n && n.id === notificationId; - }); + const notificationsIds = req.body.notificationIds; + for (const notificationId of notificationsIds) { + const index = user.notifications.findIndex(n => n && n.id === notificationId); if (index === -1) { throw new NotificationNotFound(req.language); @@ -115,18 +111,16 @@ api.seeNotification = { url: '/notifications/:notificationId/see', middlewares: [authWithHeaders()], async handler (req, res) { - let user = res.locals.user; + const { user } = res.locals; req.checkParams('notificationId', res.t('notificationIdRequired')).notEmpty(); - let validationErrors = req.validationErrors(); + const validationErrors = req.validationErrors(); if (validationErrors) throw validationErrors; - const notificationId = req.params.notificationId; + const { notificationId } = req.params; - const notification = user.notifications.find(n => { - return n && n.id === notificationId; - }); + const notification = user.notifications.find(n => n && n.id === notificationId); if (!notification) { throw new NotificationNotFound(req.language); @@ -164,19 +158,17 @@ api.seeNotifications = { url: '/notifications/see', middlewares: [authWithHeaders()], async handler (req, res) { - let user = res.locals.user; + const { user } = res.locals; req.checkBody('notificationIds', res.t('notificationsRequired')).notEmpty(); - let validationErrors = req.validationErrors(); + const validationErrors = req.validationErrors(); if (validationErrors) throw validationErrors; - let notificationsIds = req.body.notificationIds; + const notificationsIds = req.body.notificationIds; - for (let notificationId of notificationsIds) { - const notification = user.notifications.find(n => { - return n && n.id === notificationId; - }); + for (const notificationId of notificationsIds) { + const notification = user.notifications.find(n => n && n.id === notificationId); if (!notification) { throw new NotificationNotFound(req.language); diff --git a/website/server/controllers/api-v3/pushNotifications.js b/website/server/controllers/api-v3/pushNotifications.js index 64400345d9..3ee0d9c592 100644 --- a/website/server/controllers/api-v3/pushNotifications.js +++ b/website/server/controllers/api-v3/pushNotifications.js @@ -4,7 +4,7 @@ import { } from '../../libs/errors'; import { model as PushDevice } from '../../models/pushDevice'; -let api = {}; +const api = {}; /** * @apiIgnore @@ -23,7 +23,7 @@ api.addPushDevice = { url: '/user/push-devices', middlewares: [authWithHeaders()], async handler (req, res) { - const user = res.locals.user; + const { user } = res.locals; req.checkBody('regId', res.t('regIdRequired')).notEmpty(); req.checkBody('type', res.t('typeRequired')).notEmpty().isIn(['ios', 'android']); @@ -31,7 +31,7 @@ api.addPushDevice = { const validationErrors = req.validationErrors(); if (validationErrors) throw validationErrors; - const pushDevices = user.pushDevices; + const { pushDevices } = user; const item = { regId: req.body.regId, @@ -73,20 +73,18 @@ api.removePushDevice = { url: '/user/push-devices/:regId', middlewares: [authWithHeaders()], async handler (req, res) { - const user = res.locals.user; + const { user } = res.locals; req.checkParams('regId', res.t('regIdRequired')).notEmpty(); const validationErrors = req.validationErrors(); if (validationErrors) throw validationErrors; - const regId = req.params.regId; + const { regId } = req.params; - const pushDevices = user.pushDevices; + const { pushDevices } = user; - const indexOfPushDevice = pushDevices.findIndex((element) => { - return element.regId === regId; - }); + const indexOfPushDevice = pushDevices.findIndex(element => element.regId === regId); if (indexOfPushDevice === -1) { throw new NotFound(res.t('pushDeviceNotFound')); diff --git a/website/server/controllers/api-v3/quests.js b/website/server/controllers/api-v3/quests.js index 0fd401354d..d882ebf697 100644 --- a/website/server/controllers/api-v3/quests.js +++ b/website/server/controllers/api-v3/quests.js @@ -21,7 +21,7 @@ import apiError from '../../libs/apiError'; const questScrolls = common.content.quests; -function canStartQuestAutomatically (group) { +function canStartQuestAutomatically (group) { // If all members are either true (accepted) or false (rejected) return true // If any member is null/undefined (undecided) return false return _.every(group.quest.members, _.isBoolean); @@ -37,7 +37,7 @@ function canStartQuestAutomatically (group) { * The quest leader can use this route. */ -let api = {}; +const api = {}; /** * @api {post} /api/v3/groups/:groupId/quests/invite/:questKey Invite users to a quest @@ -57,16 +57,16 @@ api.inviteToQuest = { url: '/groups/:groupId/quests/invite/:questKey', middlewares: [authWithHeaders()], async handler (req, res) { - let user = res.locals.user; - let questKey = req.params.questKey; - let quest = questScrolls[questKey]; + const { user } = res.locals; + const { questKey } = req.params; + const quest = questScrolls[questKey]; req.checkParams('groupId', apiError('groupIdRequired')).notEmpty(); - let validationErrors = req.validationErrors(); + const validationErrors = req.validationErrors(); if (validationErrors) throw validationErrors; - let group = await Group.getGroup({user, groupId: req.params.groupId, fields: basicGroupFields.concat(' quest chat')}); + const group = await Group.getGroup({ user, groupId: req.params.groupId, fields: basicGroupFields.concat(' quest chat') }); if (!group) throw new NotFound(res.t('groupNotFound')); if (group.type !== 'party') throw new NotAuthorized(res.t('guildQuestsNotSupported')); @@ -75,9 +75,9 @@ api.inviteToQuest = { if (user.stats.lvl < quest.lvl) throw new NotAuthorized(res.t('questLevelTooHigh', { level: quest.lvl })); if (group.quest.key) throw new NotAuthorized(res.t('questAlreadyUnderway')); - let members = await User.find({ + const members = await User.find({ 'party._id': group._id, - _id: {$ne: user._id}, + _id: { $ne: user._id }, }) .select('auth.facebook auth.google auth.local preferences.emailNotifications preferences.pushNotifications preferences.language profile.name pushDevices') .exec(); @@ -93,15 +93,15 @@ api.inviteToQuest = { await User.update({ 'party._id': group._id, - _id: {$ne: user._id}, + _id: { $ne: user._id }, }, { $set: { 'party.quest.RSVPNeeded': true, 'party.quest.key': questKey, }, - }, {multi: true}).exec(); + }, { multi: true }).exec(); - _.each(members, (member) => { + _.each(members, member => { group.quest.members[member._id] = null; }); @@ -109,7 +109,7 @@ api.inviteToQuest = { await group.startQuest(user); } - let [savedGroup] = await Promise.all([ + const [savedGroup] = await Promise.all([ group.save(), user.save(), ]); @@ -117,8 +117,8 @@ api.inviteToQuest = { res.respond(200, savedGroup.quest); // send out invites - let inviterVars = getUserInfo(user, ['name', 'email']); - let membersToEmail = members.filter(member => { + const inviterVars = getUserInfo(user, ['name', 'email']); + const membersToEmail = members.filter(member => { // send push notifications while filtering members before sending emails if (member.preferences.pushNotifications.invitedQuest !== false) { sendPushNotification( @@ -128,16 +128,16 @@ api.inviteToQuest = { message: res.t('questInvitationNotificationInfo', member.preferences.language), identifier: 'questInvitation', category: 'questInvitation', - } + }, ); } return member.preferences.emailNotifications.invitedQuest !== false; }); sendTxnEmail(membersToEmail, `invite-${quest.boss ? 'boss' : 'collection'}-quest`, [ - {name: 'QUEST_NAME', content: quest.text()}, - {name: 'INVITER', content: inviterVars.name}, - {name: 'PARTY_URL', content: '/party'}, + { name: 'QUEST_NAME', content: quest.text() }, + { name: 'INVITER', content: inviterVars.name }, + { name: 'PARTY_URL', content: '/party' }, ]); // track that the inviting user has accepted the quest @@ -170,14 +170,14 @@ api.acceptQuest = { url: '/groups/:groupId/quests/accept', middlewares: [authWithHeaders()], async handler (req, res) { - let user = res.locals.user; + const { user } = res.locals; req.checkParams('groupId', apiError('groupIdRequired')).notEmpty(); - let validationErrors = req.validationErrors(); + const validationErrors = req.validationErrors(); if (validationErrors) throw validationErrors; - let group = await Group.getGroup({user, groupId: req.params.groupId, fields: basicGroupFields.concat(' quest chat')}); + const group = await Group.getGroup({ user, groupId: req.params.groupId, fields: basicGroupFields.concat(' quest chat') }); if (!group) throw new NotFound(res.t('groupNotFound')); if (group.type !== 'party') throw new NotAuthorized(res.t('guildQuestsNotSupported')); @@ -195,7 +195,7 @@ api.acceptQuest = { await group.startQuest(user); } - let savedGroup = await group.save(); + const savedGroup = await group.save(); res.respond(200, savedGroup.quest); @@ -229,14 +229,14 @@ api.rejectQuest = { url: '/groups/:groupId/quests/reject', middlewares: [authWithHeaders()], async handler (req, res) { - let user = res.locals.user; + const { user } = res.locals; req.checkParams('groupId', apiError('groupIdRequired')).notEmpty(); - let validationErrors = req.validationErrors(); + const validationErrors = req.validationErrors(); if (validationErrors) throw validationErrors; - let group = await Group.getGroup({user, groupId: req.params.groupId, fields: basicGroupFields.concat(' quest chat')}); + const group = await Group.getGroup({ user, groupId: req.params.groupId, fields: basicGroupFields.concat(' quest chat') }); if (!group) throw new NotFound(res.t('groupNotFound')); if (group.type !== 'party') throw new NotAuthorized(res.t('guildQuestsNotSupported')); if (!group.quest.key) throw new NotFound(res.t('questInvitationDoesNotExist')); @@ -255,7 +255,7 @@ api.rejectQuest = { await group.startQuest(user); } - let savedGroup = await group.save(); + const savedGroup = await group.save(); res.respond(200, savedGroup.quest); @@ -292,14 +292,14 @@ api.forceStart = { url: '/groups/:groupId/quests/force-start', middlewares: [authWithHeaders()], async handler (req, res) { - let user = res.locals.user; + const { user } = res.locals; req.checkParams('groupId', apiError('groupIdRequired')).notEmpty(); - let validationErrors = req.validationErrors(); + const validationErrors = req.validationErrors(); if (validationErrors) throw validationErrors; - let group = await Group.getGroup({user, groupId: req.params.groupId, fields: basicGroupFields.concat(' quest chat')}); + const group = await Group.getGroup({ user, groupId: req.params.groupId, fields: basicGroupFields.concat(' quest chat') }); if (!group) throw new NotFound(res.t('groupNotFound')); if (group.type !== 'party') throw new NotAuthorized(res.t('guildQuestsNotSupported')); @@ -311,7 +311,7 @@ api.forceStart = { await group.startQuest(user); - let [savedGroup] = await Promise.all([ + const [savedGroup] = await Promise.all([ group.save(), user.save(), ]); @@ -353,15 +353,15 @@ api.cancelQuest = { // Cancel a quest BEFORE it has begun (i.e., in the invitation stage) // Quest scroll has not yet left quest owner's inventory so no need to return it. // Do not wipe quest progress for members because they'll want it to be applied to the next quest that's started. - let user = res.locals.user; - let groupId = req.params.groupId; + const { user } = res.locals; + const { groupId } = req.params; req.checkParams('groupId', apiError('groupIdRequired')).notEmpty(); - let validationErrors = req.validationErrors(); + const validationErrors = req.validationErrors(); if (validationErrors) throw validationErrors; - let group = await Group.getGroup({user, groupId, fields: basicGroupFields.concat(' quest')}); + const group = await Group.getGroup({ user, groupId, fields: basicGroupFields.concat(' quest') }); if (!group) throw new NotFound(res.t('groupNotFound')); if (group.type !== 'party') throw new NotAuthorized(res.t('guildQuestsNotSupported')); @@ -369,7 +369,7 @@ api.cancelQuest = { if (user._id !== group.leader && group.quest.leader !== user._id) throw new NotAuthorized(res.t('onlyLeaderCancelQuest')); if (group.quest.active) throw new NotAuthorized(res.t('cantCancelActiveQuest')); - let questName = questScrolls[group.quest.key].text('en'); + const questName = questScrolls[group.quest.key].text('en'); const newChatMessage = group.sendChat({ message: `\`${user.profile.name} cancelled the party quest ${questName}.\``, info: { @@ -382,13 +382,13 @@ api.cancelQuest = { group.quest = Group.cleanGroupQuest(); group.markModified('quest'); - let [savedGroup] = await Promise.all([ + const [savedGroup] = await Promise.all([ group.save(), newChatMessage.save(), User.update( - {'party._id': groupId}, + { 'party._id': groupId }, Group.cleanQuestParty(), - {multi: true} + { multi: true }, ).exec(), ]); @@ -417,24 +417,24 @@ api.abortQuest = { middlewares: [authWithHeaders()], async handler (req, res) { // Abort a quest AFTER it has begun - let user = res.locals.user; - let groupId = req.params.groupId; + const { user } = res.locals; + const { groupId } = req.params; req.checkParams('groupId', apiError('groupIdRequired')).notEmpty(); - let validationErrors = req.validationErrors(); + const validationErrors = req.validationErrors(); if (validationErrors) throw validationErrors; - let group = await Group.getGroup({user, groupId, fields: basicGroupFields.concat(' quest chat')}); + const group = await Group.getGroup({ user, groupId, fields: basicGroupFields.concat(' quest chat') }); if (!group) throw new NotFound(res.t('groupNotFound')); if (group.type !== 'party') throw new NotAuthorized(res.t('guildQuestsNotSupported')); if (!group.quest.active) throw new NotFound(res.t('noActiveQuestToAbort')); if (user._id !== group.leader && user._id !== group.quest.leader) throw new NotAuthorized(res.t('onlyLeaderAbortQuest')); - let questName = questScrolls[group.quest.key].text('en'); + const questName = questScrolls[group.quest.key].text('en'); const newChatMessage = group.sendChat({ - message: `\`${common.i18n.t('chatQuestAborted', {username: user.profile.name, questName}, 'en')}\``, + message: `\`${common.i18n.t('chatQuestAborted', { username: user.profile.name, questName }, 'en')}\``, info: { type: 'quest_abort', user: user.profile.name, @@ -443,12 +443,12 @@ api.abortQuest = { }); await newChatMessage.save(); - let memberUpdates = User.update({ + const memberUpdates = User.update({ 'party._id': groupId, }, Group.cleanQuestParty(), - {multi: true}).exec(); + { multi: true }).exec(); - let questLeaderUpdate = User.update({ + const questLeaderUpdate = User.update({ _id: group.quest.leader, }, { $inc: { @@ -459,7 +459,7 @@ api.abortQuest = { group.quest = Group.cleanGroupQuest(); group.markModified('quest'); - let [groupSaved] = await Promise.all([group.save(), memberUpdates, questLeaderUpdate]); + const [groupSaved] = await Promise.all([group.save(), memberUpdates, questLeaderUpdate]); res.respond(200, groupSaved.quest); }, @@ -482,15 +482,15 @@ api.leaveQuest = { url: '/groups/:groupId/quests/leave', middlewares: [authWithHeaders()], async handler (req, res) { - let user = res.locals.user; - let groupId = req.params.groupId; + const { user } = res.locals; + const { groupId } = req.params; req.checkParams('groupId', apiError('groupIdRequired')).notEmpty(); - let validationErrors = req.validationErrors(); + const validationErrors = req.validationErrors(); if (validationErrors) throw validationErrors; - let group = await Group.getGroup({user, groupId, fields: basicGroupFields.concat(' quest')}); + const group = await Group.getGroup({ user, groupId, fields: basicGroupFields.concat(' quest') }); if (!group) throw new NotFound(res.t('groupNotFound')); if (group.type !== 'party') throw new NotAuthorized(res.t('guildQuestsNotSupported')); @@ -504,7 +504,7 @@ api.leaveQuest = { user.party.quest = Group.cleanQuestUser(user.party.quest.progress); user.markModified('party.quest'); - let [savedGroup] = await Promise.all([ + const [savedGroup] = await Promise.all([ group.save(), user.save(), ]); diff --git a/website/server/controllers/api-v3/shops.js b/website/server/controllers/api-v3/shops.js index b4e3c6d568..f94129cb1f 100644 --- a/website/server/controllers/api-v3/shops.js +++ b/website/server/controllers/api-v3/shops.js @@ -1,9 +1,9 @@ import { authWithHeaders } from '../../middlewares/auth'; -import common from '../../../common/'; +import common from '../../../common'; -const shops = common.shops; +const { shops } = common; -let api = {}; +const api = {}; /** * @apiIgnore @@ -19,9 +19,9 @@ api.getMarketItems = { url: '/shops/market', middlewares: [authWithHeaders()], async handler (req, res) { - let user = res.locals.user; + const { user } = res.locals; - let resObject = shops.getMarketShop(user, req.language); + const resObject = shops.getMarketShop(user, req.language); res.respond(200, resObject); }, @@ -40,9 +40,9 @@ api.getMarketGear = { url: '/shops/market-gear', middlewares: [authWithHeaders()], async handler (req, res) { - let user = res.locals.user; + const { user } = res.locals; - let resObject = { + const resObject = { categories: shops.getMarketGearCategories(user, req.language), }; @@ -64,9 +64,9 @@ api.getQuestShopItems = { url: '/shops/quests', middlewares: [authWithHeaders()], async handler (req, res) { - let user = res.locals.user; + const { user } = res.locals; - let resObject = shops.getQuestShop(user, req.language); + const resObject = shops.getQuestShop(user, req.language); res.respond(200, resObject); }, @@ -86,9 +86,9 @@ api.getTimeTravelerShopItems = { url: '/shops/time-travelers', middlewares: [authWithHeaders()], async handler (req, res) { - let user = res.locals.user; + const { user } = res.locals; - let resObject = shops.getTimeTravelersShop(user, req.language); + const resObject = shops.getTimeTravelersShop(user, req.language); res.respond(200, resObject); }, @@ -108,9 +108,9 @@ api.getSeasonalShopItems = { url: '/shops/seasonal', middlewares: [authWithHeaders()], async handler (req, res) { - let user = res.locals.user; + const { user } = res.locals; - let resObject = shops.getSeasonalShop(user, req.language); + const resObject = shops.getSeasonalShop(user, req.language); res.respond(200, resObject); }, @@ -130,9 +130,9 @@ api.getBackgroundShopItems = { url: '/shops/backgrounds', middlewares: [authWithHeaders()], async handler (req, res) { - let user = res.locals.user; + const { user } = res.locals; - let resObject = { + const resObject = { identifier: 'backgroundShop', text: res.t('backgroundShop'), notes: res.t('backgroundShopText'), diff --git a/website/server/controllers/api-v3/status.js b/website/server/controllers/api-v3/status.js index ab2c764d5c..c957388d59 100644 --- a/website/server/controllers/api-v3/status.js +++ b/website/server/controllers/api-v3/status.js @@ -1,4 +1,4 @@ -let api = {}; +const api = {}; /** * @api {get} /api/v3/status Get Habitica's API status diff --git a/website/server/controllers/api-v3/tags.js b/website/server/controllers/api-v3/tags.js index 55ecc251e5..02665d2114 100644 --- a/website/server/controllers/api-v3/tags.js +++ b/website/server/controllers/api-v3/tags.js @@ -1,11 +1,11 @@ +import _ from 'lodash'; +import find from 'lodash/find'; import { authWithHeaders } from '../../middlewares/auth'; import { model as Tag } from '../../models/tag'; import * as Tasks from '../../models/task'; import { NotFound, } from '../../libs/errors'; -import _ from 'lodash'; -import find from 'lodash/find'; /** * @apiDefine TagNotFound @@ -18,7 +18,7 @@ import find from 'lodash/find'; */ -let api = {}; +const api = {}; /** * @api {post} /api/v3/tags Create a new tag @@ -40,13 +40,13 @@ api.createTag = { url: '/tags', middlewares: [authWithHeaders()], async handler (req, res) { - let user = res.locals.user; + const { user } = res.locals; user.tags.push(Tag.sanitize(req.body)); - let savedUser = await user.save(); + const savedUser = await user.save(); - let l = savedUser.tags.length; - let tag = savedUser.tags[l - 1]; + const l = savedUser.tags.length; + const tag = savedUser.tags[l - 1]; res.respond(201, tag); }, }; @@ -66,7 +66,7 @@ api.getTags = { url: '/tags', middlewares: [authWithHeaders()], async handler (req, res) { - let user = res.locals.user; + const { user } = res.locals; res.respond(200, user.tags); }, }; @@ -91,14 +91,14 @@ api.getTag = { url: '/tags/:tagId', middlewares: [authWithHeaders()], async handler (req, res) { - let user = res.locals.user; + const { user } = res.locals; req.checkParams('tagId', res.t('tagIdRequired')).notEmpty().isUUID(); - let validationErrors = req.validationErrors(); + const validationErrors = req.validationErrors(); if (validationErrors) throw validationErrors; - let tag = _.find(user.tags, {id: req.params.tagId}); + const tag = _.find(user.tags, { id: req.params.tagId }); if (!tag) throw new NotFound(res.t('tagNotFound')); res.respond(200, tag); }, @@ -128,22 +128,22 @@ api.updateTag = { url: '/tags/:tagId', middlewares: [authWithHeaders()], async handler (req, res) { - let user = res.locals.user; + const { user } = res.locals; req.checkParams('tagId', res.t('tagIdRequired')).notEmpty().isUUID(); - let tagId = req.params.tagId; + const { tagId } = req.params; - let validationErrors = req.validationErrors(); + const validationErrors = req.validationErrors(); if (validationErrors) throw validationErrors; - let tag = _.find(user.tags, {id: tagId}); + const tag = _.find(user.tags, { id: tagId }); if (!tag) throw new NotFound(res.t('tagNotFound')); _.merge(tag, Tag.sanitize(req.body)); - let savedUser = await user.save(); - res.respond(200, _.find(savedUser.tags, {id: tagId})); + const savedUser = await user.save(); + res.respond(200, _.find(savedUser.tags, { id: tagId })); }, }; @@ -170,17 +170,15 @@ api.reorderTags = { url: '/reorder-tags', middlewares: [authWithHeaders()], async handler (req, res) { - let user = res.locals.user; + const { user } = res.locals; req.checkBody('to', res.t('toRequired')).notEmpty(); req.checkBody('tagId', res.t('tagIdRequired')).notEmpty(); - let validationErrors = req.validationErrors(); + const validationErrors = req.validationErrors(); if (validationErrors) throw validationErrors; - let tagIndex = _.findIndex(user.tags, function findTag (tag) { - return tag.id === req.body.tagId; - }); + const tagIndex = _.findIndex(user.tags, tag => tag.id === req.body.tagId); if (tagIndex === -1) throw new NotFound(res.t('tagNotFound')); const removedItem = user.tags.splice(tagIndex, 1)[0]; @@ -212,16 +210,14 @@ api.deleteTag = { url: '/tags/:tagId', middlewares: [authWithHeaders()], async handler (req, res) { - let user = res.locals.user; + const { user } = res.locals; req.checkParams('tagId', res.t('tagIdRequired')).notEmpty().isUUID(); - let validationErrors = req.validationErrors(); + const validationErrors = req.validationErrors(); if (validationErrors) throw validationErrors; - let tagFound = find(user.tags, (tag) => { - return tag.id === req.params.tagId; - }); + const tagFound = find(user.tags, tag => tag.id === req.params.tagId); if (!tagFound) throw new NotFound(res.t('tagNotFound')); await user.update({ @@ -240,7 +236,7 @@ api.deleteTag = { $pull: { tags: tagFound.id, }, - }, {multi: true}).exec(); + }, { multi: true }).exec(); res.respond(200, {}); }, diff --git a/website/server/controllers/api-v3/tasks.js b/website/server/controllers/api-v3/tasks.js index 4c93c66a4b..29fbaca4e4 100644 --- a/website/server/controllers/api-v3/tasks.js +++ b/website/server/controllers/api-v3/tasks.js @@ -1,3 +1,5 @@ +import _ from 'lodash'; +import moment from 'moment'; import { authWithHeaders } from '../../middlewares/auth'; import { taskActivityWebhook, @@ -21,15 +23,13 @@ import { setNextDue, } from '../../libs/taskManager'; import common from '../../../common'; -import _ from 'lodash'; import logger from '../../libs/logger'; -import moment from 'moment'; import apiError from '../../libs/apiError'; function canNotEditTasks (group, user, assignedUserId) { - let isNotGroupLeader = group.leader !== user._id; - let isManager = Boolean(group.managers[user._id]); - let userIsAssigningToSelf = Boolean(assignedUserId && user._id === assignedUserId); + const isNotGroupLeader = group.leader !== user._id; + const isManager = Boolean(group.managers[user._id]); + const userIsAssigningToSelf = Boolean(assignedUserId && user._id === assignedUserId); return isNotGroupLeader && !isManager && !userIsAssigningToSelf; } @@ -48,8 +48,8 @@ function canNotEditTasks (group, user, assignedUserId) { * @apiError (401) {NotAuthorized} There is no account that uses those credentials. */ -let api = {}; -let requiredGroupFields = '_id leader tasksOrder name'; +const api = {}; +const requiredGroupFields = '_id leader tasksOrder name'; /** * @api {post} /api/v3/tasks/user Create a new task belonging to the user @@ -160,12 +160,12 @@ api.createUserTasks = { url: '/tasks/user', middlewares: [authWithHeaders()], async handler (req, res) { - let user = res.locals.user; - let tasks = await createTasks(req, res, {user}); + const { user } = res.locals; + const tasks = await createTasks(req, res, { user }); res.respond(201, tasks.length === 1 ? tasks[0] : tasks); - tasks.forEach((task) => { + tasks.forEach(task => { // Track when new users (first 7 days) create tasks if (moment().diff(user.auth.timestamps.created, 'days') < 7) { res.analytics.track('task create', { @@ -234,26 +234,26 @@ api.createChallengeTasks = { async handler (req, res) { req.checkParams('challengeId', res.t('challengeIdRequired')).notEmpty().isUUID(); - let reqValidationErrors = req.validationErrors(); + const reqValidationErrors = req.validationErrors(); if (reqValidationErrors) throw reqValidationErrors; - let user = res.locals.user; - let challengeId = req.params.challengeId; + const { user } = res.locals; + const { challengeId } = req.params; - let challenge = await Challenge.findOne({_id: challengeId}).exec(); + const challenge = await Challenge.findOne({ _id: challengeId }).exec(); // If the challenge does not exist, or if it exists but user is not the leader -> throw error if (!challenge) throw new NotFound(res.t('challengeNotFound')); if (!challenge.canModify(user)) throw new NotAuthorized(res.t('onlyChalLeaderEditTasks')); - let tasks = await createTasks(req, res, {user, challenge}); + const tasks = await createTasks(req, res, { user, challenge }); res.respond(201, tasks.length === 1 ? tasks[0] : tasks); // If adding tasks to a challenge -> sync users if (challenge) challenge.addTasks(tasks); - tasks.forEach((task) => { + tasks.forEach(task => { res.analytics.track('task create', { uuid: user._id, hitType: 'event', @@ -289,15 +289,15 @@ api.getUserTasks = { userFieldsToInclude: ['tasksOrder'], })], async handler (req, res) { - let types = Tasks.tasksTypes.map(type => `${type}s`); + const types = Tasks.tasksTypes.map(type => `${type}s`); types.push('completedTodos', '_allCompletedTodos'); // _allCompletedTodos is currently in BETA and is likely to be removed in future req.checkQuery('type', res.t('invalidTasksTypeExtra')).optional().isIn(types); - let validationErrors = req.validationErrors(); + const validationErrors = req.validationErrors(); if (validationErrors) throw validationErrors; - const user = res.locals.user; - const dueDate = req.query.dueDate; + const { user } = res.locals; + const { dueDate } = req.query; const tasks = await getTasks(req, res, { user, dueDate }); return res.respond(200, tasks); @@ -328,21 +328,21 @@ api.getChallengeTasks = { middlewares: [authWithHeaders()], async handler (req, res) { req.checkParams('challengeId', res.t('challengeIdRequired')).notEmpty().isUUID(); - let types = Tasks.tasksTypes.map(type => `${type}s`); + const types = Tasks.tasksTypes.map(type => `${type}s`); req.checkQuery('type', res.t('invalidTasksType')).optional().isIn(types); - let validationErrors = req.validationErrors(); + const validationErrors = req.validationErrors(); if (validationErrors) throw validationErrors; - let user = res.locals.user; - let challengeId = req.params.challengeId; + const { user } = res.locals; + const { challengeId } = req.params; - let challenge = await Challenge.findOne({ + const challenge = await Challenge.findOne({ _id: challengeId, }).select('group leader tasksOrder').exec(); if (!challenge) throw new NotFound(res.t('challengeNotFound')); - let group = await Group.getGroup({ + const group = await Group.getGroup({ user, groupId: challenge.group, fields: '_id type privacy', @@ -350,7 +350,7 @@ api.getChallengeTasks = { }); if (!group || !challenge.canView(user, group)) throw new NotFound(res.t('challengeNotFound')); - let tasks = await getTasks(req, res, {user, challenge}); + const tasks = await getTasks(req, res, { user, challenge }); return res.respond(200, tasks); }, }; @@ -377,14 +377,14 @@ api.getTask = { url: '/tasks/:taskId', middlewares: [authWithHeaders()], async handler (req, res) { - let user = res.locals.user; - let taskId = req.params.taskId; - let task = await Tasks.Task.findByIdOrAlias(taskId, user._id); + const { user } = res.locals; + const { taskId } = req.params; + const task = await Tasks.Task.findByIdOrAlias(taskId, user._id); if (!task) { throw new NotFound(res.t('taskNotFound')); } else if (task.challenge.id && !task.userId) { // If the task belongs to a challenge make sure the user has rights - let challenge = await Challenge.find({_id: task.challenge.id}).select('leader').exec(); + const challenge = await Challenge.find({ _id: task.challenge.id }).select('leader').exec(); if (!challenge || (user.challenges.indexOf(task.challenge.id) === -1 && challenge.leader !== user._id && !user.contributor.admin)) { // eslint-disable-line no-extra-parens throw new NotFound(res.t('taskNotFound')); } @@ -431,37 +431,37 @@ api.updateTask = { url: '/tasks/:taskId', middlewares: [authWithHeaders()], async handler (req, res) { - let user = res.locals.user; + const { user } = res.locals; let challenge; req.checkParams('taskId', apiError('taskIdRequired')).notEmpty(); - let validationErrors = req.validationErrors(); + const validationErrors = req.validationErrors(); if (validationErrors) throw validationErrors; - let taskId = req.params.taskId; - let task = await Tasks.Task.findByIdOrAlias(taskId, user._id); + const { taskId } = req.params; + const task = await Tasks.Task.findByIdOrAlias(taskId, user._id); let group; if (!task) { throw new NotFound(res.t('taskNotFound')); } else if (task.group.id && !task.userId) { // @TODO: Abstract this access snippet - let fields = requiredGroupFields.concat(' managers'); - group = await Group.getGroup({user, groupId: task.group.id, fields}); + const fields = requiredGroupFields.concat(' managers'); + group = await Group.getGroup({ user, groupId: task.group.id, fields }); if (!group) throw new NotFound(res.t('groupNotFound')); if (canNotEditTasks(group, user)) throw new NotAuthorized(res.t('onlyGroupLeaderCanEditTasks')); } else if (task.challenge.id && !task.userId) { // If the task belongs to a challenge make sure the user has rights - challenge = await Challenge.findOne({_id: task.challenge.id}).exec(); + challenge = await Challenge.findOne({ _id: task.challenge.id }).exec(); if (!challenge) throw new NotFound(res.t('challengeNotFound')); if (!challenge.canModify(user)) throw new NotAuthorized(res.t('onlyChalLeaderEditTasks')); } else if (task.userId !== user._id) { // If the task is owned by a user make it's the current one throw new NotFound(res.t('taskNotFound')); } - let oldCheckList = task.checklist; + const oldCheckList = task.checklist; // we have to convert task to an object because otherwise things don't get merged correctly. Bad for performances? - let [updatedTaskObj] = common.ops.updateTask(task.toObject(), req); + const [updatedTaskObj] = common.ops.updateTask(task.toObject(), req); // Sanitize differently user tasks linked to a challenge let sanitizedObj; @@ -488,18 +488,16 @@ api.updateTask = { } setNextDue(task, user); - let savedTask = await task.save(); + const savedTask = await task.save(); if (group && task.group.id && task.group.assignedUsers.length > 0) { - let updateCheckListItems = _.remove(sanitizedObj.checklist, function getCheckListsToUpdate (checklist) { - let indexOld = _.findIndex(oldCheckList, function findIndex (check) { - return check.id === checklist.id; - }); + const updateCheckListItems = _.remove(sanitizedObj.checklist, checklist => { + const indexOld = _.findIndex(oldCheckList, check => check.id === checklist.id); if (indexOld !== -1) return checklist.text !== oldCheckList[indexOld].text; return false; // Only return changes. Adding and remove are handled differently }); - await group.updateTask(savedTask, {updateCheckListItems}); + await group.updateTask(savedTask, { updateCheckListItems }); } res.respond(200, savedTask); @@ -550,11 +548,11 @@ api.scoreTask = { const validationErrors = req.validationErrors(); if (validationErrors) throw validationErrors; - const user = res.locals.user; - const {taskId} = req.params; + const { user } = res.locals; + const { taskId } = req.params; - const task = await Tasks.Task.findByIdOrAlias(taskId, user._id, {userId: user._id}); - const direction = req.params.direction; + const task = await Tasks.Task.findByIdOrAlias(taskId, user._id, { userId: user._id }); + const { direction } = req.params; if (!task) throw new NotFound(res.t('taskNotFound')); @@ -567,10 +565,10 @@ api.scoreTask = { } if (task.group.approval.required && !task.group.approval.approved) { - let fields = requiredGroupFields.concat(' managers'); - let group = await Group.getGroup({user, groupId: task.group.id, fields}); + const fields = requiredGroupFields.concat(' managers'); + const group = await Group.getGroup({ user, groupId: task.group.id, fields }); - let managerIds = Object.keys(group.managers); + const managerIds = Object.keys(group.managers); managerIds.push(group.leader); if (managerIds.indexOf(user._id) !== -1) { @@ -585,11 +583,11 @@ api.scoreTask = { task.group.approval.requested = true; task.group.approval.requestedDate = new Date(); - let managers = await User.find({_id: managerIds}, 'notifications preferences').exec(); // Use this method so we can get access to notifications + const managers = await User.find({ _id: managerIds }, 'notifications preferences').exec(); // Use this method so we can get access to notifications // @TODO: we can use the User.pushNotification function because we need to ensure notifications are translated - let managerPromises = []; - managers.forEach((manager) => { + const managerPromises = []; + managers.forEach(manager => { manager.addNotification('GROUP_TASK_APPROVAL', { message: res.t('userHasRequestedTaskApproval', { user: user.profile.name, @@ -611,11 +609,11 @@ api.scoreTask = { } } - let wasCompleted = task.completed; + const wasCompleted = task.completed; - let [delta] = common.ops.scoreTask({task, user, direction}, req); + const [delta] = common.ops.scoreTask({ task, user, direction }, req); // Drop system (don't run on the client, as it would only be discarded since ops are sent to the API, not the results) - if (direction === 'up') common.fns.randomDrop(user, {task, delta}, req, res.analytics); + if (direction === 'up') common.fns.randomDrop(user, { task, delta }, req, res.analytics); // If a todo was completed or uncompleted move it in or out of the user.tasksOrder.todos list // TODO move to common code? @@ -638,7 +636,7 @@ api.scoreTask = { setNextDue(task, user); - let promises = [ + const promises = [ user.save(), task.save(), ]; @@ -661,12 +659,12 @@ api.scoreTask = { // Save results and handle request if (taskOrderPromise) promises.push(taskOrderPromise); - let results = await Promise.all(promises); + const results = await Promise.all(promises); - let savedUser = results[0]; + const savedUser = results[0]; - let userStats = savedUser.stats.toJSON(); - let resJsonData = _.assign({delta, _tmp: user._tmp}, userStats); + const userStats = savedUser.stats.toJSON(); + const resJsonData = _.assign({ delta, _tmp: user._tmp }, userStats); res.respond(200, resJsonData); taskScoredWebhook.send(user, { @@ -729,25 +727,25 @@ api.moveTask = { req.checkParams('taskId', apiError('taskIdRequired')).notEmpty(); req.checkParams('position', res.t('positionRequired')).notEmpty().isNumeric(); - let validationErrors = req.validationErrors(); + const validationErrors = req.validationErrors(); if (validationErrors) throw validationErrors; - let user = res.locals.user; - let taskId = req.params.taskId; - let to = Number(req.params.position); + const { user } = res.locals; + const { taskId } = req.params; + const to = Number(req.params.position); - let task = await Tasks.Task.findByIdOrAlias(taskId, user._id, { userId: user._id }); + const task = await Tasks.Task.findByIdOrAlias(taskId, user._id, { userId: user._id }); if (!task) throw new NotFound(res.t('taskNotFound')); if (task.type === 'todo' && task.completed) throw new BadRequest(res.t('cantMoveCompletedTodo')); // In memory updates - let order = user.tasksOrder[`${task.type}s`]; + const order = user.tasksOrder[`${task.type}s`]; moveTask(order, task._id, to); // Server updates // Cannot send $pull and $push on same field in one single op - let pullQuery = { $pull: {} }; + const pullQuery = { $pull: {} }; pullQuery.$pull[`tasksOrder.${task.type}s`] = task.id; await user.update(pullQuery).exec(); @@ -755,7 +753,7 @@ api.moveTask = { let position = to; if (to === -1) position = [`tasksOrder.${task.type}s`].length - 1; - let updateQuery = { $push: {} }; + const updateQuery = { $push: {} }; updateQuery.$push[`tasksOrder.${task.type}s`] = { $each: [task._id], $position: position, @@ -795,26 +793,26 @@ api.addChecklistItem = { url: '/tasks/:taskId/checklist', middlewares: [authWithHeaders()], async handler (req, res) { - let user = res.locals.user; + const { user } = res.locals; let challenge; let group; req.checkParams('taskId', apiError('taskIdRequired')).notEmpty(); - let validationErrors = req.validationErrors(); + const validationErrors = req.validationErrors(); if (validationErrors) throw validationErrors; - let taskId = req.params.taskId; - let task = await Tasks.Task.findByIdOrAlias(taskId, user._id); + const { taskId } = req.params; + const task = await Tasks.Task.findByIdOrAlias(taskId, user._id); if (!task) { throw new NotFound(res.t('taskNotFound')); } else if (task.group.id && !task.userId) { - let fields = requiredGroupFields.concat(' managers'); - group = await Group.getGroup({user, groupId: task.group.id, fields}); + const fields = requiredGroupFields.concat(' managers'); + group = await Group.getGroup({ user, groupId: task.group.id, fields }); if (canNotEditTasks(group, user)) throw new NotAuthorized(res.t('onlyGroupLeaderCanEditTasks')); } else if (task.challenge.id && !task.userId) { // If the task belongs to a challenge make sure the user has rights - challenge = await Challenge.findOne({_id: task.challenge.id}).exec(); + challenge = await Challenge.findOne({ _id: task.challenge.id }).exec(); if (!challenge) throw new NotFound(res.t('challengeNotFound')); if (!challenge.canModify(user)) throw new NotAuthorized(res.t('onlyChalLeaderEditTasks')); } else if (task.userId !== user._id) { // If the task is owned by a user make it's the current one @@ -823,16 +821,16 @@ api.addChecklistItem = { if (task.type !== 'daily' && task.type !== 'todo') throw new BadRequest(res.t('checklistOnlyDailyTodo')); - let newCheckListItem = Tasks.Task.sanitizeChecklist(req.body); + const newCheckListItem = Tasks.Task.sanitizeChecklist(req.body); task.checklist.push(newCheckListItem); - let savedTask = await task.save(); + const savedTask = await task.save(); newCheckListItem.id = savedTask.checklist[savedTask.checklist.length - 1].id; res.respond(200, savedTask); if (challenge) challenge.updateTask(savedTask); if (group && task.group.id && task.group.assignedUsers.length > 0) { - await group.updateTask(savedTask, {newCheckListItem}); + await group.updateTask(savedTask, { newCheckListItem }); } }, }; @@ -855,25 +853,25 @@ api.scoreCheckListItem = { url: '/tasks/:taskId/checklist/:itemId/score', middlewares: [authWithHeaders()], async handler (req, res) { - let user = res.locals.user; + const { user } = res.locals; req.checkParams('taskId', apiError('taskIdRequired')).notEmpty(); req.checkParams('itemId', res.t('itemIdRequired')).notEmpty().isUUID(); - let validationErrors = req.validationErrors(); + const validationErrors = req.validationErrors(); if (validationErrors) throw validationErrors; - let taskId = req.params.taskId; - let task = await Tasks.Task.findByIdOrAlias(taskId, user._id, { userId: user._id }); + const { taskId } = req.params; + const task = await Tasks.Task.findByIdOrAlias(taskId, user._id, { userId: user._id }); if (!task) throw new NotFound(res.t('taskNotFound')); if (task.type !== 'daily' && task.type !== 'todo') throw new BadRequest(res.t('checklistOnlyDailyTodo')); - let item = _.find(task.checklist, {id: req.params.itemId}); + const item = _.find(task.checklist, { id: req.params.itemId }); if (!item) throw new NotFound(res.t('checklistItemNotFound')); item.completed = !item.completed; - let savedTask = await task.save(); + const savedTask = await task.save(); res.respond(200, savedTask); @@ -909,28 +907,28 @@ api.updateChecklistItem = { url: '/tasks/:taskId/checklist/:itemId', middlewares: [authWithHeaders()], async handler (req, res) { - let user = res.locals.user; + const { user } = res.locals; let challenge; let group; req.checkParams('taskId', apiError('taskIdRequired')).notEmpty(); req.checkParams('itemId', res.t('itemIdRequired')).notEmpty().isUUID(); - let validationErrors = req.validationErrors(); + const validationErrors = req.validationErrors(); if (validationErrors) throw validationErrors; - let taskId = req.params.taskId; - let task = await Tasks.Task.findByIdOrAlias(taskId, user._id); + const { taskId } = req.params; + const task = await Tasks.Task.findByIdOrAlias(taskId, user._id); if (!task) { throw new NotFound(res.t('taskNotFound')); } else if (task.group.id && !task.userId) { - let fields = requiredGroupFields.concat(' managers'); - group = await Group.getGroup({user, groupId: task.group.id, fields}); + const fields = requiredGroupFields.concat(' managers'); + group = await Group.getGroup({ user, groupId: task.group.id, fields }); if (!group) throw new NotFound(res.t('groupNotFound')); if (canNotEditTasks(group, user)) throw new NotAuthorized(res.t('onlyGroupLeaderCanEditTasks')); } else if (task.challenge.id && !task.userId) { // If the task belongs to a challenge make sure the user has rights - challenge = await Challenge.findOne({_id: task.challenge.id}).exec(); + challenge = await Challenge.findOne({ _id: task.challenge.id }).exec(); if (!challenge) throw new NotFound(res.t('challengeNotFound')); if (!challenge.canModify(user)) throw new NotAuthorized(res.t('onlyChalLeaderEditTasks')); } else if (task.userId !== user._id) { // If the task is owned by a user make it's the current one @@ -938,11 +936,11 @@ api.updateChecklistItem = { } if (task.type !== 'daily' && task.type !== 'todo') throw new BadRequest(res.t('checklistOnlyDailyTodo')); - let item = _.find(task.checklist, {id: req.params.itemId}); + const item = _.find(task.checklist, { id: req.params.itemId }); if (!item) throw new NotFound(res.t('checklistItemNotFound')); _.merge(item, Tasks.Task.sanitizeChecklist(req.body)); - let savedTask = await task.save(); + const savedTask = await task.save(); res.respond(200, savedTask); if (challenge) challenge.updateTask(savedTask); @@ -974,28 +972,28 @@ api.removeChecklistItem = { url: '/tasks/:taskId/checklist/:itemId', middlewares: [authWithHeaders()], async handler (req, res) { - let user = res.locals.user; + const { user } = res.locals; let challenge; let group; req.checkParams('taskId', apiError('taskIdRequired')).notEmpty(); req.checkParams('itemId', res.t('itemIdRequired')).notEmpty().isUUID(); - let validationErrors = req.validationErrors(); + const validationErrors = req.validationErrors(); if (validationErrors) throw validationErrors; - let taskId = req.params.taskId; - let task = await Tasks.Task.findByIdOrAlias(taskId, user._id); + const { taskId } = req.params; + const task = await Tasks.Task.findByIdOrAlias(taskId, user._id); if (!task) { throw new NotFound(res.t('taskNotFound')); } else if (task.group.id && !task.userId) { - let fields = requiredGroupFields.concat(' managers'); - group = await Group.getGroup({user, groupId: task.group.id, fields}); + const fields = requiredGroupFields.concat(' managers'); + group = await Group.getGroup({ user, groupId: task.group.id, fields }); if (!group) throw new NotFound(res.t('groupNotFound')); if (canNotEditTasks(group, user)) throw new NotAuthorized(res.t('onlyGroupLeaderCanEditTasks')); } else if (task.challenge.id && !task.userId) { // If the task belongs to a challenge make sure the user has rights - challenge = await Challenge.findOne({_id: task.challenge.id}).exec(); + challenge = await Challenge.findOne({ _id: task.challenge.id }).exec(); if (!challenge) throw new NotFound(res.t('challengeNotFound')); if (!challenge.canModify(user)) throw new NotAuthorized(res.t('onlyChalLeaderEditTasks')); } else if (task.userId !== user._id) { // If the task is owned by a user make it's the current one @@ -1003,14 +1001,14 @@ api.removeChecklistItem = { } if (task.type !== 'daily' && task.type !== 'todo') throw new BadRequest(res.t('checklistOnlyDailyTodo')); - let hasItem = removeFromArray(task.checklist, { id: req.params.itemId }); + const hasItem = removeFromArray(task.checklist, { id: req.params.itemId }); if (!hasItem) throw new NotFound(res.t('checklistItemNotFound')); - let savedTask = await task.save(); + const savedTask = await task.save(); res.respond(200, savedTask); if (challenge) challenge.updateTask(savedTask); if (group && task.group.id && task.group.assignedUsers.length > 0) { - await group.updateTask(savedTask, {removedCheckListItemId: req.params.itemId}); + await group.updateTask(savedTask, { removedCheckListItemId: req.params.itemId }); } }, }; @@ -1037,27 +1035,27 @@ api.addTagToTask = { url: '/tasks/:taskId/tags/:tagId', middlewares: [authWithHeaders()], async handler (req, res) { - let user = res.locals.user; + const { user } = res.locals; req.checkParams('taskId', apiError('taskIdRequired')).notEmpty(); - let userTags = user.tags.map(tag => tag.id); + const userTags = user.tags.map(tag => tag.id); req.checkParams('tagId', res.t('tagIdRequired')).notEmpty().isUUID().isIn(userTags); - let validationErrors = req.validationErrors(); + const validationErrors = req.validationErrors(); if (validationErrors) throw validationErrors; - let taskId = req.params.taskId; - let task = await Tasks.Task.findByIdOrAlias(taskId, user._id, { userId: user._id }); + const { taskId } = req.params; + const task = await Tasks.Task.findByIdOrAlias(taskId, user._id, { userId: user._id }); if (!task) throw new NotFound(res.t('taskNotFound')); - let tagId = req.params.tagId; + const { tagId } = req.params; - let alreadyTagged = task.tags.indexOf(tagId) !== -1; + const alreadyTagged = task.tags.indexOf(tagId) !== -1; if (alreadyTagged) throw new BadRequest(res.t('alreadyTagged')); task.tags.push(tagId); - let savedTask = await task.save(); + const savedTask = await task.save(); res.respond(200, savedTask); }, }; @@ -1086,23 +1084,23 @@ api.removeTagFromTask = { url: '/tasks/:taskId/tags/:tagId', middlewares: [authWithHeaders()], async handler (req, res) { - let user = res.locals.user; + const { user } = res.locals; req.checkParams('taskId', apiError('taskIdRequired')).notEmpty(); req.checkParams('tagId', res.t('tagIdRequired')).notEmpty().isUUID(); - let validationErrors = req.validationErrors(); + const validationErrors = req.validationErrors(); if (validationErrors) throw validationErrors; - let taskId = req.params.taskId; - let task = await Tasks.Task.findByIdOrAlias(taskId, user._id, { userId: user._id }); + const { taskId } = req.params; + const task = await Tasks.Task.findByIdOrAlias(taskId, user._id, { userId: user._id }); if (!task) throw new NotFound(res.t('taskNotFound')); - let hasTag = removeFromArray(task.tags, req.params.tagId); + const hasTag = removeFromArray(task.tags, req.params.tagId); if (!hasTag) throw new NotFound(res.t('tagNotFound')); - let savedTask = await task.save(); + const savedTask = await task.save(); res.respond(200, savedTask); }, }; @@ -1134,21 +1132,19 @@ api.unlinkAllTasks = { req.checkParams('challengeId', res.t('challengeIdRequired')).notEmpty().isUUID(); req.checkQuery('keep', apiError('keepOrRemoveAll')).notEmpty().isIn(['keep-all', 'remove-all']); - let validationErrors = req.validationErrors(); + const validationErrors = req.validationErrors(); if (validationErrors) throw validationErrors; - let user = res.locals.user; - let keep = req.query.keep; - let challengeId = req.params.challengeId; + const { user } = res.locals; + const { keep } = req.query; + const { challengeId } = req.params; - let tasks = await Tasks.Task.find({ + const tasks = await Tasks.Task.find({ 'challenge.id': challengeId, userId: user._id, }).exec(); - let validTasks = tasks.every(task => { - return task.challenge.broken; - }); + const validTasks = tasks.every(task => task.challenge.broken); if (!validTasks) throw new BadRequest(res.t('cantOnlyUnlinkChalTask')); @@ -1158,7 +1154,7 @@ api.unlinkAllTasks = { return task.save(); })); } else { // remove - let toSave = []; + const toSave = []; tasks.forEach(task => { if (task.type !== 'todo' || !task.completed) { // eslint-disable-line no-lonely-if @@ -1201,14 +1197,14 @@ api.unlinkOneTask = { req.checkParams('taskId', apiError('taskIdRequired')).notEmpty().isUUID(); req.checkQuery('keep', apiError('keepOrRemove')).notEmpty().isIn(['keep', 'remove']); - let validationErrors = req.validationErrors(); + const validationErrors = req.validationErrors(); if (validationErrors) throw validationErrors; - let user = res.locals.user; - let keep = req.query.keep; - let taskId = req.params.taskId; + const { user } = res.locals; + const { keep } = req.query; + const { taskId } = req.params; - let task = await Tasks.Task.findByIdOrAlias(taskId, user._id, { userId: user._id }); + const task = await Tasks.Task.findByIdOrAlias(taskId, user._id, { userId: user._id }); if (!task) throw new NotFound(res.t('taskNotFound')); if (!task.challenge.id) throw new BadRequest(res.t('cantOnlyUnlinkChalTask')); @@ -1248,7 +1244,7 @@ api.clearCompletedTodos = { url: '/tasks/clearCompletedTodos', middlewares: [authWithHeaders()], async handler (req, res) { - let user = res.locals.user; + const { user } = res.locals; // Clear completed todos // Do not delete completed todos from challenges or groups, unless the task is broken @@ -1259,14 +1255,14 @@ api.clearCompletedTodos = { $and: [ // exclude challenge and group tasks { $or: [ - {'challenge.id': {$exists: false}}, - {'challenge.broken': {$exists: true}}, + { 'challenge.id': { $exists: false } }, + { 'challenge.broken': { $exists: true } }, ], }, { $or: [ - {'group.id': {$exists: false}}, - {'group.broken': {$exists: true}}, + { 'group.id': { $exists: false } }, + { 'group.broken': { $exists: true } }, ], }, ], @@ -1299,23 +1295,23 @@ api.deleteTask = { url: '/tasks/:taskId', middlewares: [authWithHeaders()], async handler (req, res) { - let user = res.locals.user; + const { user } = res.locals; let challenge; - let taskId = req.params.taskId; - let task = await Tasks.Task.findByIdOrAlias(taskId, user._id); + const { taskId } = req.params; + const task = await Tasks.Task.findByIdOrAlias(taskId, user._id); if (!task) { throw new NotFound(res.t('taskNotFound')); } else if (task.group.id && !task.userId) { // @TODO: Abstract this access snippet - let fields = requiredGroupFields.concat(' managers'); - let group = await Group.getGroup({user, groupId: task.group.id, fields}); + const fields = requiredGroupFields.concat(' managers'); + const group = await Group.getGroup({ user, groupId: task.group.id, fields }); if (!group) throw new NotFound(res.t('groupNotFound')); if (canNotEditTasks(group, user)) throw new NotAuthorized(res.t('onlyGroupLeaderCanEditTasks')); await group.removeTask(task); } else if (task.challenge.id && !task.userId) { // If the task belongs to a challenge make sure the user has rights - challenge = await Challenge.findOne({_id: task.challenge.id}).exec(); + challenge = await Challenge.findOne({ _id: task.challenge.id }).exec(); if (!challenge) throw new NotFound(res.t('challengeNotFound')); if (!challenge.canModify(user)) throw new NotAuthorized(res.t('onlyChalLeaderEditTasks')); } else if (task.userId !== user._id) { // If the task is owned by a user make it's the current one @@ -1329,9 +1325,9 @@ api.deleteTask = { if (task.type !== 'todo' || !task.completed) { removeFromArray((challenge || user).tasksOrder[`${task.type}s`], taskId); - let pullQuery = {$pull: {}}; + const pullQuery = { $pull: {} }; pullQuery.$pull[`tasksOrder.${task.type}s`] = task._id; - let taskOrderUpdate = (challenge || user).update(pullQuery).exec(); + const taskOrderUpdate = (challenge || user).update(pullQuery).exec(); // Update the user version field manually, // it cannot be updated in the pre update hook diff --git a/website/server/controllers/api-v3/tasks/groups.js b/website/server/controllers/api-v3/tasks/groups.js index 2317b4b4ff..9b76855ba0 100644 --- a/website/server/controllers/api-v3/tasks/groups.js +++ b/website/server/controllers/api-v3/tasks/groups.js @@ -15,19 +15,19 @@ import { import { handleSharedCompletion } from '../../../libs/groupTasks'; import apiError from '../../../libs/apiError'; -let requiredGroupFields = '_id leader tasksOrder name'; +const requiredGroupFields = '_id leader tasksOrder name'; // @TODO: abstract to task lib -let types = Tasks.tasksTypes.map(type => `${type}s`); +const types = Tasks.tasksTypes.map(type => `${type}s`); types.push('completedTodos', '_allCompletedTodos'); // _allCompletedTodos is currently in BETA and is likely to be removed in future function canNotEditTasks (group, user, assignedUserId) { - let isNotGroupLeader = group.leader !== user._id; - let isManager = Boolean(group.managers[user._id]); - let userIsAssigningToSelf = Boolean(assignedUserId && user._id === assignedUserId); + const isNotGroupLeader = group.leader !== user._id; + const isManager = Boolean(group.managers[user._id]); + const userIsAssigningToSelf = Boolean(assignedUserId && user._id === assignedUserId); return isNotGroupLeader && !isManager && !userIsAssigningToSelf; } -let api = {}; +const api = {}; /** * @api {post} /api/v3/tasks/group/:groupId Create a new task belonging to a group @@ -46,22 +46,22 @@ api.createGroupTasks = { async handler (req, res) { req.checkParams('groupId', apiError('groupIdRequired')).notEmpty().isUUID(); - let reqValidationErrors = req.validationErrors(); + const reqValidationErrors = req.validationErrors(); if (reqValidationErrors) throw reqValidationErrors; - let user = res.locals.user; + const { user } = res.locals; - let fields = requiredGroupFields.concat(' managers'); - let group = await Group.getGroup({user, groupId: req.params.groupId, fields}); + const fields = requiredGroupFields.concat(' managers'); + const group = await Group.getGroup({ user, groupId: req.params.groupId, fields }); if (!group) throw new NotFound(res.t('groupNotFound')); if (canNotEditTasks(group, user)) throw new NotAuthorized(res.t('onlyGroupLeaderCanEditTasks')); - let tasks = await createTasks(req, res, {user, group}); + const tasks = await createTasks(req, res, { user, group }); res.respond(201, tasks.length === 1 ? tasks[0] : tasks); - tasks.forEach((task) => { + tasks.forEach(task => { res.analytics.track('task create', { uuid: user._id, hitType: 'event', @@ -91,15 +91,15 @@ api.getGroupTasks = { req.checkParams('groupId', apiError('groupIdRequired')).notEmpty().isUUID(); req.checkQuery('type', res.t('invalidTasksType')).optional().isIn(types); - let validationErrors = req.validationErrors(); + const validationErrors = req.validationErrors(); if (validationErrors) throw validationErrors; - let user = res.locals.user; + const { user } = res.locals; - let group = await Group.getGroup({user, groupId: req.params.groupId, fields: requiredGroupFields}); + const group = await Group.getGroup({ user, groupId: req.params.groupId, fields: requiredGroupFields }); if (!group) throw new NotFound(res.t('groupNotFound')); - let tasks = await getTasks(req, res, {user, group}); + const tasks = await getTasks(req, res, { user, group }); res.respond(200, tasks); }, }; @@ -124,17 +124,17 @@ api.groupMoveTask = { req.checkParams('taskId', apiError('taskIdRequired')).notEmpty(); req.checkParams('position', res.t('positionRequired')).notEmpty().isNumeric(); - let reqValidationErrors = req.validationErrors(); + const reqValidationErrors = req.validationErrors(); if (reqValidationErrors) throw reqValidationErrors; - let user = res.locals.user; + const { user } = res.locals; - let taskId = req.params.taskId; - let task = await Tasks.Task.findOne({ + const { taskId } = req.params; + const task = await Tasks.Task.findOne({ _id: taskId, }).exec(); - let to = Number(req.params.position); + const to = Number(req.params.position); if (!task) { throw new NotFound(res.t('taskNotFound')); @@ -142,12 +142,12 @@ api.groupMoveTask = { if (task.type === 'todo' && task.completed) throw new BadRequest(res.t('cantMoveCompletedTodo')); - let group = await Group.getGroup({user, groupId: task.group.id, fields: requiredGroupFields}); + const group = await Group.getGroup({ user, groupId: task.group.id, fields: requiredGroupFields }); if (!group) throw new NotFound(res.t('groupNotFound')); if (group.leader !== user._id) throw new NotAuthorized(res.t('onlyGroupLeaderCanEditTasks')); - let order = group.tasksOrder[`${task.type}s`]; + const order = group.tasksOrder[`${task.type}s`]; moveTask(order, task._id, to); @@ -175,15 +175,15 @@ api.assignTask = { req.checkParams('taskId', apiError('taskIdRequired')).notEmpty().isUUID(); req.checkParams('assignedUserId', res.t('userIdRequired')).notEmpty().isUUID(); - let reqValidationErrors = req.validationErrors(); + const reqValidationErrors = req.validationErrors(); if (reqValidationErrors) throw reqValidationErrors; - let user = res.locals.user; - let assignedUserId = req.params.assignedUserId; - let assignedUser = await User.findById(assignedUserId).exec(); + const { user } = res.locals; + const { assignedUserId } = req.params; + const assignedUser = await User.findById(assignedUserId).exec(); - let taskId = req.params.taskId; - let task = await Tasks.Task.findByIdOrAlias(taskId, user._id); + const { taskId } = req.params; + const task = await Tasks.Task.findByIdOrAlias(taskId, user._id); if (!task) { throw new NotFound(res.t('taskNotFound')); @@ -193,24 +193,24 @@ api.assignTask = { throw new NotAuthorized(res.t('onlyGroupTasksCanBeAssigned')); } - let groupFields = `${requiredGroupFields} chat managers`; - let group = await Group.getGroup({user, groupId: task.group.id, fields: groupFields}); + const groupFields = `${requiredGroupFields} chat managers`; + const group = await Group.getGroup({ user, groupId: task.group.id, fields: groupFields }); if (!group) throw new NotFound(res.t('groupNotFound')); if (canNotEditTasks(group, user, assignedUserId)) throw new NotAuthorized(res.t('onlyGroupLeaderCanEditTasks')); - let promises = []; + const promises = []; const taskText = task.text; const userName = user.profile.name; if (user._id === assignedUserId) { const managerIds = Object.keys(group.managers); managerIds.push(group.leader); - const managers = await User.find({_id: managerIds}, 'notifications preferences').exec(); - managers.forEach((manager) => { + const managers = await User.find({ _id: managerIds }, 'notifications preferences').exec(); + managers.forEach(manager => { if (manager._id === user._id) return; manager.addNotification('GROUP_TASK_CLAIMED', { - message: res.t('taskClaimed', {userName, taskText}, manager.preferences.language), + message: res.t('taskClaimed', { userName, taskText }, manager.preferences.language), groupId: group._id, taskId: task._id, }); @@ -218,7 +218,7 @@ api.assignTask = { }); } else { assignedUser.addNotification('GROUP_TASK_ASSIGNED', { - message: res.t('youHaveBeenAssignedTask', {managerName: userName, taskText}), + message: res.t('youHaveBeenAssignedTask', { managerName: userName, taskText }), taskId: task._id, }); } @@ -250,15 +250,15 @@ api.unassignTask = { req.checkParams('taskId', apiError('taskIdRequired')).notEmpty().isUUID(); req.checkParams('assignedUserId', res.t('userIdRequired')).notEmpty().isUUID(); - let reqValidationErrors = req.validationErrors(); + const reqValidationErrors = req.validationErrors(); if (reqValidationErrors) throw reqValidationErrors; - let user = res.locals.user; - let assignedUserId = req.params.assignedUserId; - let assignedUser = await User.findById(assignedUserId).exec(); + const { user } = res.locals; + const { assignedUserId } = req.params; + const assignedUser = await User.findById(assignedUserId).exec(); - let taskId = req.params.taskId; - let task = await Tasks.Task.findByIdOrAlias(taskId, user._id); + const { taskId } = req.params; + const task = await Tasks.Task.findByIdOrAlias(taskId, user._id); if (!task) { throw new NotFound(res.t('taskNotFound')); @@ -268,17 +268,15 @@ api.unassignTask = { throw new NotAuthorized(res.t('onlyGroupTasksCanBeAssigned')); } - let fields = requiredGroupFields.concat(' managers'); - let group = await Group.getGroup({user, groupId: task.group.id, fields}); + const fields = requiredGroupFields.concat(' managers'); + const group = await Group.getGroup({ user, groupId: task.group.id, fields }); if (!group) throw new NotFound(res.t('groupNotFound')); if (canNotEditTasks(group, user, assignedUserId)) throw new NotAuthorized(res.t('onlyGroupLeaderCanEditTasks')); await group.unlinkTask(task, assignedUser); - let notificationIndex = assignedUser.notifications.findIndex(function findNotification (notification) { - return notification && notification.data && notification.type === 'GROUP_TASK_ASSIGNED' && notification.data.taskId === task._id; - }); + const notificationIndex = assignedUser.notifications.findIndex(notification => notification && notification.data && notification.type === 'GROUP_TASK_ASSIGNED' && notification.data.taskId === task._id); if (notificationIndex !== -1) { assignedUser.notifications.splice(notificationIndex, 1); @@ -309,15 +307,15 @@ api.approveTask = { req.checkParams('taskId', apiError('taskIdRequired')).notEmpty().isUUID(); req.checkParams('userId', res.t('userIdRequired')).notEmpty().isUUID(); - let reqValidationErrors = req.validationErrors(); + const reqValidationErrors = req.validationErrors(); if (reqValidationErrors) throw reqValidationErrors; - let user = res.locals.user; - let assignedUserId = req.params.userId; - let assignedUser = await User.findById(assignedUserId).exec(); + const { user } = res.locals; + const assignedUserId = req.params.userId; + const assignedUser = await User.findById(assignedUserId).exec(); - let taskId = req.params.taskId; - let task = await Tasks.Task.findOne({ + const { taskId } = req.params; + const task = await Tasks.Task.findOne({ 'group.taskId': taskId, userId: assignedUserId, }).exec(); @@ -326,8 +324,8 @@ api.approveTask = { throw new NotFound(res.t('taskNotFound')); } - let fields = requiredGroupFields.concat(' managers'); - let group = await Group.getGroup({user, groupId: task.group.id, fields}); + const fields = requiredGroupFields.concat(' managers'); + const group = await Group.getGroup({ user, groupId: task.group.id, fields }); if (!group) throw new NotFound(res.t('groupNotFound')); if (canNotEditTasks(group, user)) throw new NotAuthorized(res.t('onlyGroupLeaderCanEditTasks')); @@ -343,24 +341,20 @@ api.approveTask = { // Get Managers const managerIds = Object.keys(group.managers); managerIds.push(group.leader); - const managers = await User.find({_id: managerIds}, 'notifications').exec(); // Use this method so we can get access to notifications + const managers = await User.find({ _id: managerIds }, 'notifications').exec(); // Use this method so we can get access to notifications // Get task direction const firstManagerNotifications = managers[0].notifications; - const firstNotificationIndex = firstManagerNotifications.findIndex((notification) => { - return notification && notification.data && notification.data.taskId === task._id && notification.type === 'GROUP_TASK_APPROVAL'; - }); + const firstNotificationIndex = firstManagerNotifications.findIndex(notification => notification && notification.data && notification.data.taskId === task._id && notification.type === 'GROUP_TASK_APPROVAL'); let direction = 'up'; if (firstManagerNotifications[firstNotificationIndex]) { direction = firstManagerNotifications[firstNotificationIndex].direction; } // Remove old notifications - let approvalPromises = []; - managers.forEach((manager) => { - let notificationIndex = manager.notifications.findIndex(function findNotification (notification) { - return notification && notification.data && notification.data.taskId === task._id && notification.type === 'GROUP_TASK_APPROVAL'; - }); + const approvalPromises = []; + managers.forEach(manager => { + const notificationIndex = manager.notifications.findIndex(notification => notification && notification.data && notification.data.taskId === task._id && notification.type === 'GROUP_TASK_APPROVAL'); if (notificationIndex !== -1) { manager.notifications.splice(notificationIndex, 1); @@ -370,12 +364,12 @@ api.approveTask = { // Add new notifications to user assignedUser.addNotification('GROUP_TASK_APPROVED', { - message: res.t('yourTaskHasBeenApproved', {taskText: task.text}), + message: res.t('yourTaskHasBeenApproved', { taskText: task.text }), groupId: group._id, }); assignedUser.addNotification('SCORED_TASK', { - message: res.t('yourTaskHasBeenApproved', {taskText: task.text}), + message: res.t('yourTaskHasBeenApproved', { taskText: task.text }), scoreTask: task, direction, }); @@ -410,13 +404,13 @@ api.taskNeedsWork = { req.checkParams('taskId', apiError('taskIdRequired')).notEmpty().isUUID(); req.checkParams('userId', res.t('userIdRequired')).notEmpty().isUUID(); - let reqValidationErrors = req.validationErrors(); + const reqValidationErrors = req.validationErrors(); if (reqValidationErrors) throw reqValidationErrors; - let user = res.locals.user; + const { user } = res.locals; - let assignedUserId = req.params.userId; - let taskId = req.params.taskId; + const assignedUserId = req.params.userId; + const { taskId } = req.params; const [assignedUser, task] = await Promise.all([ User.findById(assignedUserId).exec(), @@ -430,8 +424,8 @@ api.taskNeedsWork = { throw new NotFound(res.t('taskNotFound')); } - let fields = requiredGroupFields.concat(' managers'); - let group = await Group.getGroup({user, groupId: task.group.id, fields}); + const fields = requiredGroupFields.concat(' managers'); + const group = await Group.getGroup({ user, groupId: task.group.id, fields }); if (!group) throw new NotFound(res.t('groupNotFound')); if (canNotEditTasks(group, user)) throw new NotAuthorized(res.t('onlyGroupLeaderCanEditTasks')); @@ -443,15 +437,13 @@ api.taskNeedsWork = { // Get Managers const managerIds = Object.keys(group.managers); managerIds.push(group.leader); - const managers = await User.find({_id: managerIds}, 'notifications').exec(); // Use this method so we can get access to notifications + const managers = await User.find({ _id: managerIds }, 'notifications').exec(); // Use this method so we can get access to notifications const promises = []; // Remove old notifications - managers.forEach((manager) => { - let notificationIndex = manager.notifications.findIndex(function findNotification (notification) { - return notification && notification.data && notification.data.taskId === task._id && notification.type === 'GROUP_TASK_APPROVAL'; - }); + managers.forEach(manager => { + const notificationIndex = manager.notifications.findIndex(notification => notification && notification.data && notification.data.taskId === task._id && notification.type === 'GROUP_TASK_APPROVAL'); if (notificationIndex !== -1) { manager.notifications.splice(notificationIndex, 1); @@ -465,7 +457,7 @@ api.taskNeedsWork = { const taskText = task.text; const managerName = user.profile.name; - const message = res.t('taskNeedsWork', {taskText, managerName}, assignedUser.preferences.language); + const message = res.t('taskNeedsWork', { taskText, managerName }, assignedUser.preferences.language); assignedUser.addNotification('GROUP_TASK_NEEDS_WORK', { message, @@ -506,14 +498,14 @@ api.getGroupApprovals = { async handler (req, res) { req.checkParams('groupId', apiError('groupIdRequired')).notEmpty().isUUID(); - let validationErrors = req.validationErrors(); + const validationErrors = req.validationErrors(); if (validationErrors) throw validationErrors; - let user = res.locals.user; - let groupId = req.params.groupId; + const { user } = res.locals; + const { groupId } = req.params; - let fields = requiredGroupFields.concat(' managers'); - let group = await Group.getGroup({user, groupId, fields}); + const fields = requiredGroupFields.concat(' managers'); + const group = await Group.getGroup({ user, groupId, fields }); if (!group) throw new NotFound(res.t('groupNotFound')); let approvals; diff --git a/website/server/controllers/api-v3/user.js b/website/server/controllers/api-v3/user.js index 9277df007f..c2c2dae156 100644 --- a/website/server/controllers/api-v3/user.js +++ b/website/server/controllers/api-v3/user.js @@ -1,3 +1,6 @@ +import _ from 'lodash'; +import nconf from 'nconf'; +import get from 'lodash/get'; import { authWithHeaders } from '../../middlewares/auth'; import common from '../../../common'; import { @@ -9,7 +12,6 @@ import { model as Group, } from '../../models/group'; import * as Tasks from '../../models/task'; -import _ from 'lodash'; import * as passwordUtils from '../../libs/password'; import { userActivityWebhook, @@ -20,8 +22,6 @@ import { } from '../../libs/email'; import * as inboxLib from '../../libs/inbox'; import * as userLib from '../../libs/user'; -import nconf from 'nconf'; -import get from 'lodash/get'; const TECH_ASSISTANCE_EMAIL = nconf.get('EMAILS_TECH_ASSISTANCE_EMAIL'); const DELETE_CONFIRMATION = 'DELETE'; @@ -31,7 +31,7 @@ const DELETE_CONFIRMATION = 'DELETE'; * @apiError (404) {NotFound} UserNotFound The specified user could not be found. */ -let api = {}; +const api = {}; /* NOTE this route has also an API v4 version */ @@ -118,7 +118,7 @@ api.getBuyList = { middlewares: [authWithHeaders()], url: '/user/inventory/buy', async handler (req, res) { - let list = _.cloneDeep(common.updateStore(res.locals.user)); + const list = _.cloneDeep(common.updateStore(res.locals.user)); // return text and notes strings _.each(list, item => { @@ -161,7 +161,7 @@ api.getInAppRewardsList = { middlewares: [authWithHeaders()], url: '/user/in-app-rewards', async handler (req, res) { - let list = common.inAppRewards(res.locals.user); + const list = common.inAppRewards(res.locals.user); // return text and notes strings _.each(list, item => { @@ -252,34 +252,32 @@ api.deleteUser = { middlewares: [authWithHeaders()], url: '/user', async handler (req, res) { - let user = res.locals.user; - let plan = user.purchased.plan; + const { user } = res.locals; + const { plan } = user.purchased; - let password = req.body.password; + const { password } = req.body; if (!password) throw new BadRequest(res.t('missingPassword')); if (user.auth.local.hashed_password && user.auth.local.email) { - let isValidPassword = await passwordUtils.compare(user, password); + const isValidPassword = await passwordUtils.compare(user, password); if (!isValidPassword) throw new NotAuthorized(res.t('wrongPassword')); } else if ((user.auth.facebook.id || user.auth.google.id) && password !== DELETE_CONFIRMATION) { - throw new NotAuthorized(res.t('incorrectDeletePhrase', {magicWord: 'DELETE'})); + throw new NotAuthorized(res.t('incorrectDeletePhrase', { magicWord: 'DELETE' })); } - let feedback = req.body.feedback; + const { feedback } = req.body; if (feedback && feedback.length > 10000) throw new BadRequest(`Account deletion feedback is limited to 10,000 characters. For lengthy feedback, email ${TECH_ASSISTANCE_EMAIL}.`); if (plan && plan.customerId && !plan.dateTerminated) { throw new NotAuthorized(res.t('cannotDeleteActiveAccount')); } - let types = ['party', 'guilds']; - let groupFields = basicGroupFields.concat(' leader memberCount purchased'); + const types = ['party', 'guilds']; + const groupFields = basicGroupFields.concat(' leader memberCount purchased'); - let groupsUserIsMemberOf = await Group.getGroups({user, types, groupFields}); + const groupsUserIsMemberOf = await Group.getGroups({ user, types, groupFields }); - let groupLeavePromises = groupsUserIsMemberOf.map((group) => { - return group.leave(user, 'remove-all'); - }); + const groupLeavePromises = groupsUserIsMemberOf.map(group => group.leave(user, 'remove-all')); await Promise.all(groupLeavePromises); @@ -290,13 +288,13 @@ api.deleteUser = { await user.remove(); if (feedback) { - sendTxn({email: TECH_ASSISTANCE_EMAIL}, 'admin-feedback', [ - {name: 'PROFILE_NAME', content: user.profile.name}, - {name: 'USERNAME', content: user.auth.local.username}, - {name: 'UUID', content: user._id}, - {name: 'EMAIL', content: getUserInfo(user, ['email']).email}, - {name: 'FEEDBACK_SOURCE', content: 'from deletion form'}, - {name: 'FEEDBACK', content: feedback}, + sendTxn({ email: TECH_ASSISTANCE_EMAIL }, 'admin-feedback', [ + { name: 'PROFILE_NAME', content: user.profile.name }, + { name: 'USERNAME', content: user.auth.local.username }, + { name: 'UUID', content: user._id }, + { name: 'EMAIL', content: getUserInfo(user, ['email']).email }, + { name: 'FEEDBACK_SOURCE', content: 'from deletion form' }, + { name: 'FEEDBACK', content: feedback }, ]); } @@ -333,13 +331,13 @@ function _cleanChecklist (task) { * * @apiSuccess {Object} data.user * @apiSuccess {Object} data.tasks - **/ + * */ api.getUserAnonymized = { method: 'GET', middlewares: [authWithHeaders()], url: '/user/anonymized', async handler (req, res) { - let user = await res.locals.user.toJSONWithInbox(); + const user = await res.locals.user.toJSONWithInbox(); user.stats.toNextLevel = common.tnl(user.stats.lvl); user.stats.maxHealth = common.maxHealth; user.stats.maxMP = common.statsComputed(res.locals.user).maxMP; @@ -361,25 +359,25 @@ api.getUserAnonymized = { delete user.achievements.challenges; delete user.notifications; - _.forEach(user.inbox.messages, (msg) => { + _.forEach(user.inbox.messages, msg => { msg.text = 'inbox message text'; }); - _.forEach(user.tags, (tag) => { + _.forEach(user.tags, tag => { tag.name = 'tag'; tag.challenge = 'challenge'; }); - let query = { + const query = { userId: user._id, $or: [ { type: 'todo', completed: false }, { type: { $in: ['habit', 'daily', 'reward'] } }, ], }; - let tasks = await Tasks.Task.find(query).exec(); + const tasks = await Tasks.Task.find(query).exec(); - _.forEach(tasks, (task) => { + _.forEach(tasks, task => { task.text = 'task text'; task.notes = 'task notes'; if (task.type === 'todo' || task.type === 'daily') { @@ -411,8 +409,8 @@ api.sleep = { middlewares: [authWithHeaders()], url: '/user/sleep', async handler (req, res) { - let user = res.locals.user; - let sleepRes = common.ops.sleep(user, req, res.analytics); + const { user } = res.locals; + const sleepRes = common.ops.sleep(user, req, res.analytics); await user.save(); res.respond(200, ...sleepRes); }, @@ -455,11 +453,11 @@ api.buy = { middlewares: [authWithHeaders()], url: '/user/buy/:key', async handler (req, res) { - let user = res.locals.user; + const { user } = res.locals; let buyRes; // @TODO: Remove this when mobile passes type in body - let type = req.params.key; + const type = req.params.key; if (buySpecialKeys.indexOf(type) !== -1) { req.type = 'special'; } else if (buyKnownKeys.indexOf(type) === -1) { @@ -519,8 +517,8 @@ api.buyGear = { middlewares: [authWithHeaders()], url: '/user/buy-gear/:key', async handler (req, res) { - let user = res.locals.user; - let buyGearRes = common.ops.buy(user, req, res.analytics); + const { user } = res.locals; + const buyGearRes = common.ops.buy(user, req, res.analytics); await user.save(); res.respond(200, ...buyGearRes); }, @@ -559,10 +557,10 @@ api.buyArmoire = { middlewares: [authWithHeaders()], url: '/user/buy-armoire', async handler (req, res) { - let user = res.locals.user; + const { user } = res.locals; req.type = 'armoire'; req.params.key = 'armoire'; - let buyArmoireResponse = common.ops.buy(user, req, res.analytics); + const buyArmoireResponse = common.ops.buy(user, req, res.analytics); await user.save(); res.respond(200, ...buyArmoireResponse); }, @@ -599,10 +597,10 @@ api.buyHealthPotion = { middlewares: [authWithHeaders()], url: '/user/buy-health-potion', async handler (req, res) { - let user = res.locals.user; + const { user } = res.locals; req.type = 'potion'; req.params.key = 'potion'; - let buyHealthPotionResponse = common.ops.buy(user, req, res.analytics); + const buyHealthPotionResponse = common.ops.buy(user, req, res.analytics); await user.save(); res.respond(200, ...buyHealthPotionResponse); }, @@ -641,9 +639,9 @@ api.buyMysterySet = { middlewares: [authWithHeaders()], url: '/user/buy-mystery-set/:key', async handler (req, res) { - let user = res.locals.user; + const { user } = res.locals; req.type = 'mystery'; - let buyMysterySetRes = common.ops.buy(user, req, res.analytics); + const buyMysterySetRes = common.ops.buy(user, req, res.analytics); await user.save(); res.respond(200, ...buyMysterySetRes); }, @@ -684,9 +682,9 @@ api.buyQuest = { middlewares: [authWithHeaders()], url: '/user/buy-quest/:key', async handler (req, res) { - let user = res.locals.user; + const { user } = res.locals; req.type = 'quest'; - let buyQuestRes = common.ops.buy(user, req, res.analytics); + const buyQuestRes = common.ops.buy(user, req, res.analytics); await user.save(); res.respond(200, ...buyQuestRes); }, @@ -724,9 +722,9 @@ api.buySpecialSpell = { middlewares: [authWithHeaders()], url: '/user/buy-special-spell/:key', async handler (req, res) { - let user = res.locals.user; + const { user } = res.locals; req.type = 'special'; - let buySpecialSpellRes = common.ops.buy(user, req); + const buySpecialSpellRes = common.ops.buy(user, req); await user.save(); res.respond(200, ...buySpecialSpellRes); }, @@ -768,8 +766,8 @@ api.hatch = { middlewares: [authWithHeaders()], url: '/user/hatch/:egg/:hatchingPotion', async handler (req, res) { - let user = res.locals.user; - let hatchRes = common.ops.hatch(user, req); + const { user } = res.locals; + const hatchRes = common.ops.hatch(user, req); await user.save(); @@ -820,8 +818,8 @@ api.equip = { middlewares: [authWithHeaders()], url: '/user/equip/:type/:key', async handler (req, res) { - let user = res.locals.user; - let equipRes = common.ops.equip(user, req); + const { user } = res.locals; + const equipRes = common.ops.equip(user, req); await user.save(); res.respond(200, ...equipRes); }, @@ -855,8 +853,8 @@ api.feed = { middlewares: [authWithHeaders()], url: '/user/feed/:pet/:food', async handler (req, res) { - let user = res.locals.user; - let feedRes = common.ops.feed(user, req); + const { user } = res.locals; + const feedRes = common.ops.feed(user, req); await user.save(); @@ -899,8 +897,8 @@ api.changeClass = { middlewares: [authWithHeaders()], url: '/user/change-class', async handler (req, res) { - let user = res.locals.user; - let changeClassRes = common.ops.changeClass(user, req, res.analytics); + const { user } = res.locals; + const changeClassRes = common.ops.changeClass(user, req, res.analytics); await user.save(); res.respond(200, ...changeClassRes); }, @@ -920,8 +918,8 @@ api.disableClasses = { middlewares: [authWithHeaders()], url: '/user/disable-classes', async handler (req, res) { - let user = res.locals.user; - let disableClassesRes = common.ops.disableClasses(user, req); + const { user } = res.locals; + const disableClassesRes = common.ops.disableClasses(user, req); await user.save(); res.respond(200, ...disableClassesRes); }, @@ -952,7 +950,7 @@ api.purchase = { middlewares: [authWithHeaders()], url: '/user/purchase/:type/:key', async handler (req, res) { - let user = res.locals.user; + const { user } = res.locals; const type = get(req.params, 'type'); const key = get(req.params, 'key'); @@ -969,7 +967,7 @@ api.purchase = { if (req.body.quantity) quantity = req.body.quantity; req.quantity = quantity; - let purchaseRes = common.ops.buy(user, req, res.analytics); + const purchaseRes = common.ops.buy(user, req, res.analytics); await user.save(); res.respond(200, ...purchaseRes); }, @@ -1002,10 +1000,10 @@ api.userPurchaseHourglass = { middlewares: [authWithHeaders()], url: '/user/purchase-hourglass/:type/:key', async handler (req, res) { - let user = res.locals.user; + const { user } = res.locals; const quantity = req.body.quantity || 1; if (quantity < 1 || !Number.isInteger(quantity)) throw new BadRequest(res.t('invalidQuantity'), req.language); - let purchaseHourglassRes = common.ops.buy(user, req, res.analytics, {quantity, hourglass: true}); + const purchaseHourglassRes = common.ops.buy(user, req, res.analytics, { quantity, hourglass: true }); await user.save(); res.respond(200, ...purchaseHourglassRes); }, @@ -1056,8 +1054,8 @@ api.readCard = { middlewares: [authWithHeaders()], url: '/user/read-card/:cardType', async handler (req, res) { - let user = res.locals.user; - let readCardRes = common.ops.readCard(user, req); + const { user } = res.locals; + const readCardRes = common.ops.readCard(user, req); await user.save(); res.respond(200, ...readCardRes); }, @@ -1098,8 +1096,8 @@ api.userOpenMysteryItem = { middlewares: [authWithHeaders()], url: '/user/open-mystery-item', async handler (req, res) { - let user = res.locals.user; - let openMysteryItemRes = common.ops.openMysteryItem(user, req, res.analytics); + const { user } = res.locals; + const openMysteryItemRes = common.ops.openMysteryItem(user, req, res.analytics); await user.save(); res.respond(200, ...openMysteryItemRes); }, @@ -1130,8 +1128,8 @@ api.userReleasePets = { middlewares: [authWithHeaders()], url: '/user/release-pets', async handler (req, res) { - let user = res.locals.user; - let releasePetsRes = common.ops.releasePets(user, req, res.analytics); + const { user } = res.locals; + const releasePetsRes = common.ops.releasePets(user, req, res.analytics); await user.save(); res.respond(200, ...releasePetsRes); }, @@ -1179,8 +1177,8 @@ api.userReleaseBoth = { middlewares: [authWithHeaders()], url: '/user/release-both', async handler (req, res) { - let user = res.locals.user; - let releaseBothRes = common.ops.releaseBoth(user, req, res.analytics); + const { user } = res.locals; + const releaseBothRes = common.ops.releaseBoth(user, req, res.analytics); await user.save(); res.respond(200, ...releaseBothRes); }, @@ -1215,8 +1213,8 @@ api.userReleaseMounts = { middlewares: [authWithHeaders()], url: '/user/release-mounts', async handler (req, res) { - let user = res.locals.user; - let releaseMountsRes = common.ops.releaseMounts(user, req, res.analytics); + const { user } = res.locals; + const releaseMountsRes = common.ops.releaseMounts(user, req, res.analytics); await user.save(); res.respond(200, ...releaseMountsRes); }, @@ -1245,8 +1243,8 @@ api.userSell = { middlewares: [authWithHeaders()], url: '/user/sell/:type/:key', async handler (req, res) { - let user = res.locals.user; - let sellRes = common.ops.sell(user, req); + const { user } = res.locals; + const sellRes = common.ops.sell(user, req); await user.save(); res.respond(200, ...sellRes); }, @@ -1288,8 +1286,8 @@ api.userUnlock = { middlewares: [authWithHeaders()], url: '/user/unlock', async handler (req, res) { - let user = res.locals.user; - let unlockRes = common.ops.unlock(user, req, res.analytics); + const { user } = res.locals; + const unlockRes = common.ops.unlock(user, req, res.analytics); await user.save(); res.respond(200, ...unlockRes); }, @@ -1314,8 +1312,8 @@ api.userRevive = { middlewares: [authWithHeaders()], url: '/user/revive', async handler (req, res) { - let user = res.locals.user; - let reviveRes = common.ops.revive(user, req, res.analytics); + const { user } = res.locals; + const reviveRes = common.ops.revive(user, req, res.analytics); await user.save(); res.respond(200, ...reviveRes); }, @@ -1380,8 +1378,8 @@ api.blockUser = { middlewares: [authWithHeaders()], url: '/user/block/:uuid', async handler (req, res) { - let user = res.locals.user; - let blockUserRes = common.ops.blockUser(user, req); + const { user } = res.locals; + const blockUserRes = common.ops.blockUser(user, req); await user.save(); res.respond(200, ...blockUserRes); }, @@ -1422,11 +1420,11 @@ api.deleteMessage = { middlewares: [authWithHeaders()], url: '/user/messages/:id', async handler (req, res) { - let user = res.locals.user; + const { user } = res.locals; await inboxLib.deleteMessage(user, req.params.id); - res.respond(200, ...[await inboxLib.getUserInbox(user, {asArray: false})]); + res.respond(200, ...[await inboxLib.getUserInbox(user, { asArray: false })]); }, }; @@ -1447,7 +1445,7 @@ api.clearMessages = { middlewares: [authWithHeaders()], url: '/user/messages', async handler (req, res) { - let user = res.locals.user; + const { user } = res.locals; await inboxLib.clearPMs(user); @@ -1471,8 +1469,8 @@ api.markPmsRead = { middlewares: [authWithHeaders()], url: '/user/mark-pms-read', async handler (req, res) { - let user = res.locals.user; - let markPmsResponse = common.ops.markPmsRead(user); + const { user } = res.locals; + const markPmsResponse = common.ops.markPmsRead(user); await user.save(); res.respond(200, markPmsResponse); }, @@ -1570,8 +1568,8 @@ api.setCustomDayStart = { middlewares: [authWithHeaders()], url: '/user/custom-day-start', async handler (req, res) { - let user = res.locals.user; - let dayStart = req.body.dayStart; + const { user } = res.locals; + const { dayStart } = req.body; user.preferences.dayStart = dayStart; user.lastCron = new Date(); @@ -1608,15 +1606,15 @@ api.togglePinnedItem = { middlewares: [authWithHeaders()], url: '/user/toggle-pinned-item/:type/:path', async handler (req, res) { - let user = res.locals.user; + const { user } = res.locals; const path = get(req.params, 'path'); const type = get(req.params, 'type'); - common.ops.pinnedGearUtils.togglePinnedItem(user, {type, path}, req); + common.ops.pinnedGearUtils.togglePinnedItem(user, { type, path }, req); await user.save(); - let userJson = user.toJSON(); + const userJson = user.toJSON(); res.respond(200, { pinnedItems: userJson.pinnedItems, @@ -1648,28 +1646,28 @@ api.movePinnedItem = { req.checkParams('path', res.t('taskIdRequired')).notEmpty(); req.checkParams('position', res.t('positionRequired')).notEmpty().isNumeric(); - let validationErrors = req.validationErrors(); + const validationErrors = req.validationErrors(); if (validationErrors) throw validationErrors; - let user = res.locals.user; - let path = req.params.path; - let position = Number(req.params.position); + const { user } = res.locals; + const { path } = req.params; + const position = Number(req.params.position); // If something has been added or removed from the inAppRewards, we need // to reset pinnedItemsOrder to have the correct length. Since inAppRewards // Uses the current pinnedItemsOrder to return these in the right order, // the new reset array will be in the right order before we do the swap - let currentPinnedItems = common.inAppRewards(user); + const currentPinnedItems = common.inAppRewards(user); if (user.pinnedItemsOrder.length !== currentPinnedItems.length) { user.pinnedItemsOrder = currentPinnedItems.map(item => item.path); } // Adjust the order - let currentIndex = user.pinnedItemsOrder.findIndex(item => item === path); - let currentPinnedItemPath = user.pinnedItemsOrder[currentIndex]; + const currentIndex = user.pinnedItemsOrder.findIndex(item => item === path); + const currentPinnedItemPath = user.pinnedItemsOrder[currentIndex]; if (currentIndex === -1) { - throw new BadRequest(res.t('wrongItemPath', {path}, req.language)); + throw new BadRequest(res.t('wrongItemPath', { path }, req.language)); } // Remove the one we will move @@ -1683,7 +1681,7 @@ api.movePinnedItem = { } await user.save(); - let userJson = user.toJSON(); + const userJson = user.toJSON(); res.respond(200, userJson.pinnedItemsOrder); }, diff --git a/website/server/controllers/api-v3/user/spells.js b/website/server/controllers/api-v3/user/spells.js index 4052e72876..7a22d81822 100644 --- a/website/server/controllers/api-v3/user/spells.js +++ b/website/server/controllers/api-v3/user/spells.js @@ -3,7 +3,7 @@ import { castSpell, } from '../../../libs/spells'; -let api = {}; +const api = {}; /* NOTE this route has also an API v4 version */ diff --git a/website/server/controllers/api-v3/user/stats.js b/website/server/controllers/api-v3/user/stats.js index 97e8af637a..dea525dbf0 100644 --- a/website/server/controllers/api-v3/user/stats.js +++ b/website/server/controllers/api-v3/user/stats.js @@ -2,7 +2,7 @@ import common from '../../../../common'; import { authWithHeaders } from '../../../middlewares/auth'; -let api = {}; +const api = {}; /** * @api {post} /api/v3/user/allocate Allocate a single Stat Point (previously called Attribute Point) @@ -30,8 +30,8 @@ api.allocate = { middlewares: [authWithHeaders()], url: '/user/allocate', async handler (req, res) { - let user = res.locals.user; - let allocateRes = common.ops.allocate(user, req); + const { user } = res.locals; + const allocateRes = common.ops.allocate(user, req); await user.save(); res.respond(200, ...allocateRes); }, @@ -70,8 +70,8 @@ api.allocateBulk = { middlewares: [authWithHeaders()], url: '/user/allocate-bulk', async handler (req, res) { - let user = res.locals.user; - let allocateRes = common.ops.allocateBulk(user, req); + const { user } = res.locals; + const allocateRes = common.ops.allocateBulk(user, req); await user.save(); res.respond(200, ...allocateRes); }, @@ -127,8 +127,8 @@ api.allocateNow = { middlewares: [authWithHeaders()], url: '/user/allocate-now', async handler (req, res) { - let user = res.locals.user; - let allocateNowRes = common.ops.allocateNow(user); + const { user } = res.locals; + const allocateNowRes = common.ops.allocateNow(user); await user.save(); res.respond(200, ...allocateNowRes); }, diff --git a/website/server/controllers/api-v3/webhook.js b/website/server/controllers/api-v3/webhook.js index 62079fd93b..54aa086876 100644 --- a/website/server/controllers/api-v3/webhook.js +++ b/website/server/controllers/api-v3/webhook.js @@ -3,7 +3,7 @@ import { model as Webhook } from '../../models/webhook'; import { removeFromArray } from '../../libs/collectionManipulators'; import { NotFound, BadRequest } from '../../libs/errors'; -let api = {}; +const api = {}; /** * @apiDefine Webhook Webhook @@ -76,10 +76,10 @@ api.addWebhook = { middlewares: [authWithHeaders()], url: '/user/webhook', async handler (req, res) { - let user = res.locals.user; - let webhook = new Webhook(req.body); + const { user } = res.locals; + const webhook = new Webhook(req.body); - let existingWebhook = user.webhooks.find(hook => hook.id === webhook.id); + const existingWebhook = user.webhooks.find(hook => hook.id === webhook.id); if (existingWebhook) { throw new BadRequest(res.t('webhookIdAlreadyTaken', { id: webhook.id })); @@ -107,7 +107,7 @@ api.getWebhook = { middlewares: [authWithHeaders()], url: '/user/webhook', async handler (req, res) { - const user = res.locals.user; + const { user } = res.locals; res.respond(200, user.webhooks); }, @@ -154,13 +154,15 @@ api.updateWebhook = { middlewares: [authWithHeaders()], url: '/user/webhook/:id', async handler (req, res) { - let user = res.locals.user; - let id = req.params.id; - let webhook = user.webhooks.find(hook => hook.id === id); - let { url, label, type, enabled, options } = req.body; + const { user } = res.locals; + const { id } = req.params; + const webhook = user.webhooks.find(hook => hook.id === id); + const { + url, label, type, enabled, options, + } = req.body; if (!webhook) { - throw new NotFound(res.t('noWebhookWithId', {id})); + throw new NotFound(res.t('noWebhookWithId', { id })); } if (url) { @@ -205,13 +207,13 @@ api.deleteWebhook = { middlewares: [authWithHeaders()], url: '/user/webhook/:id', async handler (req, res) { - let user = res.locals.user; - let id = req.params.id; + const { user } = res.locals; + const { id } = req.params; - let webhook = user.webhooks.find(hook => hook.id === id); + const webhook = user.webhooks.find(hook => hook.id === id); if (!webhook) { - throw new NotFound(res.t('noWebhookWithId', {id})); + throw new NotFound(res.t('noWebhookWithId', { id })); } removeFromArray(user.webhooks, webhook); diff --git a/website/server/controllers/api-v3/world.js b/website/server/controllers/api-v3/world.js index 635ae05826..0444670df8 100644 --- a/website/server/controllers/api-v3/world.js +++ b/website/server/controllers/api-v3/world.js @@ -3,10 +3,10 @@ import { TAVERN_ID as tavernId, } from '../../models/group'; -let api = {}; +const api = {}; async function getWorldBoss () { - let tavern = await Group + const tavern = await Group .findById(tavernId) .select('quest.progress quest.key quest.active quest.extra') .exec(); @@ -34,7 +34,7 @@ api.getWorldState = { method: 'GET', url: '/world-state', async handler (req, res) { - let worldState = {}; + const worldState = {}; worldState.worldBoss = await getWorldBoss(); worldState.npcImageSuffix = 'spring'; diff --git a/website/server/controllers/api-v4/auth.js b/website/server/controllers/api-v4/auth.js index cc2b269862..87a0dd5351 100644 --- a/website/server/controllers/api-v4/auth.js +++ b/website/server/controllers/api-v4/auth.js @@ -3,7 +3,7 @@ import { } from '../../middlewares/auth'; import * as authLib from '../../libs/auth'; import { model as User } from '../../models/user'; -import {verifyUsername} from '../../libs/user/validation'; +import { verifyUsername } from '../../libs/user/validation'; const api = {}; @@ -16,14 +16,14 @@ api.verifyUsername = { async handler (req, res) { req.checkBody({ username: { - notEmpty: {errorMessage: res.t('missingUsername')}, + notEmpty: { errorMessage: res.t('missingUsername') }, }, }); const validationErrors = req.validationErrors(); if (validationErrors) throw validationErrors; - const user = res.locals.user; + const { user } = res.locals; const chosenUsername = req.body.username; const issues = verifyUsername(chosenUsername, res); @@ -31,10 +31,10 @@ api.verifyUsername = { if (issues.length < 1) { const existingUser = await User.findOne({ 'auth.local.lowerCaseUsername': chosenUsername.toLowerCase(), - }, {auth: 1}).exec(); + }, { auth: 1 }).exec(); if (existingUser) { - if (!user || existingUser._id !== user._id) issues.push(res.t('usernameTaken')); + if (!user || existingUser._id !== user._id) issues.push(res.t('usernameTaken')); } } diff --git a/website/server/controllers/api-v4/coupon.js b/website/server/controllers/api-v4/coupon.js index 7b28948af0..819c0f407c 100644 --- a/website/server/controllers/api-v4/coupon.js +++ b/website/server/controllers/api-v4/coupon.js @@ -25,10 +25,10 @@ api.enterCouponCode = { url: '/coupons/enter/:code', middlewares: [authWithHeaders()], async handler (req, res) { - const user = res.locals.user; + const { user } = res.locals; await couponsLib.enterCode(req, res, user); res.respond(200, user); }, }; -export default api; \ No newline at end of file +export default api; diff --git a/website/server/controllers/api-v4/inbox.js b/website/server/controllers/api-v4/inbox.js index d0f0f00455..26b1ea33c2 100644 --- a/website/server/controllers/api-v4/inbox.js +++ b/website/server/controllers/api-v4/inbox.js @@ -37,8 +37,8 @@ api.deleteMessage = { const validationErrors = req.validationErrors(); if (validationErrors) throw validationErrors; - const messageId = req.params.messageId; - const user = res.locals.user; + const { messageId } = req.params; + const { user } = res.locals; const deleted = await inboxLib.deleteMessage(user, messageId); if (!deleted) throw new NotFound(res.t('messageGroupChatNotFound')); @@ -64,7 +64,7 @@ api.clearMessages = { middlewares: [authWithHeaders()], url: '/inbox/clear', async handler (req, res) { - const user = res.locals.user; + const { user } = res.locals; await inboxLib.clearPMs(user); @@ -99,7 +99,7 @@ api.conversations = { middlewares: [authWithHeaders()], url: '/inbox/conversations', async handler (req, res) { - const user = res.locals.user; + const { user } = res.locals; const result = await inboxLib.listConversations(user); @@ -123,9 +123,9 @@ api.getInboxMessages = { url: '/inbox/paged-messages', middlewares: [authWithHeaders()], async handler (req, res) { - const user = res.locals.user; - const page = req.query.page; - const conversation = req.query.conversation; + const { user } = res.locals; + const { page } = req.query; + const { conversation } = req.query; const userInbox = await inboxLib.getUserInbox(user, { page, conversation, mapProps: true, diff --git a/website/server/controllers/api-v4/members.js b/website/server/controllers/api-v4/members.js index d4bd021135..bfdb4c4963 100644 --- a/website/server/controllers/api-v4/members.js +++ b/website/server/controllers/api-v4/members.js @@ -1,7 +1,7 @@ import { authWithHeaders } from '../../middlewares/auth'; import { chatReporterFactory } from '../../libs/chatReporting/chatReporterFactory'; -let api = {}; +const api = {}; /** * @api {post} /api/v4/members/flag-private-message/:messageId Flag a private message diff --git a/website/server/controllers/api-v4/user.js b/website/server/controllers/api-v4/user.js index 966f000cec..8349c4e94a 100644 --- a/website/server/controllers/api-v4/user.js +++ b/website/server/controllers/api-v4/user.js @@ -216,7 +216,7 @@ api.verifyDisplayName = { async handler (req, res) { req.checkBody({ displayName: { - notEmpty: {errorMessage: res.t('messageMissingDisplayName')}, + notEmpty: { errorMessage: res.t('messageMissingDisplayName') }, }, }); diff --git a/website/server/controllers/api-v4/user/spells.js b/website/server/controllers/api-v4/user/spells.js index 59022e88cb..f8628e4f8d 100644 --- a/website/server/controllers/api-v4/user/spells.js +++ b/website/server/controllers/api-v4/user/spells.js @@ -3,7 +3,7 @@ import { castSpell, } from '../../../libs/spells'; -let api = {}; +const api = {}; /* * NOTE most spells routes are still in the v3 controller diff --git a/website/server/controllers/top-level/auth.js b/website/server/controllers/top-level/auth.js index d153020e35..ae8e08b87f 100644 --- a/website/server/controllers/top-level/auth.js +++ b/website/server/controllers/top-level/auth.js @@ -1,6 +1,6 @@ import { validatePasswordResetCodeAndFindUser } from '../../libs/password'; -let api = {}; +const api = {}; // Internal authentication routes @@ -10,7 +10,7 @@ api.resetPasswordSetNewOne = { url: '/static/user/auth/local/reset-password-set-new-one', runCron: false, async handler (req, res) { - const code = req.query.code; + const { code } = req.query; const user = await validatePasswordResetCodeAndFindUser(code); const isValidCode = Boolean(user); diff --git a/website/server/controllers/top-level/dataexport.js b/website/server/controllers/top-level/dataexport.js index d343c6faf4..a1e97d5547 100644 --- a/website/server/controllers/top-level/dataexport.js +++ b/website/server/controllers/top-level/dataexport.js @@ -1,18 +1,18 @@ -import { authWithSession } from '../../middlewares/auth'; -import { model as User } from '../../models/user'; -import * as inboxLib from '../../libs/inbox'; -import * as Tasks from '../../models/task'; -import { - NotFound, -} from '../../libs/errors'; import _ from 'lodash'; -import csvStringify from '../../libs/csvStringify'; import moment from 'moment'; import * as js2xml from 'js2xmlparser'; import Pageres from 'pageres'; import nconf from 'nconf'; import got from 'got'; import md from 'habitica-markdown'; +import csvStringify from '../../libs/csvStringify'; +import { + NotFound, +} from '../../libs/errors'; +import * as Tasks from '../../models/task'; +import * as inboxLib from '../../libs/inbox'; +import { model as User } from '../../models/user'; +import { authWithSession } from '../../middlewares/auth'; import { S3, } from '../../libs/aws'; @@ -21,7 +21,7 @@ const S3_BUCKET = nconf.get('S3_BUCKET'); const BASE_URL = nconf.get('BASE_URL'); -let api = {}; +const api = {}; /** * @apiDefine DataExport Data Export @@ -49,14 +49,14 @@ api.exportUserHistory = { url: '/export/history.csv', middlewares: [authWithSession], async handler (req, res) { - let user = res.locals.user; + const { user } = res.locals; - let tasks = await Tasks.Task.find({ + const tasks = await Tasks.Task.find({ userId: user._id, - type: {$in: ['habit', 'daily']}, + type: { $in: ['habit', 'daily'] }, }).exec(); - let output = [ + const output = [ ['Task Name', 'Task ID', 'Task Type', 'Date', 'Value'], ]; @@ -77,7 +77,7 @@ api.exportUserHistory = { 'Content-disposition': 'attachment; filename=habitica-tasks-history.csv', }); - let csvRes = await csvStringify(output); + const csvRes = await csvStringify(output); res.status(200).send(csvRes); }, }; @@ -85,7 +85,7 @@ api.exportUserHistory = { // Convert user to json and attach tasks divided by type and inbox messages // at user.tasks[`${taskType}s`] (user.tasks.{dailys/habits/...}) async function _getUserDataForExport (user, xmlMode = false) { - let userData = user.toJSON(); + const userData = user.toJSON(); userData.tasks = {}; userData.inbox.messages = {}; @@ -119,19 +119,15 @@ async function _getUserDataForExport (user, xmlMode = false) { .value(); // _id gets parsed as an bytearray => which gets casted to a chararray => "weird chars" - userData.unpinnedItems = userData.unpinnedItems.map(i => { - return { - path: i.path, - type: i.type, - }; - }); + userData.unpinnedItems = userData.unpinnedItems.map(i => ({ + path: i.path, + type: i.type, + })); - userData.pinnedItems = userData.pinnedItems.map(i => { - return { - path: i.path, - type: i.type, - }; - }); + userData.pinnedItems = userData.pinnedItems.map(i => ({ + path: i.path, + type: i.type, + })); } return userData; @@ -149,13 +145,13 @@ api.exportUserDataJson = { url: '/export/userdata.json', middlewares: [authWithSession], async handler (req, res) { - let userData = await _getUserDataForExport(res.locals.user); + const userData = await _getUserDataForExport(res.locals.user); res.set({ 'Content-Type': 'application/json', 'Content-disposition': 'attachment; filename=habitica-user-data.json', }); - let jsonRes = JSON.stringify(userData); + const jsonRes = JSON.stringify(userData); res.status(200).send(jsonRes); }, @@ -173,7 +169,7 @@ api.exportUserDataXml = { url: '/export/userdata.xml', middlewares: [authWithSession], async handler (req, res) { - let userData = await _getUserDataForExport(res.locals.user, true); + const userData = await _getUserDataForExport(res.locals.user, true); res.set({ 'Content-Type': 'text/xml', @@ -207,19 +203,19 @@ api.exportUserAvatarHtml = { async handler (req, res) { req.checkParams('memberId', res.t('memberIdRequired')).notEmpty().isUUID(); - let validationErrors = req.validationErrors(); + const validationErrors = req.validationErrors(); if (validationErrors) throw validationErrors; - let memberId = req.params.memberId; - let member = await User + const { memberId } = req.params; + const member = await User .findById(memberId) .select('stats profile items achievements preferences backer contributor') .exec(); - if (!member) throw new NotFound(res.t('userWithIDNotFound', {userId: memberId})); + if (!member) throw new NotFound(res.t('userWithIDNotFound', { userId: memberId })); res.render('avatar-static', { title: member.profile.name, - env: _.defaults({user: member}, res.locals.habitrpg), + env: _.defaults({ user: member }, res.locals.habitrpg), }); }, }; @@ -239,13 +235,13 @@ api.exportUserAvatarPng = { async handler (req, res) { req.checkParams('memberId', res.t('memberIdRequired')).notEmpty().isUUID(); - let validationErrors = req.validationErrors(); + const validationErrors = req.validationErrors(); if (validationErrors) throw validationErrors; - let memberId = req.params.memberId; + const { memberId } = req.params; - let filename = `avatars/${memberId}.png`; - let s3url = `https://${S3_BUCKET}.s3.amazonaws.com/${filename}`; + const filename = `avatars/${memberId}.png`; + const s3url = `https://${S3_BUCKET}.s3.amazonaws.com/${filename}`; let response; try { @@ -269,17 +265,17 @@ api.exportUserAvatarPng = { }) .run(); - let s3upload = S3.upload({ + const s3upload = S3.upload({ Bucket: S3_BUCKET, Key: filename, ACL: 'public-read', StorageClass: 'REDUCED_REDUNDANCY', ContentType: 'image/png', - Expires: moment().add({minutes: 5}).toDate(), + Expires: moment().add({ minutes: 5 }).toDate(), Body: pageBuffer, }); - let s3res = await new Promise((resolve, reject) => { + const s3res = await new Promise((resolve, reject) => { s3upload.send((err, s3uploadRes) => { if (err) { reject(err); @@ -305,9 +301,9 @@ api.exportUserPrivateMessages = { url: '/export/inbox.html', middlewares: [authWithSession], async handler (req, res) { - const user = res.locals.user; + const { user } = res.locals; - const timezoneOffset = user.preferences.timezoneOffset; + const { timezoneOffset } = user.preferences; const dateFormat = user.preferences.dateFormat.toUpperCase(); const TO = res.t('to'); const FROM = res.t('from'); @@ -317,10 +313,10 @@ api.exportUserPrivateMessages = { let messages = '
'; inbox.forEach((message, index) => { - let recipientLabel = message.sent ? TO : FROM; - let messageUser = message.user; - let timestamp = moment.utc(message.timestamp).zone(timezoneOffset).format(`${dateFormat} HH:mm:ss`); - let text = md.render(message.text); + const recipientLabel = message.sent ? TO : FROM; + const messageUser = message.user; + const timestamp = moment.utc(message.timestamp).zone(timezoneOffset).format(`${dateFormat} HH:mm:ss`); + const text = md.render(message.text); index = `(${index + 1}/${inbox.length})`; messages += `diff --git a/website/server/controllers/top-level/email.js b/website/server/controllers/top-level/email.js index a4da992f28..43a7725b6a 100644 --- a/website/server/controllers/top-level/email.js +++ b/website/server/controllers/top-level/email.js @@ -5,7 +5,7 @@ import { NotFound, } from '../../libs/errors'; -let api = {}; +const api = {}; /** * @api {get} /email/unsubscribe Unsubscribe an email or user from email notifications @@ -27,28 +27,28 @@ api.unsubscribe = { async handler (req, res) { req.checkQuery({ code: { - notEmpty: {errorMessage: res.t('missingUnsubscriptionCode')}, + notEmpty: { errorMessage: res.t('missingUnsubscriptionCode') }, }, }); - let validationErrors = req.validationErrors(); + const validationErrors = req.validationErrors(); if (validationErrors) throw validationErrors; - let data = JSON.parse(decrypt(req.query.code)); + const data = JSON.parse(decrypt(req.query.code)); if (data._id) { - let userUpdated = await User.update( - {_id: data._id}, - { $set: {'preferences.emailNotifications.unsubscribeFromAll': true}} + const userUpdated = await User.update( + { _id: data._id }, + { $set: { 'preferences.emailNotifications.unsubscribeFromAll': true } }, ).exec(); if (userUpdated.nModified !== 1) throw new NotFound(res.t('userNotFound')); res.send(`