<commit_before>"use strict";

Object.defineProperty(exports, "__esModule", {
    value: true
});

var _router = require("router5");

var _router5History = require("router5-history");

var _router5History2 = _interopRequireDefault(_router5History);

var _router5LinkInterceptor = require("router5-link-interceptor");

var _router5LinkInterceptor2 = _interopRequireDefault(_router5LinkInterceptor);

var _router5Listeners = require("router5-listeners");

var _router5Listeners2 = _interopRequireDefault(_router5Listeners);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

/**
 * Private store for Router.
 */
/**
 * This router extends the functionality of Router 5.
 * Mostly the methods used in this router are simple wrapper around Router 5
 * @external http://router5.github.io/
 */
var Router = new _router.Router5();
var routesStore = {};
var lastState = {};

/**
 *
 * @param routeMap [object] of the format
 * {
 *      moduleConfig:Config object of the module
 *      name: name of the route
 *      path: path of the route
 * }
 * @param Blinx [object]. Used to create and destory instances of modules.
 *
If shouldRender method is present in the moduleConfig of the module then the method is called.
 * If the value returned is false then the rendering does not happen.
 * Should render is an optional parameter in module

 *
 *
Similarly if shouldDestroy is present in the moduleConfig of the module then the method is called.
 * If the value returned is false then the module is not destryed on route change.

 *
 */
var addMethodsOnInstance = function addMethodsOnInstance(routeMap, Blinx) {

    routesStore[routeMap.moduleConfig.name] = routeMap.moduleConfig;

    routeMap.canActivate = function (toRoute, fromRoute, done) {

        if (Router.isActive(toRoute.name, toRoute.params, true, false)) {
            return true;
        }

        var moduleData = routesStore[routeMap.moduleConfig.name];

        lastState = toRoute;

        if (moduleData.module.shouldRender && moduleData.module.shouldRender(toRoute, fromRoute) || !moduleData.module.shouldRender) {
            return Blinx.createInstance(moduleData);
        }

        done();
    };

    Router.canDeactivate(routeMap.name, function (toRoute, fromRoute, done) {

        if (Router.isActive(toRoute.name, toRoute.params, true, true)) {
            return true;
        }

        var moduleData = routesStore[routeMap.moduleConfig.name];

        if (moduleData.module.shouldDestroy && moduleData.module.shouldDestroy(toRoute, fromRoute) || !moduleData.module.shouldDestroy) {
            Blinx.destroyInstance(moduleData);
        }

        moduleData.initialized = false;
        return true;
    });
};

/**
 * @param routeMap {Object|Array}. If array then iterates over routeMap to call {@link addMethodsOnInstance}
 */
var iterateToAddMethodsOnInstance = function iterateToAddMethodsOnInstance(routeMap, Blinx) {

    if (Array.isArray(routeMap)) {
        routeMap.forEach(function (route) {
            route.moduleConfig.name = route.name;
            addMethodsOnInstance(route, Blinx);
        });
    } else {
        addMethodsOnInstance(routeMap, Blinx);
    }
};

exports.default = {
    /**
     *
     * @param Blinx [object]
     */
    init: function init(Blinx) {
        this.Blinx = Blinx;
    },
    /**
     *
     * @param routeMap [array] of objects in the format
     * {
     *      moduleConfig:Config object of the module
     *      name: name of the route
     *      path: path of the route
     * }
     * @param config [object] Router configuration . This method internally calls the Router.setOption method of Router 5
     */
    configure: function configure(routeMap, config) {
        iterateToAddMethodsOnInstance(routeMap, this.Blinx);
        Router.add(routeMap);

        for (var key in config) {
            Router.setOption(key, config[key]);
        }

        if (config.logger) {
            Router.usePlugin((0, _router.loggerPlugin)());
        }

        if (config.history) {
            Router.usePlugin((0, _router5History2.default)());
        }

        if (config.listener) {
            Router.usePlugin((0, _router5Listeners2.default)());
        }
    },
    /**
     * Method to register a route.
     * iterated through the map to create instances of modules then calls Router5.add
     * {@link external:http://router5.github.io/docs/api-reference.html}
     * @param routeMap
     */
    register: function register(routeMap) {
        iterateToAddMethodsOnInstance(routeMap, this.Blinx);
        Router.add(routeMap);
    },
    /**
     * calls {@link register}
     * @param routeMap
     */
    reRegister: function reRegister(routeMap) {
        this.register(routeMap);
        Router.stop();
        Router.start();
    },
    /**
     * Wrapper around calls Router5.navigate
     * {@link external:http://router5.github.io/docs/api-reference.html}
     * @param state The route name
     * @param props [Object={}] [optional] The route params
     * @param force Route options
     * @param replace Route options
     */
    go: function go(state, props, force, replace) {
        var opts = {};

        if (force) {
            opts.reload = true;
        }

        if (replace) {
            opts.replace = true;
        }
        Router.navigate(state, props, opts);
    },
    /**
     * Wrapper around Router5.usePlugin
     * @param middleware
     */
    usePlugin: function usePlugin(middleware) {
        Router.usePlugin(middleware);
    },
    /**
     * Wrapper around Router5.useMiddleware
     * @param fn
     */
    useMiddleware: function useMiddleware(fn) {
        Router.useMiddleware(fn);
    },
    /**
     * Wrapper around Router5.start
     */
    start: function start() {
        Router.start();
    },
    /**
     * Wrapper around Router5.stop
     */
    stop: function stop() {
        Router.stop();
    },
    /**
     * returns the parameters of the current route
     * @returns {*}
     */
    getRouteParams: function getRouteParams() {
        if (Object.keys(lastState).length > 0) {
            return Object.assign({}, lastState.params);
        } else {
            return Router.lastStateAttempt.params;
        }
    },

    addRouteListener: function addRouteListener() {
        return Router.addRouteListener.apply(this, arguments);
    },

    addListener: function addListener() {
        return Router.addListener.apply(this, arguments);
    },

    addNodeListener: function addNodeListener() {
        return Router.addNodeListener.apply(this, arguments);
    },
    /**
     * Returns the current route
     * @returns {*}
     */
    getCurrentRoute: function getCurrentRoute() {
        return lastState;
    },
    /**
     * changes the window url. uses window.location.href
     * @param url
     */
    navigate: function navigate(url) {
        window.location.href = url;
    },
    /**
     * router5-link-interceptor module
     */
    intercept: _router5LinkInterceptor2.default
};<commit_msg>Adding wrapper for buildPath<commit_after>"use strict";

Object.defineProperty(exports, "__esModule", {
    value: true
});

var _router = require("router5");

var _router5History = require("router5-history");

var _router5History2 = _interopRequireDefault(_router5History);

var _router5LinkInterceptor = require("router5-link-interceptor");

var _router5LinkInterceptor2 = _interopRequireDefault(_router5LinkInterceptor);

var _router5Listeners = require("router5-listeners");

var _router5Listeners2 = _interopRequireDefault(_router5Listeners);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

/**
 * Private store for Router.
 */
/**
 * This router extends the functionality of Router 5.
 * Mostly the methods used in this router are simple wrapper around Router 5
 * @external http://router5.github.io/
 */
var Router = new _router.Router5();
var routesStore = {};
var lastState = {};

/**
 *
 * @param routeMap [object] of the format
 * {
 *      moduleConfig:Config object of the module
 *      name: name of the route
 *      path: path of the route
 * }
 * @param Blinx [object]. Used to create and destory instances of modules.
 *
If shouldRender method is present in the moduleConfig of the module then the method is called.
 * If the value returned is false then the rendering does not happen.
 * Should render is an optional parameter in module

 *
 *
Similarly if shouldDestroy is present in the moduleConfig of the module then the method is called.
 * If the value returned is false then the module is not destryed on route change.

 *
 */
var addMethodsOnInstance = function addMethodsOnInstance(routeMap, Blinx) {

    routesStore[routeMap.moduleConfig.name] = routeMap.moduleConfig;

    routeMap.canActivate = function (toRoute, fromRoute, done) {

        if (Router.isActive(toRoute.name, toRoute.params, true, false)) {
            return true;
        }

        var moduleData = routesStore[routeMap.moduleConfig.name];

        lastState = toRoute;

        if (moduleData.module.shouldRender && moduleData.module.shouldRender(toRoute, fromRoute) || !moduleData.module.shouldRender) {
            return Blinx.createInstance(moduleData);
        }

        done();
    };

    Router.canDeactivate(routeMap.name, function (toRoute, fromRoute, done) {

        if (Router.isActive(toRoute.name, toRoute.params, true, true)) {
            return true;
        }

        var moduleData = routesStore[routeMap.moduleConfig.name];

        if (moduleData.module.shouldDestroy && moduleData.module.shouldDestroy(toRoute, fromRoute) || !moduleData.module.shouldDestroy) {
            Blinx.destroyInstance(moduleData);
        }

        moduleData.initialized = false;
        return true;
    });
};

/**
 * @param routeMap {Object|Array}. If array then iterates over routeMap to call {@link addMethodsOnInstance}
 */
var iterateToAddMethodsOnInstance = function iterateToAddMethodsOnInstance(routeMap, Blinx) {

    if (Array.isArray(routeMap)) {
        routeMap.forEach(function (route) {
            route.moduleConfig.name = route.name;
            addMethodsOnInstance(route, Blinx);
        });
    } else {
        addMethodsOnInstance(routeMap, Blinx);
    }
};

exports.default = {
    /**
     *
     * @param Blinx [object]
     */
    init: function init(Blinx) {
        this.Blinx = Blinx;
    },
    /**
     *
     * @param routeMap [array] of objects in the format
     * {
     *      moduleConfig:Config object of the module
     *      name: name of the route
     *      path: path of the route
     * }
     * @param config [object] Router configuration . This method internally calls the Router.setOption method of Router 5
     */
    configure: function configure(routeMap, config) {
        iterateToAddMethodsOnInstance(routeMap, this.Blinx);
        Router.add(routeMap);

        for (var key in config) {
            Router.setOption(key, config[key]);
        }

        if (config.logger) {
            Router.usePlugin((0, _router.loggerPlugin)());
        }

        if (config.history) {
            Router.usePlugin((0, _router5History2.default)());
        }

        if (config.listener) {
            Router.usePlugin((0, _router5Listeners2.default)());
        }
    },
    /**
     * Method to register a route.
     * iterated through the map to create instances of modules then calls Router5.add
     * {@link external:http://router5.github.io/docs/api-reference.html}
     * @param routeMap
     */
    register: function register(routeMap) {
        iterateToAddMethodsOnInstance(routeMap, this.Blinx);
        Router.add(routeMap);
    },
    /**
     * calls {@link register}
     * @param routeMap
     */
    reRegister: function reRegister(routeMap) {
        this.register(routeMap);
        Router.stop();
        Router.start();
    },
    /**
     * Wrapper around calls Router5.navigate
     * {@link external:http://router5.github.io/docs/api-reference.html}
     * @param state The route name
     * @param props [Object={}] [optional] The route params
     * @param force Route options
     * @param replace Route options
     */
    go: function go(state, props, force, replace) {
        var opts = {};

        if (force) {
            opts.reload = true;
        }

        if (replace) {
            opts.replace = true;
        }
        Router.navigate(state, props, opts);
    },
    /**
     * Wrapper around Router5.usePlugin
     * @param middleware
     */
    usePlugin: function usePlugin(middleware) {
        Router.usePlugin(middleware);
    },
    /**
     * Wrapper around Router5.useMiddleware
     * @param fn
     */
    useMiddleware: function useMiddleware(fn) {
        Router.useMiddleware(fn);
    },
    /**
     * Wrapper around Router5.start
     */
    start: function start() {
        Router.start();
    },
    /**
     * Wrapper around Router5.stop
     */
    stop: function stop() {
        Router.stop();
    },
    /**
     * Wrapper around Router5.buildPath
     */
    buildPath: function buildPath(route, params) {
        return Router.buildPath(route, params);
    },
    /**
     * returns the parameters of the current route
     * @returns {*}
     */
    getRouteParams: function getRouteParams() {
        if (Object.keys(lastState).length > 0) {
            return Object.assign({}, lastState.params);
        } else {
            return Router.lastStateAttempt.params;
        }
    },

    addRouteListener: function addRouteListener() {
        return Router.addRouteListener.apply(this, arguments);
    },

    addListener: function addListener() {
        return Router.addListener.apply(this, arguments);
    },

    addNodeListener: function addNodeListener() {
        return Router.addNodeListener.apply(this, arguments);
    },
    /**
     * Returns the current route
     * @returns {*}
     */
    getCurrentRoute: function getCurrentRoute() {
        return lastState;
    },
    /**
     * changes the window url. uses window.location.href
     * @param url
     */
    navigate: function navigate(url) {
        window.location.href = url;
    },
    /**
     * router5-link-interceptor module
     */
    intercept: _router5LinkInterceptor2.default
};
<|endoftext|>


<commit_before>const logger = require('winston');
const Discord = require('discord.js');
const config = require('../config');
const fs = require('fs');
const path = require('path');
const notify = require('./notify');
const now = require('performance-now');
const perms = require('./permissions')();
const utils = require('./utilities');
require('./memoryUsage');

logger.info('Starting Bot: PID:', process.pid);

// Create the Discord Client
const client = new Discord.Client({
  fetchAllMembers: true,
  disableEveryone: true,
  disabledEvents: [
    'TYPING_START',
  ],
});

// Extent the client object
client.commands = new Discord.Collection();
client.aliases = new Discord.Collection();
client.guildConfigs = new Discord.Collection();
client.commandPerms = new Discord.Collection();

// Shortcuts to different file paths
client.tempDir = path.join(process.cwd(), 'temp');
client.assetsDir = path.join(process.cwd(), 'assets');
client.commandsDir = path.join(process.cwd(), 'lib/cmds');

// Default Guild Config
client.defaultGuildConfig = {
  prefix: config.prefix,
};

// Create property to count items
client.count = {
  messages: 0,
  commands: 0,
  tweets: 0, // TODO count this
};

// Instantiate other modules into the client object
client.mongo = require('./mongo')(client);

utils.loadAllCommands(client)
  .then(() => {
    logger.info(`Loaded ${client.commands.size} command${client.commands.size === 1 ? '' : 's'}, ` +
      `with ${client.aliases.size} aliases.`);
  })
  .catch(err => {
    logger.error('Error loading commands', err);
  });

// Create a temp directory if one doesn't not exist on startup
if (!fs.existsSync(client.tempDir)) fs.mkdirSync(client.tempDir);

// Discord has disconnected
client.on('disconnect', () => {
  logger.warn('Discord disconnected');
});

// Discord is reconnecting
client.on('reconnecting', () => {
  logger.info('Discord reconnecting');
});

// Discord has erred
client.on('error', err => {
  logger.error('Discord client error:', err ? err.stack : '');
});

let firstConnection = true;
client.on('ready', () => {
  logger.info(`Successful connection to Discord as '${client.user.username}'`);
  // Only on initial ready event, send a startup message to owner
  if (firstConnection) {
    firstConnection = false;
    // If this bot is not my test Bot...
    if (client.user.id !== '120105547633524736') {
      // Send the Owner a message that the Bot has started, indicates a crash or restart
      const owner = client.users.get(config.owner_id);
      if (owner) {
        owner.sendMessage(`I just started running. Did I crash? :worried:\nPID:\`\`${process.pid}\`\``);
      }
    }
  }
});

// The bot has joined a guild, notify the owner
client.on('guildCreate', guild => {
  notify.guildCreate(client, guild);
});

// The client has left a guild, notify the owner
client.on('guildDelete', guild => {
  notify.guildDelete(client, guild);
});

// A new member has joined a connected server
client.on('guildMemberAdd', member => {
  notify.guildMemberAdd(client, member);
});

// A member has left/kick/ban from a connected server
client.on('guildMemberRemove', member => {
  notify.guildMemberRemove(client, member);
});

// Received a message from a discord chat
client.on('message', msg => {
  // Save time of message start process
  msg.startTime = now();
  // Increment the message count if the message was not from self
  if (msg.author.id !== client.user.id) client.count.messages++;
  // Don't listen to other Bots
  if (msg.author.bot) return;
  // Check for and run any prefixed commands
  prefixedCommands(msg);
  // Do other stuff with messages...
});

// Connect to Discord
logger.debug('Connecting to Discord...');
client.login(config.bot_token).catch(logger.error);

setInterval(() => {
  // Ensure we are logged every 5 minutes
  // Exit if the client is in good status
  if (client.status !== 0) relog();
}, 1000 * 60 * 5);

async function relog() {
  logger.info('Re-logging to Discord');
  try {
    await client.destroy();
    client.login(config.bot_token);
  } catch (e) {
    logger.error(e);
  }
  return null;
}

async function prefixedCommands(msg) {
  let conf = client.defaultGuildConfig;
  // Get stored guild config if exists and not a dm channel
  if (msg.channel.type !== 'dm' && client.guildConfigs.has(msg.guild.id)) {
    conf = client.guildConfigs.get(msg.guild.id);
  }
  // Exit if message doesn't use the guild prefix
  if (!msg.content.startsWith(conf.prefix)) return null;
  // Save the prefix used on this message so we can use it to build guild specific help commands
  // Split message into an array
  const params = msg.content.split(' ');
  // Pull first index and remove prefix
  const cmd = params.shift().slice(config.prefix.length).toLowerCase();
  // Exit if no command was given (prefix only)
  if (!cmd) return null;
  logger.debug('Command:', cmd, JSON.stringify(params));
  // Attempt to get command from Collection
  let command;
  if (client.commands.has(cmd)) {
    command = client.commands.get(cmd);
  } else if (client.aliases.has(cmd)) {
    command = client.aliases.get(cmd);
  }
  if (!command || !command.run || typeof command.run !== 'function') {
    logger.debug(`The cmd '${cmd}' does not exist, is not loaded, or is missing the function 'run'`);
    return null;
  }
  // Log the command usage
  if (msg.channel.type === 'dm') {
    logger.info(`[DM] <${msg.author.username}#${msg.author.discriminator}>: ${msg.content}`);
  } else {
    logger.info(`[${msg.guild.name}] (#${msg.channel.name}) ` +
      `<${msg.author.username}#${msg.author.discriminator}>: ${msg.content}`);
  }
  const allowed = perms.check(client, msg, cmd);
  if (allowed) {
    logger.info(`ALLOWED '${msg.author.username}' ${cmd}' in channel ` +
      `'${msg.channel.type === 'dm' ? 'DM' : msg.channel.name}'`);
    client.count.commands++;
    msg.prefix = conf.prefix;
    msg.cmd = cmd;
    command.run(client, msg, params)
      .then(() => {
        utils.finish(msg, cmd);
      })
      .catch(err => {
        logger.error(`Error executing command '${cmd}'`, err);
        const owner = client.users.get(config.owner_id);
        if (owner) owner.sendMessage(`Command Error: \`\`\`js\n${err}\`\`\``); // todo detsails of command usage
      });
  } else {
    logger.info(`DENIED '${msg.author.username}' ${cmd}' in channel ` +
      `'${msg.channel.type === 'dm' ? 'DM' : msg.channel.name}'`);
    msg.reply('You do not have permission to run this command here.');
  }
  return null;
}
<commit_msg>More detailed err message to owner<commit_after>const logger = require('winston');
const Discord = require('discord.js');
const config = require('../config');
const fs = require('fs');
const path = require('path');
const notify = require('./notify');
const now = require('performance-now');
const perms = require('./permissions')();
const utils = require('./utilities');
require('./memoryUsage');

logger.info('Starting Bot: PID:', process.pid);

// Create the Discord Client
const client = new Discord.Client({
  fetchAllMembers: true,
  disableEveryone: true,
  disabledEvents: [
    'TYPING_START',
  ],
});

// Extent the client object
client.commands = new Discord.Collection();
client.aliases = new Discord.Collection();
client.guildConfigs = new Discord.Collection();
client.commandPerms = new Discord.Collection();

// Shortcuts to different file paths
client.tempDir = path.join(process.cwd(), 'temp');
client.assetsDir = path.join(process.cwd(), 'assets');
client.commandsDir = path.join(process.cwd(), 'lib/cmds');

// Default Guild Config
client.defaultGuildConfig = {
  prefix: config.prefix,
};

// Create property to count items
client.count = {
  messages: 0,
  commands: 0,
  tweets: 0,
};

// Instantiate other modules into the client object
client.mongo = require('./mongo')(client);

utils.loadAllCommands(client)
  .then(() => {
    logger.info(`Loaded ${client.commands.size} command${client.commands.size === 1 ? '' : 's'}, ` +
      `with ${client.aliases.size} aliases.`);
  })
  .catch(err => {
    logger.error('Error loading commands', err);
  });

// Create a temp directory if one doesn't not exist on startup
if (!fs.existsSync(client.tempDir)) fs.mkdirSync(client.tempDir);

// Discord has disconnected
client.on('disconnect', () => {
  logger.warn('Discord disconnected');
});

// Discord is reconnecting
client.on('reconnecting', () => {
  logger.info('Discord reconnecting');
});

// Discord has erred
client.on('error', err => {
  logger.error('Discord client error:', err ? err.stack : '');
});

let firstConnection = true;
client.on('ready', () => {
  logger.info(`Successful connection to Discord as '${client.user.username}'`);
  // Only on initial ready event, send a startup message to owner
  if (firstConnection) {
    firstConnection = false;
    // If this bot is not my test Bot...
    if (client.user.id !== '120105547633524736') {
      // Send the Owner a message that the Bot has started, indicates a crash or restart
      const owner = client.users.get(config.owner_id);
      if (owner) {
        owner.sendMessage(`I just started running. Did I crash? :worried:\nPID:\`\`${process.pid}\`\``);
      }
    }
  }
});

// The bot has joined a guild, notify the owner
client.on('guildCreate', guild => {
  notify.guildCreate(client, guild);
});

// The client has left a guild, notify the owner
client.on('guildDelete', guild => {
  notify.guildDelete(client, guild);
});

// A new member has joined a connected server
client.on('guildMemberAdd', member => {
  notify.guildMemberAdd(client, member);
});

// A member has left/kick/ban from a connected server
client.on('guildMemberRemove', member => {
  notify.guildMemberRemove(client, member);
});

// Received a message from a discord chat
client.on('message', msg => {
  // Save time of message start process
  msg.startTime = now();
  // Increment the message count if the message was not from self
  if (msg.author.id !== client.user.id) client.count.messages++;
  // Don't listen to other Bots
  if (msg.author.bot) return;
  // Check for and run any prefixed commands
  prefixedCommands(msg);
  // Do other stuff with messages...
});

// Connect to Discord
logger.debug('Connecting to Discord...');
client.login(config.bot_token).catch(logger.error);

setInterval(() => {
  // Ensure we are logged every 5 minutes
  // Exit if the client is in good status
  if (client.status !== 0) relog();
}, 1000 * 60 * 5);

async function relog() {
  logger.info('Re-logging to Discord');
  try {
    await client.destroy();
    client.login(config.bot_token);
  } catch (e) {
    logger.error(e);
  }
  return null;
}

async function prefixedCommands(msg) {
  let conf = client.defaultGuildConfig;
  // Get stored guild config if exists and not a dm channel
  if (msg.channel.type !== 'dm' && client.guildConfigs.has(msg.guild.id)) {
    conf = client.guildConfigs.get(msg.guild.id);
  }
  // Exit if message doesn't use the guild prefix
  if (!msg.content.startsWith(conf.prefix)) return null;
  // Save the prefix used on this message so we can use it to build guild specific help commands
  // Split message into an array
  const params = msg.content.split(' ');
  // Pull first index and remove prefix
  const cmd = params.shift().slice(config.prefix.length).toLowerCase();
  // Exit if no command was given (prefix only)
  if (!cmd) return null;
  logger.debug('Command:', cmd, JSON.stringify(params));
  // Attempt to get command from Collection
  let command;
  if (client.commands.has(cmd)) {
    command = client.commands.get(cmd);
  } else if (client.aliases.has(cmd)) {
    command = client.aliases.get(cmd);
  }
  if (!command || !command.run || typeof command.run !== 'function') {
    logger.debug(`The cmd '${cmd}' does not exist, is not loaded, or is missing the function 'run'`);
    return null;
  }
  // Log the command usage
  if (msg.channel.type === 'dm') {
    logger.info(`[DM] <${msg.author.username}#${msg.author.discriminator}>: ${msg.content}`);
  } else {
    logger.info(`[${msg.guild.name}] (#${msg.channel.name}) ` +
      `<${msg.author.username}#${msg.author.discriminator}>: ${msg.content}`);
  }
  const allowed = perms.check(client, msg, cmd);
  if (allowed) {
    logger.info(`ALLOWED '${msg.author.username}' ${cmd}' in channel ` +
      `'${msg.channel.type === 'dm' ? 'DM' : msg.channel.name}'`);
    client.count.commands++;
    msg.prefix = conf.prefix;
    msg.cmd = cmd;
    command.run(client, msg, params)
      .then(() => {
        utils.finish(msg, cmd);
      })
      .catch(err => {
        logger.error(`Error executing command '${cmd}'`, err);
        const owner = client.users.get(config.owner_id);
        if (owner) {
          const guild = msg.channel.type === 'dm' ? msg.author : msg.guild;
          const user = msg.channel.type === 'dm' ? msg.author.username : msg.member.nickname || msg.author.username;
          let details = `\`\`\`qml\n`;
          details += `Guild: ${msg.channel.type === 'dm' ? 'DM' : guild.name || guild.username} (${guild.id})\n`;
          details += `Channel: ${msg.channel.type === 'dm' ? 'DM' : msg.channel.name} (${msg.channel.id})\n`;
          details += `User: ${user} (${msg.author.id})\n`;
          details += `CMD: ${cmd}\`\`\``;
          let errStr = '';
          if (err) {
            errStr = `\`\`\`js\n`;
            errStr += err.stack || err;
            errStr += '```';
          }
          owner.sendMessage(`Command Error:${details}${errStr}`);
        }
      });
  } else {
    logger.info(`DENIED '${msg.author.username}' ${cmd}' in channel ` +
      `'${msg.channel.type === 'dm' ? 'DM' : msg.channel.name}'`);
    msg.reply('You do not have permission to run this command here.');
  }
  return null;
}
<|endoftext|>


<commit_before>'use strict'

import readCache from './read-cache'
import serialize from './serialize'

function cache (config = {}) {
  if (!config.store) {
    throw new Error('Cache middleware need to be provided a store.')
  }

  const store = config.store
  const key = config.key || cache.key
  const read = config.readCache || readCache
  const serialize = config.serialize || serialize

  return (req, next, service) => {
    const useCache = !service.use || (service.use && (service.use.cache !== false))

    if (!useCache) {
      return next()
    }

    return new Promise((resolve, reject) => {
      store.getItem(key(req))
        .then((value) => {
          read(req)(value)
            .then(resolve)
            .catch(() => {
              // cache miss
              next()
                .then((res) => {
                  resolve(res)
                  store.setItem(key(req), serialize(req, res))
                })
                .catch(reject)
            })
        })
        .catch(reject)
    })
  }
}

cache.readCache = readCache
cache.serialize = serialize

cache.key = function (req) {
  return req.url
}

export default cache
<commit_msg>fix(middleware): fix variables shadowing issue<commit_after>'use strict'

import readCache from './read-cache'
import serialize from './serialize'

function cache (config = {}) {
  if (!config.store) {
    throw new Error('Cache middleware need to be provided a store.')
  }

  const store = config.store
  const key = config.key || cache.key

  config.readCache = config.readCache || readCache
  config.serialize = config.serialize || serialize

  return (req, next, service) => {
    const useCache = !service.use || (service.use && (service.use.cache !== false))

    if (!useCache) {
      return next()
    }

    return new Promise((resolve, reject) => {
      store.getItem(key(req))
        .then((value) => {
          read(req)(value)
            .then(resolve)
            .catch(() => {
              // cache miss
              next()
                .then((res) => {
                  resolve(res)
                  store.setItem(key(req), serialize(req, res))
                })
                .catch(reject)
            })
        })
        .catch(reject)
    })
  }
}

cache.readCache = readCache
cache.serialize = serialize

cache.key = function (req) {
  return req.url
}

export default cache
<|endoftext|>


<commit_before>/**
 * sails-generate-frontend
 *
 * Usage:
 * `sails generate frontend`
 *
 * @type {Object}
 */

module.exports = {

	templatesDirectory: require('path').resolve(__dirname,'../templates'),

	before: require('./before'),

	targets: {

		// default assets folder and contents
		'./assets': { folder: {} },
		'./assets/favicon.ico': { copy: 'assets/favicon.ico' },
		'./assets/robots.txt': { template: 'assets/robots.txt' },
		'./assets/images': { folder: {} },
		'./assets/styles': { folder: {} },
		'./assets/styles/importer.less': { template: 'assets/styles/importer.less' },
		'./assets/templates': { folder: {} },
		'./assets/js': { folder: {} },
		'./assets/js/dependencies': { folder: {} },
		'./assets/js/dependencies/sails.io.js': { template: 'assets/js/dependencies/sails.io.js' },

		'./api/images/.gitkeep': { copy: '.gitkeep'},
		'./api/templates/.gitkeep': { copy: '.gitkeep'},
		// optional - inject other dependencies
		'./assets/js/dependencies/angular.min.js': { exec: function (scope, cb) {
				if (scope.frontend !== 'angular') return cb();
				var src = require('path').resolve(__dirname,'../templates/assets/js/dependencies/angular.min.js');
				require('fs-extra').copy(src, scope.rootPath, cb);
		} },

		// default asset pipeline config
		'./tasks/pipeline.js': { template: 'tasks/pipeline.js' },

		// grunt task configurations (`tasks/config`)
		'./tasks/config/clean.js': { template: 'tasks/config/clean.js' },
		'./tasks/config/coffee.js': { template: 'tasks/config/coffee.js' },
		'./tasks/config/concat.js': { template: 'tasks/config/concat.js' },
		'./tasks/config/copy.js': { template: 'tasks/config/copy.js' },
		'./tasks/config/cssmin.js': { template: 'tasks/config/cssmin.js' },
		'./tasks/config/jst.js': { template: 'tasks/config/jst.js' },
		'./tasks/config/less.js': { template: 'tasks/config/less.js' },
		'./tasks/config/sails-linker.js': { template: 'tasks/config/sails-linker.js' },
		'./tasks/config/sync.js': { template: 'tasks/config/sync.js' },
		'./tasks/config/uglify.js': { template: 'tasks/config/uglify.js' },
		'./tasks/config/watch.js': { template: 'tasks/config/watch.js' },

		// built-in grunt tasks which are automatically called by Sails (`tasks/register`)
		'./tasks/register/build.js': { template: 'tasks/register/build.js' },
		'./tasks/register/buildProd.js': { template: 'tasks/register/buildProd.js' },
		'./tasks/register/compileAssets.js': { template: 'tasks/register/compileAssets.js' },
		'./tasks/register/default.js': { template: 'tasks/register/default.js' },
		'./tasks/register/linkAssets.js': { template: 'tasks/register/linkAssets.js' },
		'./tasks/register/linkAssetsBuild.js': { template: 'tasks/register/linkAssetsBuild.js' },
		'./tasks/register/linkAssetsBuildProd.js': { template: 'tasks/register/linkAssetsBuildProd.js' },
		'./tasks/register/prod.js': { template: 'tasks/register/prod.js' },
		'./tasks/register/syncAssets.js': { template: 'tasks/register/syncAssets.js' }
	}
};

<commit_msg>Fixes directory path typo in 8fdbc54b7897ba6ff97ff513a055520de668d0c4<commit_after>/**
 * sails-generate-frontend
 *
 * Usage:
 * `sails generate frontend`
 *
 * @type {Object}
 */

module.exports = {

	templatesDirectory: require('path').resolve(__dirname,'../templates'),

	before: require('./before'),

	targets: {

		// default assets folder and contents
		'./assets': { folder: {} },
		'./assets/favicon.ico': { copy: 'assets/favicon.ico' },
		'./assets/robots.txt': { template: 'assets/robots.txt' },
		'./assets/images': { folder: {} },
		'./assets/styles': { folder: {} },
		'./assets/styles/importer.less': { template: 'assets/styles/importer.less' },
		'./assets/templates': { folder: {} },
		'./assets/js': { folder: {} },
		'./assets/js/dependencies': { folder: {} },
		'./assets/js/dependencies/sails.io.js': { template: 'assets/js/dependencies/sails.io.js' },

		'./assets/images/.gitkeep': { copy: '.gitkeep'},
		'./assets/templates/.gitkeep': { copy: '.gitkeep'},
		// optional - inject other dependencies
		'./assets/js/dependencies/angular.min.js': { exec: function (scope, cb) {
				if (scope.frontend !== 'angular') return cb();
				var src = require('path').resolve(__dirname,'../templates/assets/js/dependencies/angular.min.js');
				require('fs-extra').copy(src, scope.rootPath, cb);
		} },

		// default asset pipeline config
		'./tasks/pipeline.js': { template: 'tasks/pipeline.js' },

		// grunt task configurations (`tasks/config`)
		'./tasks/config/clean.js': { template: 'tasks/config/clean.js' },
		'./tasks/config/coffee.js': { template: 'tasks/config/coffee.js' },
		'./tasks/config/concat.js': { template: 'tasks/config/concat.js' },
		'./tasks/config/copy.js': { template: 'tasks/config/copy.js' },
		'./tasks/config/cssmin.js': { template: 'tasks/config/cssmin.js' },
		'./tasks/config/jst.js': { template: 'tasks/config/jst.js' },
		'./tasks/config/less.js': { template: 'tasks/config/less.js' },
		'./tasks/config/sails-linker.js': { template: 'tasks/config/sails-linker.js' },
		'./tasks/config/sync.js': { template: 'tasks/config/sync.js' },
		'./tasks/config/uglify.js': { template: 'tasks/config/uglify.js' },
		'./tasks/config/watch.js': { template: 'tasks/config/watch.js' },

		// built-in grunt tasks which are automatically called by Sails (`tasks/register`)
		'./tasks/register/build.js': { template: 'tasks/register/build.js' },
		'./tasks/register/buildProd.js': { template: 'tasks/register/buildProd.js' },
		'./tasks/register/compileAssets.js': { template: 'tasks/register/compileAssets.js' },
		'./tasks/register/default.js': { template: 'tasks/register/default.js' },
		'./tasks/register/linkAssets.js': { template: 'tasks/register/linkAssets.js' },
		'./tasks/register/linkAssetsBuild.js': { template: 'tasks/register/linkAssetsBuild.js' },
		'./tasks/register/linkAssetsBuildProd.js': { template: 'tasks/register/linkAssetsBuildProd.js' },
		'./tasks/register/prod.js': { template: 'tasks/register/prod.js' },
		'./tasks/register/syncAssets.js': { template: 'tasks/register/syncAssets.js' }
	}
};

<|endoftext|>


<commit_before>import fs from 'fs-promise';
import getFiles from './get-files';
import hash from './hash';
import Agent from './Agent';
import { resolve } from 'path';

export default async function now (path, token, { forceNew, debug }) {
  try {
    await fs.stat(path);
  } catch (err) {
    throw new Error(`Could not read directory ${path}.`);
  }

  let pkg;
  try {
    pkg = await fs.readFile(resolve(path, 'package.json'));
    pkg = JSON.parse(pkg);
  } catch (err) {
    throw new Error(`Failed to read JSON in "${path}/package.json"`);
  }

  if (debug) console.time('> [debug] Getting files');
  const files = await getFiles(path, pkg);
  if (debug) console.timeEnd('> [debug] Getting files');

  if (debug) console.time('> [debug] Computing hashes');
  const hashes = await hash(files);
  if (debug) console.timeEnd('> [debug] Computing hashes');

  if (debug) {
    hashes.forEach((sha, file) => {
      console.log(`> [debug] Found "${file}" [${sha}]`);
    });
  }

  const agent = new Agent('now.zeit.co');
  const fetch = async (url, opts) => {
    opts.headers = opts.headers || {};
    opts.headers.authorization = `Bearer ${token}`;
    const res = await agent.fetch(url, opts);
    if (403 === res.status) {
      const err = new Error('Authorization failed.');
      err.status = 403;
      throw err;
    } else if (500 === res.status) {
      const err = new Error('Server error.');
      err.status = 500;
      throw err;
    } else {
      return res;
    }
  };

  if (debug) console.time('> [debug] http');
  const res = await fetch('/now/create', {
    method: 'POST',
    body: {
      shas: hashes.keys(),
      forceNew
    }
  });

  if (200 !== res.status) {
    throw new Error('Deployment initialization failed');
  }

  if (debug) console.timeEnd('> [debug] http');
  console.log(res.status);
  agent.close();

  return 'https://test.now.run';
}
<commit_msg>index: implement file syncing and retrying<commit_after>import getFiles from './get-files';
import hash from './hash';
import retry from './retry';
import Agent from './agent';
import EventEmitter from 'events';
import { resolve } from 'path';
import { stat, readFile } from 'fs-promise';

export default class Now extends EventEmitter {
  constructor (token, { forceNew = false, debug = false }) {
    super();
    this._token = token;
    this._debug = debug;
    this._forceNew = forceNew;
    this._agent = new Agent('now.zeit.co', { debug });
    this._onRetry = this._onRetry.bind(this);
  }

  async create (path, { forceNew }) {
    this._path = path;

    try {
      await stat(path);
    } catch (err) {
      throw new Error(`Could not read directory ${path}.`);
    }

    let pkg;
    try {
      pkg = await readFile(resolve(path, 'package.json'));
      pkg = JSON.parse(pkg);
    } catch (err) {
      throw new Error(`Failed to read JSON in "${path}/package.json"`);
    }

    if (this._debug) console.time('> [debug] Getting files');
    const files = await getFiles(path, pkg);
    if (this._debug) console.timeEnd('> [debug] Getting files');

    if (this._debug) console.time('> [debug] Computing hashes');
    const hashes = await hash(files);
    if (this._debug) console.timeEnd('> [debug] Computing hashes');

    this._files = hashes;

    const deployment = await retry(async (bail) => {
      const res = await this._fetch('/create', {
        method: 'POST',
        body: {
          forceNew,
          files: Array.from(this._files).map(([sha, { data }]) => {
            return {
              sha,
              size: Buffer.byteLength(data)
            };
          })
        }
      });

      // no retry on 403
      if (403 === res.status) {
        if (this._debug) {
          console.log('> [debug] bailing on creating due to 403');
        }
        return bail(responseError(res));
      }

      if (200 !== res.status) {
        throw new Error('Deployment initialization failed');
      }

      return res.json();
    }, { retries: 3, minTimeout: 2500, onRetry: this._onRetry });

    this._id = deployment.deploymentId;
    this._url = deployment.url;
    this._missing = deployment.missing || [];

    return this._url;
  }

  upload () {
    Promise.all(this._missing.map((sha) => retry(async (bail) => {
      const file = this._files.get(sha);
      const { data, name } = file;
      const res = await this._fetch('/sync', {
        method: 'POST',
        body: {
          sha,
          data,
          name: toRelative(name, this._path),
          deploymentId: this._id
        }
      });

      // no retry on 403
      if (403 === res.status) {
        if (this._debug) console.log('> [debug] bailing on creating due to 403');
        return bail(responseError(res));
      }

      this.emit('upload', file);
    }, { retries: 5, randomize: true, onRetry: this._onRetry })))
    .then(() => this.emit('complete'))
    .catch((err) => this.emit('error', err));
  }

  _onRetry (err) {
    if (this._debug) {
      console.log(`> [debug] Retrying: ${err.stack}`);
    }
  }

  close () {
    this._agent.close();
  }

  get url () {
    return this._url;
  }

  get syncAmount () {
    if (this._syncAmount) {
      this._syncAmount = this._missing
      .map((sha) => Buffer.byteLength(this._files.get(sha).data))
      .reduce((a, b) => a + b, 0);
    }
    return this._syncAmount;
  }

  async _fetch (url, opts) {
    opts.headers = opts.headers || {};
    opts.headers.authorization = `Bearer ${this._token}`;
    return await this._agent.fetch(url, opts);
  }
}

function toRelative (path, base) {
  const fullBase = /\/$/.test(base) ? base + '/' : base;
  return path.substr(fullBase.length);
}

function responseError (res) {
  const err = new Error('Response error');
  err.status = res.status;
  return err;
}
<|endoftext|>


<commit_before>module.exports = function (_dirname) {
  const pkg = require('../package.json')
  const path = require('path')
  const _utils = require('../utils')(_dirname)
  const CURRENT_DIR = _utils.envInfo.CURRENT_DIR
  const SCRIPTS_DIR = _utils.envInfo.SCRIPTS_DIR
  const CURRENT_DIR_NAME = _utils.envInfo.CURRENT_DIR_NAME
  const ErrorType = _utils.Errors.types
  const installDeps = _utils.installDeps
  const logger = _utils.logger
  const sanitize = _utils.sanitize
  const parseWorkingDir = _utils.parseWorkingDir
  const transformContextIntoSedString = _utils.transformContextIntoSedString
  const Shell = _utils.shell
  global.console.reset = () => process.stdout.write('\033c')

  function createDir(name) {
    if (!name) return Promise.reject(false);
    const fname = (name.substr(0, 1) === '/')? name.substr(1) : name

    return Shell(`mkdir ${CURRENT_DIR}/${fname}`)
    .then(() => console.log(` -> create dir: [ ✅  ] ${CURRENT_DIR_NAME}/${fname}`))
    .catch(err => {
      if (err.message.indexOf('File exists') !== -1)
        console.log(` -> create dir: [ 🔅  ] ${CURRENT_DIR_NAME}/${fname}`)
      else
        logger.error(err, ErrorType.CREATE_DIR)}
    )
  }

  function copyFile(filename, context) {
    if (!filename) return Promise.reject(false);

    const fname = (filename.substr(0, 1) === '/')? filename.substr(1) : filename
    const _path = '/app/'
    const _dist = '/'
    const replaceWithContext = _utils.transformContextIntoSedString(context)

    return Shell(`cat ${SCRIPTS_DIR}${_path}${fname} ${replaceWithContext} > ${CURRENT_DIR}${_dist}${fname}`)
    .then(() => console.log(` ->  copy file: [ ✅  ] ${filename}`))
    .catch(err => logger.error(err, ErrorType.COPY_FILE, {
      command: `cat ${SCRIPTS_DIR}${_path}${fname} ${replaceWithContext} > ${CURRENT_DIR}${_dist}${fname}`,
      sedString: replaceWithContext
    }))
  }

  function handleGeneralError(err) {
    return logger.error(err, ErrorType.GENERAL)
  }

  function cloneStructure(dirStructure, context) {
    return dirStructure.map(obj => {
      if (obj.isFolder) {
        createDir(obj.name)
        parseWorkingDir(obj.name).then(subdirStructure => {
          cloneStructure(subdirStructure, context)
        }).catch(handleGeneralError)
      } else {
        copyFile(obj.name, context)
      }
    })
  }

  function cloneTemplateStructure(context) {
    // console.reset()
    logger.info(
      `Node version: ${process.version}`,
      `yagg version: ${pkg.version}`,
      `current: ${CURRENT_DIR}`
    )
    parseWorkingDir()
    .then(dirStructure => cloneStructure(dirStructure, context))
    .catch(handleGeneralError)
  }

  return {
    cloneTemplateStructure,
    installDeps,
  }
}<commit_msg>bug fix con copy image file<commit_after>module.exports = function (_dirname) {
  const pkg = require('../package.json')
  const path = require('path')
  const _utils = require('../utils')(_dirname)
  const CURRENT_DIR = _utils.envInfo.CURRENT_DIR
  const SCRIPTS_DIR = _utils.envInfo.SCRIPTS_DIR
  const CURRENT_DIR_NAME = _utils.envInfo.CURRENT_DIR_NAME
  const ErrorType = _utils.Errors.types
  const installDeps = _utils.installDeps
  const logger = _utils.logger
  const sanitize = _utils.sanitize
  const parseWorkingDir = _utils.parseWorkingDir
  const transformContextIntoSedString = _utils.transformContextIntoSedString
  const Shell = _utils.shell
  global.console.reset = () => process.stdout.write('\033c')

  function createDir(name) {
    if (!name) return Promise.reject(false);
    const fname = (name.substr(0, 1) === '/')? name.substr(1) : name

    return Shell(`mkdir ${CURRENT_DIR}/${fname}`)
    .then(() => console.log(` -> create dir: [ ✅  ] ${CURRENT_DIR_NAME}/${fname}`))
    .catch(err => {
      if (err.message.indexOf('File exists') !== -1)
        console.log(` -> create dir: [ 🔅  ] ${CURRENT_DIR_NAME}/${fname}`)
      else
        logger.error(err, ErrorType.CREATE_DIR)}
    )
  }

  function copyFile(filename, context) {
    if (!filename) return Promise.reject(false);

    const fname = (filename.substr(0, 1) === '/')? filename.substr(1) : filename
    const _path = '/app/'
    const _dist = '/'
    const extension = path.extname(filename)
    const isImage = extension === '.jpg' || extension === '.png' || extension === '.jpeg' || extension === '.gif'
    const replaceWithContext = (isImage)? '' : _utils.transformContextIntoSedString(context)

    return Shell(`cat ${SCRIPTS_DIR}${_path}${fname} ${replaceWithContext} > ${CURRENT_DIR}${_dist}${fname}`)
    .then(() => console.log(` ->  copy file: [ ✅  ] ${filename}`))
    .catch(err => logger.error(err, ErrorType.COPY_FILE, {
      command: `cat ${SCRIPTS_DIR}${_path}${fname} ${replaceWithContext} > ${CURRENT_DIR}${_dist}${fname}`,
      sedString: replaceWithContext
    }))
  }

  function handleGeneralError(err) {
    return logger.error(err, ErrorType.GENERAL)
  }

  function cloneStructure(dirStructure, context) {
    return dirStructure.map(obj => {
      if (obj.isFolder) {
        createDir(obj.name)
        parseWorkingDir(obj.name).then(subdirStructure => {
          cloneStructure(subdirStructure, context)
        }).catch(handleGeneralError)
      } else {
        copyFile(obj.name, context)
      }
    })
  }

  function cloneTemplateStructure(context) {
    // console.reset()
    logger.info(
      `Node version: ${process.version}`,
      `yagg version: ${pkg.version}`,
      `current: ${CURRENT_DIR}`
    )
    parseWorkingDir()
    .then(dirStructure => cloneStructure(dirStructure, context))
    .catch(handleGeneralError)
  }

  return {
    cloneTemplateStructure,
    installDeps,
  }
}<|endoftext|>


<commit_before>'use strict';

const Fs = require('fs');
const Async = require('async');

exports.register = function (server, baseOptions, next) {

    return Fs.readdir(baseOptions.dir, (err, list) => {

        if (err) {
            return next(err);
        }

        return Async.each(list, (file, callback) => {

            const path = process.cwd() + '/' + baseOptions.dir + '/' + file;
            const routeFile = require(path);

            routeFile.routes(server);

            return callback();
        }, () => {

            server.log(['hapi-routes'], 'Registered all routes in ' + baseOptions.dir);

            return next();
        });
    });
};

exports.register.attributes = {
    pkg: require('../package.json')
};
<commit_msg>arrow function<commit_after>'use strict';

const Fs = require('fs');
const Async = require('async');

exports.register = (server, baseOptions, next) => {

    return Fs.readdir(baseOptions.dir, (err, list) => {

        if (err) {
            return next(err);
        }

        return Async.each(list, (file, callback) => {

            const path = process.cwd() + '/' + baseOptions.dir + '/' + file;
            const routeFile = require(path);

            routeFile.routes(server);

            return callback();
        }, () => {

            server.log(['hapi-routes'], 'Registered all routes in ' + baseOptions.dir);

            return next();
        });
    });
};

exports.register.attributes = {
    pkg: require('../package.json')
};
<|endoftext|>


<commit_before>module.exports = {
  // Objects
  'Unit': require('./unit'),
  'Lexer': require('./lexer'),

  // Methods
  'math': require('./math'),
};
<commit_msg>Fix wrapper<commit_after>module.exports = {
  // Objects
  'Unit': require('./unit'),
  'Lexer': require('./lexer'),
  'Math': require('./math'),
};
<|endoftext|>


<commit_before>// jshint esnext: true

var compose = require('koa-compose');
var co = require('co');
var Crawler = require('x-ray-crawler');
var cheerio = require('cheerio');
var parse = require('./parse');
var absolutes = require('./absolutes');
var url = require('url');

var isUrl = function(x) {
  'use strict';
  return url.parse(x).protocol !== null;
};

var query = function(selector, $) {
  'use strict';

  if (undefined === $ || null === $) {
    throw new Error('Cannot query to empty scope');
  }
  return $.find ? $.find(selector) : $(selector);
};

var load = function(html, url) {
  'use strict';

  if (html === null || html === undefined) {
    return;
  }

  var $ = html.html ? html : cheerio.load(html);
  if (url) $ = absolutes(url, $);

  return $;
};

var luwakProto = function(url) {
  'use strict';

  var luwakO = function(newUrl) {
    var newLuwakO = luwakProto(newUrl || url);
    Object.setPrototypeOf(newLuwakO, luwakO);
    return newLuwakO;
  };

  luwakO.url = url;

  Object.setPrototypeOf(luwakO, luwakProto);

  return luwakO;
};

luwakProto.middlewares = [];
luwakProto.filters = {};

luwakProto.prepare = function(name, filter) {
  'use strict';
  this.filters[name] = filter;
  return this;
};

luwakProto.use = function(middleware) {
  'use strict';
  this.middlewares.push(middleware);
  return this;
};

luwakProto.select = function(selector) {
  'use strict';
  this.selector = selector;
  return this;
};

luwakProto.query = function(selector, $, isArray) {
  'use strict';

  return co(function *() {
    switch(typeof selector) {
      case 'string':
        var parsed = parse(selector);
        parsed.attribute = parsed.attribute || 'text';

        var results = [];
        var $els = query(parsed.selector, $);
        $els.each(function(i) {
          var $el = $els.eq(i);

          var result;
          switch(parsed.attribute) {
            case 'text':
              result = $el.text();
              break;
            case 'html':
              result = $el.html();
              break;
            default:
              result = $el.attr(parsed.attribute);
              break;
          }

          parsed.filters.forEach(function(filter) {
            if (this.filters[filter.name]) {
              var args = filter.args.slice();
              args.unshift(result);
              result = this.filters[filter.name].apply(null, args);
            }
          }.bind(this));

          results.push(result);
        }.bind(this));

        return isArray ? results : results[0];
      case 'object':
        if (Array.isArray(selector)) {
          return yield this.query(selector[0], $, true);
        } else {
          if (isArray) {
            var $scope = query(selector.$root, $);
            if ($scope.length === 0) return [];
            var arr = [];
            $scope.each(function(k, v) {
              arr.push(this.query(selector, $scope.eq(k)));
            }.bind(this));
            return yield arr;
          } else {
            var obj = {};
            for(var k in selector) {
              if (k === '$root') {
                continue;
              }
              var v = selector[k];
              obj[k] = this.query(v, $);
            }
            return yield obj;
          }
        }
        break;
      case 'function':
        if (typeof selector.start === 'function') {
          // console.log(selector.url);
          // process.exit();
          return yield selector.start($);
        }
        // pass through to next
      default:
        throw new Error('Unimplemented');
    }
  }.bind(this));
};

luwakProto.crawl = function(url) {
  'use strict';

  return co(function *() {
    var fn = co.wrap(compose(this.middlewares));

    var crawler = new Crawler(function(ctx, done) {
      co(function *() {
        try {
          yield fn.call(ctx);
          done(null, ctx);
        } catch(err) {
          done(err);
        }
      });
    });

    return yield crawler(url);
  }.bind(this));
};

luwakProto.start = function($) {
  'use strict';

  return co(function *() {
    // dont have valid url yet!, query first
    if (!isUrl(this.url)) {
      var url = yield this.query(this.url, $);
      return yield this(url).start();
    }

    var selector = this.selector;

    if (!$) {
      var ctx = yield this.crawl(this.url);
      if (!ctx.body) {
        throw new Error('Empty body problem');
      }
      $ = load(ctx.body, this.url);
    }

    return yield this.query(selector, $);
  }.bind(this));
};

module.exports = luwakProto;<commit_msg>changed child to inherit parent attributes<commit_after>// jshint esnext: true

var compose = require('koa-compose');
var co = require('co');
var Crawler = require('x-ray-crawler');
var cheerio = require('cheerio');
var parse = require('./parse');
var absolutes = require('./absolutes');
var ao = require('./utils/ao');
var url = require('url');

var isUrl = function(x) {
  'use strict';
  return url.parse(x).protocol !== null;
};

var query = function(selector, $) {
  'use strict';

  if (undefined === $ || null === $) {
    throw new Error('Cannot query to empty scope');
  }
  return $.find ? $.find(selector) : $(selector);
};

var load = function(html, url) {
  'use strict';

  if (html === null || html === undefined) {
    return;
  }

  var $ = html.html ? html : cheerio.load(html);
  if (url) $ = absolutes(url, $);

  return $;
};

module.exports = luwak();

function luwak(url, parentO) {
  'use strict';

  var luwakO = function LuwakO(url) {
    return luwak(url, luwakO);
  };

  luwakO.url = url || (parentO ? parentO.url : null);
  luwakO.selector = parentO ? parentO.selector : null;
  Object.defineProperties(luwakO, {
    middlewares: {
      enumerable: false,
      writable: false,
      configurable: false,
      value: parentO ? parentO.middlewares.slice() : [],
    },
    filters: {
      enumerable: false,
      writable: false,
      configurable: false,
      value: parentO ? ao.mixin({}, parentO.filters) : {},
    },
  });

  Object.setPrototypeOf(luwakO, luwak);

  return luwakO;
}

luwak.prepare = function(name, filter) {
  'use strict';
  this.filters[name] = filter;
  return this;
};

luwak.use = function(middleware) {
  'use strict';
  this.middlewares.push(middleware);
  return this;
};

luwak.select = function(selector) {
  'use strict';
  this.selector = selector;
  return this;
};

luwak.query = function(selector, $, isArray) {
  'use strict';

  return co(function *() {
    switch(typeof selector) {
      case 'string':
        var parsed = parse(selector);
        parsed.attribute = parsed.attribute || 'text';

        var results = [];
        var $els = query(parsed.selector, $);
        $els.each(function(i) {
          var $el = $els.eq(i);

          var result;
          switch(parsed.attribute) {
            case 'text':
              result = $el.text();
              break;
            case 'html':
              result = $el.html();
              break;
            default:
              result = $el.attr(parsed.attribute);
              break;
          }

          parsed.filters.forEach(function(filter) {
            if (this.filters[filter.name]) {
              var args = filter.args.slice();
              args.unshift(result);
              result = this.filters[filter.name].apply(null, args);
            }
          }.bind(this));

          results.push(result);
        }.bind(this));

        return isArray ? results : results[0];
      case 'object':
        if (Array.isArray(selector)) {
          return yield this.query(selector[0], $, true);
        } else {
          if (isArray) {
            var $scope = query(selector.$root, $);
            if ($scope.length === 0) return [];
            var arr = [];
            $scope.each(function(k, v) {
              arr.push(this.query(selector, $scope.eq(k)));
            }.bind(this));
            return yield arr;
          } else {
            var obj = {};
            for(var k in selector) {
              if (k === '$root') {
                continue;
              }
              var v = selector[k];
              obj[k] = this.query(v, $);
            }
            return yield obj;
          }
        }
        break;
      case 'function':
        if (typeof selector.start === 'function') {
          return yield selector.start($);
        }
        // pass through to next
      default:
        throw new Error('Unimplemented');
    }
  }.bind(this));
};

luwak.crawl = function(url) {
  'use strict';

  return co(function *() {
    var fn = co.wrap(compose(this.middlewares));

    var crawler = new Crawler(function(ctx, done) {
      co(function *() {
        try {
          yield fn.call(ctx);
          done(null, ctx);
        } catch(err) {
          done(err);
        }
      });
    });

    return yield crawler(url);
  }.bind(this));
};

luwak.start = function($) {
  'use strict';

  return co(function *() {
    // dont have valid url yet!, query first
    if (!isUrl(this.url)) {
      var url = yield this.query(this.url, $);
      return yield this(url).start();
    }

    var selector = this.selector;

    if (!$) {
      var ctx = yield this.crawl(this.url);
      if (!ctx.body) {
        throw new Error('Empty body problem');
      }
      $ = load(ctx.body, this.url);
    }

    return yield this.query(selector, $);
  }.bind(this));
};<|endoftext|>


<commit_before>'use strict';

(function () {

  // Stored options
  var vendorPrefixes = {},
    obfuscate = true,
    minify = false,
    optionsSet = false;
  var existingClassNames = [];
  var existingAnimationNames = [];
  var whitespace = /[\n\r\s]/g;
  var indent = '  ';
  var messagePrefix = 'ReactStyleSheets: ';
  var headTag = document.getElementsByTagName('head')[0];

  var commaSeparatedProperties = [
    'fontFamily'
  ];

  var noSuffixProperties = [
    'opacity',
    'animationIterationCount'
  ];

  var timeSuffixProperties = [
    'transition',
    'transitionDuration',
    'transitionDelay',
    'animation',
    'animationDuration',
    'animationDelay'
  ];

  var doubleColonStyles = [
    'before',
    'after',
    'firstLetter',
    'firstLine',
    'selection'
  ];

  var nestedStyles = [
    'active',
    'after',
    'before',
    'checked',
    'disabled',
    'empty',
    'enabled',
    'firstChild',
    'firstLetter',
    'firstLine',
    'firstOfType',
    'focus',
    'hover',
    'inRange',
    'invalid',
    // 'lang', // Takes arguments
    'lastChild',
    'lastOfType',
    'link',
    // 'not', // Takes arguments
    // 'nthChild', // Takes arguments
    // 'nthLastChild', // Takes arguments
    // 'nthLastOfType', // Takes arguments
    // 'nthOfType', // Takes arguments
    'onlyOfType',
    'onlyChild',
    'optional',
    'outOfRange',
    'readOnly',
    'readWrite',
    'required',
    'root',
    'selection',
    'target',
    'valid',
    'visited'
  ];

  function warn (message) {
    if (typeof console !== 'undefined' && typeof console.warn === 'function') {
      console.warn(messagePrefix + message);
    }
  }

  function error (message) {
    throw new Error(messagePrefix + message);
  }

  if (!headTag) {
    error('Could not locate head tag. Ensure your javascript is included after the closing head tag.');
  }

  var styleTag = document.createElement('style');
  styleTag.setAttribute('type', 'text/css');
  headTag.appendChild(styleTag);

  function toSpinalCase (value) {
    return value.replace(/(^|[a-z])([A-Z])/g, '$1-$2').toLowerCase();
  }

  function formatValue (key, value) {
    if (Array.isArray(value)) {
      var separator = commaSeparatedProperties.indexOf(key) >= 0 ? ', ' : ' ';
      return value.map(formatValue.bind(null, key)).join(separator);
    } else if (typeof value === 'number') {
      if (value === 0 || noSuffixProperties.indexOf(key) >= 0) {
        return value;
      }

      if (timeSuffixProperties.indexOf(key) >= 0) {
        return value + 'ms';
      }

      return value + 'px';
    }

    return value;
  }

  function createStyles (tag, style) {
    var prefix = '\n' + tag + ' {\n';
    var nested = '';

    for (var key in style) {
      if (key.indexOf('-') >= 0) {
        error('Found "-" in a style property name. Style property names must be defined in camelcase.');
      }

      var value = style[key];

      // Vendor prefixes
      if (key in vendorPrefixes) {
        for (var i = 0; i < vendorPrefixes[key].length; i += 1) {
          var vendorKey = '-' + vendorPrefixes[key][i] + '-' + key;
          prefix += indent + toSpinalCase(vendorKey) + ': ' + formatValue(key, value) + ';\n';
        }

        prefix += indent + toSpinalCase(key) + ': ' + formatValue(key, value) + ';\n';
      // Nested styles
      } else if (nestedStyles.indexOf(key) >= 0) {
        if (typeof value !== 'object') {
          error('Nested styles such as hover must be an object.');
        }

        var colon = doubleColonStyles.indexOf(key) >= 0 ? '::' : ':';
        nested += createStyles(tag + colon + toSpinalCase(key), value);
      // Sub styles e.g. {margin: {left, right}}
      } else if (typeof value === 'object' && !Array.isArray(value)) {
        for (var subKey in value) {
          var keySubKey = key + '-' + subKey;
          prefix += indent + toSpinalCase(keySubKey) + ': ' + formatValue(keySubKey, value[subKey]) + ';\n';
        }
      // Basic values & arrays
      } else {
        prefix += indent + toSpinalCase(key) + ': ' + formatValue(key, value) + ';\n';
      }
    }

    return prefix + '}\n' + nested;
  }

  function generateRandomString (length) {
    var concat = '';

    for (var i = 0; i < length; i += 1) {
      concat += String.fromCharCode(97 + Math.floor(Math.random() * 26));
    }

    return concat;
  }

  function generateUniqueName (className) {
    if (obfuscate) {
      var obfuscatedClassName = className + '_' + generateRandomString(5);

      while (existingClassNames.indexOf(obfuscatedClassName) >= 0) {
        obfuscatedClassName = className + '_' + generateRandomString(5);
      }

      return obfuscatedClassName;
    }

    if (existingClassNames.indexOf(className) >= 0) {
      error('The class name "' + className + '" is already in use, please choose another.');
    }

    return className;
  }

  function removeWhitespace (value) {
    return minify ? value.replace(whitespace, '') : value;
  }

  var ReactStyleSheets = {
    setOptions: function (options) {
      if (optionsSet) {
        warn('You tried to set options more than once. This is not advised.');
      }

      if (typeof options !== 'object') {
        error('Options must be an object.');
      }

      if (typeof options.vendorPrefixes !== 'undefined') {
        if (typeof options.vendorPrefixes !== 'object' || Array.isArray(options.vendorPrefixes)) {
          error('vendorPrefixes must be an object with style property names as keys, ' +
            'and arrays of prefixes as values.');
        } else {
          vendorPrefixes = options.vendorPrefixes;
        }
      }

      if (typeof options.obfuscate !== 'undefined') {
        obfuscate = options.obfuscate;
      }

      if (typeof options.minify !== 'undefined') {
        minify = options.minify;
      }

      optionsSet = true;
    },
    createTagStyleString: function (styles) {
      var concat = '';

      for (var tag in styles) {
        concat += createStyles(tag, styles[tag]);
      }

      return removeWhitespace(concat);
    },
    createClassStyleString: function (styles) {
      var concat = '';

      for (var className in styles) {
        var obfuscatedClassName = generateUniqueName(className);

        concat += createStyles('.' + className, styles[obfuscatedClassName]);

        existingClassNames.push(obfuscatedClassName);
      }

      return removeWhitespace(concat);
    },
    createGlobalTagStyles: function (styles) {
      var styleString = ReactStyleSheets.createTagStyleString(styles);
      styleTag.innerHTML = styleTag.innerHTML + removeWhitespace(styleString);
    },
    createUniqueClassStyles: function (styles) {
      var classNames = {};
      var concat = '';

      for (var className in styles) {
        var obfuscatedClassName = generateUniqueName(className);

        concat += createStyles('.' + obfuscatedClassName, styles[className]);

        classNames[className] = obfuscatedClassName;
        existingClassNames.push(obfuscatedClassName);
      }

      styleTag.innerHTML = styleTag.innerHTML + removeWhitespace(concat);

      return classNames;
    },
    createUniqueKeyframeAnimation: function (styles) {
      var animations = {};
      var concat = '';

      for (var animationName in styles) {
        var obfuscatedAnimationName = obfuscate ? generateUniqueName(animationName) : animationName;

        concat += '\n@keyframes ' + obfuscatedAnimationName + ' {\n';
        concat += ReactStyleSheets.createTagStyleString(styles[animationName]);
        concat += '\n}\n';

        animations[animationName] = obfuscatedAnimationName;
        existingAnimationNames.push(obfuscatedAnimationName);
      }

      styleTag.innerHTML = styleTag.innerHTML + removeWhitespace(concat);

      return animations;
    }
  };

  /* istanbul ignore next */

  // Export for commonjs / browserify
  if (typeof exports === 'object' && typeof module !== 'undefined') {
    module.exports = ReactStyleSheets;
  // Export for amd / require
  } else if (typeof define === 'function' && define.amd) { // eslint-disable-line no-undef
    define([], function () { // eslint-disable-line no-undef
      return ReactStyleSheets;
    });
  // Export globally
  } else {
    var root;

    if (typeof window !== 'undefined') {
      root = window;
    } else if (typeof global !== 'undefined') {
      root = global;
    } else if (typeof self !== 'undefined') {
      root = self;
    } else {
      root = this;
    }

    root.ReactStyleSheets = ReactStyleSheets;
  }

})();
<commit_msg>Generate media queries<commit_after>'use strict';

(function () {

  // Stored options
  var vendorPrefixes = {},
    obfuscate = true,
    minify = false,
    optionsSet = false;
  var existingClassNames = [];
  var existingAnimationNames = [];
  var isMediaQuery = /^@media/;
  var whitespace = /[\n\r\s]/g;
  var indent = '  ';
  var messagePrefix = 'ReactStyleSheets: ';
  var headTag = document.getElementsByTagName('head')[0];
  var styleTag;

  var commaSeparatedProperties = [
    'fontFamily'
  ];

  var noSuffixProperties = [
    'opacity',
    'animationIterationCount'
  ];

  var timeSuffixProperties = [
    'transition',
    'transitionDuration',
    'transitionDelay',
    'animation',
    'animationDuration',
    'animationDelay'
  ];

  var doubleColonStyles = [
    'before',
    'after',
    'firstLetter',
    'firstLine',
    'selection'
  ];

  var nestedStyles = [
    'active',
    'after',
    'before',
    'checked',
    'disabled',
    'empty',
    'enabled',
    'firstChild',
    'firstLetter',
    'firstLine',
    'firstOfType',
    'focus',
    'hover',
    'inRange',
    'invalid',
    // 'lang', // Takes arguments
    'lastChild',
    'lastOfType',
    'link',
    // 'not', // Takes arguments
    // 'nthChild', // Takes arguments
    // 'nthLastChild', // Takes arguments
    // 'nthLastOfType', // Takes arguments
    // 'nthOfType', // Takes arguments
    'onlyOfType',
    'onlyChild',
    'optional',
    'outOfRange',
    'readOnly',
    'readWrite',
    'required',
    'root',
    'selection',
    'target',
    'valid',
    'visited'
  ];

  function warn (message) {
    if (typeof console !== 'undefined' && typeof console.warn === 'function') {
      console.warn(messagePrefix + message);
    }
  }

  function error (message) {
    throw new Error(messagePrefix + message);
  }

  if (!headTag) {
    error('Could not locate head tag. Ensure your javascript is included after the closing head tag.');
  }

  styleTag = document.createElement('style');
  styleTag.setAttribute('type', 'text/css');
  headTag.appendChild(styleTag);

  function toSpinalCase (value) {
    return value.replace(/(^|[a-z])([A-Z])/g, '$1-$2').toLowerCase();
  }

  function formatValue (key, value) {
    if (Array.isArray(value)) {
      var separator = commaSeparatedProperties.indexOf(key) >= 0 ? ', ' : ' ';
      return value.map(formatValue.bind(null, key)).join(separator);
    } else if (typeof value === 'number') {
      if (value === 0 || noSuffixProperties.indexOf(key) >= 0) {
        return value;
      }

      if (timeSuffixProperties.indexOf(key) >= 0) {
        return value + 'ms';
      }

      return value + 'px';
    }

    return value;
  }

  function createStyles (tag, style) {
    var prefix = '\n' + tag + ' {\n';
    var nested = '';

    for (var key in style) {
      if (!isMediaQuery.test(key) && key.indexOf('-') >= 0) {
        error('Found "-" in a style property name. Style property names must be defined in camelcase.');
      }

      var value = style[key];

      if (key in vendorPrefixes) {
        // Vendor prefixes
        for (var i = 0; i < vendorPrefixes[key].length; i += 1) {
          var vendorKey = '-' + vendorPrefixes[key][i] + '-' + key;
          prefix += indent + toSpinalCase(vendorKey) + ': ' + formatValue(key, value) + ';\n';
        }

        prefix += indent + toSpinalCase(key) + ': ' + formatValue(key, value) + ';\n';
      } else if (nestedStyles.indexOf(key) >= 0) {
        // Nested styles
        if (typeof value !== 'object') {
          error('Nested styles such as hover must be an object.');
        }

        var colon = doubleColonStyles.indexOf(key) >= 0 ? '::' : ':';
        nested += createStyles(tag + colon + toSpinalCase(key), value);
      } else if (isMediaQuery.test(key)) {
        // Media queries
        if (typeof value !== 'object') {
          error('Media queries must be an object.');
        }

        nested += '\n' + key + '{\n';
        nested += createStyles(tag, value);
        nested += '\n}\n'
      } else if (typeof value === 'object' && !Array.isArray(value)) {
        // Sub styles e.g. {margin: {left, right}}
        for (var subKey in value) {
          var keySubKey = key + '-' + subKey;
          prefix += indent + toSpinalCase(keySubKey) + ': ' + formatValue(keySubKey, value[subKey]) + ';\n';
        }
      } else {
        // Basic values & arrays
        prefix += indent + toSpinalCase(key) + ': ' + formatValue(key, value) + ';\n';
      }
    }

    return prefix + '}\n' + nested;
  }

  function generateRandomString (length) {
    var concat = '';

    for (var i = 0; i < length; i += 1) {
      concat += String.fromCharCode(97 + Math.floor(Math.random() * 26));
    }

    return concat;
  }

  function generateUniqueName (className) {
    if (obfuscate) {
      var obfuscatedClassName = className + '_' + generateRandomString(5);

      while (existingClassNames.indexOf(obfuscatedClassName) >= 0) {
        obfuscatedClassName = className + '_' + generateRandomString(5);
      }

      return obfuscatedClassName;
    }

    if (existingClassNames.indexOf(className) >= 0) {
      error('The class name "' + className + '" is already in use, please choose another.');
    }

    return className;
  }

  function removeWhitespace (value) {
    return minify ? value.replace(whitespace, '') : value;
  }

  var ReactStyleSheets = {
    setOptions: function (options) {
      if (optionsSet) {
        warn('You tried to set options more than once. This is not advised.');
      }

      if (typeof options !== 'object') {
        error('Options must be an object.');
      }

      if (typeof options.vendorPrefixes !== 'undefined') {
        if (typeof options.vendorPrefixes !== 'object' || Array.isArray(options.vendorPrefixes)) {
          error('vendorPrefixes must be an object with style property names as keys, ' +
            'and arrays of prefixes as values.');
        } else {
          vendorPrefixes = options.vendorPrefixes;
        }
      }

      if (typeof options.obfuscate !== 'undefined') {
        obfuscate = options.obfuscate;
      }

      if (typeof options.minify !== 'undefined') {
        minify = options.minify;
      }

      optionsSet = true;
    },
    createTagStyleString: function (styles) {
      var concat = '';

      for (var tag in styles) {
        concat += createStyles(tag, styles[tag]);
      }

      return removeWhitespace(concat);
    },
    createClassStyleString: function (styles) {
      var concat = '';

      for (var className in styles) {
        var obfuscatedClassName = generateUniqueName(className);

        concat += createStyles('.' + className, styles[obfuscatedClassName]);

        existingClassNames.push(obfuscatedClassName);
      }

      return removeWhitespace(concat);
    },
    createGlobalTagStyles: function (styles) {
      var styleString = ReactStyleSheets.createTagStyleString(styles);
      styleTag.innerHTML = styleTag.innerHTML + removeWhitespace(styleString);
    },
    createUniqueClassStyles: function (styles) {
      var classNames = {};
      var concat = '';

      for (var className in styles) {
        var obfuscatedClassName = generateUniqueName(className);

        concat += createStyles('.' + obfuscatedClassName, styles[className]);

        classNames[className] = obfuscatedClassName;
        existingClassNames.push(obfuscatedClassName);
      }

      styleTag.innerHTML = styleTag.innerHTML + removeWhitespace(concat);

      return classNames;
    },
    createUniqueKeyframeAnimation: function (styles) {
      var animations = {};
      var concat = '';

      for (var animationName in styles) {
        var obfuscatedAnimationName = obfuscate ? generateUniqueName(animationName) : animationName;

        concat += '\n@keyframes ' + obfuscatedAnimationName + ' {\n';
        concat += ReactStyleSheets.createTagStyleString(styles[animationName]);
        concat += '\n}\n';

        animations[animationName] = obfuscatedAnimationName;
        existingAnimationNames.push(obfuscatedAnimationName);
      }

      styleTag.innerHTML = styleTag.innerHTML + removeWhitespace(concat);

      return animations;
    }
  };

  /* istanbul ignore next */

  // Export for commonjs / browserify
  if (typeof exports === 'object' && typeof module !== 'undefined') {
    module.exports = ReactStyleSheets;
  // Export for amd / require
  } else if (typeof define === 'function' && define.amd) { // eslint-disable-line no-undef
    define([], function () { // eslint-disable-line no-undef
      return ReactStyleSheets;
    });
  // Export globally
  } else {
    var root;

    if (typeof window !== 'undefined') {
      root = window;
    } else if (typeof global !== 'undefined') {
      root = global;
    } else if (typeof self !== 'undefined') {
      root = self;
    } else {
      root = this;
    }

    root.ReactStyleSheets = ReactStyleSheets;
  }

})();
<|endoftext|>


<commit_before>/* Copyright 2016 Myles Borins
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

var babel = require('babel-core');

function minify(code, cb) {
  if (typeof code !== 'string') {
    cb(new Error('strings only please'));
    return false;
  }

  try {
    // remove comments
    code = code.replace(/(\/\*([\s\S]*?)\*\/)|(\/\/(.*)$)/gm, '');
  }
  catch (e) {
    cb(new Error(e));
    return false;
  }

  var result = babel.transform(code, {
    presets: ['babili']
  }).code;

  cb(null, result);
  return true;
}

module.exports = minify;
<commit_msg>Comments are now handled by babili<commit_after>/* Copyright 2016 Myles Borins
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

var babel = require('babel-core');

function minify(code, cb) {
  if (typeof code !== 'string') {
    cb(new Error('strings only please'));
    return false;
  }

  var result = babel.transform(code, {
    presets: ['babili'],
    comments: false
  }).code;

  cb(null, result);
  return true;
}

module.exports = minify;
<|endoftext|>


<commit_before>/**
 * Copyright 2015 IBM Corp. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

'use strict';

// security.js
var secure = require('express-secure-only');
var rateLimit = require('express-rate-limit');
var helmet = require('helmet');

module.exports = function(app) {

    // 1. redirects http to https
  app.enable('trust proxy'); // required when running on bluemix or similar to know if users originally came in on HTTPS and avoid endless redirects
  app.use(secure());

    // 2. helmet with custom CSP header
  var cspReportUrl = '/report-csp-violation';
  app.use(helmet({
    contentSecurityPolicy: {
            // Specify directives as normal.
      directives: {
        defaultSrc: ['\'self\''], // default value for unspecified directives that end in -src
        scriptSrc: ['\'self\'', 'www.google-analytics.com', 'https://cdnjs.cloudflare.com', 'netdna.bootstrapcdn.com'], // jquery cdn, etc. try to avid "'unsafe-inline'"
        styleSrc: ['\'self\'', '\'unsafe-inline\''], // no inline css
        imgSrc: ['\'self\'', 'www.google-analytics.com'], // should be "'self'" and possibly 'data:' for most apps, but vr demo loads random user-supplied image urls, and apparently * doesn't include data: URIs
        connectSrc: ['\'self\'', '*.watsonplatform.net'], // ajax domains
                // fontSrc: ["'self'"], // cdn?
        objectSrc: [], // embeds (e.g. flash)
                // mediaSrc: ["'self'", '*.watsonplatform.net'], // allow watson TTS streams
        childSrc: [], // child iframes
        frameAncestors: [], // parent iframes
        formAction: ['\'self\''], // where can forms submit to
        pluginTypes: [], // mime-types, e.g. 'application/pdf'
                // sandbox: ['allow-forms', 'allow-scripts', 'allow-same-origin'], // options: allow-forms allow-same-origin allow-scripts allow-top-navigation
        reportUri: cspReportUrl
      },

            // Set to true if you only want browsers to report errors, not block them.
            // You may also set this to a function(req, res) in order to decide dynamically
            // whether to use reportOnly mode, e.g., to allow for a dynamic kill switch.
      reportOnly: false,

            // Set to true if you want to blindly set all headers: Content-Security-Policy,
            // X-WebKit-CSP, and X-Content-Security-Policy.
      setAllHeaders: false,

            // Set to true if you want to disable CSP on Android where it can be buggy.
      disableAndroid: false,

            // Set to false if you want to completely disable any user-agent sniffing.
            // This may make the headers less compatible but it will be much faster.
            // This defaults to `true`.
      browserSniff: true
    }
  }));
    // endpoint to report CSP violations
  app.post(cspReportUrl, function(req, res) {
    console.log('Content Security Policy Violation:\n', req.body);
    res.status(204).send(); // 204 = No Content
  });

    // 3. rate limiting
  var translateLimiter = rateLimit({
    windowMs: 60 * 1000,
    delayMs: 1,
    max: 10
  });
  app.use('/api/translate', translateLimiter);

  var identifyLimiter = rateLimit({
    windowMs: 60 * 1000,
    delayMs: 1,
    max: 10
  });
  app.use('/api/identify', identifyLimiter);

};
<commit_msg>remove csp validation<commit_after>/**
 * Copyright 2015 IBM Corp. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

'use strict';

// security.js
var secure = require('express-secure-only');
var rateLimit = require('express-rate-limit');
var helmet = require('helmet');

module.exports = function(app) {

    // 1. redirects http to https
  app.enable('trust proxy'); // required when running on bluemix or similar to know if users originally came in on HTTPS and avoid endless redirects
  app.use(secure());
  app.use(helmet());

    // 3. rate limiting
  var translateLimiter = rateLimit({
    windowMs: 60 * 1000,
    delayMs: 1,
    max: 10
  });
  app.use('/api/translate', translateLimiter);

  var identifyLimiter = rateLimit({
    windowMs: 60 * 1000,
    delayMs: 1,
    max: 10
  });
  app.use('/api/identify', identifyLimiter);

};
<|endoftext|>