start upgrading eslint

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -4,9 +4,9 @@ import spritesmith from 'gulp.spritesmith';
import clean from 'rimraf'; import clean from 'rimraf';
import sizeOf from 'image-size'; import sizeOf from 'image-size';
import mergeStream from 'merge-stream'; import mergeStream from 'merge-stream';
import {basename} from 'path'; import { basename } from 'path';
import {sync} from 'glob'; import { sync } from 'glob';
import {each} from 'lodash'; import { each } from 'lodash';
import vinylBuffer from 'vinyl-buffer'; import vinylBuffer from 'vinyl-buffer';
// https://github.com/Ensighten/grunt-spritesmith/issues/67#issuecomment-34786248 // 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/'; const CSS_DIST_PATH = 'website/client/src/assets/css/sprites/';
function checkForSpecialTreatment (name) { 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'; return name.match(regex) || name === 'head_0';
} }
function calculateImgDimensions (img, addPadding) { function calculateImgDimensions (img, addPadding) {
let dims = sizeOf(img); let dims = sizeOf(img);
let requiresSpecialTreatment = checkForSpecialTreatment(img); const requiresSpecialTreatment = checkForSpecialTreatment(img);
if (requiresSpecialTreatment) { if (requiresSpecialTreatment) {
let newWidth = dims.width < 90 ? 90 : dims.width; const newWidth = dims.width < 90 ? 90 : dims.width;
let newHeight = dims.height < 90 ? 90 : dims.height; const newHeight = dims.height < 90 ? 90 : dims.height;
dims = { dims = {
width: newWidth, width: newWidth,
height: newHeight, 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 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; return totalPixelSize;
} }
function calculateSpritesheetsSrcIndicies (src) { function calculateSpritesheetsSrcIndicies (src) {
let totalPixels = 0; let totalPixels = 0;
let slices = [0]; const slices = [0];
each(src, (img, index) => { each(src, (img, index) => {
let imageSize = calculateImgDimensions(img, true); const imageSize = calculateImgDimensions(img, true);
totalPixels += imageSize; totalPixels += imageSize;
if (totalPixels > MAX_SPRITESHEET_SIZE) { if (totalPixels > MAX_SPRITESHEET_SIZE) {
@@ -64,37 +64,35 @@ function calculateSpritesheetsSrcIndicies (src) {
} }
function cssVarMap (sprite) { function cssVarMap (sprite) {
// For hair, skins, beards, etc. we want to output a '.customize-options.WHATEVER' class, which works as a // For hair, skins, beards, etc. we want to output a '.customize-options.WHATEVER' class,
// 60x60 image pointing at the proper part of the 90x90 sprite. // 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. // 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) { if (requiresSpecialTreatment) {
sprite.custom = { sprite.custom = {
px: { px: {
offsetX: `-${ sprite.x + 25 }px`, offsetX: `-${sprite.x + 25}px`,
offsetY: `-${ sprite.y + 15 }px`, offsetY: `-${sprite.y + 15}px`,
width: '60px', width: '60px',
height: '60px', height: '60px',
}, },
}; };
} }
if (sprite.name.indexOf('shirt') !== -1) if (sprite.name.indexOf('shirt') !== -1) sprite.custom.px.offsetY = `-${sprite.y + 35}px`; // even more for shirts
sprite.custom.px.offsetY = `-${ sprite.y + 35 }px`; // even more for shirts
if (sprite.name.indexOf('hair_base') !== -1) { if (sprite.name.indexOf('hair_base') !== -1) {
let styleArray = sprite.name.split('_').slice(2, 3); const styleArray = sprite.name.split('_').slice(2, 3);
if (Number(styleArray[0]) > 14) if (Number(styleArray[0]) > 14) sprite.custom.px.offsetY = `-${sprite.y}px`; // don't crop updos
sprite.custom.px.offsetY = `-${ sprite.y }px`; // don't crop updos
} }
} }
function createSpritesStream (name, src) { function createSpritesStream (name, src) {
let spritesheetSliceIndicies = calculateSpritesheetsSrcIndicies(src); const spritesheetSliceIndicies = calculateSpritesheetsSrcIndicies(src);
let stream = mergeStream(); const stream = mergeStream();
each(spritesheetSliceIndicies, (start, index) => { 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({ .pipe(spritesmith({
imgName: `spritesmith-${name}-${index}.png`, imgName: `spritesmith-${name}-${index}.png`,
cssName: `spritesmith-${name}-${index}.css`, cssName: `spritesmith-${name}-${index}.css`,
@@ -104,12 +102,12 @@ function createSpritesStream (name, src) {
cssVarMap, cssVarMap,
})); }));
let imgStream = spriteData.img const imgStream = spriteData.img
.pipe(vinylBuffer()) .pipe(vinylBuffer())
.pipe(imagemin()) .pipe(imagemin())
.pipe(gulp.dest(IMG_DIST_PATH)); .pipe(gulp.dest(IMG_DIST_PATH));
let cssStream = spriteData.css const cssStream = spriteData.css
.pipe(gulp.dest(CSS_DIST_PATH)); .pipe(gulp.dest(CSS_DIST_PATH));
stream.add(imgStream); stream.add(imgStream);
@@ -120,32 +118,32 @@ function createSpritesStream (name, src) {
} }
gulp.task('sprites:main', () => { gulp.task('sprites:main', () => {
let mainSrc = sync('website/raw_sprites/spritesmith/**/*.png'); const mainSrc = sync('website/raw_sprites/spritesmith/**/*.png');
return createSpritesStream('main', mainSrc); return createSpritesStream('main', mainSrc);
}); });
gulp.task('sprites:largeSprites', () => { 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); return createSpritesStream('largeSprites', largeSrc);
}); });
gulp.task('sprites:clean', (done) => { gulp.task('sprites:clean', done => {
clean(`${IMG_DIST_PATH}spritesmith*,${CSS_DIST_PATH}spritesmith*}`, 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 console.log('Verifiying that images do not exceed max dimensions'); // eslint-disable-line no-console
let numberOfSheetsThatAreTooBig = 0; let numberOfSheetsThatAreTooBig = 0;
let distSpritesheets = sync(`${IMG_DIST_PATH}*.png`); const distSpritesheets = sync(`${IMG_DIST_PATH}*.png`);
each(distSpritesheets, (img) => { each(distSpritesheets, img => {
let spriteSize = calculateImgDimensions(img); const spriteSize = calculateImgDimensions(img);
if (spriteSize > MAX_SPRITESHEET_SIZE) { if (spriteSize > MAX_SPRITESHEET_SIZE) {
numberOfSheetsThatAreTooBig++; numberOfSheetsThatAreTooBig += 1;
let name = basename(img, '.png'); const name = basename(img, '.png');
console.error(`WARNING: ${name} might be too big - ${spriteSize} > ${MAX_SPRITESHEET_SIZE}`); // eslint-disable-line no-console 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 console.error( // eslint-disable-line no-console
`${numberOfSheetsThatAreTooBig} sheets might too big for mobile Safari to be able to handle `${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 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 { } else {
console.log('All images are within the correct dimensions'); // eslint-disable-line no-console console.log('All images are within the correct dimensions'); // eslint-disable-line no-console
} }

View File

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

View File

@@ -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 { import {
pipe, pipe,
} from './taskHelper'; } from './taskHelper';
import mongoose from 'mongoose';
import { exec } from 'child_process';
import gulp from 'gulp';
import os from 'os';
import nconf from 'nconf';
// TODO rewrite // TODO rewrite
const TEST_SERVER_PORT = 3003; const TEST_SERVER_PORT = 3003;
let server; 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 SANITY_TEST_COMMAND = 'npm run test:sanity';
const COMMON_TEST_COMMAND = 'npm run test:common'; const COMMON_TEST_COMMAND = 'npm run test:common';
const CONTENT_TEST_COMMAND = 'npm run test:content'; 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 */ /* Helper methods for reporting test summary */
let testResults = []; const testResults = [];
let testCount = (stdout, regexp) => { const testCount = (stdout, regexp) => {
let match = stdout.match(regexp); const match = stdout.match(regexp);
return parseInt(match && match[1] || 0, 10); return parseInt(match && (match[1] || 0), 10);
}; };
let testBin = (string, additionalEnvVariables = '') => { const testBin = (string, additionalEnvVariables = '') => {
if (os.platform() === 'win32') { if (os.platform() === 'win32') {
if (additionalEnvVariables !== '') { if (additionalEnvVariables !== '') {
additionalEnvVariables = additionalEnvVariables.split(' ').join('&&set '); additionalEnvVariables = additionalEnvVariables.split(' ').join('&&set ');
additionalEnvVariables = `set ${additionalEnvVariables}&&`; additionalEnvVariables = `set ${additionalEnvVariables}&&`;
} }
return `set NODE_ENV=test&&${additionalEnvVariables}${string}`; 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.PORT = TEST_SERVER_PORT; // eslint-disable-line no-process-env
process.env.NODE_DB_URI = TEST_DB_URI; // eslint-disable-line no-process-env process.env.NODE_DB_URI = TEST_DB_URI; // eslint-disable-line no-process-env
done(); done();
}, 'nodemon')); }, 'nodemon'));
gulp.task('test:prepare:mongo', (cb) => { gulp.task('test:prepare:mongo', cb => {
mongoose.connect(TEST_DB_URI, (err) => { 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}`); 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); if (err2) return cb(err2);
mongoose.connection.close(cb); 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) { if (!server) {
server = exec(testBin('node ./website/server/index.js', `NODE_DB_URI=${TEST_DB_URI} PORT=${TEST_SERVER_PORT}`), (error, stdout, stderr) => { server = exec(testBin('node ./website/server/index.js', `NODE_DB_URI=${TEST_DB_URI} PORT=${TEST_SERVER_PORT}`), (error, stdout, stderr) => {
if (error) { if (error) {
@@ -73,45 +72,43 @@ gulp.task('test:prepare:build', gulp.series('build', done => done()));
gulp.task('test:prepare', gulp.series( gulp.task('test:prepare', gulp.series(
'test:prepare:build', 'test:prepare:build',
'test:prepare:mongo', 'test:prepare:mongo',
done => done() done => done(),
)); ));
gulp.task('test:sanity', (cb) => { gulp.task('test:sanity', cb => {
let runner = exec( const runner = exec(
testBin(SANITY_TEST_COMMAND), testBin(SANITY_TEST_COMMAND),
(err) => { err => {
if (err) { if (err) {
process.exit(1); process.exit(1);
} }
cb(); cb();
} },
); );
pipe(runner); pipe(runner);
}); });
gulp.task('test:common', gulp.series('test:prepare:build', (cb) => { gulp.task('test:common', gulp.series('test:prepare:build', cb => {
let runner = exec( const runner = exec(
testBin(COMMON_TEST_COMMAND), testBin(COMMON_TEST_COMMAND),
(err) => { err => {
if (err) { if (err) {
process.exit(1); process.exit(1);
} }
cb(); cb();
} },
); );
pipe(runner); pipe(runner);
})); }));
gulp.task('test:common:clean', (cb) => { gulp.task('test:common:clean', cb => {
pipe(exec(testBin(COMMON_TEST_COMMAND), () => cb())); pipe(exec(testBin(COMMON_TEST_COMMAND), () => cb()));
}); });
gulp.task('test:common:watch', gulp.series('test:common:clean', () => { gulp.task('test:common:watch', gulp.series('test:common:clean', () => gulp.watch(['common/script/**/*', 'test/common/**/*'], gulp.series('test:common:clean', done => done()))));
return gulp.watch(['common/script/**/*', 'test/common/**/*'], gulp.series('test:common:clean', done => done()));
}));
gulp.task('test:common:safe', gulp.series('test:prepare:build', (cb) => { gulp.task('test:common:safe', gulp.series('test:prepare:build', cb => {
let runner = exec( const runner = exec(
testBin(COMMON_TEST_COMMAND), testBin(COMMON_TEST_COMMAND),
(err, stdout) => { // eslint-disable-line handle-callback-err (err, stdout) => { // eslint-disable-line handle-callback-err
testResults.push({ testResults.push({
@@ -121,38 +118,36 @@ gulp.task('test:common:safe', gulp.series('test:prepare:build', (cb) => {
pend: testCount(stdout, /(\d+) pending/), pend: testCount(stdout, /(\d+) pending/),
}); });
cb(); cb();
} },
); );
pipe(runner); pipe(runner);
})); }));
gulp.task('test:content', gulp.series('test:prepare:build', (cb) => { gulp.task('test:content', gulp.series('test:prepare:build', cb => {
let runner = exec( const runner = exec(
testBin(CONTENT_TEST_COMMAND), testBin(CONTENT_TEST_COMMAND),
CONTENT_OPTIONS, CONTENT_OPTIONS,
(err) => { err => {
if (err) { if (err) {
process.exit(1); process.exit(1);
} }
cb(); cb();
} },
); );
pipe(runner); pipe(runner);
})); }));
gulp.task('test:content:clean', (cb) => { gulp.task('test:content:clean', cb => {
pipe(exec(testBin(CONTENT_TEST_COMMAND), CONTENT_OPTIONS, () => cb())); pipe(exec(testBin(CONTENT_TEST_COMMAND), CONTENT_OPTIONS, () => cb()));
}); });
gulp.task('test:content:watch', gulp.series('test:content:clean', () => { gulp.task('test:content:watch', gulp.series('test:content:clean', () => gulp.watch(['common/script/content/**', 'test/**'], gulp.series('test:content:clean', done => done()))));
return gulp.watch(['common/script/content/**', 'test/**'], gulp.series('test:content:clean', done => done()));
}));
gulp.task('test:content:safe', gulp.series('test:prepare:build', (cb) => { gulp.task('test:content:safe', gulp.series('test:prepare:build', cb => {
let runner = exec( const runner = exec(
testBin(CONTENT_TEST_COMMAND), testBin(CONTENT_TEST_COMMAND),
CONTENT_OPTIONS, CONTENT_OPTIONS,
(err, stdout) => { // eslint-disable-line handle-callback-err (err, stdout) => { // eslint-disable-line handle-callback-err
testResults.push({ testResults.push({
suite: 'Content Specs\t', suite: 'Content Specs\t',
pass: testCount(stdout, /(\d+) passing/), 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/), pend: testCount(stdout, /(\d+) pending/),
}); });
cb(); cb();
} },
); );
pipe(runner); pipe(runner);
})); }));
gulp.task('test:api:unit', (done) => { gulp.task('test:api:unit', done => {
let runner = exec( const runner = exec(
testBin('istanbul cover --dir coverage/api-unit node_modules/mocha/bin/_mocha -- test/api/unit --recursive --require ./test/helpers/start-server'), 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) { if (err) {
process.exit(1); process.exit(1);
} }
done(); done();
} },
); );
pipe(runner); pipe(runner);
}); });
gulp.task('test:api:unit:watch', () => { gulp.task('test:api:unit:watch', () => gulp.watch(['website/server/libs/*', 'test/api/unit/**/*', 'website/server/controllers/**/*'], gulp.series('test:api:unit', done => done())));
return 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) => { gulp.task('test:api-v3:integration', done => {
let runner = exec( 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'), 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}, { maxBuffer: 500 * 1024 },
(err) => { err => {
if (err) { if (err) {
process.exit(1); process.exit(1);
} }
done(); done();
} },
); );
pipe(runner); pipe(runner);
}); });
gulp.task('test:api-v3:integration:watch', () => { gulp.task('test:api-v3:integration:watch', () => gulp.watch([
return gulp.watch([ 'website/server/controllers/api-v3/**/*', 'common/script/ops/*', 'website/server/libs/*.js',
'website/server/controllers/api-v3/**/*', 'common/script/ops/*', 'website/server/libs/*.js', 'test/api/v3/integration/**/*',
'test/api/v3/integration/**/*', ], gulp.series('test:api-v3:integration', done => done())));
], gulp.series('test:api-v3:integration', done => done()));
});
gulp.task('test:api-v3:integration:separate-server', (done) => { gulp.task('test:api-v3:integration:separate-server', done => {
let runner = exec( const runner = exec(
testBin('mocha test/api/v3/integration --recursive --require ./test/helpers/start-server', 'LOAD_SERVER=0'), testBin('mocha test/api/v3/integration --recursive --require ./test/helpers/start-server', 'LOAD_SERVER=0'),
{maxBuffer: 500 * 1024}, { maxBuffer: 500 * 1024 },
(err) => done(err) err => done(err),
); );
pipe(runner); pipe(runner);
}); });
gulp.task('test:api-v4:integration', (done) => { gulp.task('test:api-v4:integration', done => {
let runner = exec( 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'), 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}, { maxBuffer: 500 * 1024 },
(err) => { err => {
if (err) { if (err) {
process.exit(1); process.exit(1);
} }
done(); done();
} },
); );
pipe(runner); pipe(runner);
}); });
gulp.task('test:api-v4:integration:separate-server', (done) => { gulp.task('test:api-v4:integration:separate-server', done => {
let runner = exec( const runner = exec(
testBin('mocha test/api/v4 --recursive --require ./test/helpers/start-server', 'LOAD_SERVER=0'), testBin('mocha test/api/v4 --recursive --require ./test/helpers/start-server', 'LOAD_SERVER=0'),
{maxBuffer: 500 * 1024}, { maxBuffer: 500 * 1024 },
(err) => done(err) err => done(err),
); );
pipe(runner); pipe(runner);
@@ -247,11 +238,11 @@ gulp.task('test', gulp.series(
'test:api:unit', 'test:api:unit',
'test:api-v3:integration', 'test:api-v3:integration',
'test:api-v4:integration', 'test:api-v4:integration',
done => done() done => done(),
)); ));
gulp.task('test:api-v3', gulp.series( gulp.task('test:api-v3', gulp.series(
'test:api:unit', 'test:api:unit',
'test:api-v3:integration', 'test:api-v3:integration',
done => done() done => done(),
)); ));

View File

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

View File

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

View File

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

View File

@@ -1 +1 @@
db.users.update({_id: {$in: ['']}}, {$inc: {balance: 0.5}}, {multi: true}); db.users.update({ _id: { $in: [''] } }, { $inc: { balance: 0.5 } }, { multi: true });

View File

@@ -4,8 +4,10 @@
// the FAQ (http://goo.gl/1uoPGQ) they insist... // the FAQ (http://goo.gl/1uoPGQ) they insist...
db.users.update( db.users.update(
{_id: ''}, { _id: '' },
{$set: { {
'purchased.plan.dateTerminated': moment().add('month', 1).toDate(), $set: {
}} 'purchased.plan.dateTerminated': moment().add('month', 1).toDate(),
); },
},
);

View File

@@ -2,7 +2,7 @@
db.users.update( db.users.update(
{ {
'contributor.level': {$gte: 7}, 'contributor.level': { $gte: 7 },
'purchased.plan.customerId': null, 'purchased.plan.customerId': null,
}, },
@@ -18,6 +18,6 @@ db.users.update(
}, },
}, },
{multi: true} { multi: true },
); );

View File

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

View File

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

View File

@@ -1,10 +1,9 @@
let oldId = ''; const oldId = '';
let newId = ''; const newId = '';
let newUser = db.users.findOne({_id: 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, // 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 // 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 } });

View File

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

View File

@@ -1,13 +1,15 @@
// mongo habitrpg ./node_modules/moment/moment.js ./migrations/freeMonth.js // mongo habitrpg ./node_modules/moment/moment.js ./migrations/freeMonth.js
db.users.update( db.users.update(
{_id: ''}, { _id: '' },
{$set: { {
'purchased.plan.customerId': 'temporary', $set: {
'purchased.plan.paymentMethod': 'Stripe', 'purchased.plan.customerId': 'temporary',
'purchased.plan.planId': 'basic_earned', 'purchased.plan.paymentMethod': 'Stripe',
'purchased.plan.dateTerminated': moment().add('month', 1).toDate(), 'purchased.plan.planId': 'basic_earned',
}} 'purchased.plan.dateTerminated': moment().add('month', 1).toDate(),
},
},
); );
// var m = 12; // var m = 12;
// db.users.update( // db.users.update(
@@ -29,4 +31,4 @@ db.users.update(
// trinkets: m/3 // trinkets: m/3
// } // }
// }}} // }}}
// ) // )

View File

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

View File

@@ -1 +1 @@
db.users.update({_id: ''}, {$inc: {balance: 5}}); db.users.update({ _id: '' }, { $inc: { balance: 5 } });

View File

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

View File

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

View File

@@ -8,29 +8,27 @@ import { model as Group } from '../../website/server/models/group';
import { model as User } from '../../website/server/models/user'; import { model as User } from '../../website/server/models/user';
async function handOutJackalopes () { async function handOutJackalopes () {
let promises = []; const promises = [];
let cursor = User.find({ const cursor = User.find({
'purchased.plan.customerId': 'habitrpg', 'purchased.plan.customerId': 'habitrpg',
}).cursor(); }).cursor();
cursor.on('data', async (user) => { cursor.on('data', async user => {
console.log(`User: ${ user._id}`); console.log(`User: ${user._id}`);
let groupList = []; let groupList = [];
if (user.party._id) groupList.push(user.party._id); if (user.party._id) groupList.push(user.party._id);
groupList = groupList.concat(user.guilds); groupList = groupList.concat(user.guilds);
let subscribedGroup = const subscribedGroup = await Group.findOne({
await Group.findOne({ _id: { $in: groupList },
_id: {$in: groupList}, 'purchased.plan.planId': 'group_monthly',
'purchased.plan.planId': 'group_monthly', 'purchased.plan.dateTerminated': null,
'purchased.plan.dateTerminated': null, },
}, { _id: 1 });
{_id: 1}
);
if (subscribedGroup) { 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()); promises.push(user.save());
} }
}); });

View File

@@ -12,8 +12,8 @@ import stripePayments from '../../website/server/libs/payments/stripe';
const CONNECTION_STRING = nconf.get('MIGRATION_CONNECT_STRING'); const CONNECTION_STRING = nconf.get('MIGRATION_CONNECT_STRING');
let dbGroups = monk(CONNECTION_STRING).get('groups', { castIds: false }); const dbGroups = monk(CONNECTION_STRING).get('groups', { castIds: false });
let dbUsers = monk(CONNECTION_STRING).get('users', { castIds: false }); const dbUsers = monk(CONNECTION_STRING).get('users', { castIds: false });
async function fixGroupPlanMembers () { async function fixGroupPlanMembers () {
console.info('Group ID, Customer ID, Plan ID, Quantity, Recorded Member Count, Actual Member Count'); console.info('Group ID, Customer ID, Plan ID, Quantity, Recorded Member Count, Actual Member Count');
@@ -24,15 +24,15 @@ async function fixGroupPlanMembers () {
{ {
$and: $and:
[ [
{'purchased.plan.planId': {$ne: null}}, { 'purchased.plan.planId': { $ne: null } },
{'purchased.plan.planId': {$ne: ''}}, { 'purchased.plan.planId': { $ne: '' } },
{'purchased.plan.customerId': {$ne: 'cus_9f0DV4g7WHRzpM'}}, // Demo groups { 'purchased.plan.customerId': { $ne: 'cus_9f0DV4g7WHRzpM' } }, // Demo groups
{'purchased.plan.customerId': {$ne: 'cus_9maalqDOFTrvqx'}}, { 'purchased.plan.customerId': { $ne: 'cus_9maalqDOFTrvqx' } },
], ],
$or: $or:
[ [
{'purchased.plan.dateTerminated': null}, { 'purchased.plan.dateTerminated': null },
{'purchased.plan.dateTerminated': ''}, { 'purchased.plan.dateTerminated': '' },
], ],
}, },
{ {
@@ -40,8 +40,8 @@ async function fixGroupPlanMembers () {
memberCount: 1, memberCount: 1,
'purchased.plan': 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(); pause();
groupPlanCount++; groupPlanCount++;
@@ -49,10 +49,10 @@ async function fixGroupPlanMembers () {
{ {
$or: $or:
[ [
{'party._id': group._id}, { 'party._id': group._id },
{guilds: group._id}, { guilds: group._id },
], ],
} },
); );
const incorrectMemberCount = group.memberCount !== canonicalMemberCount; const incorrectMemberCount = group.memberCount !== canonicalMemberCount;
@@ -73,7 +73,7 @@ async function fixGroupPlanMembers () {
$set: { $set: {
memberCount: canonicalMemberCount, memberCount: canonicalMemberCount,
}, },
} },
); );
if (!groupUpdate) return; if (!groupUpdate) return;
@@ -82,15 +82,15 @@ async function fixGroupPlanMembers () {
if (group.purchased.plan.paymentMethod === 'Stripe') { if (group.purchased.plan.paymentMethod === 'Stripe') {
await stripePayments.chargeForAdditionalGroupMember(group); await stripePayments.chargeForAdditionalGroupMember(group);
await dbGroups.update( await dbGroups.update(
{_id: group._id}, { _id: group._id },
{$set: {'purchased.plan.quantity': canonicalMemberCount + 2}} { $set: { 'purchased.plan.quantity': canonicalMemberCount + 2 } },
); );
} }
if (incorrectQuantity) { if (incorrectQuantity) {
await dbGroups.update( await dbGroups.update(
{_id: group._id}, { _id: group._id },
{$set: {'purchased.plan.quantity': canonicalMemberCount + 2}} { $set: { 'purchased.plan.quantity': canonicalMemberCount + 2 } },
); );
} }
@@ -98,7 +98,7 @@ async function fixGroupPlanMembers () {
}).then(() => { }).then(() => {
console.info(`Fixed ${fixedGroupCount} out of ${groupPlanCount} active Group Plans`); console.info(`Fixed ${fixedGroupCount} out of ${groupPlanCount} active Group Plans`);
return process.exit(0); return process.exit(0);
}).catch((err) => { }).catch(err => {
console.log(err); console.log(err);
return process.exit(1); return process.exit(1);
}); });

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,6 +1,6 @@
let migrationName = 'restock_armoire_for_users_that_need_it.js'; const migrationName = 'restock_armoire_for_users_that_need_it.js';
let authorName = 'Alys (ALittleYellowSpider)'; // in case script author needs to know when their ... const authorName = 'Alys (ALittleYellowSpider)'; // in case script author needs to know when their ...
let authorUuid = '3e595299-3d8a-4a10-bfe0-88f555e4aa0c'; // ... own data is done const authorUuid = '3e595299-3d8a-4a10-bfe0-88f555e4aa0c'; // ... own data is done
/* /*
* Remove flag stating that the Enchanted Armoire is empty, * 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'); const monk = require('monk');
let dbUsers = monk(connectionString).get('users', { castIds: false });
const dbUsers = monk(connectionString).get('users', { castIds: false });
function processUsers (lastId) { function processUsers (lastId) {
// specify a query to limit the affected users (empty for all users): // specify a query to limit the affected users (empty for all users):
let query = { const query = {
'auth.timestamps.loggedin': {$gt: new Date('2016-01-04')}, 'auth.timestamps.loggedin': { $gt: new Date('2016-01-04') },
// '_id': authorUuid // FOR TESTING // '_id': authorUuid // FOR TESTING
}; };
@@ -35,7 +36,7 @@ function processUsers (lastId) {
/* let fields = { /* let fields = {
'flags.armoireEmpty': 1, 'flags.armoireEmpty': 1,
'items.gear.owned': 1, 'items.gear.owned': 1,
};*/ }; */
if (lastId) { if (lastId) {
query._id = { query._id = {
@@ -44,7 +45,7 @@ function processUsers (lastId) {
} }
dbUsers.find(query, { dbUsers.find(query, {
sort: {_id: 1}, sort: { _id: 1 },
limit: 250, limit: 250,
fields: { fields: {
'flags.armoireEmpty': 1, '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): }, // specify fields we are interested in to limit retrieved data (empty if we're not reading data):
}) })
.then(updateUsers) .then(updateUsers)
.catch((err) => { .catch(err => {
console.log(err); console.log(err);
return exiting(1, `ERROR! ${ err}`); return exiting(1, `ERROR! ${err}`);
}); });
} }
let progressCount = 1000; const progressCount = 1000;
let count = 0; let count = 0;
function updateUsers (users) { function updateUsers (users) {
@@ -68,8 +69,8 @@ function updateUsers (users) {
return; return;
} }
let userPromises = users.map(updateUser); const userPromises = users.map(updateUser);
let lastUser = users[users.length - 1]; const lastUser = users[users.length - 1];
return Promise.all(userPromises) return Promise.all(userPromises)
.then(() => { .then(() => {
@@ -80,7 +81,7 @@ function updateUsers (users) {
function updateUser (user) { function updateUser (user) {
count++; count++;
let set = {migration: migrationName, 'flags.armoireEmpty': false}; const set = { migration: migrationName, 'flags.armoireEmpty': false };
if (user.flags.armoireEmpty) { if (user.flags.armoireEmpty) {
@@ -90,7 +91,7 @@ function updateUser (user) {
// console.log("don't change: " + user._id); // FOR TESTING // console.log("don't change: " + user._id); // FOR TESTING
} else { } else {
// console.log("change: " + user._id); // FOR TESTING // console.log("change: " + user._id); // FOR TESTING
dbUsers.update({_id: user._id}, {$set: set}); dbUsers.update({ _id: user._id }, { $set: set });
} }
} else { } else {
// this user already has armoire marked as containing items to be bought // 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 // console.log("DON'T CHANGE: " + user._id); // FOR TESTING
} }
if (count % progressCount === 0) console.warn(`${count } ${ user._id}`); if (count % progressCount === 0) console.warn(`${count} ${user._id}`);
if (user._id === authorUuid) console.warn(`${authorName } processed`); if (user._id === authorUuid) console.warn(`${authorName} processed`);
} }
function displayData () { function displayData () {
console.warn(`\n${ count } users processed\n`); console.warn(`\n${count} users processed\n`);
return exiting(0); return exiting(0);
} }
@@ -115,7 +116,7 @@ function exiting (code, msg) {
if (msg) { if (msg) {
if (code) { if (code) {
console.error(msg); console.error(msg);
} else { } else {
console.log(msg); console.log(msg);
} }
} }

View File

@@ -1,22 +1,24 @@
/* let migrationName = 'restore_profile_data.js'; */ /* let migrationName = 'restore_profile_data.js'; */
let authorName = 'ThehollidayInn'; // in case script author needs to know when their ... const authorName = 'ThehollidayInn'; // in case script author needs to know when their ...
let authorUuid = ''; // ... own data is done const authorUuid = ''; // ... own data is done
/* /*
* Check if users have empty profile data in new database and update it with old database info * Check if users have empty profile data in new database and update it with old database info
*/ */
let monk = require('monk'); const monk = require('monk');
let connectionString = ''; // FOR TEST DATABASE
let dbUsers = monk(connectionString).get('users', { castIds: false });
let monk2 = require('monk'); const connectionString = ''; // FOR TEST DATABASE
let oldDbConnectionString = 'mongodb://localhost:27017/habitrpg?auto_reconnect=true'; // FOR TEST DATABASE const dbUsers = monk(connectionString).get('users', { castIds: false });
let olDbUsers = monk2(oldDbConnectionString).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) { function processUsers (lastId) {
// specify a query to limit the affected users (empty for all users): // specify a query to limit the affected users (empty for all users):
let query = { const query = {
// 'profile.name': 'profile name not found', // 'profile.name': 'profile name not found',
'profile.blurb': null, 'profile.blurb': null,
// 'auth.timestamps.loggedin': {$gt: new Date('11/30/2016')}, // 'auth.timestamps.loggedin': {$gt: new Date('11/30/2016')},
@@ -29,18 +31,18 @@ function processUsers (lastId) {
} }
dbUsers.find(query, { dbUsers.find(query, {
sort: {_id: 1}, sort: { _id: 1 },
limit: 250, 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): 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) .then(updateUsers)
.catch((err) => { .catch(err => {
console.log(err); console.log(err);
return exiting(1, `ERROR! ${ err}`); return exiting(1, `ERROR! ${err}`);
}); });
} }
let progressCount = 1000; const progressCount = 1000;
let count = 0; let count = 0;
function updateUsers (users) { function updateUsers (users) {
@@ -50,28 +52,26 @@ function updateUsers (users) {
return; return;
} }
let userPaymentPromises = users.map(updateUser); const userPaymentPromises = users.map(updateUser);
let lastUser = users[users.length - 1]; const lastUser = users[users.length - 1];
return Promise.all(userPaymentPromises) return Promise.all(userPaymentPromises)
.then(() => { .then(() => processUsers(lastUser._id));
return processUsers(lastUser._id);
});
} }
function updateUser (user) { function updateUser (user) {
count++; count++;
if (!user.profile.name || user.profile.name === 'profile name not found' || !user.profile.imageUrl || !user.profile.blurb) { 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') return olDbUsers.findOne({ _id: user._id }, '_id profile')
.then((oldUserData) => { .then(oldUserData => {
if (!oldUserData) return; if (!oldUserData) return;
// specify user data to change: // specify user data to change:
let set = {}; const set = {};
if (oldUserData.profile.name === 'profile name not found') return; 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) { if (userNeedsProfileName && oldUserData.profile.name) {
set['profile.name'] = 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) { if (Object.keys(set).length !== 0 && set.constructor === Object) {
console.log(set); 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 (count % progressCount === 0) console.warn(`${count} ${user._id}`);
if (user._id === authorUuid) console.warn(`${authorName } processed`); if (user._id === authorUuid) console.warn(`${authorName} processed`);
} }
function displayData () { function displayData () {
console.warn(`\n${ count } users processed\n`); console.warn(`\n${count} users processed\n`);
return exiting(0); return exiting(0);
} }
@@ -108,7 +108,7 @@ function exiting (code, msg) {
if (msg) { if (msg) {
if (code) { if (code) {
console.error(msg); console.error(msg);
} else { } else {
console.log(msg); console.log(msg);
} }
} }

View File

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

View File

@@ -9,13 +9,14 @@
const monk = require('monk'); const monk = require('monk');
const _ = require('lodash'); const _ = require('lodash');
const moment = require('moment'); const moment = require('moment');
const connectionString = 'mongodb://localhost:27017/habitrpg?auto_reconnect=true'; // FOR TEST DATABASE const connectionString = 'mongodb://localhost:27017/habitrpg?auto_reconnect=true'; // FOR TEST DATABASE
const dbTasks = monk(connectionString).get('tasks', { castIds: false }); const dbTasks = monk(connectionString).get('tasks', { castIds: false });
function processChallengeHabits (lastId) { function processChallengeHabits (lastId) {
let query = { const query = {
'challenge.id': {$exists: true}, 'challenge.id': { $exists: true },
userId: {$exists: false}, userId: { $exists: false },
type: 'habit', type: 'habit',
}; };
@@ -26,17 +27,17 @@ function processChallengeHabits (lastId) {
} }
dbTasks.find(query, { dbTasks.find(query, {
sort: {_id: 1}, sort: { _id: 1 },
limit: 500, limit: 500,
}) })
.then(updateChallengeHabits) .then(updateChallengeHabits)
.catch((err) => { .catch(err => {
console.log(err); console.log(err);
return exiting(1, `ERROR! ${ err}`); return exiting(1, `ERROR! ${err}`);
}); });
} }
let progressCount = 1000; const progressCount = 1000;
let count = 0; let count = 0;
function updateChallengeHabits (habits) { function updateChallengeHabits (habits) {
@@ -46,13 +47,11 @@ function updateChallengeHabits (habits) {
return; return;
} }
let habitsPromises = habits.map(updateChallengeHabit); const habitsPromises = habits.map(updateChallengeHabit);
let lastHabit = habits[habits.length - 1]; const lastHabit = habits[habits.length - 1];
return Promise.all(habitsPromises) return Promise.all(habitsPromises)
.then(() => { .then(() => processChallengeHabits(lastHabit._id));
return processChallengeHabits(lastHabit._id);
});
} }
function updateChallengeHabit (habit) { function updateChallengeHabit (habit) {
@@ -76,13 +75,12 @@ function updateChallengeHabit (habit) {
entry.scoreDirection = entry.value > previousValue ? 'up' : 'down'; entry.scoreDirection = entry.value > previousValue ? 'up' : 'down';
} }
}) })
.groupBy(entry => { // group entries by aggregateBy .groupBy(entry => // group entries by aggregateBy
return moment(entry.date).format('YYYYMMDD'); moment(entry.date).format('YYYYMMDD'))
})
.toPairs() // [key, entry] .toPairs() // [key, entry]
.sortBy(([key]) => key) // sort by date .sortBy(([key]) => key) // sort by date
.map(keyEntryPair => { .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 scoredUp = 0;
let scoredDown = 0; let scoredDown = 0;
@@ -107,16 +105,16 @@ function updateChallengeHabit (habit) {
}) })
.value(); .value();
return dbTasks.update({_id: habit._id}, { return dbTasks.update({ _id: habit._id }, {
$set: {history: habit.history}, $set: { history: habit.history },
}); });
} }
if (count % progressCount === 0) console.warn(`${count } habits processed`); if (count % progressCount === 0) console.warn(`${count} habits processed`);
} }
function displayData () { function displayData () {
console.warn(`\n${ count } tasks processed\n`); console.warn(`\n${count} tasks processed\n`);
return exiting(0); return exiting(0);
} }
@@ -128,7 +126,7 @@ function exiting (code, msg) {
if (msg) { if (msg) {
if (code) { if (code) {
console.error(msg); console.error(msg);
} else { } else {
console.log(msg); console.log(msg);
} }
} }

View File

@@ -9,13 +9,14 @@ const authorUuid = 'ed4c688c-6652-4a92-9d03-a5a79844174a'; // ... own data is do
const monk = require('monk'); const monk = require('monk');
const _ = require('lodash'); const _ = require('lodash');
const moment = require('moment'); const moment = require('moment');
const connectionString = 'mongodb://localhost:27017/habitrpg?auto_reconnect=true'; // FOR TEST DATABASE const connectionString = 'mongodb://localhost:27017/habitrpg?auto_reconnect=true'; // FOR TEST DATABASE
const dbTasks = monk(connectionString).get('tasks', { castIds: false }); const dbTasks = monk(connectionString).get('tasks', { castIds: false });
const dbUsers = monk(connectionString).get('users', { castIds: false }); const dbUsers = monk(connectionString).get('users', { castIds: false });
function processUsers (lastId) { function processUsers (lastId) {
let query = { const query = {
migration: {$ne: migrationName}, migration: { $ne: migrationName },
}; };
if (lastId) { if (lastId) {
@@ -25,18 +26,18 @@ function processUsers (lastId) {
} }
dbUsers.find(query, { 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 limit: 50, // just 50 users per time since we have to process all their habits as well
fields: ['_id', 'preferences.timezoneOffset', 'preferences.dayStart'], fields: ['_id', 'preferences.timezoneOffset', 'preferences.dayStart'],
}) })
.then(updateUsers) .then(updateUsers)
.catch((err) => { .catch(err => {
console.log(err); console.log(err);
return exiting(1, `ERROR! ${ err}`); return exiting(1, `ERROR! ${err}`);
}); });
} }
let progressCount = 1000; const progressCount = 1000;
let count = 0; let count = 0;
function updateUsers (users) { function updateUsers (users) {
@@ -46,13 +47,11 @@ function updateUsers (users) {
return; return;
} }
let usersPromises = users.map(updateUser); const usersPromises = users.map(updateUser);
let lastUser = users[users.length - 1]; const lastUser = users[users.length - 1];
return Promise.all(usersPromises) return Promise.all(usersPromises)
.then(() => { .then(() => processUsers(lastUser._id));
return processUsers(lastUser._id);
});
} }
function updateHabit (habit, timezoneOffset, dayStart) { function updateHabit (habit, timezoneOffset, dayStart) {
@@ -82,7 +81,7 @@ function updateHabit (habit, timezoneOffset, dayStart) {
.toPairs() // [key, entry] .toPairs() // [key, entry]
.sortBy(([key]) => key) // sort by date .sortBy(([key]) => key) // sort by date
.map(keyEntryPair => { .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 scoredUp = 0;
let scoredDown = 0; let scoredDown = 0;
@@ -107,8 +106,8 @@ function updateHabit (habit, timezoneOffset, dayStart) {
}) })
.value(); .value();
return dbTasks.update({_id: habit._id}, { return dbTasks.update({ _id: habit._id }, {
$set: {history: habit.history}, $set: { history: habit.history },
}); });
} }
} }
@@ -116,32 +115,28 @@ function updateHabit (habit, timezoneOffset, dayStart) {
function updateUser (user) { function updateUser (user) {
count++; count++;
const timezoneOffset = user.preferences.timezoneOffset; const { timezoneOffset } = user.preferences;
const dayStart = user.preferences.dayStart; const { dayStart } = user.preferences;
if (count % progressCount === 0) console.warn(`${count } ${ user._id}`); if (count % progressCount === 0) console.warn(`${count} ${user._id}`);
if (user._id === authorUuid) console.warn(`${authorName } being processed`); if (user._id === authorUuid) console.warn(`${authorName} being processed`);
return dbTasks.find({ return dbTasks.find({
type: 'habit', type: 'habit',
userId: user._id, userId: user._id,
}) })
.then(habits => { .then(habits => Promise.all(habits.map(habit => updateHabit(habit, timezoneOffset, dayStart))))
return Promise.all(habits.map(habit => updateHabit(habit, timezoneOffset, dayStart))); .then(() => dbUsers.update({ _id: user._id }, {
}) $set: { migration: migrationName },
.then(() => { }))
return dbUsers.update({_id: user._id}, { .catch(err => {
$set: {migration: migrationName},
});
})
.catch((err) => {
console.log(err); console.log(err);
return exiting(1, `ERROR! ${ err}`); return exiting(1, `ERROR! ${err}`);
}); });
} }
function displayData () { function displayData () {
console.warn(`\n${ count } tasks processed\n`); console.warn(`\n${count} tasks processed\n`);
return exiting(0); return exiting(0);
} }
@@ -153,7 +148,7 @@ function exiting (code, msg) {
if (msg) { if (msg) {
if (code) { if (code) {
console.error(msg); console.error(msg);
} else { } else {
console.log(msg); console.log(msg);
} }
} }

View File

@@ -1,18 +1,19 @@
/* let migrationName = 'tasks-set-everyX'; */ /* let migrationName = 'tasks-set-everyX'; */
let authorName = 'Sabe'; // in case script author needs to know when their ... const authorName = 'Sabe'; // in case script author needs to know when their ...
let authorUuid = '7f14ed62-5408-4e1b-be83-ada62d504931'; // ... own data is done 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 * 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'); const monk = require('monk');
let connectionString = 'mongodb://localhost:27017/habitrpg?auto_reconnect=true';
let dbTasks = monk(connectionString).get('tasks', { castIds: false }); const connectionString = 'mongodb://localhost:27017/habitrpg?auto_reconnect=true';
const dbTasks = monk(connectionString).get('tasks', { castIds: false });
function processTasks (lastId) { function processTasks (lastId) {
// specify a query to limit the affected tasks (empty for all tasks): // specify a query to limit the affected tasks (empty for all tasks):
let query = { const query = {
type: 'daily', type: 'daily',
everyX: { everyX: {
$not: { $not: {
@@ -30,18 +31,18 @@ function processTasks (lastId) {
} }
dbTasks.find(query, { dbTasks.find(query, {
sort: {_id: 1}, sort: { _id: 1 },
limit: 250, limit: 250,
fields: [], fields: [],
}) })
.then(updateTasks) .then(updateTasks)
.catch((err) => { .catch(err => {
console.log(err); console.log(err);
return exiting(1, `ERROR! ${ err}`); return exiting(1, `ERROR! ${err}`);
}); });
} }
let progressCount = 1000; const progressCount = 1000;
let count = 0; let count = 0;
function updateTasks (tasks) { function updateTasks (tasks) {
@@ -51,27 +52,25 @@ function updateTasks (tasks) {
return; return;
} }
let taskPromises = tasks.map(updatetask); const taskPromises = tasks.map(updatetask);
let lasttask = tasks[tasks.length - 1]; const lasttask = tasks[tasks.length - 1];
return Promise.all(taskPromises) return Promise.all(taskPromises)
.then(() => { .then(() => processTasks(lasttask._id));
return processTasks(lasttask._id);
});
} }
function updatetask (task) { function updatetask (task) {
count++; 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 (count % progressCount === 0) console.warn(`${count} ${task._id}`);
if (task._id === authorUuid) console.warn(`${authorName } processed`); if (task._id === authorUuid) console.warn(`${authorName} processed`);
} }
function displayData () { function displayData () {
console.warn(`\n${ count } tasks processed\n`); console.warn(`\n${count} tasks processed\n`);
return exiting(0); return exiting(0);
} }
@@ -83,7 +82,7 @@ function exiting (code, msg) {
if (msg) { if (msg) {
if (code) { if (code) {
console.error(msg); console.error(msg);
} else { } else {
console.log(msg); console.log(msg);
} }
} }

View File

@@ -1,6 +1,5 @@
/* let migrationName = 'tasks-set-yesterdaily'; */ /* let migrationName = 'tasks-set-yesterdaily'; */
let authorName = 'TheHollidayInn'; // in case script author needs to know when their ... // ... own data is done
let authorUuid = ''; // ... own data is done
/* /*
* Iterates over all tasks and sets the yseterDaily field to True * 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'; import monk from 'monk';
let connectionString = 'mongodb://localhost:27017/habitrpg?auto_reconnect=true'; // FOR TEST DATABASE const authorName = 'TheHollidayInn'; // in case script author needs to know when their ...
let dbTasks = monk(connectionString).get('tasks', { castIds: false }); 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; let count = 0;
function exiting (code, msg) { function exiting (code, msg) {
@@ -22,7 +24,7 @@ function exiting (code, msg) {
if (msg) { if (msg) {
if (code) { if (code) {
console.error(msg); console.error(msg);
} else { } else {
console.log(msg); console.log(msg);
} }
} }
@@ -30,18 +32,18 @@ function exiting (code, msg) {
} }
function displayData () { function displayData () {
console.warn(`\n${ count } tasks processed\n`); console.warn(`\n${count} tasks processed\n`);
return exiting(0); return exiting(0);
} }
function updatetask (task) { function updatetask (task) {
count++; 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 (count % progressCount === 0) console.warn(`${count} ${task._id}`);
if (task._id === authorUuid) console.warn(`${authorName } processed`); if (task._id === authorUuid) console.warn(`${authorName} processed`);
} }
function updateTasks (tasks) { function updateTasks (tasks) {
@@ -51,18 +53,17 @@ function updateTasks (tasks) {
return; return;
} }
let taskPromises = tasks.map(updatetask); const taskPromises = tasks.map(updatetask);
let lasttask = tasks[tasks.length - 1]; const lasttask = tasks[tasks.length - 1];
return Promise.all(taskPromises) return Promise.all(taskPromises)
.then(() => { .then(() => processTasks(lasttask._id), // eslint-disable-line no-use-before-define
return processTasks(lasttask._id); // eslint-disable-line no-use-before-define );
});
} }
function processTasks (lastId) { function processTasks (lastId) {
// specify a query to limit the affected tasks (empty for all tasks): // specify a query to limit the affected tasks (empty for all tasks):
let query = { const query = {
yesterDaily: false, yesterDaily: false,
}; };
@@ -73,15 +74,15 @@ function processTasks (lastId) {
} }
dbTasks.find(query, { dbTasks.find(query, {
sort: {_id: 1}, sort: { _id: 1 },
limit: 250, limit: 250,
fields: [ // specify fields we are interested in to limit retrieved data (empty if we're not reading data): fields: [ // specify fields we are interested in to limit retrieved data (empty if we're not reading data):
], ],
}) })
.then(updateTasks) .then(updateTasks)
.catch((err) => { .catch(err => {
console.log(err); console.log(err);
return exiting(1, `ERROR! ${ err}`); return exiting(1, `ERROR! ${err}`);
}); });
} }

View File

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

View File

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

View File

@@ -1,8 +1,9 @@
/* eslint-disable no-console */ /* 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 moment from 'moment';
import nconf from 'nconf'; 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 BASE_URL = nconf.get('BASE_URL');
const EMAIL_SLUG = 'mandrill-email-slug'; // Set email template to send const EMAIL_SLUG = 'mandrill-email-slug'; // Set email template to send
const MIGRATION_NAME = 'bulk-email'; const MIGRATION_NAME = 'bulk-email';
@@ -18,16 +19,16 @@ async function updateUser (user) {
sendTxn( sendTxn(
user, user,
EMAIL_SLUG, 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 () { module.exports = async function processUsers () {
let query = { const query = {
migration: {$ne: MIGRATION_NAME}, migration: { $ne: MIGRATION_NAME },
'auth.timestamps.loggedin': {$gt: moment().subtract(2, 'weeks').toDate()}, // customize or remove to target different populations 'auth.timestamps.loggedin': { $gt: moment().subtract(2, 'weeks').toDate() }, // customize or remove to target different populations
}; };
const fields = { const fields = {
@@ -41,7 +42,7 @@ module.exports = async function processUsers () {
const users = await User // eslint-disable-line no-await-in-loop const users = await User // eslint-disable-line no-await-in-loop
.find(query) .find(query)
.limit(250) .limit(250)
.sort({_id: 1}) .sort({ _id: 1 })
.select(fields) .select(fields)
.lean() .lean()
.exec(); .exec();

View File

@@ -1,11 +1,12 @@
/* eslint-disable no-console */ /* eslint-disable no-console */
const MIGRATION_NAME = 'full-stable';
import each from 'lodash/each'; import each from 'lodash/each';
import keys from 'lodash/keys'; import keys from 'lodash/keys';
import content from '../../website/common/script/content/index'; import content from '../../website/common/script/content/index';
import { model as User } from '../../website/server/models/user'; import { model as User } from '../../website/server/models/user';
const MIGRATION_NAME = 'full-stable';
const progressCount = 1000; const progressCount = 1000;
let count = 0; let count = 0;
@@ -20,39 +21,39 @@ async function updateUser (user) {
set.migration = MIGRATION_NAME; set.migration = MIGRATION_NAME;
each(keys(content.pets), (pet) => { each(keys(content.pets), pet => {
set[`items.pets.${pet}`] = 5; set[`items.pets.${pet}`] = 5;
}); });
each(keys(content.premiumPets), (pet) => { each(keys(content.premiumPets), pet => {
set[`items.pets.${pet}`] = 5; set[`items.pets.${pet}`] = 5;
}); });
each(keys(content.questPets), (pet) => { each(keys(content.questPets), pet => {
set[`items.pets.${pet}`] = 5; set[`items.pets.${pet}`] = 5;
}); });
each(keys(content.specialPets), (pet) => { each(keys(content.specialPets), pet => {
set[`items.pets.${pet}`] = 5; set[`items.pets.${pet}`] = 5;
}); });
each(keys(content.mounts), (mount) => { each(keys(content.mounts), mount => {
set[`items.mounts.${mount}`] = true; set[`items.mounts.${mount}`] = true;
}); });
each(keys(content.premiumMounts), (mount) => { each(keys(content.premiumMounts), mount => {
set[`items.mounts.${mount}`] = true; set[`items.mounts.${mount}`] = true;
}); });
each(keys(content.questMounts), (mount) => { each(keys(content.questMounts), mount => {
set[`items.mounts.${mount}`] = true; set[`items.mounts.${mount}`] = true;
}); });
each(keys(content.specialMounts), (mount) => { each(keys(content.specialMounts), mount => {
set[`items.mounts.${mount}`] = true; set[`items.mounts.${mount}`] = true;
}); });
if (count % progressCount === 0) console.warn(`${count} ${user._id}`); 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 () { module.exports = async function processUsers () {
let query = { const query = {
migration: {$ne: MIGRATION_NAME}, migration: { $ne: MIGRATION_NAME },
'auth.local.username': 'olson22', 'auth.local.username': 'olson22',
}; };
@@ -64,7 +65,7 @@ module.exports = async function processUsers () {
const users = await User // eslint-disable-line no-await-in-loop const users = await User // eslint-disable-line no-await-in-loop
.find(query) .find(query)
.limit(250) .limit(250)
.sort({_id: 1}) .sort({ _id: 1 })
.select(fields) .select(fields)
.lean() .lean()
.exec(); .exec();

View File

@@ -1,9 +1,10 @@
/* eslint-disable no-console */ /* 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 User } from '../../website/server/models/user';
import { model as UserNotification } from '../../website/server/models/userNotification'; 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; const progressCount = 1000;
let count = 0; let count = 0;
@@ -29,12 +30,12 @@ async function updateUser (user) {
if (count % progressCount === 0) console.warn(`${count} ${user._id}`); 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 () { module.exports = async function processUsers () {
let query = { const query = {
migration: {$ne: MIGRATION_NAME}, migration: { $ne: MIGRATION_NAME },
'purchased.plan.customerId': { $ne: null }, 'purchased.plan.customerId': { $ne: null },
$or: [ $or: [
{ 'purchased.plan.dateTerminated': { $gte: new Date() } }, { '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 const users = await User // eslint-disable-line no-await-in-loop
.find(query) .find(query)
.limit(250) .limit(250)
.sort({_id: 1}) .sort({ _id: 1 })
.select(fields) .select(fields)
.lean() .lean()
.exec(); .exec();

View File

@@ -1,9 +1,10 @@
/* eslint-disable no-console */ /* eslint-disable no-console */
const MIGRATION_NAME = '20190314_pi_day';
import { v4 as uuid } from 'uuid'; import { v4 as uuid } from 'uuid';
import { model as User } from '../../website/server/models/user'; import { model as User } from '../../website/server/models/user';
const MIGRATION_NAME = '20190314_pi_day';
const progressCount = 1000; const progressCount = 1000;
let count = 0; let count = 0;
@@ -29,19 +30,19 @@ async function updateUser (user) {
set['items.gear.owned.head_special_piDay'] = false; set['items.gear.owned.head_special_piDay'] = false;
set['items.gear.owned.shield_special_piDay'] = false; set['items.gear.owned.shield_special_piDay'] = false;
const push = [ const push = [
{type: 'marketGear', path: 'gear.flat.head_special_piDay', _id: uuid()}, { 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.shield_special_piDay', _id: uuid() },
]; ];
if (count % progressCount === 0) console.warn(`${count} ${user._id}`); 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 () { module.exports = async function processUsers () {
let query = { const query = {
migration: {$ne: MIGRATION_NAME}, migration: { $ne: MIGRATION_NAME },
'auth.timestamps.loggedin': {$gt: new Date('2019-02-15')}, 'auth.timestamps.loggedin': { $gt: new Date('2019-02-15') },
}; };
const fields = { const fields = {
@@ -53,7 +54,7 @@ module.exports = async function processUsers () {
const users = await User // eslint-disable-line no-await-in-loop const users = await User // eslint-disable-line no-await-in-loop
.find(query) .find(query)
.limit(250) .limit(250)
.sort({_id: 1}) .sort({ _id: 1 })
.select(fields) .select(fields)
.lean() .lean()
.exec(); .exec();

View File

@@ -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 connectionString = 'mongodb://localhost:27017/habitrpg?auto_reconnect=true'; // FOR TEST DATABASE
const monk = require('monk'); const monk = require('monk');
const dbUsers = monk(connectionString).get('users', { castIds: false }); const dbUsers = monk(connectionString).get('users', { castIds: false });
function processUsers (lastId) { function processUsers (lastId) {
// specify a query to limit the affected users (empty for all users): // specify a query to limit the affected users (empty for all users):
let query = { const query = {
migration: {$ne: migrationName}, migration: { $ne: migrationName },
$or: [ $or: [
{ 'auth.facebook.id': { $exists: true } }, { 'auth.facebook.id': { $exists: true } },
{ 'auth.google.id': { $exists: true } }, { 'auth.google.id': { $exists: true } },
@@ -27,17 +28,17 @@ function processUsers (lastId) {
} }
dbUsers.find(query, { dbUsers.find(query, {
sort: {_id: 1}, sort: { _id: 1 },
limit: 250, limit: 250,
}) })
.then(updateUsers) .then(updateUsers)
.catch((err) => { .catch(err => {
console.log(err); console.log(err);
return exiting(1, `ERROR! ${ err}`); return exiting(1, `ERROR! ${err}`);
}); });
} }
let progressCount = 1000; const progressCount = 1000;
let count = 0; let count = 0;
function updateUsers (users) { function updateUsers (users) {
@@ -47,8 +48,8 @@ function updateUsers (users) {
return; return;
} }
let userPromises = users.map(updateUser); const userPromises = users.map(updateUser);
let lastUser = users[users.length - 1]; const lastUser = users[users.length - 1];
return Promise.all(userPromises) return Promise.all(userPromises)
.then(() => { .then(() => {
@@ -82,12 +83,12 @@ function updateUser (user) {
_id: user._id, _id: user._id,
}, update); }, update);
if (count % progressCount === 0) console.warn(`${count } ${ user._id}`); if (count % progressCount === 0) console.warn(`${count} ${user._id}`);
if (user._id === authorUuid) console.warn(`${authorName } processed`); if (user._id === authorUuid) console.warn(`${authorName} processed`);
} }
function displayData () { function displayData () {
console.warn(`\n${ count } users processed\n`); console.warn(`\n${count} users processed\n`);
return exiting(0); return exiting(0);
} }
@@ -99,7 +100,7 @@ function exiting (code, msg) {
if (msg) { if (msg) {
if (code) { if (code) {
console.error(msg); console.error(msg);
} else { } else {
console.log(msg); console.log(msg);
} }
} }

View File

@@ -1,9 +1,10 @@
/* eslint-disable no-console */ /* eslint-disable no-console */
const MIGRATION_NAME = '20181203_take_this';
import { v4 as uuid } from 'uuid'; import { v4 as uuid } from 'uuid';
import { model as User } from '../../website/server/models/user'; import { model as User } from '../../website/server/models/user';
const MIGRATION_NAME = '20181203_take_this';
const progressCount = 1000; const progressCount = 1000;
let count = 0; let count = 0;
@@ -19,36 +20,35 @@ async function updateUser (user) {
push = false; push = false;
} else if (typeof user.items.gear.owned.body_special_takeThis !== 'undefined') { } else if (typeof user.items.gear.owned.body_special_takeThis !== 'undefined') {
set['items.gear.owned.back_special_takeThis'] = false; 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') { } else if (typeof user.items.gear.owned.head_special_takeThis !== 'undefined') {
set['items.gear.owned.body_special_takeThis'] = false; 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') { } else if (typeof user.items.gear.owned.armor_special_takeThis !== 'undefined') {
set['items.gear.owned.head_special_takeThis'] = false; 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') { } else if (typeof user.items.gear.owned.weapon_special_takeThis !== 'undefined') {
set['items.gear.owned.armor_special_takeThis'] = false; 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') { } else if (typeof user.items.gear.owned.shield_special_takeThis !== 'undefined') {
set['items.gear.owned.weapon_special_takeThis'] = false; 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 { } else {
set['items.gear.owned.shield_special_takeThis'] = false; 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 (count % progressCount === 0) console.warn(`${count} ${user._id}`);
if (push) { if (push) {
return await User.update({_id: user._id}, {$set: set, $push: push}).exec(); return await User.update({ _id: user._id }, { $set: set, $push: push }).exec();
} else {
return await User.update({_id: user._id}, {$set: set}).exec();
} }
return await User.update({ _id: user._id }, { $set: set }).exec();
} }
module.exports = async function processUsers () { module.exports = async function processUsers () {
let query = { const query = {
migration: {$ne: MIGRATION_NAME}, migration: { $ne: MIGRATION_NAME },
challenges: '00708425-d477-41a5-bf27-6270466e7976', 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 const users = await User // eslint-disable-line no-await-in-loop
.find(query) .find(query)
.limit(250) .limit(250)
.sort({_id: 1}) .sort({ _id: 1 })
.select(fields) .select(fields)
.lean() .lean()
.exec(); .exec();

View File

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

View File

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

View File

@@ -1,10 +1,9 @@
'use strict';
const chalk = require('chalk'); const chalk = require('chalk');
function loggerGenerator (type, color) { function loggerGenerator (type, color) {
return function logger () { 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); console[type].apply(null, args);
}; };
} }

View File

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

View File

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

911
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -72,7 +72,7 @@
"npm": "^6" "npm": "^6"
}, },
"scripts": { "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": "npm run lint && gulp test && gulp apidoc",
"test:build": "gulp test:prepare:build", "test:build": "gulp test:prepare:build",
"test:api-v3": "gulp test:api-v3", "test:api-v3": "gulp test:api-v3",
@@ -101,8 +101,8 @@
"chai": "^4.1.2", "chai": "^4.1.2",
"chai-as-promised": "^7.1.1", "chai-as-promised": "^7.1.1",
"chalk": "^2.4.1", "chalk": "^2.4.1",
"eslint": "^4.19.1", "eslint": "^6.5.1",
"eslint-config-habitrpg": "^4.0.0", "eslint-config-habitrpg": "^6.0.3",
"eslint-plugin-mocha": "^5.0.0", "eslint-plugin-mocha": "^5.0.0",
"expect.js": "^0.3.1", "expect.js": "^0.3.1",
"istanbul": "^1.1.0-alpha.1", "istanbul": "^1.1.0-alpha.1",

View File

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

View File

@@ -12,11 +12,12 @@ const nconf = require('nconf');
const _ = require('lodash'); const _ = require('lodash');
const paypal = require('paypal-rest-sdk'); const paypal = require('paypal-rest-sdk');
const blocks = require('../website/common').content.subscriptionBlocks; const blocks = require('../website/common').content.subscriptionBlocks;
const live = nconf.get('PAYPAL_MODE') === 'live'; const live = nconf.get('PAYPAL_MODE') === 'live';
nconf.argv().env().file('user', path.join(path.resolve(__dirname, '../config.json'))); 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({ paypal.configure({
mode: nconf.get('PAYPAL_MODE'), // sandbox or live mode: nconf.get('PAYPAL_MODE'), // sandbox or live
@@ -25,8 +26,8 @@ paypal.configure({
}); });
// https://developer.paypal.com/docs/api/#billing-plans-and-agreements // https://developer.paypal.com/docs/api/#billing-plans-and-agreements
let billingPlanTitle = 'Habitica Subscription'; const billingPlanTitle = 'Habitica Subscription';
let billingPlanAttributes = { const billingPlanAttributes = {
description: billingPlanTitle, description: billingPlanTitle,
type: 'INFINITE', type: 'INFINITE',
merchant_preferences: { merchant_preferences: {
@@ -41,7 +42,7 @@ let billingPlanAttributes = {
}], }],
}; };
_.each(blocks, (block) => { _.each(blocks, block => {
block.definition = _.cloneDeep(billingPlanAttributes); block.definition = _.cloneDeep(billingPlanAttributes);
_.merge(block.definition.payment_definitions[0], { _.merge(block.definition.payment_definitions[0], {
name: `${billingPlanTitle} ($${block.price} every ${block.months} months, recurring)`, name: `${billingPlanTitle} ($${block.price} every ${block.months} months, recurring)`,
@@ -57,17 +58,17 @@ _.each(blocks, (block) => {
switch (OP) { switch (OP) {
case 'list': case 'list':
paypal.billingPlan.list({status: 'ACTIVE'}, (err, plans) => { paypal.billingPlan.list({ status: 'ACTIVE' }, (err, plans) => {
console.log({err, plans}); console.log({ err, plans });
}); });
break; break;
case 'get': case 'get':
paypal.billingPlan.get(nconf.get('PAYPAL_BILLING_PLANS_basic_12mo'), (err, plan) => { paypal.billingPlan.get(nconf.get('PAYPAL_BILLING_PLANS_basic_12mo'), (err, plan) => {
console.log({err, plan}); console.log({ err, plan });
}); });
break; break;
case 'update': case 'update':
let updatePayload = { const updatePayload = {
op: 'replace', op: 'replace',
path: '/merchant_preferences', path: '/merchant_preferences',
value: { value: {
@@ -75,7 +76,7 @@ switch (OP) {
}, },
}; };
paypal.billingPlan.update(nconf.get('PAYPAL_BILLING_PLANS_basic_12mo'), updatePayload, (err, res) => { paypal.billingPlan.update(nconf.get('PAYPAL_BILLING_PLANS_basic_12mo'), updatePayload, (err, res) => {
console.log({err, plan: res}); console.log({ err, plan: res });
}); });
break; break;
case 'create': case 'create':
@@ -83,10 +84,10 @@ switch (OP) {
if (err) return console.log(err); if (err) return console.log(err);
if (plan.state === 'ACTIVE') { if (plan.state === 'ACTIVE') {
return console.log({err, plan}); return console.log({ err, plan });
} }
let billingPlanUpdateAttributes = [{ const billingPlanUpdateAttributes = [{
op: 'replace', op: 'replace',
path: '/', path: '/',
value: { value: {
@@ -96,12 +97,12 @@ switch (OP) {
// Activate the plan by changing status to Active // Activate the plan by changing status to Active
paypal.billingPlan.update(plan.id, billingPlanUpdateAttributes, (err2, response) => { 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; break;
case 'create-webprofile': case 'create-webprofile':
let webexpinfo = { const webexpinfo = {
name: 'HabiticaProfile', name: 'HabiticaProfile',
input_fields: { input_fields: {
no_shipping: 1, no_shipping: 1,

View File

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

View File

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

View File

@@ -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 // @TODO use those constants to replace hard-coded numbers
export const SUPPORTED_SOCIAL_NETWORKS = [ export const SUPPORTED_SOCIAL_NETWORKS = [
{key: 'facebook', name: 'Facebook'}, { key: 'facebook', name: 'Facebook' },
{key: 'google', name: 'Google'}, { key: 'google', name: 'Google' },
]; ];
export const GUILDS_PER_PAGE = 30; // number of guilds to return per page when using pagination export const GUILDS_PER_PAGE = 30; // number of guilds to return per page when using pagination

View File

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

View File

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

View File

@@ -4,23 +4,23 @@ import sets from '../sets.js';
export default prefill({ export default prefill({
0: {}, 0: {},
1: {}, 1: {},
2: {price: 2, set: sets.baseHair1}, 2: { price: 2, set: sets.baseHair1 },
3: {}, 3: {},
4: {price: 2, set: sets.baseHair1}, 4: { price: 2, set: sets.baseHair1 },
5: {price: 2, set: sets.baseHair1}, 5: { price: 2, set: sets.baseHair1 },
6: {price: 2, set: sets.baseHair1}, 6: { price: 2, set: sets.baseHair1 },
7: {price: 2, set: sets.baseHair1}, 7: { price: 2, set: sets.baseHair1 },
8: {price: 2, set: sets.baseHair1}, 8: { price: 2, set: sets.baseHair1 },
9: {price: 2, set: sets.baseHair2}, 9: { price: 2, set: sets.baseHair2 },
10: {price: 2, set: sets.baseHair2}, 10: { price: 2, set: sets.baseHair2 },
11: {price: 2, set: sets.baseHair2}, 11: { price: 2, set: sets.baseHair2 },
12: {price: 2, set: sets.baseHair2}, 12: { price: 2, set: sets.baseHair2 },
13: {price: 2, set: sets.baseHair2}, 13: { price: 2, set: sets.baseHair2 },
14: {price: 2, set: sets.baseHair2}, 14: { price: 2, set: sets.baseHair2 },
15: {price: 2, set: sets.baseHair3}, 15: { price: 2, set: sets.baseHair3 },
16: {price: 2, set: sets.baseHair3}, 16: { price: 2, set: sets.baseHair3 },
17: {price: 2, set: sets.baseHair3}, 17: { price: 2, set: sets.baseHair3 },
18: {price: 2, set: sets.baseHair3}, 18: { price: 2, set: sets.baseHair3 },
19: {price: 2, set: sets.baseHair3}, 19: { price: 2, set: sets.baseHair3 },
20: {price: 2, set: sets.baseHair3}, 20: { price: 2, set: sets.baseHair3 },
}); });

View File

@@ -3,7 +3,7 @@ import prefill from '../prefill.js';
export default prefill({ export default prefill({
0: {}, 0: {},
1: {price: 2, set: sets.facialHair}, 1: { price: 2, set: sets.facialHair },
2: {price: 2, set: sets.facialHair}, 2: { price: 2, set: sets.facialHair },
3: {price: 2, set: sets.facialHair}, 3: { price: 2, set: sets.facialHair },
}); });

View File

@@ -8,43 +8,43 @@ export default prefill({
red: {}, red: {},
black: {}, black: {},
candycane: {price: 2, set: sets.winterHairColors}, candycane: { price: 2, set: sets.winterHairColors },
frost: {price: 2, set: sets.winterHairColors}, frost: { price: 2, set: sets.winterHairColors },
winternight: {price: 2, set: sets.winterHairColors}, winternight: { price: 2, set: sets.winterHairColors },
holly: {price: 2, set: sets.winterHairColors}, holly: { price: 2, set: sets.winterHairColors },
pblue: {price: 2, set: sets.pastelHairColors}, pblue: { price: 2, set: sets.pastelHairColors },
pgreen: {price: 2, set: sets.pastelHairColors}, pgreen: { price: 2, set: sets.pastelHairColors },
porange: {price: 2, set: sets.pastelHairColors}, porange: { price: 2, set: sets.pastelHairColors },
ppink: {price: 2, set: sets.pastelHairColors}, ppink: { price: 2, set: sets.pastelHairColors },
ppurple: {price: 2, set: sets.pastelHairColors}, ppurple: { price: 2, set: sets.pastelHairColors },
pyellow: {price: 2, set: sets.pastelHairColors}, pyellow: { price: 2, set: sets.pastelHairColors },
rainbow: {price: 2, set: sets.rainbowHairColors}, rainbow: { price: 2, set: sets.rainbowHairColors },
yellow: {price: 2, set: sets.rainbowHairColors}, yellow: { price: 2, set: sets.rainbowHairColors },
green: {price: 2, set: sets.rainbowHairColors}, green: { price: 2, set: sets.rainbowHairColors },
purple: {price: 2, set: sets.rainbowHairColors}, purple: { price: 2, set: sets.rainbowHairColors },
blue: {price: 2, set: sets.rainbowHairColors}, blue: { price: 2, set: sets.rainbowHairColors },
TRUred: {price: 2, set: sets.rainbowHairColors}, TRUred: { price: 2, set: sets.rainbowHairColors },
pblue2: {price: 2, set: sets.shimmerHairColors}, pblue2: { price: 2, set: sets.shimmerHairColors },
pgreen2: {price: 2, set: sets.shimmerHairColors}, pgreen2: { price: 2, set: sets.shimmerHairColors },
porange2: {price: 2, set: sets.shimmerHairColors}, porange2: { price: 2, set: sets.shimmerHairColors },
ppink2: {price: 2, set: sets.shimmerHairColors}, ppink2: { price: 2, set: sets.shimmerHairColors },
ppurple2: {price: 2, set: sets.shimmerHairColors}, ppurple2: { price: 2, set: sets.shimmerHairColors },
pyellow2: {price: 2, set: sets.shimmerHairColors}, pyellow2: { price: 2, set: sets.shimmerHairColors },
candycorn: {price: 2, set: sets.hauntedHairColors}, candycorn: { price: 2, set: sets.hauntedHairColors },
ghostwhite: {price: 2, set: sets.hauntedHairColors}, ghostwhite: { price: 2, set: sets.hauntedHairColors },
halloween: {price: 2, set: sets.hauntedHairColors}, halloween: { price: 2, set: sets.hauntedHairColors },
midnight: {price: 2, set: sets.hauntedHairColors}, midnight: { price: 2, set: sets.hauntedHairColors },
pumpkin: {price: 2, set: sets.hauntedHairColors}, pumpkin: { price: 2, set: sets.hauntedHairColors },
zombie: {price: 2, set: sets.hauntedHairColors}, zombie: { price: 2, set: sets.hauntedHairColors },
aurora: {price: 2, set: sets.winteryHairColors}, aurora: { price: 2, set: sets.winteryHairColors },
festive: {price: 2, set: sets.winteryHairColors}, festive: { price: 2, set: sets.winteryHairColors },
hollygreen: {price: 2, set: sets.winteryHairColors}, hollygreen: { price: 2, set: sets.winteryHairColors },
peppermint: {price: 2, set: sets.winteryHairColors}, peppermint: { price: 2, set: sets.winteryHairColors },
snowy: {price: 2, set: sets.winteryHairColors}, snowy: { price: 2, set: sets.winteryHairColors },
winterstar: {price: 2, set: sets.winteryHairColors}, winterstar: { price: 2, set: sets.winteryHairColors },
}); });

View File

@@ -3,6 +3,6 @@ import prefill from '../prefill.js';
export default prefill({ export default prefill({
0: {}, 0: {},
1: {price: 2, set: sets.facialHair}, 1: { price: 2, set: sets.facialHair },
2: {price: 2, set: sets.facialHair}, 2: { price: 2, set: sets.facialHair },
}); });

View File

@@ -3,10 +3,10 @@ import sets from '../sets.js';
export default prefill({ export default prefill({
0: {}, 0: {},
1: {price: 2, set: sets.topHair}, 1: { price: 2, set: sets.topHair },
2: {price: 2, set: sets.topHair}, 2: { price: 2, set: sets.topHair },
3: {price: 2, set: sets.topHair}, 3: { price: 2, set: sets.topHair },
4: {price: 2, set: sets.topHair}, 4: { price: 2, set: sets.topHair },
5: {price: 2, set: sets.topHair}, 5: { price: 2, set: sets.topHair },
6: {price: 2, set: sets.topHair}, 6: { price: 2, set: sets.topHair },
}); });

View File

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

View File

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

View File

@@ -2,22 +2,36 @@ import t from '../translation';
import prefill from './prefill.js'; import prefill from './prefill.js';
export default prefill({ export default prefill({
baseHair1: {setPrice: 5, text: t('hairSet1')}, baseHair1: { setPrice: 5, text: t('hairSet1') },
baseHair2: {setPrice: 5, text: t('hairSet2')}, baseHair2: { setPrice: 5, text: t('hairSet2') },
baseHair3: {setPrice: 5, text: t('hairSet3')}, baseHair3: { setPrice: 5, text: t('hairSet3') },
facialHair: {setPrice: 5, text: t('bodyFacialHair')}, facialHair: { setPrice: 5, text: t('bodyFacialHair') },
specialShirts: {setPrice: 5, text: t('specialShirts')}, specialShirts: { setPrice: 5, text: t('specialShirts') },
winterHairColors: {setPrice: 5, availableUntil: '2016-01-01'}, winterHairColors: { setPrice: 5, availableUntil: '2016-01-01' },
pastelHairColors: {setPrice: 5, availableUntil: '2016-01-01'}, pastelHairColors: { setPrice: 5, availableUntil: '2016-01-01' },
rainbowHairColors: {setPrice: 5, text: t('rainbowColors')}, rainbowHairColors: { setPrice: 5, text: t('rainbowColors') },
shimmerHairColors: {setPrice: 5, availableFrom: '2019-04-09', availableUntil: '2019-05-02', text: t('shimmerColors')}, shimmerHairColors: {
hauntedHairColors: {setPrice: 5, availableFrom: '2018-10-11', availableUntil: '2018-11-02', text: t('hauntedColors')}, setPrice: 5, availableFrom: '2019-04-09', availableUntil: '2019-05-02', text: t('shimmerColors'),
winteryHairColors: {setPrice: 5, availableFrom: '2019-01-08', availableUntil: '2019-02-02', text: t('winteryColors')}, },
rainbowSkins: {setPrice: 5, text: t('rainbowSkins')}, hauntedHairColors: {
animalSkins: {setPrice: 5, text: t('animalSkins')}, setPrice: 5, availableFrom: '2018-10-11', availableUntil: '2018-11-02', text: t('hauntedColors'),
pastelSkins: {setPrice: 5, availableFrom: '2019-04-09', availableUntil: '2019-05-02', text: t('pastelSkins')}, },
spookySkins: {setPrice: 5, availableUntil: '2016-01-01', text: t('spookySkins')}, winteryHairColors: {
supernaturalSkins: {setPrice: 5, availableFrom: '2018-10-11', availableUntil: '2018-11-02', text: t('supernaturalSkins')}, setPrice: 5, availableFrom: '2019-01-08', availableUntil: '2019-02-02', text: t('winteryColors'),
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')}, 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'),
},
}); });

View File

@@ -9,15 +9,15 @@ export default prefill({
white: {}, white: {},
yellow: {}, yellow: {},
convict: {price: 2, set: sets.specialShirts}, convict: { price: 2, set: sets.specialShirts },
cross: {price: 2, set: sets.specialShirts}, cross: { price: 2, set: sets.specialShirts },
fire: {price: 2, set: sets.specialShirts}, fire: { price: 2, set: sets.specialShirts },
horizon: {price: 2, set: sets.specialShirts}, horizon: { price: 2, set: sets.specialShirts },
ocean: {price: 2, set: sets.specialShirts}, ocean: { price: 2, set: sets.specialShirts },
purple: {price: 2, set: sets.specialShirts}, purple: { price: 2, set: sets.specialShirts },
rainbow: {price: 2, set: sets.specialShirts}, rainbow: { price: 2, set: sets.specialShirts },
redblue: {price: 2, set: sets.specialShirts}, redblue: { price: 2, set: sets.specialShirts },
thunder: {price: 2, set: sets.specialShirts}, thunder: { price: 2, set: sets.specialShirts },
tropical: {price: 2, set: sets.specialShirts}, tropical: { price: 2, set: sets.specialShirts },
zombie: {price: 2, set: sets.specialShirts}, zombie: { price: 2, set: sets.specialShirts },
}); });

View File

@@ -12,66 +12,66 @@ export default prefill({
'c3e1dc': {}, 'c3e1dc': {},
'6bd049': {}, '6bd049': {},
'eb052b': {price: 2, set: sets.rainbowSkins}, 'eb052b': { price: 2, set: sets.rainbowSkins },
'f69922': {price: 2, set: sets.rainbowSkins}, 'f69922': { price: 2, set: sets.rainbowSkins },
'f5d70f': {price: 2, set: sets.rainbowSkins}, 'f5d70f': { price: 2, set: sets.rainbowSkins },
'0ff591': {price: 2, set: sets.rainbowSkins}, '0ff591': { price: 2, set: sets.rainbowSkins },
'2b43f6': {price: 2, set: sets.rainbowSkins}, '2b43f6': { price: 2, set: sets.rainbowSkins },
'd7a9f7': {price: 2, set: sets.rainbowSkins}, 'd7a9f7': { price: 2, set: sets.rainbowSkins },
'800ed0': {price: 2, set: sets.rainbowSkins}, '800ed0': { price: 2, set: sets.rainbowSkins },
'rainbow': {price: 2, set: sets.rainbowSkins}, 'rainbow': { price: 2, set: sets.rainbowSkins },
'bear': {price: 2, set: sets.animalSkins}, 'bear': { price: 2, set: sets.animalSkins },
'cactus': {price: 2, set: sets.animalSkins}, 'cactus': { price: 2, set: sets.animalSkins },
'fox': {price: 2, set: sets.animalSkins}, 'fox': { price: 2, set: sets.animalSkins },
'lion': {price: 2, set: sets.animalSkins}, 'lion': { price: 2, set: sets.animalSkins },
'panda': {price: 2, set: sets.animalSkins}, 'panda': { price: 2, set: sets.animalSkins },
'pig': {price: 2, set: sets.animalSkins}, 'pig': { price: 2, set: sets.animalSkins },
'tiger': {price: 2, set: sets.animalSkins}, 'tiger': { price: 2, set: sets.animalSkins },
'wolf': {price: 2, set: sets.animalSkins}, 'wolf': { price: 2, set: sets.animalSkins },
'pastelPink': {price: 2, set: sets.pastelSkins}, 'pastelPink': { price: 2, set: sets.pastelSkins },
'pastelOrange': {price: 2, set: sets.pastelSkins}, 'pastelOrange': { price: 2, set: sets.pastelSkins },
'pastelYellow': {price: 2, set: sets.pastelSkins}, 'pastelYellow': { price: 2, set: sets.pastelSkins },
'pastelGreen': {price: 2, set: sets.pastelSkins}, 'pastelGreen': { price: 2, set: sets.pastelSkins },
'pastelBlue': {price: 2, set: sets.pastelSkins}, 'pastelBlue': { price: 2, set: sets.pastelSkins },
'pastelPurple': {price: 2, set: sets.pastelSkins}, 'pastelPurple': { price: 2, set: sets.pastelSkins },
'pastelRainbowChevron': {price: 2, set: sets.pastelSkins}, 'pastelRainbowChevron': { price: 2, set: sets.pastelSkins },
'pastelRainbowDiagonal': {price: 2, set: sets.pastelSkins}, 'pastelRainbowDiagonal': { price: 2, set: sets.pastelSkins },
'monster': {price: 2, set: sets.spookySkins}, 'monster': { price: 2, set: sets.spookySkins },
'pumpkin': {price: 2, set: sets.spookySkins}, 'pumpkin': { price: 2, set: sets.spookySkins },
'skeleton': {price: 2, set: sets.spookySkins}, 'skeleton': { price: 2, set: sets.spookySkins },
'zombie': {price: 2, set: sets.spookySkins}, 'zombie': { price: 2, set: sets.spookySkins },
'ghost': {price: 2, set: sets.spookySkins}, 'ghost': { price: 2, set: sets.spookySkins },
'shadow': {price: 2, set: sets.spookySkins}, 'shadow': { price: 2, set: sets.spookySkins },
'candycorn': {price: 2, set: sets.supernaturalSkins}, 'candycorn': { price: 2, set: sets.supernaturalSkins },
'ogre': {price: 2, set: sets.supernaturalSkins}, 'ogre': { price: 2, set: sets.supernaturalSkins },
'pumpkin2': {price: 2, set: sets.supernaturalSkins}, 'pumpkin2': { price: 2, set: sets.supernaturalSkins },
'reptile': {price: 2, set: sets.supernaturalSkins}, 'reptile': { price: 2, set: sets.supernaturalSkins },
'shadow2': {price: 2, set: sets.supernaturalSkins}, 'shadow2': { price: 2, set: sets.supernaturalSkins },
'skeleton2': {price: 2, set: sets.supernaturalSkins}, 'skeleton2': { price: 2, set: sets.supernaturalSkins },
'transparent': {price: 2, set: sets.supernaturalSkins}, 'transparent': { price: 2, set: sets.supernaturalSkins },
'zombie2': {price: 2, set: sets.supernaturalSkins}, 'zombie2': { price: 2, set: sets.supernaturalSkins },
'clownfish': {price: 2, set: sets.splashySkins}, 'clownfish': { price: 2, set: sets.splashySkins },
'deepocean': {price: 2, set: sets.splashySkins}, 'deepocean': { price: 2, set: sets.splashySkins },
'merblue': {price: 2, set: sets.splashySkins}, 'merblue': { price: 2, set: sets.splashySkins },
'mergold': {price: 2, set: sets.splashySkins}, 'mergold': { price: 2, set: sets.splashySkins },
'mergreen': {price: 2, set: sets.splashySkins}, 'mergreen': { price: 2, set: sets.splashySkins },
'merruby': {price: 2, set: sets.splashySkins}, 'merruby': { price: 2, set: sets.splashySkins },
'shark': {price: 2, set: sets.splashySkins}, 'shark': { price: 2, set: sets.splashySkins },
'tropicalwater': {price: 2, set: sets.splashySkins}, 'tropicalwater': { price: 2, set: sets.splashySkins },
'aurora': {price: 2, set: sets.winterySkins}, 'aurora': { price: 2, set: sets.winterySkins },
'dapper': {price: 2, set: sets.winterySkins}, 'dapper': { price: 2, set: sets.winterySkins },
'festive': {price: 2, set: sets.winterySkins}, 'festive': { price: 2, set: sets.winterySkins },
'holly': {price: 2, set: sets.winterySkins}, 'holly': { price: 2, set: sets.winterySkins },
'polar': {price: 2, set: sets.winterySkins}, 'polar': { price: 2, set: sets.winterySkins },
'sugar': {price: 2, set: sets.winterySkins}, 'sugar': { price: 2, set: sets.winterySkins },
'snowy': {price: 2, set: sets.winterySkins}, 'snowy': { price: 2, set: sets.winterySkins },
'winterstar': {price: 2, set: sets.winterySkins}, 'winterstar': { price: 2, set: sets.winterySkins },
/* eslint-enable quote-props */ /* eslint-enable quote-props */
}); });

View File

@@ -203,19 +203,19 @@ export const GEAR_TYPES = [
]; ];
export const ITEM_LIST = { export const ITEM_LIST = {
weapon: { localeKey: 'weapon', isEquipment: true }, weapon: { localeKey: 'weapon', isEquipment: true },
armor: { localeKey: 'armor', isEquipment: true }, armor: { localeKey: 'armor', isEquipment: true },
head: { localeKey: 'headgear', isEquipment: true }, head: { localeKey: 'headgear', isEquipment: true },
shield: { localeKey: 'offhand', isEquipment: true }, shield: { localeKey: 'offhand', isEquipment: true },
back: { localeKey: 'back', isEquipment: true }, back: { localeKey: 'back', isEquipment: true },
body: { localeKey: 'body', isEquipment: true }, body: { localeKey: 'body', isEquipment: true },
headAccessory: { localeKey: 'headAccessory', isEquipment: true }, headAccessory: { localeKey: 'headAccessory', isEquipment: true },
eyewear: { localeKey: 'eyewear', isEquipment: true }, eyewear: { localeKey: 'eyewear', isEquipment: true },
hatchingPotions: { localeKey: 'hatchingPotion', isEquipment: false }, hatchingPotions: { localeKey: 'hatchingPotion', isEquipment: false },
premiumHatchingPotions: { localeKey: 'hatchingPotion', isEquipment: false }, premiumHatchingPotions: { localeKey: 'hatchingPotion', isEquipment: false },
eggs: { localeKey: 'eggSingular', isEquipment: false }, eggs: { localeKey: 'eggSingular', isEquipment: false },
quests: { localeKey: 'quest', isEquipment: false }, quests: { localeKey: 'quest', isEquipment: false },
food: { localeKey: 'foodTextThe', isEquipment: false }, food: { localeKey: 'foodTextThe', isEquipment: false },
Saddle: { localeKey: 'foodSaddleText', isEquipment: false }, Saddle: { localeKey: 'foodSaddleText', isEquipment: false },
bundles: { localeKey: 'discountBundle', isEquipment: false }, bundles: { localeKey: 'discountBundle', isEquipment: false },
}; };
@@ -264,6 +264,10 @@ export const QUEST_SERIES_ACHIEVEMENTS = {
}; };
export const ANIMAL_COLOR_ACHIEVEMENTS = [ export const ANIMAL_COLOR_ACHIEVEMENTS = [
{color: 'Base', petAchievement: 'backToBasics', petNotificationType: 'ACHIEVEMENT_BACK_TO_BASICS', mountAchievement: 'allYourBase', mountNotificationType: 'ACHIEVEMENT_ALL_YOUR_BASE'}, {
{color: 'Desert', petAchievement: 'dustDevil', petNotificationType: 'ACHIEVEMENT_DUST_DEVIL', mountAchievement: 'aridAuthority', mountNotificationType: 'ACHIEVEMENT_ARID_AUTHORITY'}, color: 'Base', petAchievement: 'backToBasics', petNotificationType: 'ACHIEVEMENT_BACK_TO_BASICS', mountAchievement: 'allYourBase', mountNotificationType: 'ACHIEVEMENT_ALL_YOUR_BASE',
},
{
color: 'Desert', petAchievement: 'dustDevil', petNotificationType: 'ACHIEVEMENT_DUST_DEVIL', mountAchievement: 'aridAuthority', mountNotificationType: 'ACHIEVEMENT_ARID_AUTHORITY',
},
]; ];

View File

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

View File

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

View File

@@ -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 warriorArmor } from './sets/warrior';
import {armor as rogueArmor} from './sets/rogue'; import { armor as rogueArmor } from './sets/rogue';
import {armor as healerArmor} from './sets/healer'; import { armor as healerArmor } from './sets/healer';
import {armor as wizardArmor} from './sets/wizard'; import { armor as wizardArmor } from './sets/wizard';
import {armor as specialArmor} from './sets/special'; import { armor as specialArmor } from './sets/special';
import {armor as mysteryArmor} from './sets/mystery'; import { armor as mysteryArmor } from './sets/mystery';
import {armor as armoireArmor} from './sets/armoire'; import { armor as armoireArmor } from './sets/armoire';
let armor = { const armor = {
base: baseArmor, base: baseArmor,
warrior: warriorArmor, warrior: warriorArmor,

View File

@@ -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 mysteryBack } from './sets/mystery';
import {back as specialBack} from './sets/special'; import { back as specialBack } from './sets/special';
let back = { const back = {
base: baseBack, base: baseBack,
mystery: mysteryBack, mystery: mysteryBack,
special: specialBack, special: specialBack,
}; };
export default back; export default back;

View File

@@ -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 mysteryBody } from './sets/mystery';
import {body as specialBody} from './sets/special'; import { body as specialBody } from './sets/special';
import {body as armoireBody} from './sets/armoire'; import { body as armoireBody } from './sets/armoire';
let body = { const body = {
base: baseBody, base: baseBody,
mystery: mysteryBody, mystery: mysteryBody,
special: specialBody, special: specialBody,

View File

@@ -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 armoireEyewear } from './sets/armoire';
import {eyewear as mysteryEyewear} from './sets/mystery'; import { eyewear as mysteryEyewear } from './sets/mystery';
import {eyewear as specialEyewear} from './sets/special'; import { eyewear as specialEyewear } from './sets/special';
let eyewear = { const eyewear = {
base: baseEyewear, base: baseEyewear,
special: specialEyewear, special: specialEyewear,
mystery: mysteryEyewear, mystery: mysteryEyewear,

View File

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

View File

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

View File

@@ -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 healerHead } from './sets/healer';
import {head as rogueHead} from './sets/rogue'; import { head as rogueHead } from './sets/rogue';
import {head as warriorHead} from './sets/warrior'; import { head as warriorHead } from './sets/warrior';
import {head as wizardHead} from './sets/wizard'; import { head as wizardHead } from './sets/wizard';
import {head as armoireHead} from './sets/armoire'; import { head as armoireHead } from './sets/armoire';
import {head as mysteryHead} from './sets/mystery'; import { head as mysteryHead } from './sets/mystery';
import {head as specialHead} from './sets/special'; import { head as specialHead } from './sets/special';
let head = { const head = {
base: baseHead, base: baseHead,
warrior: warriorHead, warrior: warriorHead,

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,19 +1,19 @@
import cloneDeep from 'lodash/cloneDeep'; 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 { shield as healerShield } from './sets/healer';
import {weapon as rogueWeapon} from './sets/rogue'; import { weapon as rogueWeapon } from './sets/rogue';
import {shield as warriorShield} from './sets/warrior'; import { shield as warriorShield } from './sets/warrior';
import {shield as wizardShield} from './sets/wizard'; import { shield as wizardShield } from './sets/wizard';
import {shield as armoireShield} from './sets/armoire'; import { shield as armoireShield } from './sets/armoire';
import {shield as mysteryShield} from './sets/mystery'; import { shield as mysteryShield } from './sets/mystery';
import {shield as specialShield} from './sets/special'; import { shield as specialShield } from './sets/special';
let rogueShield = cloneDeep(rogueWeapon); const rogueShield = cloneDeep(rogueWeapon);
let shield = { const shield = {
base: baseShield, base: baseShield,
warrior: warriorShield, warrior: warriorShield,

View File

@@ -1,17 +1,17 @@
import t from '../translation'; 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 healerWeapon } from './sets/healer';
import {weapon as rogueWeapon} from './sets/rogue'; import { weapon as rogueWeapon } from './sets/rogue';
import {weapon as warriorWeapon} from './sets/warrior'; import { weapon as warriorWeapon } from './sets/warrior';
import {weapon as wizardWeapon} from './sets/wizard'; import { weapon as wizardWeapon } from './sets/wizard';
import {weapon as armoireWeapon} from './sets/armoire'; import { weapon as armoireWeapon } from './sets/armoire';
import {weapon as mysteryWeapon} from './sets/mystery'; import { weapon as mysteryWeapon } from './sets/mystery';
import {weapon as specialWeapon} from './sets/special'; import { weapon as specialWeapon } from './sets/special';
let weapon = { const weapon = {
base: baseWeapon, base: baseWeapon,
warrior: warriorWeapon, warrior: warriorWeapon,
@@ -27,31 +27,31 @@ let weapon = {
// Add Two Handed message to all weapons // Add Two Handed message to all weapons
const rtlLanguages = [ const rtlLanguages = [
'ae', /* Avestan */ 'ae', /* Avestan */
'ar', /* 'العربية', Arabic */ 'ar', /* 'العربية', Arabic */
'arc', /* Aramaic */ 'arc', /* Aramaic */
'bcc', /* 'بلوچی مکرانی', Southern Balochi */ 'bcc', /* 'بلوچی مکرانی', Southern Balochi */
'bqi', /* 'بختياري', Bakthiari */ 'bqi', /* 'بختياري', Bakthiari */
'ckb', /* 'Soranî / کوردی', Sorani */ 'ckb', /* 'Soranî / کوردی', Sorani */
'dv', /* Dhivehi */ 'dv', /* Dhivehi */
'fa', /* 'فارسی', Persian */ 'fa', /* 'فارسی', Persian */
'glk', /* 'گیلکی', Gilaki */ 'glk', /* 'گیلکی', Gilaki */
'he', /* 'עברית', Hebrew */ 'he', /* 'עברית', Hebrew */
'ku', /* 'Kurdî / كوردی', Kurdish */ 'ku', /* 'Kurdî / كوردی', Kurdish */
'mzn', /* 'مازِرونی', Mazanderani */ 'mzn', /* 'مازِرونی', Mazanderani */
'nqo', /* N'Ko */ 'nqo', /* N'Ko */
'pnb', /* 'پنجابی', Western Punjabi */ 'pnb', /* 'پنجابی', Western Punjabi */
'ps', /* 'پښتو', Pashto, */ 'ps', /* 'پښتو', Pashto, */
'sd', /* 'سنڌي', Sindhi */ 'sd', /* 'سنڌي', Sindhi */
'ug', /* 'Uyghurche / ئۇيغۇرچە', Uyghur */ 'ug', /* 'Uyghurche / ئۇيغۇرچە', Uyghur */
'ur', /* 'اردو', Urdu */ 'ur', /* 'اردو', Urdu */
'yi', /* 'ייִדיש', Yiddish */ 'yi', /* 'ייִדיש', Yiddish */
]; ];
for (let key in weapon) { for (const key in weapon) {
const set = weapon[key]; const set = weapon[key];
for (let weaponKey in set) { for (const weaponKey in set) {
const item = set[weaponKey]; const item = set[weaponKey];
const oldnotes = item.notes; const oldnotes = item.notes;
item.notes = (lang) => { item.notes = lang => {
const twoHandedText = item.twoHanded ? t('twoHandedItem')(lang) : ''; const twoHandedText = item.twoHanded ? t('twoHandedItem')(lang) : '';
if (rtlLanguages.indexOf(lang) !== -1) { if (rtlLanguages.indexOf(lang) !== -1) {

View File

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

View File

@@ -2,7 +2,7 @@ import defaults from 'lodash/defaults';
import each from 'lodash/each'; import each from 'lodash/each';
import moment from 'moment'; import moment from 'moment';
import t from './translation'; import t from './translation';
import {tasksByCategory} from './tasks'; import { tasksByCategory } from './tasks';
import { import {
CLASSES, CLASSES,
@@ -12,8 +12,6 @@ import {
ANIMAL_COLOR_ACHIEVEMENTS, ANIMAL_COLOR_ACHIEVEMENTS,
} from './constants'; } from './constants';
const api = {};
import achievements from './achievements'; import achievements from './achievements';
import * as eggs from './eggs'; import * as eggs from './eggs';
@@ -27,7 +25,7 @@ import {
} from './quests'; } from './quests';
import appearances from './appearance'; import appearances from './appearance';
import {backgroundsTree, backgroundsFlat} from './appearance/backgrounds'; import { backgroundsTree, backgroundsFlat } from './appearance/backgrounds';
import spells from './spells'; import spells from './spells';
import subscriptionBlocks from './subscriptionBlocks'; import subscriptionBlocks from './subscriptionBlocks';
import faq from './faq'; import faq from './faq';
@@ -37,6 +35,8 @@ import loginIncentives from './loginIncentives';
import officialPinnedItems from './officialPinnedItems'; import officialPinnedItems from './officialPinnedItems';
const api = {};
api.achievements = achievements; api.achievements = achievements;
api.questSeriesAchievements = QUEST_SERIES_ACHIEVEMENTS; api.questSeriesAchievements = QUEST_SERIES_ACHIEVEMENTS;
api.animalColorAchievements = ANIMAL_COLOR_ACHIEVEMENTS; api.animalColorAchievements = ANIMAL_COLOR_ACHIEVEMENTS;
@@ -810,17 +810,15 @@ api.food = {
/* eslint-enable camelcase */ /* eslint-enable camelcase */
}; };
each(api.food, (food, key) => { each(api.food, (food, key) => defaults(food, {
return defaults(food, { value: 1,
value: 1, key,
key, notes: t('foodNotes'),
notes: t('foodNotes'), canBuy () {
canBuy () { return false;
return false; },
}, canDrop: false,
canDrop: false, }));
});
});
api.appearances = appearances; api.appearances = appearances;
@@ -837,9 +835,9 @@ api.userDefaults = {
down: false, down: false,
attribute: 'per', attribute: 'per',
tags: [ tags: [
t('defaultTag1'), // Work t('defaultTag1'), // Work
t('defaultTag4'), // School t('defaultTag4'), // School
t('defaultTag6'), // Chores t('defaultTag6'), // Chores
], ],
}, { }, {
type: 'habit', type: 'habit',
@@ -849,7 +847,7 @@ api.userDefaults = {
down: true, down: true,
attribute: 'str', attribute: 'str',
tags: [ tags: [
t('defaultTag3'), // Health + Wellness t('defaultTag3'), // Health + Wellness
], ],
}, { }, {
type: 'habit', type: 'habit',
@@ -859,8 +857,8 @@ api.userDefaults = {
down: true, down: true,
attribute: 'str', attribute: 'str',
tags: [ tags: [
t('defaultTag2'), // Exercise t('defaultTag2'), // Exercise
t('defaultTag3'), // Health + Wellness t('defaultTag3'), // Health + Wellness
], ],
}, },
], ],

View File

@@ -4,7 +4,7 @@ import { MAX_INCENTIVES } from '../constants';
// NOTE do not import this file alone but only access it through common.content // NOTE do not import this file alone but only access it through common.content
// so that it's already compiled // so that it's already compiled
export default function getLoginIncentives (api) { export default function getLoginIncentives (api) {
let loginIncentives = { const loginIncentives = {
1: { 1: {
rewardKey: ['armor_special_bardRobes'], rewardKey: ['armor_special_bardRobes'],
reward: [api.gear.flat.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. // 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 // Create a new array if we want the loginIncentives to be immutable in the future
let nextRewardKey; let nextRewardKey;
range(MAX_INCENTIVES + 1).reverse().forEach(function addNextRewardLink (index) { range(MAX_INCENTIVES + 1).reverse().forEach(index => {
if (loginIncentives[index] && loginIncentives[index].rewardKey) { if (loginIncentives[index] && loginIncentives[index].rewardKey) {
loginIncentives[index].nextRewardAt = nextRewardKey; loginIncentives[index].nextRewardAt = nextRewardKey;
nextRewardKey = index; nextRewardKey = index;
@@ -659,7 +659,7 @@ export default function getLoginIncentives (api) {
}); });
let prevRewardKey; let prevRewardKey;
range(MAX_INCENTIVES + 1).forEach(function addPrevRewardLink (index) { range(MAX_INCENTIVES + 1).forEach(index => {
loginIncentives[index].prevRewardKey = prevRewardKey; loginIncentives[index].prevRewardKey = prevRewardKey;
if (loginIncentives[index].rewardKey) prevRewardKey = index; if (loginIncentives[index].rewardKey) prevRewardKey = index;
}); });

View File

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

View File

@@ -6,9 +6,9 @@ import {
USER_CAN_OWN_QUEST_CATEGORIES, USER_CAN_OWN_QUEST_CATEGORIES,
} from './constants'; } from './constants';
let userCanOwnQuestCategories = USER_CAN_OWN_QUEST_CATEGORIES; const userCanOwnQuestCategories = USER_CAN_OWN_QUEST_CATEGORIES;
let quests = { const quests = {
dilatory: { dilatory: {
text: t('questDilatoryText'), text: t('questDilatoryText'),
notes: t('questDilatoryNotes'), notes: t('questDilatoryNotes'),
@@ -2261,7 +2261,7 @@ let quests = {
unlockCondition: { unlockCondition: {
condition: 'party invite', condition: 'party invite',
incentiveThreshold: 7, incentiveThreshold: 7,
text: t('loginReward', {count: 7}), text: t('loginReward', { count: 7 }),
}, },
collect: { collect: {
shard: { shard: {
@@ -2292,7 +2292,7 @@ let quests = {
unlockCondition: { unlockCondition: {
condition: 'party invite', condition: 'party invite',
incentiveThreshold: 22, incentiveThreshold: 22,
text: t('loginReward', {count: 22}), text: t('loginReward', { count: 22 }),
}, },
boss: { boss: {
name: t('questMoon2Boss'), name: t('questMoon2Boss'),
@@ -2322,7 +2322,7 @@ let quests = {
unlockCondition: { unlockCondition: {
condition: 'party invite', condition: 'party invite',
incentiveThreshold: 40, incentiveThreshold: 40,
text: t('loginReward', {count: 40}), text: t('loginReward', { count: 40 }),
}, },
boss: { boss: {
name: t('questMoon3Boss'), name: t('questMoon3Boss'),
@@ -3527,9 +3527,7 @@ each(quests, (v, key) => {
} }
}); });
let questsByLevel = sortBy(quests, (quest) => { const questsByLevel = sortBy(quests, quest => quest.lvl || 0);
return quest.lvl || 0;
});
export { export {
quests, quests,

View File

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

View File

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

View File

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

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