169 lines
		
	
	
		
			5.3 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			169 lines
		
	
	
		
			5.3 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
/* 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);
 | 
						|
    }
 | 
						|
  );
 |