/* eslint-disable no-process-exit */ require('babel-register'); require('dotenv').load(); const adler32 = require('adler32'); const Rx = require('rx'); const _ = require('lodash'); const createDebugger = require('debug'); const utils = require('../server/utils'); const getChallenges = require('./getChallenges'); const { validateChallenge } = require( './schema/challengeSchema' ); const app = require('../server/server'); const log = createDebugger('fcc:seed'); // force logger to always output // this may be brittle log.enabled = true; const dasherize = utils.dasherize; const nameify = utils.nameify; const Observable = Rx.Observable; const Challenge = app.models.Challenge; const destroyChallenges = Observable.fromNodeCallback(Challenge.destroyAll, Challenge); const createChallenges = Observable.fromNodeCallback(Challenge.create, Challenge); const Block = app.models.Block; const destroyBlocks = Observable.fromNodeCallback(Block.destroyAll, Block); const createBlocks = Observable.fromNodeCallback(Block.create, Block); const arrToString = arr => Array.isArray(arr) ? arr.join('\n') : _.toString(arr); Observable.combineLatest( destroyChallenges(), destroyBlocks() ) .last() .flatMap(function() { return Observable.from(getChallenges()); }) .flatMap(function(challengeSpec) { const order = challengeSpec.order; const blockName = challengeSpec.name; const superBlock = challengeSpec.superBlock; const superOrder = challengeSpec.superOrder; const isBeta = !!challengeSpec.isBeta; const isComingSoon = !!challengeSpec.isComingSoon; const fileName = challengeSpec.fileName; const helpRoom = challengeSpec.helpRoom || 'Help'; const time = challengeSpec.time; const isLocked = !!challengeSpec.isLocked; const message = challengeSpec.message; const required = challengeSpec.required || []; const template = challengeSpec.template; const isPrivate = !!challengeSpec.isPrivate; log('parsed %s successfully', blockName); // challenge file has no challenges... if (challengeSpec.challenges.length === 0) { return Rx.Observable.just([{ block: 'empty ' + blockName }]); } const block = { title: blockName, name: nameify(blockName), dashedName: dasherize(blockName), superOrder, superBlock, superBlockMessage: message, order, time, isLocked, isPrivate }; return createBlocks(block) .map(block => { log('successfully created %s block', block.name); return challengeSpec.challenges .map(function(challenge, index) { challenge.name = nameify(challenge.title); challenge.dashedName = dasherize(challenge.name); challenge.checksum = adler32.sum( Buffer( challenge.title + JSON.stringify(challenge.description) + JSON.stringify(challenge.challengeSeed) + JSON.stringify(challenge.tests) ) ); if (challenge.files) { challenge.files = _.reduce(challenge.files, (map, file) => { map[file.key] = { ...file, head: arrToString(file.head), contents: arrToString(file.contents), tail: arrToString(file.tail) }; return map; }, {}); } challenge.fileName = fileName; challenge.helpRoom = helpRoom; challenge.order = order; challenge.suborder = index + 1; challenge.block = dasherize(blockName); challenge.blockId = '' + block.id; challenge.isBeta = challenge.isBeta || isBeta; challenge.isComingSoon = challenge.isComingSoon || isComingSoon; challenge.isLocked = challenge.isLocked || isLocked; challenge.isPrivate = challenge.isPrivate || isPrivate; challenge.time = challengeSpec.time; challenge.superOrder = superOrder; challenge.superBlock = superBlock .split('-') .map(function(word) { return _.capitalize(word); }) .join(' '); challenge.required = (challenge.required || []).concat(required); challenge.template = challenge.template || template; return _.omit( challenge, [ 'betaSolutions', 'betaTests', 'hints', 'MDNlinks', 'null', 'rawSolutions', 'react', 'reactRedux', 'redux', 'releasedOn', 'translations', 'type' ] ); }); }) .flatMap(challenges => { challenges.forEach(challenge => { const result = validateChallenge(challenge); if (result.error) { console.log(result.value); throw new Error(result.error); } }); return createChallenges(challenges); }); }) .subscribe( function(challenges) { log('%s successfully saved', challenges[0].block); }, function(err) { throw err; }, function() { log('challenge seed completed'); process.exit(0); } );