<commit_before>const React = require('react');
const ReactDOM = require('react-dom');
const StackBlur = require('../shared/stackblur');

function getStyles(target, styles, condition) {
  let conditionalStyles = require('../shared/styles');

  return Object.assign({},
    styles,
    condition && conditionalStyles[target].true,
    !condition && conditionalStyles[target].false
  )
}

class FullImage extends React.Component {
  constructor(props) {
    super(props)
  }
  render() {
    var {src, onLoad, style, ...other} = this.props
    return (

    )
  }
}
class LazyImage extends React.Component {
  constructor(props) {
    super(props);
  }

  componentDidMount(){
    var container = ReactDOM.findDOMNode(this);
    this.width = container.offsetWidth;
    this.height = container.offsetHeight;
    this.canvas = ReactDOM.findDOMNode(this.refs.canvas);
    this.canvas.height = this.height;
    this.canvas.width = this.width;
    var blurRadius = this.props.blurRadius || 0;
    this.preImg = document.createElement('img');
    this.preImg.crossOrigin = 'Anonymous';
    this.preImg.onload = () => {
      StackBlur(this.preImg, this.canvas, blurRadius, 600, 190);
    };
    this.preImg.src = this.props.src;
  }
  componentWillUpdate(nextProps) {
    if (this.preImg.src !== nextProps.src) {
      this.preImg.src = nextProps.src;
    }
    StackBlur(this.preImg, this.canvas, nextProps.blurRadius, 600, 190);
  }
  render() {
    var { src, style, ...other } = this.props;
    return (

        <canvas ref='canvas' />

    )
  }
}

class LazyImageWrapper extends React.Component {
  constructor(props) {
    super(props)
    this.handleLoaded = this.handleLoaded.bind(this);
    this.state = {
      loaded: false
    }
  }
  handleLoaded() {
    console.log('loaded')
    this.setState({
      loaded: true
    })
  }
  render() {
    var { src, small, width, height, children, className, blurRadius, ...other } = this.props;
    var styles = {
      width,
      height,
      padding: 0,
      margin: 0,
      position: 'absolute',
      top: 0
    }

    var wrapperStyles = {
      paddingBottom: styles.height,
      position: 'relative'
    }
    return (

        <FullImage src={src} style={getStyles('FullImage', styles, this.state.loaded)} onLoad={this.handleLoaded} />
        <LazyImage src={small} style={getStyles('LazyImage', styles, this.state.loaded)} blurRadius={this.props.blurRadius}/>

    )
  }
}

module.exports = LazyImageWrapper
<commit_msg>removes console.log<commit_after>const React = require('react');
const ReactDOM = require('react-dom');
const StackBlur = require('../shared/stackblur');

function getStyles(target, styles, condition) {
  let conditionalStyles = require('../shared/styles');

  return Object.assign({},
    styles,
    condition && conditionalStyles[target].true,
    !condition && conditionalStyles[target].false
  )
}

class FullImage extends React.Component {
  constructor(props) {
    super(props)
  }
  render() {
    var {src, onLoad, style, ...other} = this.props
    return (

    )
  }
}
class LazyImage extends React.Component {
  constructor(props) {
    super(props);
  }

  componentDidMount(){
    var container = ReactDOM.findDOMNode(this);
    this.width = container.offsetWidth;
    this.height = container.offsetHeight;
    this.canvas = ReactDOM.findDOMNode(this.refs.canvas);
    this.canvas.height = this.height;
    this.canvas.width = this.width;
    var blurRadius = this.props.blurRadius || 0;
    this.preImg = document.createElement('img');
    this.preImg.crossOrigin = 'Anonymous';
    this.preImg.onload = () => {
      StackBlur(this.preImg, this.canvas, blurRadius, 600, 190);
    };
    this.preImg.src = this.props.src;
  }
  componentWillUpdate(nextProps) {
    if (this.preImg.src !== nextProps.src) {
      this.preImg.src = nextProps.src;
    }
    StackBlur(this.preImg, this.canvas, nextProps.blurRadius, 600, 190);
  }
  render() {
    var { src, style, ...other } = this.props;
    return (

        <canvas ref='canvas' />

    )
  }
}

class LazyImageWrapper extends React.Component {
  constructor(props) {
    super(props)
    this.handleLoaded = this.handleLoaded.bind(this);
    this.state = {
      loaded: false
    }
  }
  handleLoaded() {
    this.setState({
      loaded: true
    })
  }
  render() {
    var { src, small, width, height, children, className, blurRadius, ...other } = this.props;
    var styles = {
      width,
      height,
      padding: 0,
      margin: 0,
      position: 'absolute',
      top: 0
    }

    var wrapperStyles = {
      paddingBottom: styles.height,
      position: 'relative'
    }
    return (

        <FullImage src={src} style={getStyles('FullImage', styles, this.state.loaded)} onLoad={this.handleLoaded} />
        <LazyImage src={small} style={getStyles('LazyImage', styles, this.state.loaded)} blurRadius={this.props.blurRadius}/>

    )
  }
}

module.exports = LazyImageWrapper
<|endoftext|>


<commit_before>/**
 * Copyright 2017, Google, Inc.
 * 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.
 */

require('colors');

const assert = require('assert');
const childProcess = require('child_process');
const path = require('path');
const proxyquire = require('proxyquire').noPreserveCache();
const sinon = require('sinon');
const supertest = require('supertest');

const utils = require('./utils');

exports.getRequest = (config) => {
  if (process.env.E2E_TESTS) {
    return supertest(utils.getUrl(config));
  }
  return supertest(proxyquire(path.join(config.cwd, 'app'), {}));
};

exports.run = (cmd, cwd) => {
  return childProcess.execSync(cmd, { cwd: cwd }).toString().trim();
};

exports.runAsync = (cmd, cwd, cb) => {
  return new Promise((resolve, reject) => {
    childProcess.exec(cmd, { cwd: cwd }, (err, stdout, stderr) => {
      if (err) {
        reject(err);
        return;
      }
      if (stdout) {
        resolve(stdout.toString().trim());
      } else {
        resolve(stdout);
      }
    });
  });
};

exports.runAsyncWithIO = (cmd, cwd, cb) => {
  return new Promise((resolve, reject) => {
    childProcess.exec(cmd, { cwd: cwd }, (err, stdout, stderr) => {
      const result = {
        err: err,
        stdout: stdout ? stdout.toString().trim() : null,
        stderr: stderr ? stderr.toString().trim() : null
      };
      if (err) {
        reject(result);
        return;
      }
      if (stdout) {
        resolve(result);
      }
    });
  });
};

class Try {
  constructor (test) {
    this._maxTries = 10;
    this._maxDelay = 20000;
    this._timeout = 60000;
    this._iteration = 1;
    this._multiplier = 1.3;
    this._delay = 500;
    this._test = test;
  }

  execute () {
    if (this._iteration >= this._maxTries) {
      return this.reject(this._error || new Error('Reached maximum number of tries'));
    } else if ((Date.now() - this._start) >= this._timeout) {
      return this.reject(this._error || new Error('Test timed out'));
    }

    return Promise.resolve()
      .then(() => this._test(assert))
      .then(() => this.resolve())
      .catch((err) => {
        this._error = err;
        this._iteration++;
        this._delay = Math.min(this._delay * this._multiplier, this._maxDelay);
        return new Promise((resolve, reject) => {
          setTimeout(() => {
            Promise.resolve()
              .then(() => this.execute())
              .then(resolve, reject);
          }, this._delay);
        });
      });
  }

  timeout (timeout) {
    this._timeout = timeout;
  }

  tries (maxTries) {
    this._maxTries = maxTries;
  }

  start () {
    this._start = Date.now();
    this.promise = new Promise((resolve, reject) => {
      this.resolve = resolve;
      this.reject = reject;
      this.execute().then(resolve, reject);
    });
    return this.promise;
  }
}

exports.tryTest = (test) => {
  return new Try(test);
};

exports.stubConsole = () => {
  if (typeof console.log.restore !== `function` && typeof console.error.restore !== `function`) {
    if (process.env.DEBUG) {
      sinon.spy(console, `error`);
      sinon.spy(console, `log`);
    } else {
      sinon.stub(console, `error`);
      sinon.stub(console, `log`).callsFake((a, b, c) => {
        if (typeof a === `string` && a.indexOf(`\u001b`) !== -1 && typeof b === `string`) {
          console.log.apply(console, arguments);
        }
      });
    }
  }
};

exports.restoreConsole = () => {
  if (typeof console.log.restore === `function`) {
    console.log.restore();
  }
  if (typeof console.error.restore === `function`) {
    console.error.restore();
  }
};

exports.checkCredentials = (t) => {
  if (t && typeof t.truthy === 'function') {
    t.truthy(process.env.GCLOUD_PROJECT, `Must set GCLOUD_PROJECT environment variable!`);
    t.truthy(process.env.GOOGLE_APPLICATION_CREDENTIALS, `Must set GOOGLE_APPLICATION_CREDENTIALS environment variable!`);
  } else {
    assert(process.env.GCLOUD_PROJECT, `Must set GCLOUD_PROJECT environment variable!`);
    assert(process.env.GOOGLE_APPLICATION_CREDENTIALS, `Must set GOOGLE_APPLICATION_CREDENTIALS environment variable!`);
  }
};
<commit_msg>Allow custom app-starting commands<commit_after>/**
 * Copyright 2017, Google, Inc.
 * 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.
 */

require('colors');

const assert = require('assert');
const childProcess = require('child_process');
const path = require('path');
const proxyquire = require('proxyquire').noPreserveCache();
const sinon = require('sinon');
const supertest = require('supertest');

const utils = require('./utils');

exports.getRequest = (config) => {
  if (process.env.E2E_TESTS) {
    return supertest(utils.getUrl(config));
  }
  return supertest(proxyquire(path.join(config.cwd, config.cmd || 'app'), {}));
};

exports.run = (cmd, cwd) => {
  return childProcess.execSync(cmd, { cwd: cwd }).toString().trim();
};

exports.runAsync = (cmd, cwd, cb) => {
  return new Promise((resolve, reject) => {
    childProcess.exec(cmd, { cwd: cwd }, (err, stdout, stderr) => {
      if (err) {
        reject(err);
        return;
      }
      if (stdout) {
        resolve(stdout.toString().trim());
      } else {
        resolve(stdout);
      }
    });
  });
};

exports.runAsyncWithIO = (cmd, cwd, cb) => {
  return new Promise((resolve, reject) => {
    childProcess.exec(cmd, { cwd: cwd }, (err, stdout, stderr) => {
      const result = {
        err: err,
        stdout: stdout ? stdout.toString().trim() : null,
        stderr: stderr ? stderr.toString().trim() : null
      };
      if (err) {
        reject(result);
        return;
      }
      if (stdout) {
        resolve(result);
      }
    });
  });
};

class Try {
  constructor (test) {
    this._maxTries = 10;
    this._maxDelay = 20000;
    this._timeout = 60000;
    this._iteration = 1;
    this._multiplier = 1.3;
    this._delay = 500;
    this._test = test;
  }

  execute () {
    if (this._iteration >= this._maxTries) {
      return this.reject(this._error || new Error('Reached maximum number of tries'));
    } else if ((Date.now() - this._start) >= this._timeout) {
      return this.reject(this._error || new Error('Test timed out'));
    }

    return Promise.resolve()
      .then(() => this._test(assert))
      .then(() => this.resolve())
      .catch((err) => {
        this._error = err;
        this._iteration++;
        this._delay = Math.min(this._delay * this._multiplier, this._maxDelay);
        return new Promise((resolve, reject) => {
          setTimeout(() => {
            Promise.resolve()
              .then(() => this.execute())
              .then(resolve, reject);
          }, this._delay);
        });
      });
  }

  timeout (timeout) {
    this._timeout = timeout;
  }

  tries (maxTries) {
    this._maxTries = maxTries;
  }

  start () {
    this._start = Date.now();
    this.promise = new Promise((resolve, reject) => {
      this.resolve = resolve;
      this.reject = reject;
      this.execute().then(resolve, reject);
    });
    return this.promise;
  }
}

exports.tryTest = (test) => {
  return new Try(test);
};

exports.stubConsole = () => {
  if (typeof console.log.restore !== `function` && typeof console.error.restore !== `function`) {
    if (process.env.DEBUG) {
      sinon.spy(console, `error`);
      sinon.spy(console, `log`);
    } else {
      sinon.stub(console, `error`);
      sinon.stub(console, `log`).callsFake((a, b, c) => {
        if (typeof a === `string` && a.indexOf(`\u001b`) !== -1 && typeof b === `string`) {
          console.log.apply(console, arguments);
        }
      });
    }
  }
};

exports.restoreConsole = () => {
  if (typeof console.log.restore === `function`) {
    console.log.restore();
  }
  if (typeof console.error.restore === `function`) {
    console.error.restore();
  }
};

exports.checkCredentials = (t) => {
  if (t && typeof t.truthy === 'function') {
    t.truthy(process.env.GCLOUD_PROJECT, `Must set GCLOUD_PROJECT environment variable!`);
    t.truthy(process.env.GOOGLE_APPLICATION_CREDENTIALS, `Must set GOOGLE_APPLICATION_CREDENTIALS environment variable!`);
  } else {
    assert(process.env.GCLOUD_PROJECT, `Must set GCLOUD_PROJECT environment variable!`);
    assert(process.env.GOOGLE_APPLICATION_CREDENTIALS, `Must set GOOGLE_APPLICATION_CREDENTIALS environment variable!`);
  }
};
<|endoftext|>


<commit_before>#!/usr/bin/env node

const emoji = require('node-emoji');
const Storage = require('./Storage');
const gui = require('./gui');
const commands = require('./commands');
const assets = require('./assets');
const discord = require('./discord');
const snekparse = require('snekparse');
const userLookup = require('./util/userLookup');

const ctx = {
  gui, assets,
  discord: discord.client,
  allowInput: false,
  current: {
    scope: null,
    channel: null,
  },
  rc: Storage.rc,
};

module.exports = ctx;

gui.on('input', (message) => {
  const prefix = ctx.rc.prefix || '/';
  if (message.startsWith(prefix)) {
    const [command, ...args] = message.slice(prefix.length).split(' ');
    if (command in commands) commands[command].run(ctx, snekparse(args));
  } else {
    if (!ctx.allowInput) return;
    const args = message.split(' ');
    for (const word in args) {
      if (args[word].startsWith('@')) {
        const users = ctx.current.scope && ctx.current.scope !== 'dm' ?
          ctx.current.scope.members.map((m) => m.user) :
          ctx.discord.users;
        const user = userLookup(args[word].slice(1), users);
        if (user) args[word] = user.toString();
      } else if (args[word].startsWith('#')) {
        if (!ctx.current.scope || ctx.current.scope === 'dm') continue;
        const name = args[word].slice(1);
        const channel = ctx.current.scope.channels
          .filter((c) => c.type === 'text')
          .find((c) =>
            c.name.toLowerCase() === name.toLowerCase());
        if (channel) args[word] = channel.toString();
      }
    }
    message = args.join(' ');

    const customEmojis = getEmojis();
    for (const match of message.match(/:[^:]+:/g) || []) {
      const unicode = emoji.get(match);
      if (unicode !== match) {
        message = message.replace(match, unicode);
        continue;
      }
      const found = customEmojis.find((x) => x.name.toLowerCase() === match.replace(/:/g, '').toLowerCase());
      message = message.replace(match, found ? found.toString() : emoji.get(match));
    }

    if (ctx.current.channel) {
      ctx.current.channel.send(message).catch((err) => {
        ctx.gui.put(`{bold}${err.message}{/bold}`);
      });
    }
  }
});

gui.init();
gui.put(`{center}${assets.logo}{/center}`, { center: true });

if (Storage.has('token')) {
  discord.run(ctx);
} else {
  gui.put('{bold}Please Login!{/bold}', { center: true });
}

function getEmojis() {
  if (ctx.discord.user && ctx.discord.user.premium) {
    return ctx.discord.emojis;
  } else if (ctx.current.scope && ctx.current.scope !== 'dm') {
    return ctx.current.scope.emojis;
  } else {
    return [];
  }
}

process.on('unhandledRejection', handleError);
process.on('uncaughtException', handleError);

function handleError(e) {
  ctx.gui.put(`{red-fg}{bold}Unhandled Error (You should report this){/bold}{/red-fg}\n${e.stack}
 {red-fg}{bold}-- End Error --{/bold}{/red-fg}`);
}
<commit_msg>Prevent empty messages from being sent (#15)<commit_after>#!/usr/bin/env node

const emoji = require('node-emoji');
const Storage = require('./Storage');
const gui = require('./gui');
const commands = require('./commands');
const assets = require('./assets');
const discord = require('./discord');
const snekparse = require('snekparse');
const userLookup = require('./util/userLookup');

const ctx = {
  gui, assets,
  discord: discord.client,
  allowInput: false,
  current: {
    scope: null,
    channel: null,
  },
  rc: Storage.rc,
};

module.exports = ctx;

gui.on('input', (message) => {
  if(!message.length) return;
  const prefix = ctx.rc.prefix || '/';
  if (message.startsWith(prefix)) {
    const [command, ...args] = message.slice(prefix.length).split(' ');
    if (command in commands) commands[command].run(ctx, snekparse(args));
  } else {
    if (!ctx.allowInput) return;
    const args = message.split(' ');
    for (const word in args) {
      if (args[word].startsWith('@')) {
        const users = ctx.current.scope && ctx.current.scope !== 'dm' ?
          ctx.current.scope.members.map((m) => m.user) :
          ctx.discord.users;
        const user = userLookup(args[word].slice(1), users);
        if (user) args[word] = user.toString();
      } else if (args[word].startsWith('#')) {
        if (!ctx.current.scope || ctx.current.scope === 'dm') continue;
        const name = args[word].slice(1);
        const channel = ctx.current.scope.channels
          .filter((c) => c.type === 'text')
          .find((c) =>
            c.name.toLowerCase() === name.toLowerCase());
        if (channel) args[word] = channel.toString();
      }
    }
    message = args.join(' ');

    const customEmojis = getEmojis();
    for (const match of message.match(/:[^:]+:/g) || []) {
      const unicode = emoji.get(match);
      if (unicode !== match) {
        message = message.replace(match, unicode);
        continue;
      }
      const found = customEmojis.find((x) => x.name.toLowerCase() === match.replace(/:/g, '').toLowerCase());
      message = message.replace(match, found ? found.toString() : emoji.get(match));
    }

    if (ctx.current.channel) {
      ctx.current.channel.send(message).catch((err) => {
        ctx.gui.put(`{bold}${err.message}{/bold}`);
      });
    }
  }
});

gui.init();
gui.put(`{center}${assets.logo}{/center}`, { center: true });

if (Storage.has('token')) {
  discord.run(ctx);
} else {
  gui.put('{bold}Please Login!{/bold}', { center: true });
}

function getEmojis() {
  if (ctx.discord.user && ctx.discord.user.premium) {
    return ctx.discord.emojis;
  } else if (ctx.current.scope && ctx.current.scope !== 'dm') {
    return ctx.current.scope.emojis;
  } else {
    return [];
  }
}

process.on('unhandledRejection', handleError);
process.on('uncaughtException', handleError);

function handleError(e) {
  ctx.gui.put(`{red-fg}{bold}Unhandled Error (You should report this){/bold}{/red-fg}\n${e.stack}
 {red-fg}{bold}-- End Error --{/bold}{/red-fg}`);
}
<|endoftext|>


<commit_before>import {asyncReplace, isArray, isString, md5} from 'stc-helper';
import {isMaster} from 'cluster';
import PluginInvoke from 'stc-plugin-invoke';
import path from 'path';
import url from 'url';
import ConcurrentLimit from './concurrent_limit.js';
import {
  getAst,
  checkInMaster,
  checkRunIsExecute
} from './helper.js';

/**
 * concurrent limit task instances
 */
const concurrentLimitInstances = {};

/**
 * stc plugin abstract class
 */
export default class StcPlugin {
  /**
   * constructor
   */
  constructor(file, opts = {}){
    this.file = file;
    this.options = opts.options || {};
    this.stc = opts.stc;
    this.config = this.stc.config;
    this.TokenType = this.stc.flkit.TokenType;
    this.include = opts.include;
    //can not use ext in sub plugins
    this._ext = opts.ext || {};
    //store other properties
    this._prop = {};
  }
  /**
   * get matches
   */
  get matches(){
    return this.stc.resource.match(this.file, this.include);
  }
  /**
   * get or set properties
   */
  prop(name, value){
    if(value === undefined){
      return this._prop[name];
    }
    this._prop[name] = value;
    return this;
  }
  /**
   * is template file
   */
  isTpl(){
    return !!this.file.prop('tpl');
  }
  /**
   * get md5 value of plugin
   */
  getMd5(){
    if(this.prop('md5')){
      return this.prop('md5');
    }
    let value = md5(this.constructor.toString());
    this.prop('md5', value);
    return value;
  }
  /**
   * get file content
   */
  async getContent(encoding = null){
    if(isMaster){
      return this.file.getContent(encoding);
    }
    let content = await this.stc.cluster.workerInvoke({
      method: 'getContent',
      encoding: encoding,
      file: this.file.path
    });
    if(encoding !== null){
      return content;
    }
    return new Buffer(content, 'base64');
  }
  /**
   * set file content
   */
  setContent(content){
    checkInMaster('setContent');
    checkRunIsExecute(this, 'setContent');
    this.file.setContent(content);
    return this;
  }
  /**
   * get file ast
   */
  async getAst(){
    let content = await this.getContent('utf8');

    if(isMaster){
      if(this.file.hasAst()){
        return this.file.getAst();
      }
      return getAst(this, content, async () => {
        // turn off cluster
        if(this.config.cluster === false){
          return this.file.getAst();
        }
        //get ast in worker parsed
        let ret = await this.stc.cluster.masterInvoke({
          type: 'getAst',
          content,
          file: this.file.path
        });
        this.file.setAst(ret);
        return ret;
      });
    }

    return getAst(this, content, async () => {
      // if have ast in master, return directory
      let ast = await this.stc.cluster.workerInvoke({
        method: 'getAstIfExist',
        file: this.file.path
      });
      if(ast){
        return ast;
      }
      this.file.setContent(content);
      let ret = await this.file.getAst();
      // update ast in master
      await this.stc.cluster.workerInvoke({
        method: 'updateAst',
        file: this.file.path,
        ast: ret
      });
      return ret;
    });
  }
  /**
   * set ast
   */
  setAst(ast){
    checkInMaster('setAst');
    checkRunIsExecute(this, 'setAst');
    this.file.setAst(ast);
    return this;
  }
  /**
   * add file dependence
   */
  addDependence(dependencies){
    if(!isMaster){
      throw new Error('addDependence must be invoked in master');
    }
    if(!isArray(dependencies)){
      dependencies = [dependencies];
    }
    dependencies = dependencies.map(item => {
      if(!isString(item)){
        return item;
      }
      let filepath = this.getResolvePath(item);
      let file = this.stc.resource.getFileByPath(filepath, this.file.path);
      if(!file){
        throw new Error(`file ${item} is not exist in ${this.file.path}`);
      }
      return file;
    });
    this.file.dependence.add(dependencies);
    return dependencies;
  }
  /**
   * get file dependence
   */
  getDependence(file = this.file){
    return file.dependence.get();
  }

  /**
   * add file
   */
  async addFile(filepath, content, virtual){
    if(!virtual){
      checkRunIsExecute(this, 'addFile');
    }
    let resolvePath = this.getResolvePath(filepath);
    if(isMaster){
      return this.stc.resource.addFile(resolvePath, content, virtual);
    }
    await this.stc.cluster.workerInvoke({
      method: 'addFile',
      file: resolvePath,
      virtual,
      content
    });
    return this.stc.resource.createFile(resolvePath, content, virtual);
  }
  /**
   * get resolve path
   */
  getResolvePath(filepath){
    // parse filepath, remove query & hash in filepath
    filepath = decodeURIComponent(url.parse(filepath).pathname);
    let currentFilePath = path.dirname(this.file.path);
    let resolvePath = path.resolve(currentFilePath, filepath);
    let currentPath = process.cwd() + path.sep;
    if(resolvePath.indexOf(currentPath) === 0){
      resolvePath = resolvePath.slice(currentPath.length);
    }
    return resolvePath;
  }
  /**
   * get file by path
   */
  getFileByPath(filepath){
    filepath = this.getResolvePath(filepath);
    if(isMaster){
      return this.stc.resource.getFileByPath(filepath, this.file.path);
    }
    return this.stc.resource.createFile(filepath);
  }

  /**
   * invoke self plugin
   */
  async invokeSelf(file = this.file){
    if(isString(file)){
      file = this.getFileByPath(file);
    }
    return this.invokePlugin(this.constructor, file);
  }

  /**
   * invoke plugin
   */
  async invokePlugin(plugin, file = this.file){
    if(isString(file)){
      file = this.getFileByPath(file);
    }
    let instance = new PluginInvoke(plugin, file, {
      stc: this.stc,
      options: this.options,
      ext: plugin === this.constructor ? this._ext : {}
    });
    return instance.run();
  }

  /**
   * async content replace
   * must be use RegExp
   */
  asyncReplace(content = '', replace, callback){
    return asyncReplace(content, replace, callback);
  }
  /**
   * get or set cache
   */
  async cache(name, value){
    if(isMaster){
      let md5Value = this.getMd5();
      if(!this.stc.cacheInstances[md5Value]){
        this.stc.cacheInstances[md5Value] = new this.stc.cache({
          onlyMemory: true
        });
      }
      let instance = this.stc.cacheInstances[md5Value];
      if(value === undefined){
        return instance.get(name);
      }
      instance.set(name, value);
      return this;
    }
    //get or set cache from master
    return this.stc.cluster.workerInvoke({
      method: 'cache',
      key: this.getMd5(),
      name,
      value
    });
  }
  /**
   * create token
   */
  createToken(type, value, referToken){
    return this.stc.flkit.createToken(type, value, referToken);
  }
  /**
   * concurrent limit task
   */
  concurrentLimit(fn, ignoreErrorFn, limit, key = this.constructor.name){
    if(!(key in concurrentLimitInstances)){
     concurrentLimitInstances[key] = new ConcurrentLimit(limit, ignoreErrorFn);
    }
    let instance = concurrentLimitInstances[key];
    return instance.run(fn);
  }
  /**
   * throw fatal error
   */
  fatal(message, line, column, file = this.file.path){
    let msg = {
      message,
      className: this.constructor.name,
      file,
      line,
      column
    }
    throw new Error(JSON.stringify(msg));
  }

  /**
   * show error log
   */
  error(message, line, column, file = this.file.path){
    this.stc.log.error({
      message,
      line: line,
      column: column,
      file,
      className: this.constructor.name
    });
  }

   /**
   * show warning log
   */
  warning(message, line, column, file = this.file.path){
    this.stc.log.warning({
      message,
      line: line,
      column: column,
      file,
      className: this.constructor.name
    });
  }

   /**
   * show notice log
   */
  notice(message, line, column, file = this.file.path){
    this.stc.log.notice({
      message,
      line: line,
      column: column,
      file,
      className: this.constructor.name
    });
  }

  /**
   * run
   */
  run(){

  }
  /**
   * update
   */
  update(){

  }
}<commit_msg>Make sure error, warning, notice methods must be invoked in update method<commit_after>import {asyncReplace, isArray, isString, md5} from 'stc-helper';
import {isMaster} from 'cluster';
import PluginInvoke from 'stc-plugin-invoke';
import path from 'path';
import url from 'url';
import ConcurrentLimit from './concurrent_limit.js';
import {
  getAst,
  checkInMaster,
  checkRunIsExecute
} from './helper.js';

/**
 * concurrent limit task instances
 */
const concurrentLimitInstances = {};

/**
 * stc plugin abstract class
 */
export default class StcPlugin {
  /**
   * constructor
   */
  constructor(file, opts = {}){
    this.file = file;
    this.options = opts.options || {};
    this.stc = opts.stc;
    this.config = this.stc.config;
    this.TokenType = this.stc.flkit.TokenType;
    this.include = opts.include;
    //can not use ext in sub plugins
    this._ext = opts.ext || {};
    //store other properties
    this._prop = {};
  }
  /**
   * get matches
   */
  get matches(){
    return this.stc.resource.match(this.file, this.include);
  }
  /**
   * get or set properties
   */
  prop(name, value){
    if(value === undefined){
      return this._prop[name];
    }
    this._prop[name] = value;
    return this;
  }
  /**
   * is template file
   */
  isTpl(){
    return !!this.file.prop('tpl');
  }
  /**
   * get md5 value of plugin
   */
  getMd5(){
    if(this.prop('md5')){
      return this.prop('md5');
    }
    let value = md5(this.constructor.toString());
    this.prop('md5', value);
    return value;
  }
  /**
   * get file content
   */
  async getContent(encoding = null){
    if(isMaster){
      return this.file.getContent(encoding);
    }
    let content = await this.stc.cluster.workerInvoke({
      method: 'getContent',
      encoding: encoding,
      file: this.file.path
    });
    if(encoding !== null){
      return content;
    }
    return new Buffer(content, 'base64');
  }
  /**
   * set file content
   */
  setContent(content){
    checkInMaster('setContent');
    checkRunIsExecute(this, 'setContent');
    this.file.setContent(content);
    return this;
  }
  /**
   * get file ast
   */
  async getAst(){
    let content = await this.getContent('utf8');

    if(isMaster){
      if(this.file.hasAst()){
        return this.file.getAst();
      }
      return getAst(this, content, async () => {
        // turn off cluster
        if(this.config.cluster === false){
          return this.file.getAst();
        }
        //get ast in worker parsed
        let ret = await this.stc.cluster.masterInvoke({
          type: 'getAst',
          content,
          file: this.file.path
        });
        this.file.setAst(ret);
        return ret;
      });
    }

    return getAst(this, content, async () => {
      // if have ast in master, return directory
      let ast = await this.stc.cluster.workerInvoke({
        method: 'getAstIfExist',
        file: this.file.path
      });
      if(ast){
        return ast;
      }
      this.file.setContent(content);
      let ret = await this.file.getAst();
      // update ast in master
      await this.stc.cluster.workerInvoke({
        method: 'updateAst',
        file: this.file.path,
        ast: ret
      });
      return ret;
    });
  }
  /**
   * set ast
   */
  setAst(ast){
    checkInMaster('setAst');
    checkRunIsExecute(this, 'setAst');
    this.file.setAst(ast);
    return this;
  }
  /**
   * add file dependence
   */
  addDependence(dependencies){
    if(!isMaster){
      throw new Error('addDependence must be invoked in master');
    }
    if(!isArray(dependencies)){
      dependencies = [dependencies];
    }
    dependencies = dependencies.map(item => {
      if(!isString(item)){
        return item;
      }
      let filepath = this.getResolvePath(item);
      let file = this.stc.resource.getFileByPath(filepath, this.file.path);
      if(!file){
        throw new Error(`file ${item} is not exist in ${this.file.path}`);
      }
      return file;
    });
    this.file.dependence.add(dependencies);
    return dependencies;
  }
  /**
   * get file dependence
   */
  getDependence(file = this.file){
    return file.dependence.get();
  }

  /**
   * add file
   */
  async addFile(filepath, content, virtual){
    if(!virtual){
      checkRunIsExecute(this, 'addFile');
    }
    let resolvePath = this.getResolvePath(filepath);
    if(isMaster){
      return this.stc.resource.addFile(resolvePath, content, virtual);
    }
    await this.stc.cluster.workerInvoke({
      method: 'addFile',
      file: resolvePath,
      virtual,
      content
    });
    return this.stc.resource.createFile(resolvePath, content, virtual);
  }
  /**
   * get resolve path
   */
  getResolvePath(filepath){
    // parse filepath, remove query & hash in filepath
    filepath = decodeURIComponent(url.parse(filepath).pathname);
    let currentFilePath = path.dirname(this.file.path);
    let resolvePath = path.resolve(currentFilePath, filepath);
    let currentPath = process.cwd() + path.sep;
    if(resolvePath.indexOf(currentPath) === 0){
      resolvePath = resolvePath.slice(currentPath.length);
    }
    return resolvePath;
  }
  /**
   * get file by path
   */
  getFileByPath(filepath){
    filepath = this.getResolvePath(filepath);
    if(isMaster){
      return this.stc.resource.getFileByPath(filepath, this.file.path);
    }
    return this.stc.resource.createFile(filepath);
  }

  /**
   * invoke self plugin
   */
  async invokeSelf(file = this.file){
    if(isString(file)){
      file = this.getFileByPath(file);
    }
    return this.invokePlugin(this.constructor, file);
  }

  /**
   * invoke plugin
   */
  async invokePlugin(plugin, file = this.file){
    if(isString(file)){
      file = this.getFileByPath(file);
    }
    let instance = new PluginInvoke(plugin, file, {
      stc: this.stc,
      options: this.options,
      ext: plugin === this.constructor ? this._ext : {}
    });
    return instance.run();
  }

  /**
   * async content replace
   * must be use RegExp
   */
  asyncReplace(content = '', replace, callback){
    return asyncReplace(content, replace, callback);
  }
  /**
   * get or set cache
   */
  async cache(name, value){
    if(isMaster){
      let md5Value = this.getMd5();
      if(!this.stc.cacheInstances[md5Value]){
        this.stc.cacheInstances[md5Value] = new this.stc.cache({
          onlyMemory: true
        });
      }
      let instance = this.stc.cacheInstances[md5Value];
      if(value === undefined){
        return instance.get(name);
      }
      instance.set(name, value);
      return this;
    }
    //get or set cache from master
    return this.stc.cluster.workerInvoke({
      method: 'cache',
      key: this.getMd5(),
      name,
      value
    });
  }
  /**
   * create token
   */
  createToken(type, value, referToken){
    return this.stc.flkit.createToken(type, value, referToken);
  }
  /**
   * concurrent limit task
   */
  concurrentLimit(fn, ignoreErrorFn, limit, key = this.constructor.name){
    if(!(key in concurrentLimitInstances)){
     concurrentLimitInstances[key] = new ConcurrentLimit(limit, ignoreErrorFn);
    }
    let instance = concurrentLimitInstances[key];
    return instance.run(fn);
  }
  /**
   * throw fatal error
   */
  fatal(message, line, column, file = this.file.path){
    let msg = {
      message,
      className: this.constructor.name,
      file,
      line,
      column
    }
    throw new Error(JSON.stringify(msg));
  }

  /**
   * show error log
   */
  error(message, line, column, file = this.file.path){
    checkRunIsExecute(this, 'error');
    this.stc.log.error({
      message,
      line: line,
      column: column,
      file,
      className: this.constructor.name
    });
  }

   /**
   * show warning log
   */
  warning(message, line, column, file = this.file.path){
    checkRunIsExecute(this, 'warning')
    this.stc.log.warning({
      message,
      line: line,
      column: column,
      file,
      className: this.constructor.name
    });
  }

   /**
   * show notice log
   */
  notice(message, line, column, file = this.file.path){
    checkRunIsExecute(this, 'notice');
    this.stc.log.notice({
      message,
      line: line,
      column: column,
      file,
      className: this.constructor.name
    });
  }

  /**
   * run
   */
  run(){

  }
  /**
   * update
   */
  update(){

  }
}<|endoftext|>


<commit_before>// Set up your application entry point here...
import configureStore from './store/configureStore';
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import { persistStore } from 'redux-persist';
import {Router, browserHistory} from 'react-router';
import {getRoutes} from './routes';
import {getIp} from './actions/actionCreators';
import 'bootstrap/dist/css/bootstrap.css';
require("font-awesome-webpack");

const store = configureStore();
persistStore(store);
store.dispatch(getIp());

const reactRoot = window.document.getElementById("app");
  ReactDOM.render(
    <Provider store={store}>
      <Router history={browserHistory}>
        {getRoutes(store)}
      </Router>
    </Provider>,
    reactRoot);
<commit_msg>Retreive all polls on client load.<commit_after>// Set up your application entry point here...
import configureStore from './store/configureStore';
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import { persistStore } from 'redux-persist';
import {Router, browserHistory} from 'react-router';
import {getRoutes} from './routes';
import {getIp, getAllPolls} from './actions/actionCreators';
import 'bootstrap/dist/css/bootstrap.css';
require("font-awesome-webpack");

const store = configureStore();
persistStore(store);
store.dispatch(getIp());
store.dispatch(getAllPolls());

const reactRoot = window.document.getElementById("app");
  ReactDOM.render(
    <Provider store={store}>
      <Router history={browserHistory}>
        {getRoutes(store)}
      </Router>
    </Provider>,
    reactRoot);
<|endoftext|>


<commit_before>import React from 'react';
import Mousetrap from 'mousetrap';

/*
 * Compare two keymaps
 */
function areKeyMapsEqual(a, b) {
    const aKeys = Object.keys(a);
    const aSize = aKeys.length;
    const bSize = Object.keys(b).length;

    if (aSize != bSize) {
        return false;
    }

    for (let i = 0; i < aSize; i++) {
        const aKey = aKeys[i];
        const aValue = a[aKey];
        const bValue = b[aKey];

        if (aValue != bValue) {
            return false;
        }
    }

    return true;
}

/*
 * Bind a keymap using mousetrap.
 */
class ComboKeys extends React.Component {
    constructor(props) {
        super(props);

        // Is it server-side rendering ?
        if (typeof Mousetrap !== 'function') {
            return;
        }

        const self = this;
        this.mousetrap = Mousetrap();

        const _stopCallback = this.mousetrap.stopCallback;
        this.mousetrap.stopCallback = (e, element, combo) => {
            let result = _stopCallback(e, element, combo);

            if (result && self.props.stopAt) {
                result = self.props.stopAt(e, element, combo);
            }

            return result;
        };
    }

    componentDidMount() {
        this.bindKeyMap(
            this.props.keyMap
        );
    }

    componentDidUpdate(prevProps) {
        if (areKeyMapsEqual(prevProps.keyMap, this.props.keyMap)) {
            return;
        }

        this.unbindKeyMap(prevProps.keyMap);
        this.bindKeyMap(this.props.keyMap);
    }

    componentWillUnmount() {
        this.unbindKeyMap(
            this.props.keyMap
        );
    }

    unbindKeyMap(keyMap) {
        Object.keys(keyMap)
        .forEach((combo) => {
            this.mousetrap.unbind(combo);
        });
    }

    bindKeyMap(keyMap) {
        Object.keys(keyMap)
        .forEach((combo) => {
            const onTrigger = keyMap[combo];
            this.mousetrap.bind(combo, onTrigger);
        });
    }

    render() {
        const { children } = this.props;
        return children ? React.Children.only(children) : null;
    }
}

ComboKeys.propTypes = {
    children: React.PropTypes.node,
    keyMap: React.PropTypes.objectOf(
        React.PropTypes.func
    ).isRequired,
    stopAt: React.PropTypes.func
};

/*
 * Component to bind a single handler. This is a wrapper around ComboKeys.
 */
class ComboKey extends React.PureComponent {
    render() {
        const { children, combo, onTrigger, stopAt } = this.props;
        const keyMap = { [combo]: onTrigger };

        return (
            <ComboKeys keyMap={keyMap} stopAt={stopAt} >
                {children}
            </ComboKeys>
        );
    }
}

ComboKey.propTypes = {
    children: React.PropTypes.node,
    combo: React.PropTypes.string.isRequired,
    onTrigger: React.PropTypes.func.isRequired,
    stopAt: React.PropTypes.func
};

export {
    ComboKey,
    ComboKeys
};
<commit_msg>Fix @Soreine mess (#2)<commit_after>import React from 'react';
import Mousetrap from 'mousetrap';

/*
 * Compare two keymaps
 */
function areKeyMapsEqual(a, b) {
    const aKeys = Object.keys(a);
    const aSize = aKeys.length;
    const bSize = Object.keys(b).length;

    if (aSize != bSize) {
        return false;
    }

    for (let i = 0; i < aSize; i++) {
        const aKey = aKeys[i];
        const aValue = a[aKey];
        const bValue = b[aKey];

        if (aValue != bValue) {
            return false;
        }
    }

    return true;
}

/*
 * Bind a keymap using mousetrap.
 */
class ComboKeys extends React.Component {
    constructor(props) {
        super(props);

        // Is it server-side rendering ?
        if (typeof Mousetrap !== 'function') {
            return;
        }

        const self = this;
        this.mousetrap = Mousetrap();

        const stopAt = self.props.stopAt;
        if (stopAt) {
            // Plug the custom stopAt in
            const _stopCallback = this.mousetrap.stopCallback;
            this.mousetrap.stopCallback = (e, element, combo) => {
                return _stopCallback(e, element, combo)
                    && stopAt(e, element, combo);
            };
        }
    }

    componentDidMount() {
        this.bindKeyMap(
            this.props.keyMap
        );
    }

    componentDidUpdate(prevProps) {
        if (areKeyMapsEqual(prevProps.keyMap, this.props.keyMap)) {
            return;
        }

        this.unbindKeyMap(prevProps.keyMap);
        this.bindKeyMap(this.props.keyMap);
    }

    componentWillUnmount() {
        this.unbindKeyMap(
            this.props.keyMap
        );
    }

    unbindKeyMap(keyMap) {
        Object.keys(keyMap)
        .forEach((combo) => {
            this.mousetrap.unbind(combo);
        });
    }

    bindKeyMap(keyMap) {
        Object.keys(keyMap)
        .forEach((combo) => {
            const onTrigger = keyMap[combo];
            this.mousetrap.bind(combo, onTrigger);
        });
    }

    render() {
        const { children } = this.props;
        return children ? React.Children.only(children) : null;
    }
}

ComboKeys.propTypes = {
    children: React.PropTypes.node,
    keyMap: React.PropTypes.objectOf(
        React.PropTypes.func
    ).isRequired,
    stopAt: React.PropTypes.func
};

/*
 * Component to bind a single handler. This is a wrapper around ComboKeys.
 */
class ComboKey extends React.PureComponent {
    render() {
        const { children, combo, onTrigger, stopAt } = this.props;
        const keyMap = { [combo]: onTrigger };

        return (
            <ComboKeys keyMap={keyMap} stopAt={stopAt} >
                {children}
            </ComboKeys>
        );
    }
}

ComboKey.propTypes = {
    children: React.PropTypes.node,
    combo: React.PropTypes.string.isRequired,
    onTrigger: React.PropTypes.func.isRequired,
    stopAt: React.PropTypes.func
};

export {
    ComboKey,
    ComboKeys
};
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2015 TechnologyAdvice
 */

import _ from 'lodash';
import path from 'path';

const defaultFilename = 'cryptex.json';
const defaultEnv = 'default';

class Cryptex {

  /**
   * Constructs a new instance of Cryptex.
   * @param {Object} [opts={}] An options object
   * @param {string} [opts.file] The config file to load, containing environment names mapped to config objects. If not
   *    specified, Cryptex will look for a "cryptex.json" file in the process's current working directory. Can be
   *    overridden with the `CRYPTEX_FILE` env var.
   * @param {string} [opts.env] The environment key to use in the config file. If not specified, `$NODE_ENV` and
   *    `default` are tried, in that order. Can be overridden with the `CRYPTEX_ENV` env var.
   * @param {boolean} [opts.cacheKey=true] If true, the key provided by the keySource will be cached in memory for
   *    a specified period of time. Set to false for highest security, the possible expense of performance. Can be
   *    overridden with the `CRYPTEX_CACHEKEY` env var (set to "true", or anything else for false).
   * @param {number} [opts.cacheTimeout=5000] The amount of time, in milliseconds, to cache the key provided by the
   *    keySource. If 0, the cache will never be cleared automatically. Has no effect unless `opts.cacheKey` is true.
   *    Can be overridden with the `CRYPTEX_CACHETIMEOUT` env var.
   * @param {Object} [opts.config] A configuration object specifying the key source, encryption algorithm, and
   *    optionally encrypted keys to initialize Crypto with. If specified, no file load will be attempted. To prevent
   *    a file load without specifying a config, pass an empty object here.
   */
  constructor(opts = {}) {
    this._opts = {
      file: process.env.CRYPTEX_FILE || path.join(process.cwd(), defaultFilename),
      env: process.env.CRYPTEX_ENV || process.env.NODE_ENV || defaultEnv,
      cacheKey: process.env.CRYPTEX_CACHEKEY ? process.env.CRYPTEX_CACHEKEY === 'true' : true,
      cacheTimeout: process.env.CRYPTEX_CACHETIMEOUT ? parseInt(process.env.CRYPTEX_CACHETIMEOUT, 10) : 5000
    };
    this.update(opts);
  }

  decrypt(data, encoding = 'base64') {
    const enc = Cryptex._bufferize(data, encoding);
    return Promise.resolve().then(() => {
      return this._getKey();
    }).then((key) => {
      return this._getAlgo().decrypt(key, enc);
    });
  }

  encrypt(data, encoding = 'utf8') {
    const dec = Cryptex._bufferize(data, encoding);
    return Promise.resolve().then(() => {
      return this._getKey();
    }).then((key) => {
      return this._getAlgo().encrypt(key, dec);
    });
  }

  getSecret(secret) {
    const secretUp = secret.toUpperCase();
    const enc = process.env[`CRYPTEX_SECRET_${secretUp}`] || this._config.secrets[secret];
    if (!enc) {
      return Promise.reject(new Error(`Cryptex secret "${secret}" not found`));
    }
    return this.decrypt(enc, this._config.secretEncoding);
  }

  /**
   * Updates this Cryptex instance with new configuration. Note that this will cause this instance to clear all
   * caches, reload any configuration files, and apply any changes to environment variables since it was last
   * initialized.
   * @param {Object} [opts={}] An options object
   * @param {string} [opts.file] The config file to load, containing environment names mapped to config objects. If not
   *    specified, Cryptex will look for a "cryptex.json" file in the process's current working directory. Can be
   *    overridden with the `CRYPTEX_FILE` env var.
   * @param {string} [opts.env] The environment key to use in the config file. If not specified, `$NODE_ENV` and
   *    `default` are tried, in that order. Can be overridden with the `CRYPTEX_ENV` env var.
   * @param {boolean} [opts.cacheKey=true] If true, the key provided by the keySource will be cached in memory for
   *    a specified period of time. Set to false for highest security, the possible expense of performance. Can be
   *    overridden with the `CRYPTEX_CACHEKEY` env var (set to "true", or anything else for false).
   * @param {number} [opts.cacheTimeout=5000] The amount of time, in milliseconds, to cache the key provided by the
   *    keySource. If 0, the cache will never be cleared automatically. Has no effect unless `opts.cacheKey` is true.
   *    Can be overridden with the `CRYPTEX_CACHETIMEOUT` env var.
   * @param {Object} [opts.config] A configuration object specifying the key source, encryption algorithm, and
   *    optionally encrypted keys to initialize Crypto with. If specified, no file load will be attempted. To prevent
   *    a file load without specifying a config, pass an empty object here.
   */
  update(opts = {}) {
    _.assign(this._opts, opts);
    if (this._opts.config) {
      this._config = this._opts.config;
    } else {
      this._config = this._loadEnvFromFile();
    }
    this._config.secrets = this._config.secrets || {};
    this._config.secretEncoding = process.env.CRYPTEX_SECRETENCODING || this._config.secretEncoding || 'base64';
    this._config.algorithm = process.env.CRYPTEX_ALGORITHM || this._config.algorithm || 'aes256';
    this._config.keySource = process.env.CRYPTEX_KEYSOURCE || this._config.keySource || 'none';
    this._config.keySourceEncoding = process.env.CRYPTEX_KEYSOURCEENCODING || this._config.keySourceEncoding ||
      'binary';
    delete this._key;
    delete this._algoInst;
  }

  _getAlgo() {
    if (!this._algoInst) {
      const AlgoClass = Cryptex._require('algorithms', this._config.algorithm);
      this._algoInst = new AlgoClass(this._config.algorithmOpts);
    }
    return this._algoInst;
  }

  _getKey() {
    if (this._key) {
      return Promise.resolve(this._key);
    }
    const sourceGetKey = Cryptex._require('keySources', this._config.keySource);
    const toBuffer = Cryptex._require('encodings', this._config.keySourceEncoding);
    return sourceGetKey(this._config.keySourceOpts).then((keyData) => {
      if (keyData && !Buffer.isBuffer(keyData) && this._config.keySourceEncoding === 'binary') {
        throw new Error("Please specify a key encoding. Looks like it's not a binary buffer!");
      }
      const key = keyData && toBuffer(keyData);
      if (this._opts.cacheKey) {
        this._key = key;
        if (this._opts.cacheTimeout) {
          setTimeout(() => delete this._key, this._opts.cacheTimeout);
        }
      }
      return key;
    });
  }

  _loadEnvFromFile() {
    if (this._opts.file.substr(-5) !== '.json') {
      throw new Error('Cryptex files must end in .json');
    }
    try {
      this._confFile = _.clone(require(this._opts.file), true);
    } catch (e) {
      this._confFile = {};
    }
    return this._confFile[this._opts.env] || this._confFile[defaultEnv] || {};
  }

  static _bufferize(data, encoding) {
    let buf = data;
    if (!Buffer.isBuffer(buf)) {
      buf = new Buffer(data, encoding);
    }
    return buf;
  }

  static _require(dir, module) {
    if (module.includes(path.sep)) {
      throw new Error(`Invalid module name: "${module}"`);
    }
    const reqPath = '.' + path.sep + path.join(dir, module);
    if (!Cryptex._requires[reqPath]) {
      try {
        Cryptex._requires[reqPath] = require(reqPath);
      } catch (e) {
        throw new Error(`The module "${reqPath}" does not exist.`);
      }
    }
    return Cryptex._requires[reqPath];
  }
}
Cryptex._requires = {};

const cryptex = new Cryptex();
cryptex.Cryptex = Cryptex;
export default cryptex;
<commit_msg>KMS: Fix relative path issue<commit_after>/*
 * Copyright (c) 2015 TechnologyAdvice
 */

import _ from 'lodash';
import path from 'path';

const defaultFilename = 'cryptex.json';
const defaultEnv = 'default';

class Cryptex {

  /**
   * Constructs a new instance of Cryptex.
   * @param {Object} [opts={}] An options object
   * @param {string} [opts.file] The config file to load, containing environment names mapped to config objects. If not
   *    specified, Cryptex will look for a "cryptex.json" file in the process's current working directory. Can be
   *    overridden with the `CRYPTEX_FILE` env var.
   * @param {string} [opts.env] The environment key to use in the config file. If not specified, `$NODE_ENV` and
   *    `default` are tried, in that order. Can be overridden with the `CRYPTEX_ENV` env var.
   * @param {boolean} [opts.cacheKey=true] If true, the key provided by the keySource will be cached in memory for
   *    a specified period of time. Set to false for highest security, the possible expense of performance. Can be
   *    overridden with the `CRYPTEX_CACHEKEY` env var (set to "true", or anything else for false).
   * @param {number} [opts.cacheTimeout=5000] The amount of time, in milliseconds, to cache the key provided by the
   *    keySource. If 0, the cache will never be cleared automatically. Has no effect unless `opts.cacheKey` is true.
   *    Can be overridden with the `CRYPTEX_CACHETIMEOUT` env var.
   * @param {Object} [opts.config] A configuration object specifying the key source, encryption algorithm, and
   *    optionally encrypted keys to initialize Crypto with. If specified, no file load will be attempted. To prevent
   *    a file load without specifying a config, pass an empty object here.
   */
  constructor(opts = {}) {
    this._opts = {
      file: process.env.CRYPTEX_FILE || path.join(process.cwd(), defaultFilename),
      env: process.env.CRYPTEX_ENV || process.env.NODE_ENV || defaultEnv,
      cacheKey: process.env.CRYPTEX_CACHEKEY ? process.env.CRYPTEX_CACHEKEY === 'true' : true,
      cacheTimeout: process.env.CRYPTEX_CACHETIMEOUT ? parseInt(process.env.CRYPTEX_CACHETIMEOUT, 10) : 5000
    };
    this.update(opts);
  }

  decrypt(data, encoding = 'base64') {
    const enc = Cryptex._bufferize(data, encoding);
    return Promise.resolve().then(() => {
      return this._getKey();
    }).then((key) => {
      return this._getAlgo().decrypt(key, enc);
    });
  }

  encrypt(data, encoding = 'utf8') {
    const dec = Cryptex._bufferize(data, encoding);
    return Promise.resolve().then(() => {
      return this._getKey();
    }).then((key) => {
      return this._getAlgo().encrypt(key, dec);
    });
  }

  getSecret(secret) {
    const secretUp = secret.toUpperCase();
    const enc = process.env[`CRYPTEX_SECRET_${secretUp}`] || this._config.secrets[secret];
    if (!enc) {
      return Promise.reject(new Error(`Cryptex secret "${secret}" not found`));
    }
    return this.decrypt(enc, this._config.secretEncoding);
  }

  /**
   * Updates this Cryptex instance with new configuration. Note that this will cause this instance to clear all
   * caches, reload any configuration files, and apply any changes to environment variables since it was last
   * initialized.
   * @param {Object} [opts={}] An options object
   * @param {string} [opts.file] The config file to load, containing environment names mapped to config objects. If not
   *    specified, Cryptex will look for a "cryptex.json" file in the process's current working directory. Can be
   *    overridden with the `CRYPTEX_FILE` env var.
   * @param {string} [opts.env] The environment key to use in the config file. If not specified, `$NODE_ENV` and
   *    `default` are tried, in that order. Can be overridden with the `CRYPTEX_ENV` env var.
   * @param {boolean} [opts.cacheKey=true] If true, the key provided by the keySource will be cached in memory for
   *    a specified period of time. Set to false for highest security, the possible expense of performance. Can be
   *    overridden with the `CRYPTEX_CACHEKEY` env var (set to "true", or anything else for false).
   * @param {number} [opts.cacheTimeout=5000] The amount of time, in milliseconds, to cache the key provided by the
   *    keySource. If 0, the cache will never be cleared automatically. Has no effect unless `opts.cacheKey` is true.
   *    Can be overridden with the `CRYPTEX_CACHETIMEOUT` env var.
   * @param {Object} [opts.config] A configuration object specifying the key source, encryption algorithm, and
   *    optionally encrypted keys to initialize Crypto with. If specified, no file load will be attempted. To prevent
   *    a file load without specifying a config, pass an empty object here.
   */
  update(opts = {}) {
    _.assign(this._opts, opts);
    if (this._opts.config) {
      this._config = this._opts.config;
    } else {
      this._config = this._loadEnvFromFile();
    }
    this._config.secrets = this._config.secrets || {};
    this._config.secretEncoding = process.env.CRYPTEX_SECRETENCODING || this._config.secretEncoding || 'base64';
    this._config.algorithm = process.env.CRYPTEX_ALGORITHM || this._config.algorithm || 'aes256';
    this._config.keySource = process.env.CRYPTEX_KEYSOURCE || this._config.keySource || 'none';
    this._config.keySourceEncoding = process.env.CRYPTEX_KEYSOURCEENCODING || this._config.keySourceEncoding ||
      'binary';
    delete this._key;
    delete this._algoInst;
  }

  _getAlgo() {
    if (!this._algoInst) {
      const AlgoClass = Cryptex._require('algorithms', this._config.algorithm);
      this._algoInst = new AlgoClass(this._config.algorithmOpts);
    }
    return this._algoInst;
  }

  _getKey() {
    if (this._key) {
      return Promise.resolve(this._key);
    }
    const sourceGetKey = Cryptex._require('keySources', this._config.keySource);
    const toBuffer = Cryptex._require('encodings', this._config.keySourceEncoding);
    return sourceGetKey(this._config.keySourceOpts).then((keyData) => {
      if (keyData && !Buffer.isBuffer(keyData) && this._config.keySourceEncoding === 'binary') {
        throw new Error("Please specify a key encoding. Looks like it's not a binary buffer!");
      }
      const key = keyData && toBuffer(keyData);
      if (this._opts.cacheKey) {
        this._key = key;
        if (this._opts.cacheTimeout) {
          setTimeout(() => delete this._key, this._opts.cacheTimeout);
        }
      }
      return key;
    });
  }

  _loadEnvFromFile() {
    if (this._opts.file.substr(-5) !== '.json') {
      throw new Error('Cryptex files must end in .json');
    }
    try {
      this._confFile = _.clone(require(this._opts.file), true);
    } catch (e) {
      this._confFile = {};
    }
    return this._confFile[this._opts.env] || this._confFile[defaultEnv] || {};
  }

  static _bufferize(data, encoding) {
    let buf = data;
    if (!Buffer.isBuffer(buf)) {
      buf = new Buffer(data, encoding);
    }
    return buf;
  }

  static _require(dir, module) {
    if (module.includes(path.sep)) {
      throw new Error(`Invalid module name: "${module}"`);
    }
    const reqPath = path.join(__dirname, dir, module);
    if (!Cryptex._requires[reqPath]) {
      try {
        Cryptex._requires[reqPath] = require(reqPath);
      } catch (e) {
        throw new Error(`The module "${reqPath}" does not exist.`);
      }
    }
    return Cryptex._requires[reqPath];
  }
}
Cryptex._requires = {};

const cryptex = new Cryptex();
cryptex.Cryptex = Cryptex;
export default cryptex;
<|endoftext|>


<commit_before>'use strict';

var Snoocore  = require('snoocore');
var fivebeans = require('fivebeans');
var Config    = require('../config');
var twitter   = require('./adapter/twitter');
var reddit    = require('./adapter/reddit');

var bean = new fivebeans.client(Config.beanstalkd.host, Config.beanstalkd.port);
bean.on('connect', function () {
    bean.watch(Config.beanstalkd.tube, function (err) {
        if (err) {
            throw err;
        }
        reserveQueued();
        setInterval(reserveQueued, Config.beanstalkd.delay);
    });
}).on('error', function (err) {
    throw err;
}).connect();

var twitter_counter = 0;

function reserveQueued() {
    try {
        console.log("Reserving beanstalkd job.");
        bean.reserve_with_timeout(1, function (err, job_id, payload) {
            if (typeof job_id == 'undefined') {
                return;
            }
            console.log("Got job #" + job_id);
            var media = JSON.parse(payload);

            reddit.update(media, function() {
                console.log("Reddit has been updated.");

                twitter_counter++;
                //if (twitter_counter == 35) {
                    console.log("Updating twitter.");

                    twitter.tweetMedia(media, function (err) {
                        if (err) {
                            console.log(err);
                        } else {
                            console.log("Twitter has been updated.");
                        }
                    });
                    twitter_counter = 0;
                //}

                bean.destroy(job_id, function (err) {
                    if (err) {
                        console.log(err);
                    }
                });
            });
        });
    } catch (e) {
        console.log(e);
    }
}<commit_msg>Removed debugging code<commit_after>'use strict';

var Snoocore  = require('snoocore');
var fivebeans = require('fivebeans');
var Config    = require('../config');
var twitter   = require('./adapter/twitter');
var reddit    = require('./adapter/reddit');

var bean = new fivebeans.client(Config.beanstalkd.host, Config.beanstalkd.port);
bean.on('connect', function () {
    bean.watch(Config.beanstalkd.tube, function (err) {
        if (err) {
            throw err;
        }
        reserveQueued();
        setInterval(reserveQueued, Config.beanstalkd.delay);
    });
}).on('error', function (err) {
    throw err;
}).connect();

var twitter_counter = 0;

function reserveQueued() {
    try {
        console.log("Reserving beanstalkd job.");
        bean.reserve_with_timeout(1, function (err, job_id, payload) {
            if (typeof job_id == 'undefined') {
                return;
            }
            console.log("Got job #" + job_id);
            var media = JSON.parse(payload);

            reddit.update(media, function() {
                console.log("Reddit has been updated.");

                twitter_counter++;
                if (twitter_counter == 35) {
                    console.log("Updating twitter.");

                    twitter.tweetMedia(media, function (err) {
                        if (err) {
                            console.log(err);
                        } else {
                            console.log("Twitter has been updated.");
                        }
                    });
                    twitter_counter = 0;
                }

                bean.destroy(job_id, function (err) {
                    if (err) {
                        console.log(err);
                    }
                });
            });
        });
    } catch (e) {
        console.log(e);
    }
}<|endoftext|>


<commit_before>import storage from './libs/Storage';
import * as CONSTANTES from './constantes';

export const persistor = (recordAction = true, key) => {
  this.persistActionType = CONSTANTES.PERSIST_STORE;
  this.recordAction = recordAction;
  storage.initLocalStorage(key);
};

export const persistWithConditions = (currentState, action) => {
  if (!currentState) return;

  if (action.type === this.persistActionType) {
    this.setStorage(currentState);
  }
};

export const start = store => next => (action) => {
  const result = next(action);
  const currentState = store.getState();
  persistWithConditions(currentState, action);
  if (this.recordAction) {
    this.persistAction(action);
  }
  return result;
};

export const persistAction = (action) => {
  if (!action) return;
  const actionArray = this.getStorage('REDUX_RECOVER_ACTION') || [];

  if (actionArray.length === this.nbSavedActions) {
    actionArray.shift(action);
  } else {
    actionArray.push(action);
  }
  storage.setStorage('REDUX_RECOVER_ACTION', actionArray.reverse());
};
<commit_msg>wip' (#5)<commit_after>import storage from './libs/Storage';
import * as CONSTANTES from './constantes';

export const persistor = (recordAction = true, key) => {
  this.persistActionType = CONSTANTES.PERSIST_STORE;
  this.recordAction = recordAction;
  storage.initLocalStorage(key);
};

export const persistWithConditions = (currentState, action) => {
  if (!currentState) return;

  if (action.type === this.persistActionType) {
    this.setStorage(currentState);
  }
};

export const start = store => next => (action) => {
  const result = next(action);
  const currentState = store.getState();
  persistWithConditions(currentState, action);
  if (this.recordAction) {
    this.persistAction(action);
  }
  return result;
};

export const persistAction = (action) => {
  if (!action) return;
  const actionArray = this.getStorage('REDUX_RECOVER_ACTION') || [];

  if (actionArray.length === this.nbSavedActions) {
    actionArray.shift(action);
  } else {
    actionArray.push(action);
  }
  storage.setStorage('REDUX_RECOVER_ACTION', actionArray.reverse());
};

export const purge = () => new Promise((resolve, reject) => {
  storage.clearStorage();
  resolve();
});<|endoftext|>


<commit_before>import generate from "babel-generator";

type Plugin = {
  visitor: Visitors
};

type PluginParams = {
  types: Object;
  template: (source: string) => (ids: Object) => Node;
};

type Visitors = {
  [key: string]: Visitor
}

type Visitor = (path: NodePath) => void;

type Node = {
  type: string;
  node?: void;
};

type Literal = {
  type: 'StringLiteral' | 'BooleanLiteral' | 'NumericLiteral' | 'NullLiteral' | 'RegExpLiteral'
};

type Identifier = {
  type: string;
  name: string;
};

type Scope = {};

type NodePath = {
  type: string;
  node: Node;
  scope: Scope;
};

/**
 * # Design By Contract Transformer
 */
export default function ({types: t, template}: PluginParams): Plugin {

  const PRECONDITION_NAME = 'pre';
  const POSTCONDITION_NAME = 'post';
  const INVARIANT_NAME = 'invariant';
  const RETURN_NAME = 'it';

  const returnId: Identifier = t.identifier(RETURN_NAME);

  const guard: (ids: {[key: string]: Node}) => Node = template(`
    if (!condition) {
      throw new Error(message);
    }
  `);

  const guardFn: (ids: {[key: string]: Node}) => Node = template(`
    function id (it) {
      conditions;
      return it;
    }
  `);

  function assemblePrecondition (path: NodePath): void {
    const body: NodePath = path.get('body');
    const fn: NodePath = path.getFunctionParent();
    const name: string = fn.node.id ? `"${fn.node.id.name}" `: ' ';
    if (body.isExpressionStatement()) {
      let condition: NodePath = body.get('expression');
      let message: ?Node;
      if (condition.isSequenceExpression()) {
        const expressions = condition.get('expressions');
        condition = expressions[0];
        message = expressions[1].node;
      }
      else {
        message = t.stringLiteral(`Function ${name}precondition failed: ${generate(condition.node).code}`);
      }
      path.replaceWith(guard({
        condition,
        message
      }));
      return;
    }

    body.traverse({
      VariableDeclaration (item: NodePath): void {
        throw path.buildCodeFrameError(`Preconditions cannot have side effects.`);
      },
      Function (item: NodePath): void {
        throw path.buildCodeFrameError(`Preconditions cannot have side effects.`);
      },
      AssignmentExpression (item: NodePath): void {
        throw path.buildCodeFrameError(`Preconditions cannot have side effects.`);
      },
      UpdateExpression (item: NodePath): void {
        throw path.buildCodeFrameError(`Preconditions cannot have side effects.`);
      },
      YieldExpression (item: NodePath): void {
        throw path.buildCodeFrameError(`Preconditions cannot have side effects.`);
      },
      ReturnStatement (item: NodePath): void {
        throw path.buildCodeFrameError(`Preconditions cannot have side effects.`);
      },
      ExpressionStatement (statement: NodePath): void {
        let condition: NodePath = statement.get('expression');
        let message: ?Node;
        if (condition.isSequenceExpression()) {
          const expressions = condition.get('expressions');
          condition = expressions[0];
          message = expressions[1].node;
        }
        else {
          message = t.stringLiteral(`Function ${name}precondition failed: ${generate(condition.node).code}`);
        }
        statement.replaceWith(guard({
          condition,
          message
        }));
      }
    });

    if (body.isBlockStatement()) {
      path.replaceWithMultiple(path.get('body').node.body);
    }
    else {
      path.replaceWith(path.get('body'));
    }
  }

  function assemblePostcondition (path: NodePath): Identifier {
    const body: NodePath = path.get('body');
    const fn: NodePath = path.getFunctionParent();
    const name: string = fn.node.id ? `"${fn.node.id.name}" `: ' ';
    const conditions: Node[] = [];

    if (body.isExpressionStatement()) {
      let condition: NodePath = body.get('expression');
      let message: ?Node;
      if (condition.isSequenceExpression()) {
        const expressions = condition.get('expressions');
        condition = expressions[0];
        message = expressions[1].node;
      }
      else {
        message = t.stringLiteral(`Function ${name}postcondition failed: ${generate(condition.node).code}`);
      }
      conditions.push(guard({
        condition,
        message
      }));
    }
    else {
      body.traverse({
        VariableDeclaration (item: NodePath): void {
          throw path.buildCodeFrameError(`Postconditions cannot have side effects.`);
        },
        Function (item: NodePath): void {
          throw path.buildCodeFrameError(`Postconditions cannot have side effects.`);
        },
        AssignmentExpression (item: NodePath): void {
          throw path.buildCodeFrameError(`Postconditions cannot have side effects.`);
        },
        UpdateExpression (item: NodePath): void {
          throw path.buildCodeFrameError(`Postconditions cannot have side effects.`);
        },
        YieldExpression (item: NodePath): void {
          throw path.buildCodeFrameError(`Postconditions cannot have side effects.`);
        },
        ReturnStatement (item: NodePath): void {
          throw path.buildCodeFrameError(`Postconditions cannot have side effects.`);
        },
        ExpressionStatement (statement: NodePath): void {
          let condition: NodePath = statement.get('expression');
          let message: ?Node;
          if (condition.isSequenceExpression()) {
            const expressions = condition.get('expressions');
            condition = expressions[0];
            message = expressions[1].node;
          }
          else {
            message = t.stringLiteral(`Function ${name}postcondition failed: ${generate(condition.node).code}`);
          }
          statement.replaceWith(guard({
            condition,
            message
          }));
        }
      });
      conditions.push(...body.node.body);
    }

    const id = path.scope.generateUidIdentifier(`${fn.node.id ? fn.node.id.name : 'check'}Postcondition`);

    path.replaceWith(guardFn({
      id,
      conditions,
      it: returnId
    }));

    return id;
  }

  function assembleInvariant (path: NodePath): Identifier {
    const body: NodePath = path.get('body');
    const fn: NodePath = path.getFunctionParent();
    const name: string = fn.node.id ? `"${fn.node.id.name}" `: ' ';
    const conditions: Node[] = [];

    if (body.isExpressionStatement()) {
      let condition: NodePath = body.get('expression');
      let message: ?Node;
      if (condition.isSequenceExpression()) {
        const expressions = condition.get('expressions');
        condition = expressions[0];
        message = expressions[1].node;
      }
      else {
        message = t.stringLiteral(`Function ${name}invariant failed: ${generate(condition.node).code}`);
      }
      conditions.push(guard({
        condition,
        message
      }));
    }
    else {
      body.traverse({
        VariableDeclaration (item: NodePath): void {
          throw path.buildCodeFrameError(`Invariants cannot have side effects.`);
        },
        Function (item: NodePath): void {
          throw path.buildCodeFrameError(`Invariants cannot have side effects.`);
        },
        AssignmentExpression (item: NodePath): void {
          throw path.buildCodeFrameError(`Invariants cannot have side effects.`);
        },
        UpdateExpression (item: NodePath): void {
          throw path.buildCodeFrameError(`Invariants cannot have side effects.`);
        },
        YieldExpression (item: NodePath): void {
          throw path.buildCodeFrameError(`Invariants cannot have side effects.`);
        },
        ReturnStatement (item: NodePath): void {
          throw path.buildCodeFrameError(`Invariants cannot have side effects.`);
        },
        ExpressionStatement (statement: NodePath): void {
          let condition: NodePath = statement.get('expression');
          let message: ?Node;
          if (condition.isSequenceExpression()) {
            const expressions = condition.get('expressions');
            condition = expressions[0];
            message = expressions[1].node;
          }
          else {
            message = t.stringLiteral(`Function ${name}invariant failed: ${generate(condition.node).code}`);
          }
          statement.replaceWith(guard({
            condition,
            message
          }));
        }
      });
      conditions.push(...body.node.body);
    }

    const id = path.scope.generateUidIdentifier(`${fn.node.id ? fn.node.id.name : 'check'}Invariant`);

    path.replaceWith(guardFn({
      id,
      conditions,
      it: returnId
    }));

    return id;
  }

  function expression (input: string): Function {
    const fn: Function = template(input);
    return function (...args) {
      const node: Node = fn(...args);
      return getExpression(node);
    };
  }

  return {
    visitor: {
      Function (fn: NodePath): void {
        if (fn.isArrowFunctionExpression() && !fn.get('body').isBlockStatement()) {
          // Naked arrow functions cannot contain contracts.
          return;
        }
        fn.traverse({
          Function (path: NodePath): void {
            // This will be handled by the outer visitor, so skip it.
            path.skip();
          },

          LabeledStatement (path: NodePath): void {
            const label: NodePath = path.get('label');
            let id: ?Identifer;
            let children: ?NodePath;
            let parent: NodePath = fn;
            if (label.node.name === PRECONDITION_NAME) {
              assemblePrecondition(path);
              return;
            }
            else if (label.node.name === POSTCONDITION_NAME) {
              id = assemblePostcondition(path);
              children = fn.get('body').get('body');
            }
            else if (label.node.name === INVARIANT_NAME) {
              id = assembleInvariant(path);
              parent = path.findParent(t.isBlockStatement);
              children = parent.get('body');
              const first: NodePath = children[0];
              first.insertBefore(t.expressionStatement(t.callExpression(id, [])))
            }
            parent.traverse({
              Function (path: NodePath): void {
                // This will be handled by the outer visitor, so skip it.
                path.skip();
              },
              ReturnStatement (statement: NodePath): void {
                statement.get('argument').replaceWith(t.callExpression(id, [statement.node.argument]));
              }
            });
            const last: NodePath = children[children.length - 1];
            if (!last.isReturnStatement()) {
              last.insertAfter(t.expressionStatement(t.callExpression(id, [])));
            }
          }
        });
      }
    }
  };
}
<commit_msg>fix typo, dedupe checks<commit_after>import generate from "babel-generator";

type Plugin = {
  visitor: Visitors
};

type PluginParams = {
  types: Object;
  template: (source: string) => (ids: Object) => Node;
};

type Visitors = {
  [key: string]: Visitor
}

type Visitor = (path: NodePath) => void;

type Node = {
  type: string;
  node?: void;
};

type Literal = {
  type: 'StringLiteral' | 'BooleanLiteral' | 'NumericLiteral' | 'NullLiteral' | 'RegExpLiteral'
};

type Identifier = {
  type: string;
  name: string;
};

type Scope = {};

type NodePath = {
  type: string;
  node: Node;
  scope: Scope;
};

/**
 * # Design By Contract Transformer
 */
export default function ({types: t, template}: PluginParams): Plugin {

  const PRECONDITION_NAME = 'pre';
  const POSTCONDITION_NAME = 'post';
  const INVARIANT_NAME = 'invariant';
  const RETURN_NAME = 'it';

  const returnId: Identifier = t.identifier(RETURN_NAME);

  const guard: (ids: {[key: string]: Node}) => Node = template(`
    if (!condition) {
      throw new Error(message);
    }
  `);

  const guardFn: (ids: {[key: string]: Node}) => Node = template(`
    function id (it) {
      conditions;
      return it;
    }
  `);

  function assemblePrecondition (path: NodePath): void {
    const body: NodePath = path.get('body');
    const fn: NodePath = path.getFunctionParent();
    const name: string = fn.node.id ? `"${fn.node.id.name}" `: ' ';
    if (body.isExpressionStatement()) {
      let condition: NodePath = body.get('expression');
      let message: ?Node;
      if (condition.isSequenceExpression()) {
        const expressions = condition.get('expressions');
        condition = expressions[0];
        message = expressions[1].node;
      }
      else {
        message = t.stringLiteral(`Function ${name}precondition failed: ${generate(condition.node).code}`);
      }
      path.replaceWith(guard({
        condition,
        message
      }));
      return;
    }

    body.traverse({
      "VariableDeclaration|Function|AssignmentExpression|UpdateExpression|YieldExpression|ReturnStatement" (item: NodePath): void {
        throw path.buildCodeFrameError(`Preconditions cannot have side effects.`);
      },
      ExpressionStatement (statement: NodePath): void {
        let condition: NodePath = statement.get('expression');
        let message: ?Node;
        if (condition.isSequenceExpression()) {
          const expressions = condition.get('expressions');
          condition = expressions[0];
          message = expressions[1].node;
        }
        else {
          message = t.stringLiteral(`Function ${name}precondition failed: ${generate(condition.node).code}`);
        }
        statement.replaceWith(guard({
          condition,
          message
        }));
      }
    });

    if (body.isBlockStatement()) {
      path.replaceWithMultiple(path.get('body').node.body);
    }
    else {
      path.replaceWith(path.get('body'));
    }
  }

  function assemblePostcondition (path: NodePath): Identifier {
    const body: NodePath = path.get('body');
    const fn: NodePath = path.getFunctionParent();
    const name: string = fn.node.id ? `"${fn.node.id.name}" `: ' ';
    const conditions: Node[] = [];

    if (body.isExpressionStatement()) {
      let condition: NodePath = body.get('expression');
      let message: ?Node;
      if (condition.isSequenceExpression()) {
        const expressions = condition.get('expressions');
        condition = expressions[0];
        message = expressions[1].node;
      }
      else {
        message = t.stringLiteral(`Function ${name}postcondition failed: ${generate(condition.node).code}`);
      }
      conditions.push(guard({
        condition,
        message
      }));
    }
    else {
      body.traverse({
        "VariableDeclaration|Function|AssignmentExpression|UpdateExpression|YieldExpression|ReturnStatement" (item: NodePath): void {
          throw path.buildCodeFrameError(`Postconditions cannot have side effects.`);
        },
        ExpressionStatement (statement: NodePath): void {
          let condition: NodePath = statement.get('expression');
          let message: ?Node;
          if (condition.isSequenceExpression()) {
            const expressions = condition.get('expressions');
            condition = expressions[0];
            message = expressions[1].node;
          }
          else {
            message = t.stringLiteral(`Function ${name}postcondition failed: ${generate(condition.node).code}`);
          }
          statement.replaceWith(guard({
            condition,
            message
          }));
        }
      });
      conditions.push(...body.node.body);
    }

    const id = path.scope.generateUidIdentifier(`${fn.node.id ? fn.node.id.name : 'check'}Postcondition`);

    path.replaceWith(guardFn({
      id,
      conditions,
      it: returnId
    }));

    return id;
  }

  function assembleInvariant (path: NodePath): Identifier {
    const body: NodePath = path.get('body');
    const fn: NodePath = path.getFunctionParent();
    const name: string = fn.node.id ? `"${fn.node.id.name}" `: ' ';
    const conditions: Node[] = [];

    if (body.isExpressionStatement()) {
      let condition: NodePath = body.get('expression');
      let message: ?Node;
      if (condition.isSequenceExpression()) {
        const expressions = condition.get('expressions');
        condition = expressions[0];
        message = expressions[1].node;
      }
      else {
        message = t.stringLiteral(`Function ${name}invariant failed: ${generate(condition.node).code}`);
      }
      conditions.push(guard({
        condition,
        message
      }));
    }
    else {
      body.traverse({
        "VariableDeclaration|Function|AssignmentExpression|UpdateExpression|YieldExpression|ReturnStatement" (item: NodePath): void {
          throw path.buildCodeFrameError(`Invariants cannot have side effects.`);
        },
        ExpressionStatement (statement: NodePath): void {
          let condition: NodePath = statement.get('expression');
          let message: ?Node;
          if (condition.isSequenceExpression()) {
            const expressions = condition.get('expressions');
            condition = expressions[0];
            message = expressions[1].node;
          }
          else {
            message = t.stringLiteral(`Function ${name}invariant failed: ${generate(condition.node).code}`);
          }
          statement.replaceWith(guard({
            condition,
            message
          }));
        }
      });
      conditions.push(...body.node.body);
    }

    const id = path.scope.generateUidIdentifier(`${fn.node.id ? fn.node.id.name : 'check'}Invariant`);

    path.replaceWith(guardFn({
      id,
      conditions,
      it: returnId
    }));

    return id;
  }

  function expression (input: string): Function {
    const fn: Function = template(input);
    return function (...args) {
      const node: Node = fn(...args);
      return getExpression(node);
    };
  }

  return {
    visitor: {
      Function (fn: NodePath): void {
        if (fn.isArrowFunctionExpression() && !fn.get('body').isBlockStatement()) {
          // Naked arrow functions cannot contain contracts.
          return;
        }
        fn.traverse({
          Function (path: NodePath): void {
            // This will be handled by the outer visitor, so skip it.
            path.skip();
          },

          LabeledStatement (path: NodePath): void {
            const label: NodePath = path.get('label');
            let id: ?Identifier;
            let children: ?NodePath[];
            let parent: NodePath = fn;
            if (label.node.name === PRECONDITION_NAME) {
              assemblePrecondition(path);
              return;
            }
            else if (label.node.name === POSTCONDITION_NAME) {
              id = assemblePostcondition(path);
              children = fn.get('body').get('body');
            }
            else if (label.node.name === INVARIANT_NAME) {
              id = assembleInvariant(path);
              parent = path.findParent(t.isBlockStatement);
              children = parent.get('body');
              const first: NodePath = children[0];
              first.insertBefore(t.expressionStatement(t.callExpression(id, [])))
            }
            parent.traverse({
              Function (path: NodePath): void {
                // This will be handled by the outer visitor, so skip it.
                path.skip();
              },
              ReturnStatement (statement: NodePath): void {
                statement.get('argument').replaceWith(t.callExpression(id, [statement.node.argument]));
              }
            });
            const last: NodePath = children[children.length - 1];
            if (!last.isReturnStatement()) {
              last.insertAfter(t.expressionStatement(t.callExpression(id, [])));
            }
          }
        });
      }
    }
  };
}
<|endoftext|>


<commit_before>'use strict';

var superagent= require('superagent');
var Base64 = require('./Base64');
module.exports = {};

/**
 * FlavorUtils constructor
 * @param {Object} config - options
 * @param {string} config.couchUrl - couchdb root url. It should contain username + password if necessary
 * @param {string} config.couchDatabase - couchdb database
 */
module.exports = function FlavorUtils(config) {
    this.config = config;
    this.config.couchUrl = this.config.couchUrl.replace(/\/$/,'');
    this.dbUrl = this.config.couchUrl + '/' + this.config.couchDatabase;
};

/**
 * Clone a flavor from one user to another
 * @param {Object} opts - clone options
 * @param {Object} opts.source - source description
 * @param {string} opts.source.username - The name of the user's from which to clone
 * @param {string} opts.source.flavor - The name of the flavor to clone
 * @param {string} opts.target - target description
 * @param {String} opts.target.username - The target username to which to clone the flavor
 * @param {string} opts.target.flavor - The name of the flavor in the target
 */
module.exports.prototype.cloneFlavor = function(opts) {
    var that = this;
    var key = [opts.source.flavor, opts.source.username];
    var url = this.dbUrl + '/_design/flavor/_view/docs?key=' + encodeURIComponent(JSON.stringify(key));
    getJSON(url).then(function(res) {
        var result = res.rows;
        if(!result) return;
        var done = Promise.resolve();
        var i= 0;
        var uuids = [];
        done.then(function() {
            return that.getUUIDs(result.length)
        }).then(function(res) {
            uuids = res.uuids;
        });
        for(i=0; i<result.length; i++) {
            done = done.then(doEl(i));
        }
        done.then(function() {
            console.log('all done');
        }, function(err) {
            console.log('error:', err);
        });

        function doEl(i) {
            return function () {
                var prom = [];
                var view, data, meta, doc, newDoc;
                prom.push(getJSON(that.dbUrl + '/' + result[i].id));
                if (result[i].value.view) {
                    view = getJSON(that.dbUrl + '/' + result[i].id + '/view.json');
                    prom.push(view);
                }
                else prom.push(undefined);
                if (result[i].value.data) {
                    data = getJSON(that.dbUrl + '/' + result[i].id + '/data.json');
                    prom.push(data);
                }
                else prom.push(undefined);
                if (result[i].value.meta) {
                    meta = getJSON(that.dbUrl + '/' + result[i].id + '/meta.json');
                    prom.push(meta);
                }
                else prom.push(undefined);
                var prom = Promise.all(prom);
                prom = prom.then(function (arr) {
                    doc = arr[0];
                    newDoc = {};
                    var view = arr[1];
                    var data = arr[2];
                    var meta = arr[3];
                    newDoc._id = uuids[i];
                    delete doc._rev;

                    newDoc.flavors = {};
                    if(doc.flavors[opts.source.flavor]) {
                        newDoc.flavors[opts.target.flavor] = doc.flavors[opts.source.flavor];
                    }

                    newDoc.name = opts.target.username;

                    if(meta) {
                        newDoc._attachments = newDoc._attachments || {};
                        newDoc._attachments['meta.json'] = {
                            'content_type': 'application/json',
                            'data': Base64.encode(JSON.stringify(meta))
                        };
                    }
                    if(view) {
                        newDoc._attachments = newDoc._attachments || {};
                        newDoc._attachments['view.json'] = {
                            'content_type': 'application/json',
                            'data': Base64.encode(JSON.stringify(view))
                        };
                    }
                    if(data) {
                        newDoc._attachments = newDoc._attachments || {};
                        newDoc._attachments['data.json'] = {
                            'content_type': 'application/json',
                            'data': Base64.encode(JSON.stringify(data))
                        };
                    }
                });
                return prom.then(function() {
                    return that.saveDoc(newDoc);
                });
            }
        }
    });
};

module.exports.prototype.saveDoc = function(doc) {
    var that = this;
    delete doc._id;
    var url = that.dbUrl;
        return new Promise(function(resolve, reject) {
            superagent
                .post(url)
                .set('Content-Type', 'application/json')
                .send(doc)
                .end(function(err, res) {
                    if(err) {
                        return reject(err);
                    }
                    resolve(res.body);
                })
        });
};
/**
 * Get couchdb uuids
 * @param {Object} count - the number of uuids needed
 *
 */
module.exports.prototype.getUUIDs = function(count) {
    var that = this;
    count = count || 1;
    return getJSON(that.config.couchUrl + '/_uuids?count=' + count);
};

function getJSON(url) {
    return new Promise(function(resolve, reject) {
        superagent
            .get(url)
            .set('Accept', 'application/json')
            .end(function(err, res) {
                if(err) {
                    return reject(err);
                }
                resolve(res.body);
            })
    });
}

<commit_msg>Change api and add deleteFlavor method<commit_after>'use strict';

var superagent= require('superagent');
var Base64 = require('./Base64');
module.exports = {};

var FlavorUtils = module.exports = {};

/**
 * Clone a flavor from one user to another
 * @param {Object} opts - clone options
 * @param {Object} opts.source - source description
 * @param {string} opts.source.username - The name of the user's from which to clone
 * @param {string} opts.source.flavor - The name of the flavor to clone
 * @param {string} opts.source.couchUrl - Couchdb root url of the source. It should contain username + password if necessary
 * @param {string} opts.target.couchDatabase - the name of the target couchdb database
 * @param {string} opts.target - target description
 * @param {String} opts.target.username - The target username to which to clone the flavor
 * @param {string} opts.target.flavor - The name of the flavor in the target
 * @param {string} opts.target.couchUrl - Couchdb root url of the target. It should contain username + password if necessary
 * @param {string} opts.target.couchDatabase - the name of the target couchdb database
 */
FlavorUtils.cloneFlavor = function(opts) {
    processCommonParams(opts.source);
    processCommonParams(opts.target);
    var key = [opts.source.flavor, opts.source.username];
    getView(opts.source, 'flavor/docs', key).then(function(res) {
        var result = res.rows;
        if(!result) return;
        var done = Promise.resolve();
        var i= 0;
        for(i=0; i<result.length; i++) {
            done = done.then(doEl(i));
        }
        done.then(function() {
            console.log('all done');
        }, function(err) {
            console.log('error:', err);
        });

        function doEl(i) {
            return function () {
                var prom = [];
                var view, data, meta, doc, newDoc;
                prom.push(getJSON(opts.source.databaseUrl + '/' + result[i].id));
                if (result[i].value.view) {
                    view = getJSON(opts.source.databaseUrl + '/' + result[i].id + '/view.json');
                    prom.push(view);
                }
                else prom.push(undefined);
                if (result[i].value.data) {
                    data = getJSON(opts.source.databaseUrl + '/' + result[i].id + '/data.json');
                    prom.push(data);
                }
                else prom.push(undefined);
                if (result[i].value.meta) {
                    meta = getJSON(opts.source.databaseUrl + '/' + result[i].id + '/meta.json');
                    prom.push(meta);
                }
                else prom.push(undefined);
                var prom = Promise.all(prom);
                prom = prom.then(function (arr) {
                    doc = arr[0];
                    newDoc = {};
                    var view = arr[1];
                    var data = arr[2];
                    var meta = arr[3];
                    delete doc._rev;

                    newDoc.flavors = {};
                    if(doc.flavors[opts.source.flavor]) {
                        newDoc.flavors[opts.target.flavor] = doc.flavors[opts.source.flavor];
                    }

                    newDoc.name = opts.target.username;

                    if(meta) {
                        newDoc._attachments = newDoc._attachments || {};
                        newDoc._attachments['meta.json'] = {
                            'content_type': 'application/json',
                            'data': Base64.encode(JSON.stringify(meta))
                        };
                    }
                    if(view) {
                        newDoc._attachments = newDoc._attachments || {};
                        newDoc._attachments['view.json'] = {
                            'content_type': 'application/json',
                            'data': Base64.encode(JSON.stringify(view))
                        };
                    }
                    if(data) {
                        newDoc._attachments = newDoc._attachments || {};
                        newDoc._attachments['data.json'] = {
                            'content_type': 'application/json',
                            'data': Base64.encode(JSON.stringify(data))
                        };
                    }
                });
                return prom.then(function() {
                    saveDoc(opts.target, newDoc);
                });
            }
        }
    });
};

FlavorUtils.deleteFlavor = function(opts) {
    processCommonParams(opts);
    var key = [opts.flavor, opts.username];
    return getView(opts, 'flavor/docs', key).then(function(res) {
        var result = res.rows;
        var done = Promise.resolve();
        for(var i=0; i<result.length; i++) {
            done.then(doEl(i));
        }

        done.then(function() {
            console.log('delete flavor done');
        }, function(err) {
            console.log('Error!', err, err.stack);
        });

        function doEl(i) {
            var prom = getJSON(opts.databaseUrl + '/' + result[i].id);
            prom = prom.then(function(doc) {
                delete doc.flavors[opts.flavor];
                var keys = Object.keys(doc.flavors);
                if(keys.length === 0) {
                    return deleteDoc(opts, doc);
                }
                else {
                    return updateDoc(opts, doc);
                }
            });
            return prom;
        }
        return done;
    });
};

function deleteDoc(opts, doc) {
    return new Promise(function(resolve, reject) {
        var url = opts.databaseUrl + '/' + doc._id;
        console.log(url);
        superagent
            .del(url)
            .query({rev: doc._rev})
            .end(function(err, res) {
                if(err) {
                    console.log(err);
                    return reject(err);
                }
                console.log(res)
                resolve(res);
            })
    });
}

function updateDoc(opts, doc) {
    return new Promise(function(resolve, reject) {
        console.log('update doc');
        var url = opts.databaseUrl + '/' + doc._id;
        superagent
            .put(url)
            .set('Content-Type', 'application/json')
            .send(doc)
            .end(function(err, res) {
                if(err) {
                    return reject(err);
                }
                resolve(res.body);
            })
    });
}

function saveDoc(opts, doc) {
    return new Promise(function(resolve, reject) {
        var url = opts.databaseUrl;
        delete doc._id;
        superagent
            .post(url)
            .set('Content-Type', 'application/json')
            .send(doc)
            .end(function(err, res) {
                if(err) {
                    return reject(err);
                }
                resolve(res.body);
            })
    });
}
/**
 * Get couchdb uuids
 * @param {Object} count - the number of uuids needed
 *
 */
function getUUIDs(opts, count) {
    count = count || 1;
    return getJSON(opts.couchUrl + '/_uuids?count=' + count);
}

function getJSON(url) {
    return new Promise(function(resolve, reject) {
        superagent
            .get(url)
            .set('Accept', 'application/json')
            .end(function(err, res) {
                if(err) {
                    return reject(err);
                }
                resolve(res.body);
            })
    });
}

function getView(opts, view, key) {
    var x = view.split('/');
    var designDoc = '_design/' + x[0];
    var viewName = x[1];

    return getJSON(opts.databaseUrl + '/' + designDoc + '/_view/' + viewName + '?key=' + encodeURIComponent(JSON.stringify(key)));
}

function processCommonParams(params) {
    if(!params) return;
    if(params.couchUrl) params.couchUrl = params.couchUrl.replace(/\/$/, '');
    if(params.couchUrl && params.couchDatabase) {
        params.databaseUrl =params.couchUrl + '/' + params.couchDatabase;
    }

}

<|endoftext|>


<commit_before>module.exports = {
  Client: require('./Client')
};
<commit_msg>Update index.js<commit_after>module.exports = {
  Client: require('./Client'),
  APIError: require('./exceptions').APIError,
  ArgumentError: require('./exceptions').ArgumentError
};
<|endoftext|>