<commit_before>'use strict';

var Combine = require('stream-combiner');
var closureTemplates = require('closure-templates');
var fs = require('fs');
var gutil = require('gulp-util');
var path = require('path');
var soynode = require('soynode');
var spawn = require('child_process').spawn;
var through = require('through2');

var PATH_TO_MSG_EXTRACTOR = closureTemplates['SoyMsgExtractor.jar'];

var gulpSoynode = function(options) {
  options = options || {};

  // Resolve internal options.
  var optionsInternal = {};
  optionsInternal.renderSoyWeb = options.renderSoyWeb;
  optionsInternal.renderSoyWebContext = options.renderSoyWebContext;
  optionsInternal.renderSoyWebInjectedData = options.renderSoyWebInjectedData || {};
  optionsInternal.renderSoyWebFileExtension = options.renderSoyWebFileExtension || '.html';
  delete options.renderSoyWeb;
  delete options.renderSoyWebContext;
  delete options.renderSoyWebInjectedData;
  delete options.renderSoyWebFileExtension;

  // Resolve soynode options.
  var optionsSoynode = options;
  optionsSoynode.uniqueDir = false;
  optionsSoynode.outputDir = path.resolve(options.outputDir || '/tmp/soynode');

  return new Combine(
    gutil.buffer(),
    through.obj(function(files, enc, cb) {
      // Discourage usage of `allowDynamicRecompile` option.
      if (optionsSoynode.allowDynamicRecompile) {
        this.emit('error', new gutil.PluginError(
        'gulp-soynode',
        'Option `allowDynamicRecompile` is not supported, use `gulp.watch` instead.'));
      }

      // When rendering soyweb templates make sure to load compiled templates.
      if (optionsInternal.renderSoyWeb) {
        if (optionsSoynode.loadCompiledTemplates === false) {
          this.emit('error', new gutil.PluginError(
          'gulp-soynode',
          'Option `renderSoyWeb` requires `loadCompiledTemplates` to be enabled.'));
        }
      }

      compileFiles(this, files, optionsInternal, optionsSoynode, cb);
    }));
};

/**
 * Extracts messages from the given soy template files.
 * @param {object} options
 */
gulpSoynode.lang = function(options) {
  options = options || {};

  return new Combine(
    gutil.buffer(),
    through.obj(function(files, enc, cb) {
      var stream = this;
      var outputFile = options.outputFile || '/tmp/soynode/translations.xlf';

      var args = [
        '-jar', PATH_TO_MSG_EXTRACTOR,
        '--outputFile', outputFile
      ];
      args = args.concat(getFilePaths(files));

      var process = spawn('java', args);
      process.on('exit', function (err) {
        if (err) {
          stream.emit('error', new gutil.PluginError('gulp-soynode', err));
          stream.emit('end');
          cb();
          return;
        }

        var translationFile = new gutil.File({
          contents: fs.readFileSync(outputFile),
          path: outputFile
        });

        stream.emit('data', translationFile);
        stream.emit('end');
        cb();
      });
    })
  );
};

/**
 * Compiles buffered files from a through stream.
 * @param {Stream} stream
 * @param {array} files Buffered files array.
 * @param {object} optionsInternal
 * @param {object} optionsSoynode
 * @param {function} cb
 */
function compileFiles(stream, files, optionsInternal, optionsSoynode, cb) {
  var filepaths = getFilePaths(files);

  soynode.setOptions(optionsSoynode);
  soynode.compileTemplateFiles(filepaths, function(err) {
    if (err) {
      stream.emit('error', new gutil.PluginError('gulp-soynode', err));
      return;
    }

    var locales = optionsSoynode.locales || [''];

    files.forEach(function(file) {
      var soyFileAlreadyEmitted = false;
      var extname = path.extname(file.path);
      var relative = path.relative(file.cwd, path.dirname(file.path));
      var basename = path.basename(file.path, extname);
      var base = file.base;

      locales.forEach(function(locale) {
        var relativePath = path.join(relative, basename) + ((locales.length > 1 && locale) ? '_' + locale : '') + extname + '.js';

        var compiled = new gutil.File({
          base: base,
          contents: fs.readFileSync(path.join(optionsSoynode.outputDir, relativePath)),
          cwd: file.cwd,
          path: path.resolve(file.base, path.relative(file.base, relativePath))
        });

        if (optionsInternal.renderSoyWeb) {
          try {
            // When building a static SoyWeb template make sure to only emit
            // the output file, no need to emit the .soy and .soy.js.
            file = renderSoyWeb(file, optionsInternal, optionsSoynode);
            compiled = null;
          } catch (err) {
            stream.emit('error', new gutil.PluginError('gulp-soynode', err));
          }
        }

        if (!soyFileAlreadyEmitted) {
          stream.emit('data', file);
          soyFileAlreadyEmitted = true;
        }

        if (compiled) {
          stream.emit('data', compiled);
        }
      });
    });

    stream.emit('end');
    cb();
  });
}

/**
 * Calls the given arg if it's a function. Otherwise, just returns it as it is.
 * @param {*} arg
 * @param {!Object} file File object to pass to called function.
 * @return {*}
 */
function callFunctionArg(arg, file) {
  return (typeof arg === 'function') ? arg(file) : arg;
}

/**
 * Returns the file paths of the given files.
 * @param {array} files Buffered files array.
 * @return {array}
 */
function getFilePaths(files) {
  return files.map(function(file) {
    return path.relative(file.cwd, file.path);
  });
}

/**
 * This method allows templates to be rendered by SoyWeb. It deliberately
 * includes dummy data so the designer can get a feel for how the task list
 * will appear with real data rather with minimal copy and paste. For more
 * information visit: http://plovr.com/soyweb.html
 * @param {File} file The soy template file.
 * @param {object} optionsInternal
 * @param {object} optionsSoynode
 * @return {File} Returns a file containing the rendered SoyWeb content.
 */
function renderSoyWeb(file, optionsInternal, optionsSoynode) {
  var namespace = lookupNamespace(file.contents.toString());

  var rendered = soynode.render(
    namespace + '.soyweb',
    callFunctionArg(optionsInternal.renderSoyWebContext, file),
    callFunctionArg(optionsInternal.renderSoyWebInjectedData, file),
    optionsSoynode.locales ? optionsSoynode.locales[0] : null
  );
  var renderedFile = new gutil.File({
    base: file.base,
    contents: new Buffer(rendered),
    cwd: file.cwd,
    path: gutil.replaceExtension(file.path, optionsInternal.renderSoyWebFileExtension)
  });
  return renderedFile;
}

/**
 * Lookups namespace from template content.
 * @param {string} contents
 * @return {string} The template namespace
 */
function lookupNamespace(contents) {
  var startToken = '{namespace ';
  var startPos = contents.indexOf(startToken);
  var namespace = contents.substring(startPos + startToken.length, contents.indexOf('}'));
  var spacePos = namespace.indexOf(' ');
  if (spacePos > -1) {
    namespace = namespace.substring(0, spacePos);
  }
  return namespace;
}

module.exports = gulpSoynode;
<commit_msg>caught error isn’t a string<commit_after>'use strict';

var Combine = require('stream-combiner');
var closureTemplates = require('closure-templates');
var fs = require('fs');
var gutil = require('gulp-util');
var path = require('path');
var soynode = require('soynode');
var spawn = require('child_process').spawn;
var through = require('through2');

var PATH_TO_MSG_EXTRACTOR = closureTemplates['SoyMsgExtractor.jar'];

var gulpSoynode = function(options) {
  options = options || {};

  // Resolve internal options.
  var optionsInternal = {};
  optionsInternal.renderSoyWeb = options.renderSoyWeb;
  optionsInternal.renderSoyWebContext = options.renderSoyWebContext;
  optionsInternal.renderSoyWebInjectedData = options.renderSoyWebInjectedData || {};
  optionsInternal.renderSoyWebFileExtension = options.renderSoyWebFileExtension || '.html';
  delete options.renderSoyWeb;
  delete options.renderSoyWebContext;
  delete options.renderSoyWebInjectedData;
  delete options.renderSoyWebFileExtension;

  // Resolve soynode options.
  var optionsSoynode = options;
  optionsSoynode.uniqueDir = false;
  optionsSoynode.outputDir = path.resolve(options.outputDir || '/tmp/soynode');

  return new Combine(
    gutil.buffer(),
    through.obj(function(files, enc, cb) {
      // Discourage usage of `allowDynamicRecompile` option.
      if (optionsSoynode.allowDynamicRecompile) {
        this.emit('error', new gutil.PluginError(
        'gulp-soynode',
        'Option `allowDynamicRecompile` is not supported, use `gulp.watch` instead.'));
      }

      // When rendering soyweb templates make sure to load compiled templates.
      if (optionsInternal.renderSoyWeb) {
        if (optionsSoynode.loadCompiledTemplates === false) {
          this.emit('error', new gutil.PluginError(
          'gulp-soynode',
          'Option `renderSoyWeb` requires `loadCompiledTemplates` to be enabled.'));
        }
      }

      compileFiles(this, files, optionsInternal, optionsSoynode, cb);
    }));
};

/**
 * Extracts messages from the given soy template files.
 * @param {object} options
 */
gulpSoynode.lang = function(options) {
  options = options || {};

  return new Combine(
    gutil.buffer(),
    through.obj(function(files, enc, cb) {
      var stream = this;
      var outputFile = options.outputFile || '/tmp/soynode/translations.xlf';

      var args = [
        '-jar', PATH_TO_MSG_EXTRACTOR,
        '--outputFile', outputFile
      ];
      args = args.concat(getFilePaths(files));

      var process = spawn('java', args);
      process.on('exit', function (err) {
        if (err) {
          stream.emit('error', new gutil.PluginError('gulp-soynode', err));
          stream.emit('end');
          cb();
          return;
        }

        var translationFile = new gutil.File({
          contents: fs.readFileSync(outputFile),
          path: outputFile
        });

        stream.emit('data', translationFile);
        stream.emit('end');
        cb();
      });
    })
  );
};

/**
 * Compiles buffered files from a through stream.
 * @param {Stream} stream
 * @param {array} files Buffered files array.
 * @param {object} optionsInternal
 * @param {object} optionsSoynode
 * @param {function} cb
 */
function compileFiles(stream, files, optionsInternal, optionsSoynode, cb) {
  var filepaths = getFilePaths(files);

  soynode.setOptions(optionsSoynode);
  soynode.compileTemplateFiles(filepaths, function(err) {
    if (err) {
      stream.emit('error', new gutil.PluginError('gulp-soynode', err));
      return;
    }

    var locales = optionsSoynode.locales || [''];

    files.forEach(function(file) {
      var soyFileAlreadyEmitted = false;
      var extname = path.extname(file.path);
      var relative = path.relative(file.cwd, path.dirname(file.path));
      var basename = path.basename(file.path, extname);
      var base = file.base;

      locales.forEach(function(locale) {
        var relativePath = path.join(relative, basename) + ((locales.length > 1 && locale) ? '_' + locale : '') + extname + '.js';

        var compiled = new gutil.File({
          base: base,
          contents: fs.readFileSync(path.join(optionsSoynode.outputDir, relativePath)),
          cwd: file.cwd,
          path: path.resolve(file.base, path.relative(file.base, relativePath))
        });

        if (optionsInternal.renderSoyWeb) {
          try {
            // When building a static SoyWeb template make sure to only emit
            // the output file, no need to emit the .soy and .soy.js.
            file = renderSoyWeb(file, optionsInternal, optionsSoynode);
            compiled = null;
          } catch (err) {
            stream.emit('error', new gutil.PluginError('gulp-soynode', err.stack || err.message));
          }
        }

        if (!soyFileAlreadyEmitted) {
          stream.emit('data', file);
          soyFileAlreadyEmitted = true;
        }

        if (compiled) {
          stream.emit('data', compiled);
        }
      });
    });

    stream.emit('end');
    cb();
  });
}

/**
 * Calls the given arg if it's a function. Otherwise, just returns it as it is.
 * @param {*} arg
 * @param {!Object} file File object to pass to called function.
 * @return {*}
 */
function callFunctionArg(arg, file) {
  return (typeof arg === 'function') ? arg(file) : arg;
}

/**
 * Returns the file paths of the given files.
 * @param {array} files Buffered files array.
 * @return {array}
 */
function getFilePaths(files) {
  return files.map(function(file) {
    return path.relative(file.cwd, file.path);
  });
}

/**
 * This method allows templates to be rendered by SoyWeb. It deliberately
 * includes dummy data so the designer can get a feel for how the task list
 * will appear with real data rather with minimal copy and paste. For more
 * information visit: http://plovr.com/soyweb.html
 * @param {File} file The soy template file.
 * @param {object} optionsInternal
 * @param {object} optionsSoynode
 * @return {File} Returns a file containing the rendered SoyWeb content.
 */
function renderSoyWeb(file, optionsInternal, optionsSoynode) {
  var namespace = lookupNamespace(file.contents.toString());

  var rendered = soynode.render(
    namespace + '.soyweb',
    callFunctionArg(optionsInternal.renderSoyWebContext, file),
    callFunctionArg(optionsInternal.renderSoyWebInjectedData, file),
    optionsSoynode.locales ? optionsSoynode.locales[0] : null
  );
  var renderedFile = new gutil.File({
    base: file.base,
    contents: new Buffer(rendered),
    cwd: file.cwd,
    path: gutil.replaceExtension(file.path, optionsInternal.renderSoyWebFileExtension)
  });
  return renderedFile;
}

/**
 * Lookups namespace from template content.
 * @param {string} contents
 * @return {string} The template namespace
 */
function lookupNamespace(contents) {
  var startToken = '{namespace ';
  var startPos = contents.indexOf(startToken);
  var namespace = contents.substring(startPos + startToken.length, contents.indexOf('}'));
  var spacePos = namespace.indexOf(' ');
  if (spacePos > -1) {
    namespace = namespace.substring(0, spacePos);
  }
  return namespace;
}

module.exports = gulpSoynode;
<|endoftext|>


<commit_before>/* globals process */
'use strict'

// other
const bigInt = require('big-integer')

// twitter api
const twitterParse = require('twitter-url-parser')
const twitterAPI = require('node-twitter-api')
const twitter = new twitterAPI({
  consumerKey: process.env.TWITTER_CONSUMER_KEY,
  consumerSecret: process.env.TWITTER_CONSUMER_SECRET,
  callback: process.env.TWITTER_OAUTH_CALLBACK || 'http://localhost:8080/oauth'
})

// redis
const redis = require('redis')
const client = redis.createClient(process.env.REDIS_URL)

client.on('error', (error) => {
  console.log(error)
})

// request-json
const request = require('request')

// express
const express = require('express')
const app = express()
const bodyParser = require('body-parser')

app.use(bodyParser.json())

// request body:
// id
// text
// username
app.post('/', (req, res) => {
  tweetsplain(req, res, true)
})

app.post('/test', (req, res) => {
  tweetsplain(req, res, false)
})

function tweetsplain (req, res, tweetTheResult) {
  const twitterId = twitterParse(req.body.link).id
  client.hgetall('access', (error, access) => {
    if (error) {
      console.log(error)
      res.end()
    } else if (access) {
      console.log(twitterId)
      twitter.statuses(
        'show',
        {
          id: twitterId
        },
        access.token,
        access.tokenSecret,
        (error, tweet, showResponse) => {
          if (error) {
            console.log(error)
            res.end()
          } else {
            console.log(tweet.text)
            twitter.search(
              {
                q: tweet.text.replace('(', '%28').replace(')', '%29'),
                max_id: bigInt(twitterId).minus(1).toString()
              },
              access.token,
              access.tokenSecret,
              (error, data, response) => {
                if (error) {
                  console.log(error)
                  res.end()
                } else {
                  const sourceTweet = data && data.statuses && data.statuses[0]
                    ? data.statuses[0].retweeted_status
                      ? data.statuses[0].retweeted_status
                      : data.statuses[0]
                    : undefined

                  if (sourceTweet) {
                    console.log('@' + req.body.username + ' @' + sourceTweet.user.screen_name + ' https://twitter.com/' + sourceTweet.user.screen_name + '/status/' + sourceTweet.id_str)
                    res.send('@' + req.body.username + ' @' + sourceTweet.user.screen_name + ' https://twitter.com/' + sourceTweet.user.screen_name + '/status/' + sourceTweet.id_str)
                    if (tweetTheResult) {
                      twitter.statuses(
                        'update',
                        {
                          status: '@' + req.body.username + ' @' + sourceTweet.user.screen_name + ' https://twitter.com/' + sourceTweet.user.screen_name + '/status/' + sourceTweet.id_str,
                          in_reply_to_status_id: twitterId
                        },
                        access.token,
                        access.tokenSecret,
                        (error, data, response) => {
                          if (error) {
                            console.log(error)
                          }
                        }
                      )
                    }
                  } else {
                    console.log('no matching tweet')
                    request(
                      {
                        uri: process.env.ALGOLIA_URL,
                        method: 'POST',
                        json: {
                          'params': 'query=%22' + encodeURIComponent(tweet.text) + '%22'
                        }
                      },
                      (error, response, body) => {
                        if (error) {
                          console.log(error)
                          res.end()
                        } else {
                          if (body && body.hits && body.hits[0]) {
                            console.log('@' + req.body.username + ' https://hn.algolia.com/?query=%22' + encodeURIComponent(tweet.text) + '%22&type=all ' + body.hits[0].story_url)
                            res.send('@' + req.body.username + ' https://hn.algolia.com/?query=%22' + encodeURIComponent(tweet.text) + '%22&type=all ' + body.hits[0].story_url)
                            if (tweetTheResult) {
                              twitter.statuses(
                                'update',
                                {
                                  status: '@' + req.body.username + ' https://hn.algolia.com/?query=%22' + encodeURIComponent(tweet.text) + '%22&type=all ' + body.hits[0].story_url,
                                  in_reply_to_status_id: twitterId
                                },
                                access.token,
                                access.tokenSecret,
                                (error, data, response) => {
                                  if (error) {
                                    console.log(error)
                                  }
                                }
                              )
                            }
                          } else {
                            console.log('no matching comment')
                            res.end()
                          }
                        }
                      }
                    )
                  }
                }
              }
            )
          }
        }
      )
    }
  })
}

app.get('/authenticate', (req, res) => {
  twitter.getRequestToken((error, requestToken, requestTokenSecret, results) => {
    if (error) {
      console.log('Error getting OAuth request token : ' + error)
    } else {
      client.del('request')
      client.hmset('request', 'token', requestToken, 'tokenSecret', requestTokenSecret, (error, result) => {
        if (error) {
          console.log(error)
        } else {
          res.redirect(twitter.getAuthUrl(requestToken))
        }
      })
    }
  })
})

app.get('/oauth', (req, res) => {
  client.hgetall('request', (error, request) => {
    if (error) {
      console.log(error)
    } else if (request) {
      twitter.getAccessToken(
        request.token,
        request.tokenSecret,
        req.query.oauth_verifier,
        (error, accessToken, accessTokenSecret, results) => {
          if (error) {
            console.log(error)
          } else {
            twitter.verifyCredentials(
              accessToken,
              accessTokenSecret,
              {},
              (error, data, response) => {
                if (error) {
                  console.log(error)
                } else {
                  client.del('access')
                  client.hmset('access', 'token', accessToken, 'tokenSecret', accessTokenSecret, (error, result) => {
                    if (error) {
                      console.log(error)
                    } else {
                      res.send(data['screen_name'])
                    }
                  })
                }
              })
          }
        })
    }
  })
})

app.listen(process.env.PORT || 8080, () => console.log('listening ' + (process.env.PORT || 8080)))
<commit_msg>remove exact search from hacker news results<commit_after>/* globals process */
'use strict'

// other
const bigInt = require('big-integer')

// twitter api
const twitterParse = require('twitter-url-parser')
const twitterAPI = require('node-twitter-api')
const twitter = new twitterAPI({
  consumerKey: process.env.TWITTER_CONSUMER_KEY,
  consumerSecret: process.env.TWITTER_CONSUMER_SECRET,
  callback: process.env.TWITTER_OAUTH_CALLBACK || 'http://localhost:8080/oauth'
})

// redis
const redis = require('redis')
const client = redis.createClient(process.env.REDIS_URL)

client.on('error', (error) => {
  console.log(error)
})

// request-json
const request = require('request')

// express
const express = require('express')
const app = express()
const bodyParser = require('body-parser')

app.use(bodyParser.json())

// request body:
// id
// text
// username
app.post('/', (req, res) => {
  tweetsplain(req, res, true)
})

app.post('/test', (req, res) => {
  tweetsplain(req, res, false)
})

function tweetsplain (req, res, tweetTheResult) {
  const twitterId = twitterParse(req.body.link).id
  client.hgetall('access', (error, access) => {
    if (error) {
      console.log(error)
      res.end()
    } else if (access) {
      console.log(twitterId)
      twitter.statuses(
        'show',
        {
          id: twitterId
        },
        access.token,
        access.tokenSecret,
        (error, tweet, showResponse) => {
          if (error) {
            console.log(error)
            res.end()
          } else {
            console.log(tweet.text)
            twitter.search(
              {
                q: tweet.text.replace('(', '%28').replace(')', '%29'),
                max_id: bigInt(twitterId).minus(1).toString()
              },
              access.token,
              access.tokenSecret,
              (error, data, response) => {
                if (error) {
                  console.log(error)
                  res.end()
                } else {
                  const sourceTweet = data && data.statuses && data.statuses[0]
                    ? data.statuses[0].retweeted_status
                      ? data.statuses[0].retweeted_status
                      : data.statuses[0]
                    : undefined

                  if (sourceTweet) {
                    console.log('@' + req.body.username + ' @' + sourceTweet.user.screen_name + ' https://twitter.com/' + sourceTweet.user.screen_name + '/status/' + sourceTweet.id_str)
                    res.send('@' + req.body.username + ' @' + sourceTweet.user.screen_name + ' https://twitter.com/' + sourceTweet.user.screen_name + '/status/' + sourceTweet.id_str)
                    if (tweetTheResult) {
                      twitter.statuses(
                        'update',
                        {
                          status: '@' + req.body.username + ' @' + sourceTweet.user.screen_name + ' https://twitter.com/' + sourceTweet.user.screen_name + '/status/' + sourceTweet.id_str,
                          in_reply_to_status_id: twitterId
                        },
                        access.token,
                        access.tokenSecret,
                        (error, data, response) => {
                          if (error) {
                            console.log(error)
                          }
                        }
                      )
                    }
                  } else {
                    console.log('no matching tweet')
                    request(
                      {
                        uri: process.env.ALGOLIA_URL,
                        method: 'POST',
                        json: {
                          'params': 'query=%22' + encodeURIComponent(tweet.text) + '%22'
                        }
                      },
                      (error, response, body) => {
                        if (error) {
                          console.log(error)
                          res.end()
                        } else {
                          if (body && body.hits && body.hits[0]) {
                            console.log('@' + req.body.username + ' https://hn.algolia.com/?query=' + encodeURIComponent(tweet.text) + '&type=all ' + body.hits[0].story_url)
                            res.send('@' + req.body.username + ' https://hn.algolia.com/?query=' + encodeURIComponent(tweet.text) + '&type=all ' + body.hits[0].story_url)
                            if (tweetTheResult) {
                              twitter.statuses(
                                'update',
                                {
                                  status: '@' + req.body.username + ' https://hn.algolia.com/?query=' + encodeURIComponent(tweet.text) + '&type=all ' + body.hits[0].story_url,
                                  in_reply_to_status_id: twitterId
                                },
                                access.token,
                                access.tokenSecret,
                                (error, data, response) => {
                                  if (error) {
                                    console.log(error)
                                  }
                                }
                              )
                            }
                          } else {
                            console.log('no matching comment')
                            res.end()
                          }
                        }
                      }
                    )
                  }
                }
              }
            )
          }
        }
      )
    }
  })
}

app.get('/authenticate', (req, res) => {
  twitter.getRequestToken((error, requestToken, requestTokenSecret, results) => {
    if (error) {
      console.log('Error getting OAuth request token : ' + error)
    } else {
      client.del('request')
      client.hmset('request', 'token', requestToken, 'tokenSecret', requestTokenSecret, (error, result) => {
        if (error) {
          console.log(error)
        } else {
          res.redirect(twitter.getAuthUrl(requestToken))
        }
      })
    }
  })
})

app.get('/oauth', (req, res) => {
  client.hgetall('request', (error, request) => {
    if (error) {
      console.log(error)
    } else if (request) {
      twitter.getAccessToken(
        request.token,
        request.tokenSecret,
        req.query.oauth_verifier,
        (error, accessToken, accessTokenSecret, results) => {
          if (error) {
            console.log(error)
          } else {
            twitter.verifyCredentials(
              accessToken,
              accessTokenSecret,
              {},
              (error, data, response) => {
                if (error) {
                  console.log(error)
                } else {
                  client.del('access')
                  client.hmset('access', 'token', accessToken, 'tokenSecret', accessTokenSecret, (error, result) => {
                    if (error) {
                      console.log(error)
                    } else {
                      res.send(data['screen_name'])
                    }
                  })
                }
              })
          }
        })
    }
  })
})

app.listen(process.env.PORT || 8080, () => console.log('listening ' + (process.env.PORT || 8080)))
<|endoftext|>


<commit_before>'use strict';

var data = module.exports = {
  jquery: {
    versions: ['2.1.1', '2.1.0', '2.0.3', '2.0.2', '2.0.1', '2.0.0', '1.11.1', '1.11.0', '1.10.2', '1.10.1', '1.10.0', '1.9.1', '1.9.0', '1.8.3', '1.8.2', '1.8.1', '1.8.0', '1.7.2', '1.7.1', '1.7.0', '1.6.4', '1.6.3', '1.6.2', '1.6.1', '1.6.0', '1.5.2', '1.5.1', '1.5.0', '1.4.4', '1.4.3', '1.4.2', '1.4.1', '1.4.0', '1.3.2', '1.3.1', '1.3.0', '1.2.6', '1.2.3'],
    url: function (version) {
      return '//ajax.googleapis.com/ajax/libs/jquery/' + version + '/jquery.min.js';
    }
  },
  'jquery-ui': {
    versions: ['1.10.4', '1.10.3', '1.10.2', '1.10.1', '1.10.0', '1.9.2', '1.9.1', '1.9.0', '1.8.24', '1.8.23', '1.8.22', '1.8.21', '1.8.20', '1.8.19', '1.8.18', '1.8.17', '1.8.16', '1.8.15', '1.8.14', '1.8.13', '1.8.12', '1.8.11', '1.8.10', '1.8.9', '1.8.8', '1.8.7', '1.8.6', '1.8.5', '1.8.4', '1.8.2', '1.8.1', '1.8.0', '1.7.3', '1.7.2', '1.7.1', '1.7.0', '1.6.0', '1.5.3', '1.5.2'],
    url: function (version) {
      return '//ajax.googleapis.com/ajax/libs/jqueryui/' + version + '/jquery-ui.min.js';
    }
  },
  dojo: {
    versions: ['1.9.2', '1.9.1', '1.9.0', '1.8.5', '1.8.4', '1.8.3', '1.8.2', '1.8.1', '1.8.0', '1.7.5', '1.7.4', '1.7.3', '1.7.2', '1.7.1', '1.7.0', '1.6.1', '1.6.0', '1.5.2', '1.5.1', '1.5.0', '1.4.4', '1.4.3', '1.4.1', '1.4.0', '1.3.2', '1.3.1', '1.3.0', '1.2.3', '1.2.0', '1.1.1'],
    url: function (version) {
      return '//ajax.googleapis.com/ajax/libs/dojo/' + version + '/dojo/dojo.js';
    }
  },
  swfobject: {
    versions: ['2.2', '2.1'],
    url: function (version) {
      return '//ajax.googleapis.com/ajax/libs/swfobject/' + version + '/swfobject.js';
    }
  }
};

// AngularJS

var angularFiles = [
  'angular',
  'angular-animate',
  'angular-cookies',
  'angular-loader',
  'angular-resource',
  'angular-route',
  'angular-sanitize',
  'angular-touch'
];

angularFiles.forEach(function (item) {
  data[item] = {
    versions: ['1.2.18', '1.2.17', '1.2.16', '1.2.15', '1.2.14', '1.2.13', '1.2.12', '1.2.11', '1.2.10', '1.2.9', '1.2.8', '1.2.7', '1.2.6', '1.2.5', '1.2.4', '1.2.3', '1.2.2', '1.2.1', '1.2.0', '1.0.8', '1.0.7', '1.0.6', '1.0.5', '1.0.4', '1.0.3', '1.0.2', '1.0.1'],
    url: function (version) {
      return '//ajax.googleapis.com/ajax/libs/angularjs/' + version + '/' + item + '.min.js';
    }
  };
});
<commit_msg>Update index.js<commit_after>'use strict';

var data = module.exports = {
  jquery: {
    versions: ['2.1.1', '2.1.0', '2.0.3', '2.0.2', '2.0.1', '2.0.0', '1.11.1', '1.11.0', '1.10.2', '1.10.1', '1.10.0', '1.9.1', '1.9.0', '1.8.3', '1.8.2', '1.8.1', '1.8.0', '1.7.2', '1.7.1', '1.7.0', '1.6.4', '1.6.3', '1.6.2', '1.6.1', '1.6.0', '1.5.2', '1.5.1', '1.5.0', '1.4.4', '1.4.3', '1.4.2', '1.4.1', '1.4.0', '1.3.2', '1.3.1', '1.3.0', '1.2.6', '1.2.3'],
    url: function (version) {
      return '//ajax.googleapis.com/ajax/libs/jquery/' + version + '/jquery.min.js';
    }
  },
  'jquery-ui': {
    versions: ['1.10.4', '1.10.3', '1.10.2', '1.10.1', '1.10.0', '1.9.2', '1.9.1', '1.9.0', '1.8.24', '1.8.23', '1.8.22', '1.8.21', '1.8.20', '1.8.19', '1.8.18', '1.8.17', '1.8.16', '1.8.15', '1.8.14', '1.8.13', '1.8.12', '1.8.11', '1.8.10', '1.8.9', '1.8.8', '1.8.7', '1.8.6', '1.8.5', '1.8.4', '1.8.2', '1.8.1', '1.8.0', '1.7.3', '1.7.2', '1.7.1', '1.7.0', '1.6.0', '1.5.3', '1.5.2'],
    url: function (version) {
      return '//ajax.googleapis.com/ajax/libs/jqueryui/' + version + '/jquery-ui.min.js';
    }
  },
  dojo: {
    versions: ['1.9.2', '1.9.1', '1.9.0', '1.8.5', '1.8.4', '1.8.3', '1.8.2', '1.8.1', '1.8.0', '1.7.5', '1.7.4', '1.7.3', '1.7.2', '1.7.1', '1.7.0', '1.6.1', '1.6.0', '1.5.2', '1.5.1', '1.5.0', '1.4.4', '1.4.3', '1.4.1', '1.4.0', '1.3.2', '1.3.1', '1.3.0', '1.2.3', '1.2.0', '1.1.1'],
    url: function (version) {
      return '//ajax.googleapis.com/ajax/libs/dojo/' + version + '/dojo/dojo.js';
    }
  },
  swfobject: {
    versions: ['2.2', '2.1'],
    url: function (version) {
      return '//ajax.googleapis.com/ajax/libs/swfobject/' + version + '/swfobject.js';
    }
  }
};

// AngularJS

var angularFiles = [
  'angular',
  'angular-animate',
  'angular-cookies',
  'angular-loader',
  'angular-resource',
  'angular-route',
  'angular-sanitize',
  'angular-touch'
];

angularFiles.forEach(function (item) {
  data[item] = {
    versions: ['1.2.19', '1.2.18', '1.2.17', '1.2.16', '1.2.15', '1.2.14', '1.2.13', '1.2.12', '1.2.11', '1.2.10', '1.2.9', '1.2.8', '1.2.7', '1.2.6', '1.2.5', '1.2.4', '1.2.3', '1.2.2', '1.2.1', '1.2.0', '1.0.8', '1.0.7', '1.0.6', '1.0.5', '1.0.4', '1.0.3', '1.0.2', '1.0.1'],
    url: function (version) {
      return '//ajax.googleapis.com/ajax/libs/angularjs/' + version + '/' + item + '.min.js';
    }
  };
});
<|endoftext|>


<commit_before>var process = require('process');
var EventEmitter = require('events').EventEmitter;

var errors = require('./errors.js');
var readDatacenter = require('./read-datacenter.js');
var getConfigState = require('./get-config-state.js');
var ConfigWrapper = require('./config-wrapper.js');

module.exports = fetchConfigSync;

function fetchConfigSync(dirname, opts) {
    if (typeof dirname !== 'string' || dirname === '') {
        throw errors.InvalidDirname({
            dirname: dirname,
            strDirname: JSON.stringify(dirname)
        });
    }

    opts = opts || {};

    // config is EventEmitter purely for `.emit('error', err)`
    var config = new EventEmitter();

    var datacenterTuple = readDatacenter(opts);

    if (datacenterTuple[0]) {
        // throw error async. this allows for breaking a
        // circular dependency between config & logger.
        process.nextTick(function () {
            config.emit('error', datacenterTuple[0]);
        });
    } else {
        opts.datacenterValue = datacenterTuple[1];
    }

    var configState = getConfigState(dirname, opts);
    var localConfigWrapper = ConfigWrapper(configState);
    var remoteConfigWrapper = ConfigWrapper({});

    config.get = localConfigWrapper.get;
    config.set = localConfigWrapper.set;
    config.freeze = localConfigWrapper.freeze;
    config.getRemote = remoteConfigWrapper.get;
    config.setRemote = remoteConfigWrapper.set;

    return config;
}

<commit_msg>whitespace<commit_after>var process = require('process');
var EventEmitter = require('events').EventEmitter;

var errors = require('./errors.js');
var readDatacenter = require('./read-datacenter.js');
var getConfigState = require('./get-config-state.js');
var ConfigWrapper = require('./config-wrapper.js');

module.exports = fetchConfigSync;

function fetchConfigSync(dirname, opts) {
    if (typeof dirname !== 'string' || dirname === '') {
        throw errors.InvalidDirname({
            dirname: dirname,
            strDirname: JSON.stringify(dirname)
        });
    }

    opts = opts || {};

    // config is EventEmitter purely for `.emit('error', err)`
    var config = new EventEmitter();

    var datacenterTuple = readDatacenter(opts);

    if (datacenterTuple[0]) {
        // throw error async. this allows for breaking a
        // circular dependency between config & logger.
        process.nextTick(function () {
            config.emit('error', datacenterTuple[0]);
        });
    } else {
        opts.datacenterValue = datacenterTuple[1];
    }

    var configState = getConfigState(dirname, opts);
    var localConfigWrapper = ConfigWrapper(configState);
    var remoteConfigWrapper = ConfigWrapper({});

    config.get = localConfigWrapper.get;
    config.set = localConfigWrapper.set;
    config.freeze = localConfigWrapper.freeze;
    config.getRemote = remoteConfigWrapper.get;
    config.setRemote = remoteConfigWrapper.set;

    return config;
}
<|endoftext|>


<commit_before>'use strict'

const Trailpack = require('trailpack-datastore')
const lib = require('./lib')
const _ = require('lodash')

module.exports = class SequelizeTrailpack extends Trailpack {

  /**
   * Validate the database config, and api.model definitions
   */
  validate() {
    const stores = _.get(this.app.config, 'database.stores')
    if (stores && Object.keys(stores).length === 0) {
      this.app.config.log.logger.warn('No store configured at config.database.stores, models will be ignored')
    }
    return Promise.all([
      lib.Validator.validateDatabaseConfig(this.app.config.database)
    ])
  }

  /**
   * Merge configuration into models, load Sequelize collections.
   */
  configure() {
    this.app.config.database.orm = 'sequelize'
    _.merge(this.app.config, lib.FailsafeConfig)
  }

  /**
   * Initialize Sequelize. This will compile the schema and connect to the
   * database.
   */
  initialize() {
    super.initialize()

    this.orm = this.orm || {}
    this.app.orm = {}
    this.connections = lib.Transformer.transformStores(this.app)
    this.models = lib.Transformer.transformModels(this.app)

    _.each(this.models, (model, modelName) => {
      _.each(this.connections, (connection, name) => {
        if (model.connection == name) {
          this.app.orm[model.globalId] = connection.define(modelName, model.schema, model.config)
        }
      })
    })

    _.each(this.models, (model, modelName) => {
      if (!this.app.orm[model.globalId]) return //ignore model if not configured

      if (this.app.orm[model.globalId].associate)
        this.app.orm[model.globalId].associate(this.app.orm)

      this.orm[model.globalId.toLowerCase()] = this.app.orm[model.globalId]
    })

    return this.migrate()
  }

  /**
   * Close all database connections
   */
  unload() {
    return Promise.all(
      _.map(this.connections, connection => {
        return new Promise((resolve, reject) => {
          connection.close()
          resolve()
        })
      })
    )
  }

  migrate() {
    const SchemaMigrationService = this.app.services.SchemaMigrationService

    return Promise.all(
      _.map(this.models, model => {
        if (!this.app.orm[model.globalId]) return //ignore model if not configured
        if (model.migrate == 'drop') {
          return SchemaMigrationService.dropModel(this.app.orm[model.globalId])
        }
        else if (model.migrate == 'alter') {
          return SchemaMigrationService.alterModel(this.app.orm[model.globalId])
        }
      })
    )
  }

  constructor(app) {
    super(app, {
      config: require('./config'),
      api: require('./api'),
      pkg: require('./package')
    })
  }
}

<commit_msg>Fix migration<commit_after>'use strict'

const Trailpack = require('trailpack-datastore')
const lib = require('./lib')
const _ = require('lodash')

module.exports = class SequelizeTrailpack extends Trailpack {

  /**
   * Validate the database config, and api.model definitions
   */
  validate() {
    const stores = _.get(this.app.config, 'database.stores')
    if (stores && Object.keys(stores).length === 0) {
      this.app.config.log.logger.warn('No store configured at config.database.stores, models will be ignored')
    }
    return Promise.all([
      lib.Validator.validateDatabaseConfig(this.app.config.database)
    ])
  }

  /**
   * Merge configuration into models, load Sequelize collections.
   */
  configure() {
    this.app.config.database.orm = 'sequelize'
    _.merge(this.app.config, lib.FailsafeConfig)
  }

  /**
   * Initialize Sequelize. This will compile the schema and connect to the
   * database.
   */
  initialize() {
    super.initialize()

    this.orm = this.orm || {}
    this.app.orm = {}
    this.connections = lib.Transformer.transformStores(this.app)
    this.models = lib.Transformer.transformModels(this.app)

    _.each(this.models, (model, modelName) => {
      _.each(this.connections, (connection, name) => {
        if (model.connection == name) {
          this.app.orm[model.globalId] = connection.define(modelName, model.schema, model.config)
        }
      })
    })

    _.each(this.models, (model, modelName) => {
      if (!this.app.orm[model.globalId]) return //ignore model if not configured

      if (this.app.orm[model.globalId].associate)
        this.app.orm[model.globalId].associate(this.app.orm)

      this.orm[model.globalId.toLowerCase()] = this.app.orm[model.globalId]
    })

    return this.migrate()
  }

  /**
   * Close all database connections
   */
  unload() {
    return Promise.all(
      _.map(this.connections, connection => {
        return new Promise((resolve, reject) => {
          connection.close()
          resolve()
        })
      })
    )
  }

  migrate() {
    const SchemaMigrationService = this.app.services.SchemaMigrationService
    const database = this.app.config.database

    if (database.models.migrate == 'none') return

    return Promise.all(
      _.map(this.connections, connection => {

        if (database.models.migrate == 'drop') {
          return SchemaMigrationService.dropDB(connection)
        }
        else if (database.models.migrate == 'alter') {
          return SchemaMigrationService.alterDB(connection)
        }
      })
    )
  }

  constructor(app) {
    super(app, {
      config: require('./config'),
      api: require('./api'),
      pkg: require('./package')
    })
  }
}

<|endoftext|>


<commit_before>var crypto = require('crypto')

var exportFn = require('./pbkdf2')
var exported = exportFn(crypto)

module.exports = {
  pbkdf2: exported.pbkdf2,
  pbkdf2Sync: exported.pbkdf2Sync,

  // for crypto-browserify
  __pbkdf2Export: exportFn
}
<commit_msg>index: remove unnecessary __pbkdf2Export<commit_after>var crypto = require('crypto')

var exportFn = require('./pbkdf2')
var exported = exportFn(crypto)

module.exports = {
  pbkdf2: exported.pbkdf2,
  pbkdf2Sync: exported.pbkdf2Sync
}
<|endoftext|>


<commit_before>/*
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

'use strict';

var assert = require('assert');
var bunyan = require('bunyan');
var Executor = require('./executor.js');
var findImage = require('./docker').findImage;

module.exports = function(config, logger) {
  logger = logger || bunyan.createLogger({name: 'docker-registry-container'});
  var executor = new Executor(config);

  /**
   * build the container
   * system - the system definition
   * cdef - contianer definition block
   * out - ouput stream
   * cb - complete callback
   */
  var build = function build(mode, system, containerDef, out, cb) {
    logger.info('building');
    out.stdout('--> building');

    var name = containerDef.specific.name;

    if (!name) {
      return cb(new Error('missing name for definition ' + containerDef.id));
    }

    var pull = 'docker pull ' + name;
    var tag = 'docker tag ' + name + ' ' + system.name + '/' + name;

    if (mode === 'preview') {
      out.preview({ host: target.privateIpAddress || 'localhost', cmd: pull });
      out.preview({ host: target.privateIpAddress || 'localhost', cmd: tag });
      return cb();
    }

    executor.exec(null, pull, out, function(err) {
      if (err) {
        return cb(err);
      }

      executor.exec(null, tag, out, function(err) {

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

        findImage(system.name + '/' + name, function(err, image) {
          if (err) {
            return cb(err);
          }

          cb(null, {
            dockerImageId: image.Id
          });
        });
      });
    });
  };

  /**
   * deploy the continaer
   * target - target to deploy to
   * system - the target system defintinion
   * cdef - the contianer definition
   * container - the container as defined in the system topology
   * out - ouput stream
   * cb - complete callback
   */
  var deploy = function deploy(mode, target, system, containerDef, container, out, cb) {
    cb();
  };

  /**
   * undeploy the container from the target
   * target - target to deploy to
   * system - the target system defintinion
   * cdef - the contianer definition
   * container - the container as defined in the system topology
   * out - ouput stream
   * cb - complete callback
   */
  var undeploy = function undeploy(mode, target, system, containerDef, container, out, cb) {
    cb();
  };

  /**
   * start the container on the target
   * target - target to deploy to
   * system - the target system defintinion
   * cdef - the contianer definition
   * container - the container as defined in the system topology
   * out - ouput stream
   * cb - complete callback
   */
  var start = function start(mode, target, system, containerDef, container, out, cb) {
    logger.info('starting');
    out.stdout('--> starting');

    var name = containerDef.specific.name;
    var args = containerDef.specific.execute.args || '';
    var exec = containerDef.specific.execute.exec || '';
    var cmd = 'docker run ' + args + ' ' + name + ' ' + exec;

    if (mode === 'preview') {
      out.preview({ host: target.privateIpAddress || 'localhost', cmd: cmd });
      return cb();
    }

    executor.exec(target.privateIpAddress, cmd, out, cb);
  };

  /**
   * stop the container on the target
   * target - target to deploy to
   * system - the target system defintinion
   * cdef - the contianer definition
   * container - the container as defined in the system topology
   * out - ouput stream
   * cb - complete callback
   */
  var stop = function stop(mode, target, system, containerDef, container, out, cb) {
    logger.info('stopping');
    out.stdout('stopping');
    cb();
  };

  /**
   * link the container to the target
   * target - target to deploy to
   * system - the target system defintinion
   * cdef - the contianer definition
   * container - the container as defined in the system topology
   * out - ouput stream
   * cb - complete callback
   */
  var link = function link(mode, target, system, containerDef, container, out, cb) {
    logger.info('linking');
    out.stdout('linking');
    cb();
  };

  /**
   * unlink the container from the target
   * target - target to deploy to
   * system - the target system defintinion
   * cdef - the contianer definition
   * container - the container as defined in the system topology
   * out - ouput stream
   * cb - complete callback
   */
  var unlink = function unlink(mode, target, system, containerDef, container, out, cb) {
    logger.info('unlinking');
    out.stdout('unlinking');
    cb();
  };

  return {
    build: build,
    deploy: deploy,
    start: start,
    stop: stop,
    link: link,
    unlink: unlink,
    undeploy: undeploy,
    add: deploy,
    remove: undeploy
  };
};

<commit_msg>Use the containerDef id for tagging and not the registry name.<commit_after>/*
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

'use strict';

var assert = require('assert');
var bunyan = require('bunyan');
var Executor = require('./executor.js');
var findImage = require('./docker').findImage;

module.exports = function(config, logger) {
  logger = logger || bunyan.createLogger({name: 'docker-registry-container'});
  var executor = new Executor(config);

  /**
   * build the container
   * system - the system definition
   * cdef - contianer definition block
   * out - ouput stream
   * cb - complete callback
   */
  var build = function build(mode, system, containerDef, out, cb) {
    logger.info('building');
    out.stdout('--> building');

    var name = containerDef.specific.name;

    if (!name) {
      return cb(new Error('missing name for definition ' + containerDef.id));
    }

    if (containerDef.specific.execute) {
      return cb(new Error('missing execute block in ' + containerDef.id + ' container definition'));
    }

    var pullCmd = 'docker pull ' + name;
    var tag = system.name + '/' + containerDef.id;
    var tagCmd = 'docker tag ' + name + ' ' + tag;

    executor.exec(null, pullCmd, out, function(err) {
      if (err) {
        return cb(err);
      }

      executor.exec(null, tagCmd, out, function(err) {

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

        findImage(tag, function(err, image) {
          if (err) {
            return cb(err);
          }

          cb(null, {
            dockerImageId: image.Id,
            imageTag: tag
          });
        });
      });
    });
  };

  /**
   * deploy the continaer
   * target - target to deploy to
   * system - the target system defintinion
   * cdef - the contianer definition
   * container - the container as defined in the system topology
   * out - ouput stream
   * cb - complete callback
   */
  var deploy = function deploy(mode, target, system, containerDef, container, out, cb) {
    cb();
  };

  /**
   * undeploy the container from the target
   * target - target to deploy to
   * system - the target system defintinion
   * cdef - the contianer definition
   * container - the container as defined in the system topology
   * out - ouput stream
   * cb - complete callback
   */
  var undeploy = function undeploy(mode, target, system, containerDef, container, out, cb) {
    cb();
  };

  /**
   * start the container on the target
   * target - target to deploy to
   * system - the target system defintinion
   * cdef - the contianer definition
   * container - the container as defined in the system topology
   * out - ouput stream
   * cb - complete callback
   */
  var start = function start(mode, target, system, containerDef, container, out, cb) {
    logger.info('starting');
    out.stdout('--> starting');

    var name = containerDef.specific.name;
    var args = containerDef.specific.execute.args || '';
    var exec = containerDef.specific.execute.exec || '';
    var cmd = 'docker run ' + args + ' ' + name + ' ' + exec;

    if (mode === 'preview') {
      out.preview({ host: target.privateIpAddress || 'localhost', cmd: cmd });
      return cb();
    }

    executor.exec(target.privateIpAddress, cmd, out, cb);
  };

  /**
   * stop the container on the target
   * target - target to deploy to
   * system - the target system defintinion
   * cdef - the contianer definition
   * container - the container as defined in the system topology
   * out - ouput stream
   * cb - complete callback
   */
  var stop = function stop(mode, target, system, containerDef, container, out, cb) {
    logger.info('stopping');
    out.stdout('stopping');
    cb();
  };

  /**
   * link the container to the target
   * target - target to deploy to
   * system - the target system defintinion
   * cdef - the contianer definition
   * container - the container as defined in the system topology
   * out - ouput stream
   * cb - complete callback
   */
  var link = function link(mode, target, system, containerDef, container, out, cb) {
    logger.info('linking');
    out.stdout('linking');
    cb();
  };

  /**
   * unlink the container from the target
   * target - target to deploy to
   * system - the target system defintinion
   * cdef - the contianer definition
   * container - the container as defined in the system topology
   * out - ouput stream
   * cb - complete callback
   */
  var unlink = function unlink(mode, target, system, containerDef, container, out, cb) {
    logger.info('unlinking');
    out.stdout('unlinking');
    cb();
  };

  return {
    build: build,
    deploy: deploy,
    start: start,
    stop: stop,
    link: link,
    unlink: unlink,
    undeploy: undeploy,
    add: deploy,
    remove: undeploy
  };
};

<|endoftext|>


<commit_before>/* global Blob */

module.exports = Socket

var debug = require('debug')('simple-websocket')
var inherits = require('inherits')
var isTypedArray = require('is-typedarray')
var stream = require('stream')
var toBuffer = require('typedarray-to-buffer')
var ws = require('ws') // websockets in node - will be empty object in browser

var WebSocket = typeof window !== 'undefined' ? window.WebSocket : ws

inherits(Socket, stream.Duplex)

/**
 * WebSocket. Same API as node core `net.Socket`. Duplex stream.
 * @param {string} url websocket server url
 * @param {Object} opts options to stream.Duplex
 */
function Socket (url, opts) {
  var self = this
  if (!(self instanceof Socket)) return new Socket(url, opts)
  if (!opts) opts = {}
  debug('new websocket: %s %o', url, opts)

  opts.allowHalfOpen = false
  stream.Duplex.call(self, opts)

  self.url = url
  self.connected = false
  self.destroyed = false

  self._chunk = null
  self._cb = null
  self._interval = null

  self._ws = new WebSocket(self.url)
  self._ws.binaryType = 'arraybuffer'
  self._ws.onopen = self._onOpen.bind(self)
  self._ws.onmessage = self._onMessage.bind(self)
  self._ws.onclose = self._onClose.bind(self)
  self._ws.onerror = self._onError.bind(self)

  self.on('finish', function () {
    if (self.connected) {
      // When stream is finished writing, close socket connection. Half open connections
      // are currently not supported.
      // Wait a bit before destroying so the socket flushes.
      // TODO: is there a more reliable way to accomplish this?
      setTimeout(function () {
        self._destroy()
      }, 100)
    } else {
      // If socket is not connected when stream is finished writing, wait until data is
      // flushed to network at "connect" event.
      // TODO: is there a more reliable way to accomplish this?
      self.once('connect', function () {
        setTimeout(function () {
          self._destroy()
        }, 100)
      })
    }
  })

}

Socket.prototype.send = function (chunk) {
  var self = this
  var len = chunk.length || chunk.byteLength || chunk.size
  self._ws.send(chunk)
  debug('write: %d bytes', len)
}

Socket.prototype.destroy = function (onclose) {
  var self = this
  self._destroy(null, onclose)
}

Socket.prototype._destroy = function (err, onclose) {
  var self = this
  if (self.destroyed) return
  if (onclose) self.once('close', onclose)

  debug('destroy (error: %s)', err && err.message)

  self.connected = false
  self.destroyed = true

  clearInterval(self._interval)
  self._interval = null
  self._chunk = null
  self._cb = null

  if (self._ws) {
    try {
      self._ws.close()
    } catch (err) {}

    self._ws.onopen = null
    self._ws.onmessage = null
    self._ws.onclose = null
    self._ws.onerror = null
  }
  self._ws = null

  this.readable = this.writable = false

  if (!self._readableState.ended) self.push(null)
  if (!self._writableState.finished) self.end()

  if (err) self.emit('error', err)
  self.emit('close')
}

Socket.prototype._read = function () {}

/**
 * Send text/binary data to the WebSocket server.
 * @param {string|Buffer|TypedArrayView|ArrayBuffer|Blob} chunk
 * @param {string} encoding
 * @param {function} cb
 */
Socket.prototype._write = function (chunk, encoding, cb) {
  var self = this
  if (self.destroyed) return cb(new Error('cannot write after socket is destroyed'))

  if (!isTypedArray.strict(chunk) && !(chunk instanceof ArrayBuffer) &&
    !Buffer.isBuffer(chunk) && typeof chunk !== 'string' &&
    (typeof Blob === 'undefined' || !(chunk instanceof Blob))) {
    chunk = JSON.stringify(chunk)
  }

  if (self.connected) {
    self.send(chunk)
    if (typeof ws !== 'function' && self._ws.bufferedAmount) {
      debug('start backpressure: bufferedAmount %d', self._ws.bufferedAmount)
      self._cb = cb
    } else {
      cb(null)
    }
  } else {
    debug('write before connect')
    self._chunk = chunk
    self._cb = cb
  }
}

Socket.prototype._onMessage = function (event) {
  var self = this
  if (self.destroyed) return
  var data = event.data
  debug('on message: length %d', data.byteLength || data.length)

  if (data instanceof ArrayBuffer) {
    data = toBuffer(new Uint8Array(data))
    self.push(data)
  } else if (Buffer.isBuffer(data)) {
    self.push(data)
  } else {
    try {
      data = JSON.parse(data)
    } catch (err) {}
    self.emit('data', data)
  }
}

Socket.prototype._onOpen = function () {
  var self = this
  if (self.connected || self.destroyed) return
  self.connected = true

  if (self._chunk) {
    self.send(self._chunk)
    self._chunk = null
    debug('sent chunk from "write before connect"')

    var cb = self._cb
    self._cb = null
    cb(null)
  }

  // No backpressure in node. The `ws` module has a buggy `bufferedAmount` property.
  // See: https://github.com/websockets/ws/issues/492
  if (typeof ws !== 'function') {
    self._interval = setInterval(function () {
      if (!self._cb || !self._ws || self._ws.bufferedAmount) return
      debug('ending backpressure: bufferedAmount %d', self._ws.bufferedAmount)
      var cb = self._cb
      self._cb = null
      cb(null)
    }, 150)
    if (self._interval.unref) self._interval.unref()
  }

  debug('connect')
  self.emit('connect')
}

Socket.prototype._onClose = function () {
  var self = this
  if (self.destroyed) return
  debug('on close')
  self._destroy()
}

Socket.prototype._onError = function () {
  var self = this
  if (self.destroyed) return
  var err = new Error('connection error to ' + self.url)
  debug('error: %s', err.message || err)
  self._destroy(err)
}
<commit_msg>better debug log<commit_after>/* global Blob */

module.exports = Socket

var debug = require('debug')('simple-websocket')
var inherits = require('inherits')
var isTypedArray = require('is-typedarray')
var stream = require('stream')
var toBuffer = require('typedarray-to-buffer')
var ws = require('ws') // websockets in node - will be empty object in browser

var WebSocket = typeof window !== 'undefined' ? window.WebSocket : ws

inherits(Socket, stream.Duplex)

/**
 * WebSocket. Same API as node core `net.Socket`. Duplex stream.
 * @param {string} url websocket server url
 * @param {Object} opts options to stream.Duplex
 */
function Socket (url, opts) {
  var self = this
  if (!(self instanceof Socket)) return new Socket(url, opts)
  if (!opts) opts = {}
  debug('new websocket: %s %o', url, opts)

  opts.allowHalfOpen = false
  stream.Duplex.call(self, opts)

  self.url = url
  self.connected = false
  self.destroyed = false

  self._chunk = null
  self._cb = null
  self._interval = null

  self._ws = new WebSocket(self.url)
  self._ws.binaryType = 'arraybuffer'
  self._ws.onopen = self._onOpen.bind(self)
  self._ws.onmessage = self._onMessage.bind(self)
  self._ws.onclose = self._onClose.bind(self)
  self._ws.onerror = self._onError.bind(self)

  self.on('finish', function () {
    if (self.connected) {
      // When stream is finished writing, close socket connection. Half open connections
      // are currently not supported.
      // Wait a bit before destroying so the socket flushes.
      // TODO: is there a more reliable way to accomplish this?
      setTimeout(function () {
        self._destroy()
      }, 100)
    } else {
      // If socket is not connected when stream is finished writing, wait until data is
      // flushed to network at "connect" event.
      // TODO: is there a more reliable way to accomplish this?
      self.once('connect', function () {
        setTimeout(function () {
          self._destroy()
        }, 100)
      })
    }
  })

}

Socket.prototype.send = function (chunk) {
  var self = this
  var len = chunk.length || chunk.byteLength || chunk.size
  self._ws.send(chunk)
  debug('write: %d bytes', len)
}

Socket.prototype.destroy = function (onclose) {
  var self = this
  self._destroy(null, onclose)
}

Socket.prototype._destroy = function (err, onclose) {
  var self = this
  if (self.destroyed) return
  if (onclose) self.once('close', onclose)

  debug('destroy (error: %s)', err && err.message)

  self.connected = false
  self.destroyed = true

  clearInterval(self._interval)
  self._interval = null
  self._chunk = null
  self._cb = null

  if (self._ws) {
    try {
      self._ws.close()
    } catch (err) {}

    self._ws.onopen = null
    self._ws.onmessage = null
    self._ws.onclose = null
    self._ws.onerror = null
  }
  self._ws = null

  this.readable = this.writable = false

  if (!self._readableState.ended) self.push(null)
  if (!self._writableState.finished) self.end()

  if (err) self.emit('error', err)
  self.emit('close')
}

Socket.prototype._read = function () {}

/**
 * Send text/binary data to the WebSocket server.
 * @param {string|Buffer|TypedArrayView|ArrayBuffer|Blob} chunk
 * @param {string} encoding
 * @param {function} cb
 */
Socket.prototype._write = function (chunk, encoding, cb) {
  var self = this
  if (self.destroyed) return cb(new Error('cannot write after socket is destroyed'))

  if (!isTypedArray.strict(chunk) && !(chunk instanceof ArrayBuffer) &&
    !Buffer.isBuffer(chunk) && typeof chunk !== 'string' &&
    (typeof Blob === 'undefined' || !(chunk instanceof Blob))) {
    chunk = JSON.stringify(chunk)
  }

  if (self.connected) {
    self.send(chunk)
    if (typeof ws !== 'function' && self._ws.bufferedAmount) {
      debug('start backpressure: bufferedAmount %d', self._ws.bufferedAmount)
      self._cb = cb
    } else {
      cb(null)
    }
  } else {
    debug('write before connect')
    self._chunk = chunk
    self._cb = cb
  }
}

Socket.prototype._onMessage = function (event) {
  var self = this
  if (self.destroyed) return
  var data = event.data
  debug('got message: %d bytes', data.byteLength || data.length)

  if (data instanceof ArrayBuffer) {
    data = toBuffer(new Uint8Array(data))
    self.push(data)
  } else if (Buffer.isBuffer(data)) {
    self.push(data)
  } else {
    try {
      data = JSON.parse(data)
    } catch (err) {}
    self.emit('data', data)
  }
}

Socket.prototype._onOpen = function () {
  var self = this
  if (self.connected || self.destroyed) return
  self.connected = true

  if (self._chunk) {
    self.send(self._chunk)
    self._chunk = null
    debug('sent chunk from "write before connect"')

    var cb = self._cb
    self._cb = null
    cb(null)
  }

  // No backpressure in node. The `ws` module has a buggy `bufferedAmount` property.
  // See: https://github.com/websockets/ws/issues/492
  if (typeof ws !== 'function') {
    self._interval = setInterval(function () {
      if (!self._cb || !self._ws || self._ws.bufferedAmount) return
      debug('ending backpressure: bufferedAmount %d', self._ws.bufferedAmount)
      var cb = self._cb
      self._cb = null
      cb(null)
    }, 150)
    if (self._interval.unref) self._interval.unref()
  }

  debug('connect')
  self.emit('connect')
}

Socket.prototype._onClose = function () {
  var self = this
  if (self.destroyed) return
  debug('on close')
  self._destroy()
}

Socket.prototype._onError = function () {
  var self = this
  if (self.destroyed) return
  var err = new Error('connection error to ' + self.url)
  debug('error: %s', err.message || err)
  self._destroy(err)
}
<|endoftext|>


<commit_before>'use strict';

const app = require('./lib/app');
require('./lib/mongoose-setup');
const port = process.env.PORT || 3000;

app.listen(port);

console.log('Server running on', port);
<commit_msg>trying travis fix<commit_after>'use strict';

const app = require('./lib/app');
require('./lib/mongoose-setup');
const http = require('http');
const port = process.env.PORT || 3000;

const server = http.createServer(app);
server.listen(port, () => {
  console.log('server running at', server.address());
});
<|endoftext|>


<commit_before>'use strict';

var repeat = require('repeat-string');

/**
 * Align string with whitespace.
 *
 * @arg {*} string - Data to be aligned. Converted to a string.
 * @arg {number} width
 * @arg {"center","left","right"} [alignment="center"]
 * @arg {string} [placeholder=" "]
 */
module.exports = function (string, width, alignment, placeholder) {
  string = string.toString();
  placeholder = placeholder || ' ';

  if (placeholder.length != 1) {
    throw new Error('Placeholder must be of length 1');
  }

  if (width <= string.length) {
    return string;
  }

  if (!alignment || alignment == 'center') {
    var left = Math.floor((width - string.length) / 2)
      , right = width - string.length - left;

    return repeat(placeholder, left) + string + repeat(placeholder, right);
  }
  else {
    var whitespace = repeat(placeholder, width);

    if (alignment == 'left') {
      return (string + whitespace).slice(0, width);
    }
    else if (alignment == 'right') {
      return (whitespace + string).slice(-width);
    }
  }

  throw new Error('Invalid alignment type: ' + alignment);
};
<commit_msg>Accept options object<commit_after>'use strict';

var repeat = require('repeat-string');

/**
 * Align string with whitespace.
 *
 * @arg {*} string - Data to be aligned. Converted to a string.
 * @arg {number} width
 * @arg {"center","left","right"} [alignment="center"]
 * @arg {string} [placeholder=" "]
 */
module.exports = function (string, width, alignment, placeholder) {
  string = string.toString();

  if (typeof width == 'object') {
    var options = width;

    width = options.width;
    alignment = options.alignment;
    placeholder = options.placeholder;
  }
  else if (typeof alignment == 'string' && alignment.length == 1) {
    placeholder = alignment;
    alignment = null;
  }

  alignment = alignment || 'center';
  placeholder = placeholder || ' ';

  if (placeholder.length != 1) {
    throw new Error('Placeholder must be of length 1');
  }

  if (width <= string.length) {
    return string;
  }

  if (alignment == 'center') {
    var left = Math.floor((width - string.length) / 2)
      , right = width - string.length - left;

    return repeat(placeholder, left) + string + repeat(placeholder, right);
  }
  else {
    var whitespace = repeat(placeholder, width);

    if (alignment == 'left') {
      return (string + whitespace).slice(0, width);
    }
    else if (alignment == 'right') {
      return (whitespace + string).slice(-width);
    }
  }

  throw new Error('Invalid alignment type: ' + alignment);
};
<|endoftext|>


<commit_before>module.exports = {
  extends: 'standard',
  rules: {
    'computed-property-spacing': ['error', 'never'],
    'array-bracket-spacing': ['error', 'never'],
    'func-name-matching': 'error',
    'consistent-return': 'error',
    'multiline-ternary': ['error', 'never'],
    'no-nested-ternary': 'error',
    'block-scoped-var': 'error',
    'no-invalid-this': 'error',
    'global-require': 'error',
    'no-unused-vars': [2, { 'vars': 'all', 'args': 'after-used' }],
    'no-lonely-if': 'error',
    'valid-jsdoc': 'error',
    'func-style': ['error', 'declaration'],
    'no-shadow': 'error',
    'max-len': [2, 80],
    'strict': ['error', 'global'],
    'no-new': 'off'
  },
  env: {
    browser: true,
    node: true,
    jest: true
  }
}
<commit_msg>Add no-useless-return rule<commit_after>module.exports = {
  extends: 'standard',
  rules: {
    'computed-property-spacing': ['error', 'never'],
    'array-bracket-spacing': ['error', 'never'],
    'func-name-matching': 'error',
    'no-useless-return': 'error',
    'consistent-return': 'error',
    'multiline-ternary': ['error', 'never'],
    'no-nested-ternary': 'error',
    'block-scoped-var': 'error',
    'no-invalid-this': 'error',
    'global-require': 'error',
    'no-unused-vars': [2, { 'vars': 'all', 'args': 'after-used' }],
    'no-lonely-if': 'error',
    'valid-jsdoc': 'error',
    'func-style': ['error', 'declaration'],
    'no-shadow': 'error',
    'max-len': [2, 80],
    'strict': ['error', 'global'],
    'no-new': 'off'
  },
  env: {
    browser: true,
    node: true,
    jest: true
  }
}
<|endoftext|>


<commit_before>var BasePlugin = require('ember-cli-deploy-plugin');
var Rsync = require('rsync');

module.exports = {
  name: 'ember-cli-deploy-scp',

  createDeployPlugin: function(options) {
    var DeployPlugin = BasePlugin.extend({
      name: options.name,

      defaultConfig: {
        port: '22',
        directory: 'tmp/deploy-dist/.',
        exclude: false,
        flags: 'rtvu',
        displayCommands: false,
        beforeBuild: function(){},
        beforeUpload: function(){}
      },

      requiredConfig: ['username', 'path', 'host'],

      willBuild: function(context) {
        this.readConfig('beforeBuild');
      },
      willUpload: function(context) {
        this.readConfig('beforeUpload');
      },
      build: function(context) {
        this.log('Building...');
      },
      rsync: function (destination){
        var _this = this;
        var rsync = new Rsync()
          .shell('ssh -p '+this.readConfig('port'))
          .flags(this.readConfig('flags'))
          .source(this.readConfig('directory'))
          .destination(destination);

        if (this.readConfig('exclude')){
          rsync.exclude(this.readConfig('exclude'));
        }

        if (this.readConfig('displayCommands')){
          this.log(rsync.command())
        }

        rsync.execute(function(error, code, cmd) {
            _this.log('Done !');
        });
      },

      upload: function(context) {
        this.log('Uploading...');
        var MyDate = new Date(),
            MyDateString,
            generatedPath = this.readConfig('username') + '@' + this.readConfig('host') + ':' + this.readConfig('path'),
            parentPath = generatedPath.substr(0, generatedPath.lastIndexOf("/"));

        MyDate.setDate(MyDate.getDate());
        MyDateString = ('0' + MyDate.getDate()).slice(-2) + ('0' + (MyDate.getMonth()+1)).slice(-2) + MyDate.getFullYear() + ('0' + MyDate.getHours()).slice(-2) + ('0' + MyDate.getMinutes()).slice(-2);
        this.rsync(parentPath + '/' + MyDateString);
        this.rsync(generatedPath);
        this.log('Done !');
      }
    });

    return new DeployPlugin();
  }
};
<commit_msg>Error Handling Fix<commit_after>var BasePlugin = require('ember-cli-deploy-plugin');
var Rsync = require('rsync');

module.exports = {
  name: 'ember-cli-deploy-scp',

  createDeployPlugin: function(options) {
    var DeployPlugin = BasePlugin.extend({
      name: options.name,

      defaultConfig: {
        port: '22',
        directory: 'tmp/deploy-dist/.',
        exclude: false,
        flags: 'rtvu',
        displayCommands: false,
        beforeBuild: function(){},
        beforeUpload: function(){}
      },

      requiredConfig: ['username', 'path', 'host'],

      willBuild: function(context) {
        this.readConfig('beforeBuild');
      },
      willUpload: function(context) {
        this.readConfig('beforeUpload');
      },
      build: function(context) {
      },
      rsync: function (destination) {
        var _this = this;
        var rsync = new Rsync()
          .shell('ssh -p '+this.readConfig('port'))
          .flags(this.readConfig('flags'))
          .source(this.readConfig('directory'))
          .destination(destination);

        if (this.readConfig('exclude')){
          rsync.exclude(this.readConfig('exclude'));
        }

        if (this.readConfig('displayCommands')) {
          this.log(rsync.command())
        }

        return new Promise(function(resolve, reject) {
          rsync.execute(function(error, code, cmd) {
              if(error) {
                reject(_this.log(error));
              } else {
                _this.log('Done !');
                resolve();
              }
          });
        });
      },

      upload: function(context) {
        var MyDate = new Date(),
            MyDateString,
            generatedPath = this.readConfig('username') + '@' + this.readConfig('host') + ':' + this.readConfig('path'),
            parentPath = generatedPath.substr(0, generatedPath.lastIndexOf("/"));

        MyDate.setDate(MyDate.getDate());
        MyDateString = ('0' + MyDate.getDate()).slice(-2) + ('0' + (MyDate.getMonth()+1)).slice(-2) + MyDate.getFullYear() + ('0' + MyDate.getHours()).slice(-2) + ('0' + MyDate.getMinutes()).slice(-2);

        this.rsync(parentPath + '/' + MyDateString);
        return this.rsync(generatedPath);
      }
    });

    return new DeployPlugin();
  }
};
<|endoftext|>


<commit_before>var fs = require('fs');
var path = require('path'), dirname = path.dirname, basename = path.basename;
var spawn = require('child_process').spawn;
var cli = require('cli-define');
var Program = cli.Program;
var parser = require('cli-argparse');
var codes = require('./lib/codes');
var types = require('./lib/types');
var ArgumentTypeError = types.ArgumentTypeError;
var clierr = require('cli-error');
var ErrorDefinition = clierr.ErrorDefinition;
var CliError = clierr.CliError;
var errors = clierr.errors;
var config = {
  exit: true
}

var actions = {
  help: require('./lib/help'),
  version: require('./lib/version')
}

/**
 *  Retrieve the handler for a built in action.
 *
 *  @param key The argument key.
 */
function handler(key) {
  var fn = actions[key];
  if(this._arguments[key] && this._arguments[key]._action) {
    return this._arguments[key]._action;
  }
  return fn;
}

/**
 *  Retrieve a configuration suitable for passing to
 *  the arguments parser.
 */
function configuration() {
  var config = {alias: {}, flags: [], options: []}, k, arg, key, no = /^no/;
  for(k in this._arguments) {
    arg = this._arguments[k]; key = arg.key;
    if(key) {
      if(no.test(key)) {
        key = key.replace(no, '');
        key = key.charAt(0).toLowerCase() + key.slice(1);
      }
      config.alias[arg._names.join(' ')] = key;
    }
    if(arg instanceof cli.Flag) {
      config.flags = config.flags.concat(arg._names);
    }else if(arg instanceof cli.Option) {
      config.options = config.options.concat(arg._names);
    }
  }
  return config;
}

/**
 *  Retrievet the converter reference for an argument,
 *  respecting the type map.
 *
 *  @param arg The argument definition.
 *  @param func A specific function.
 */
function getConverter(arg, func) {
  var converter = func || arg._converter, name;
  if(Array.isArray(converter)) return converter;
  try {
    name = new converter().constructor.name;
  }catch(e){}
  if(name && types.map[name]) return types.map[name];
  if(arg._converter === JSON) return types.map.JSON;
  return converter;
}

function getConverterNames(arg) {
  var converter = arg._converter, names = [], i, name;
  for(i = 0;i < converter.length;i++) {
    try{
      name = new converter[i]().constructor.name;
      if(name) name = name.toLowerCase();
      names.push(name);
    }catch(e){}
  }
  return names;
}

/**
 *  Convert an arguments value.
 *
 *  @param value The parsed argument value.
 *  @param arg The argument definition.
 *  @param index The index into an array (multiple only).
 */
function convert(value, arg, index) {
  var converter = getConverter(arg), i, func;
  function error(e, message, parameters) {
    if(e instanceof ArgumentTypeError) {
      if(e.code == 1) e.code = errors.ETYPE.code;
      e.key = errors.ETYPE.key;
      raise.call(this, e)
    }else{
      // pass down as uncaught exception
      throw e;
    }
  }
  function invoke(converter, fast) {
    try {
      value = converter.call(this, value, arg, index);
    }catch(e) {
      if(!fast) throw e;
      error.call(this, e);
    }
    return value;
  }
  if(Array.isArray(converter)) {
    for(i = 0;i < converter.length;i++) {
      func = getConverter(arg, converter[i]);
      try {
        return invoke.call(this, func, false);
      }catch(e) {
        // NOTE: all coercion attempts failed
        if(i == (converter.length -1)) {
          error.call(this, e, 'invalid type for %s, expected (%s)',
            [arg.names.join(' | '), getConverterNames(arg).join(', ')]);
        }
      }
    }
  }else{
    invoke.call(this, converter, true);
  }
  return value;
}

/**
 *  Coerce an argument value using an assigned converter
 *  function.
 *
 *  @param arg The argument definition.
 *  @param v The value as specified on the command line.
 */
function coerce(arg, v) {
  var type = false, i;
  var converter = getConverter(arg);
  // NOTE: we check whether the converter is one of
  // NOTE: the built in converters as they are responsible
  // NOTE: for handling array values, other custom converters
  // NOTE: are invoked for each array entry if the argument
  // NOTE: value has already been converted to an array
  var keys = Object.keys(types);
  for(i = 0;i < keys.length;i++) {
    if(types[keys[i]] === converter) {
      type = true; break;
    }
  }
  if(typeof converter == 'function' || Array.isArray(converter)) {
    if(Array.isArray(v) && !type) {
      v.forEach(function(value, index, arr) {
        arr[index] = convert.call(this, value, arg, index);
      });
    }else{
      v = convert.call(this, v, arg);
    }
  }
  return v;
}

/**
 *  Merge parsed arguments into the program.
 *
 *  @param target The target object encapsulated by
 *  the argument parsing result object.
 *  @param options An object that will receive the arguments
 *  being merged.
 */
function merge(target, options) {
  var k, v, arg, re = /^no/;
  for(k in target) {
    arg = this._arguments[k];
    //console.log('%s %s', k, arg);
    if(arg) {
      v = target[k];
      if(arg.multiple && !Array.isArray(v)) {
        v = [v];
      }else if(!arg.multiple && Array.isArray(v)) {
        raise.call(this, errors.EMULTIPLE,
          [arg.names.join(' | '), v.join(', ')], {arg: arg, value: v});
      }
      v = coerce.call(this, arg, v);
      // TODO: validate at this point?
      this[k] = options[k] = arg.value = v;
    }
  }
}

/**
 *  Validate that required arguments are present.
 */
function required() {
  var z, arg;
  for(z in this._arguments) {
    arg = this._arguments[z];
    if(!arg.optional && !this._args.options[arg.key]) {
      raise.call(this, errors.EREQUIRED, [arg.names.join(' | ')], {arg: arg});
      return true;
    }
  }
  return false;
}

/**
 *  Execute builtin handlers for help and version.
 */
function builtins() {
  var i, action, fn, arr = Object.keys(actions);
  for(i = 0;i < arr.length;i++) {
    action = arr[i];
    if(this._args.flags[action]) {
      fn = handler.call(this, action);
      fn.call(this, actions[action]);
      return true;
    }
  }
  return false;
}

/**
 *  Raise an error from an error definition or error
 *  instance.
 *
 *  @param err The error definition.
 *  @param parameters The message replacement parameters.
 *  @param data Additional error data.
 */
function raise(err, parameters, data) {
  var e;
  if(err instanceof CliError) {
    e = err;
  }else if(err instanceof ErrorDefinition) {
    // TODO: do not include this method in the stack trace
    var e = err.toError();
    e.parameters = parameters || [];
    e.key = err.key;
    e.data = data;
    if(data && data.error) e.source = data.error;
  }
  // TODO: wrap normal errors in a CliError for consistency
  this.emit('error', e, errors);
}

/**
 *  Check file permissions.
 *
 *  canExecute():
 *  checkPermission (stat, 1);
 *
 *  canRead():
 *  checkPermission (stat, 4);
 *
 *  canWrite():
 *  checkPermission (stat, 2);
 */
function permissions(stat, mask) {
  return !!(mask &
    parseInt((stat.mode & parseInt("777", 8)).toString (8)[0]));
}

/**
 *  Execute a command as an external program.
 *
 *  @param argv The program arguments.
 *  @param cmd The command to execute.
 *  @param args Array of arguments to pass to the command.
 */
function execute(argv, cmd, args) {
  var scope = this;
  var dir = this._config.bin || dirname(argv[1]);
  var bin = this._name + '-' + cmd;
  var local = path.join(dir, bin);
  var exists = fs.existsSync(local);
  var data = {bin: bin, dir: dir, local: local, args: args};
  if(!exists) {
    return raise.call(this, errors.ENOENT, [bin], data);
  }
  var stat = fs.statSync(local);
  //var perms = stat.mode & 0777;
  //console.log('%s', perms);
  //console.log('%s', check(stat, 1));
  if(!permissions(stat, 1)) {
    return raise.call(this, errors.EPERM, [bin], data);
  }
  var ps = spawn(local, args, {stdio: 'inherit'});
  //ps.on('error', function(err){
    // NOTE: keep these tests just in case the above logic is wrong
    // NOTE: or quite likely fails on windows
    //if(err.code == 'ENOENT') {
      //raise.call(scope, codes.ENOENT, null, [bin, dir, local, args]);
    //}else if (err.code == 'EACCES') {
      //raise.call(scope, codes.EPERM, null, [bin, dir, local, args]);
    //}
  //});
  ps.on('close', function (code, signal) {
    // NOTE: workaround for https://github.com/joyent/node/issues/3222
    // NOTE: assume child process exited gracefully on SIGINT
    if(signal == 'SIGINT') {
      return process.exit(0);
    }
    scope.emit('close');
    process.exit(code);
  });
  return ps;
}

/**
 *  Searches the raw arguments looking for the first argument
 *  that matches a known command and either executes the command
 *  as an external program or invokes an action associated
 *  with the command.
 *
 *  @param options An object containing all flags and option values.
 */
function command(options) {
  var z, i, raw = this._args.raw.slice(0), action, cmd, arg, ind;
  for(i = 0;i < raw.length;i++) {
    cmd = raw[i]; arg = this._commands[cmd];
    if(arg) {
      raw.splice(i, 1);
      if(!arg._action) {
        return execute.call(this, process.argv, cmd, raw);
      }else if(arg._action) {
        ind = this.args.indexOf(cmd);
        if(~ind) this.args.splice(ind, 1);
        return arg._action.call(this, arg, options, raw);
      }
    }
  }
}

/**
 *  Emits the empty event.
 */
function empty() {
  // NOTE: this little dance allows custom help and version
  // NOTE: callbacks to invoke the original implementations
  // NOTE: from empty event listeners
  var help, version, _help, _version, scope = this;
  help = _help = handler.call(this, 'help');
  version = _version = handler.call(this, 'version');
  if(help != actions.help) {
    help = function() {
      _help.call(scope, actions.help);
    }
  }
  if(version != actions.version) {
    version = function() {
      _version.call(scope, actions.version);
    }
  }
  this.emit('empty', help, version);
}

/**
 *  Default error handler for the error event.
 *
 *  @param e The error instance.
 *  @param errors Map of error definitinons.
 */
Program.prototype.error = function(e, errors) {
  var key = (e.key || '').toLowerCase();
  var trace = key == 'euncaught' ? true : false;
  e.error(trace);
  if(this._configuration.exit) e.exit();
}

/**
 *  Assigns configuration information to the program.
 *
 *  @param config The program configuration.
 */
Program.prototype.configuration = function(config) {
  this._configuration = config;
  //console.dir(config);
  return this;
}

/**
 *  Parse the supplied arguments and execute any commands
 *  found in the arguments, preferring the built in commands
 *  for help and version.
 *
 *  @param args The arguments to parse, default is process.argv.slice(2).
 *  @param options Configuration options.
 */
function parse(args, options) {
  args = args || process.argv.slice(2);
  var listeners = this.listeners('error');
  if(!listeners.length) {
    this.on('error', function(e) {
      var key = (e.key || '').toLowerCase();
      if(this.listeners(key).length) return this.emit(key, e);
      this.error(e, errors);
    })
  }
  this._config = options || {};
  var config = configuration.call(this), handled;
  this._args = parser(args, config);
  this._args.config = config;
  this.args = this._args.unparsed;
  var opts = {};
  merge.call(this, this._args.flags, opts);
  merge.call(this, this._args.options, opts);
  handled = builtins.call(this);
  if(!handled) handled = required.call(this);
  if(!args.length) return empty.call(this);
  if(!handled) return command.call(this, opts);
}

module.exports = function(package, name, description, configuration) {
  var locales = path.join(__dirname, 'lib', 'error', 'locales');
  clierr.file({locales: locales}, function (err, file, errors, lang) {
    //console.dir(err);
    //console.log('loaded %s', file);
    //console.dir(errors);
  });
  var program = cli(package, name, description);
  program.configuration(configuration || config);
  var listeners = process.listeners('uncaughtException');
  if(!listeners.length) {
    process.on('uncaughtException', function(err) {
      console.error(err);
      raise.call(program, errors.EUNCAUGHT, [err.message], {error: err});
    })
  }
  program.parse = parse;
  clierr({name: program.name});
  return program;
}

module.exports.types = types;
<commit_msg>Move parse() to program prototype.<commit_after>var fs = require('fs');
var path = require('path'), dirname = path.dirname, basename = path.basename;
var spawn = require('child_process').spawn;
var cli = require('cli-define');
var Program = cli.Program;
var parser = require('cli-argparse');
var codes = require('./lib/codes');
var types = require('./lib/types');
var ArgumentTypeError = types.ArgumentTypeError;
var clierr = require('cli-error');
var ErrorDefinition = clierr.ErrorDefinition;
var CliError = clierr.CliError;
var errors = clierr.errors;
var config = {
  exit: true
}

var actions = {
  help: require('./lib/help'),
  version: require('./lib/version')
}

/**
 *  Retrieve the handler for a built in action.
 *
 *  @param key The argument key.
 */
function handler(key) {
  var fn = actions[key];
  if(this._arguments[key] && this._arguments[key]._action) {
    return this._arguments[key]._action;
  }
  return fn;
}

/**
 *  Retrieve a configuration suitable for passing to
 *  the arguments parser.
 */
function configuration() {
  var config = {alias: {}, flags: [], options: []}, k, arg, key, no = /^no/;
  for(k in this._arguments) {
    arg = this._arguments[k]; key = arg.key;
    if(key) {
      if(no.test(key)) {
        key = key.replace(no, '');
        key = key.charAt(0).toLowerCase() + key.slice(1);
      }
      config.alias[arg._names.join(' ')] = key;
    }
    if(arg instanceof cli.Flag) {
      config.flags = config.flags.concat(arg._names);
    }else if(arg instanceof cli.Option) {
      config.options = config.options.concat(arg._names);
    }
  }
  return config;
}

/**
 *  Retrievet the converter reference for an argument,
 *  respecting the type map.
 *
 *  @param arg The argument definition.
 *  @param func A specific function.
 */
function getConverter(arg, func) {
  var converter = func || arg._converter, name;
  if(Array.isArray(converter)) return converter;
  try {
    name = new converter().constructor.name;
  }catch(e){}
  if(name && types.map[name]) return types.map[name];
  if(arg._converter === JSON) return types.map.JSON;
  return converter;
}

function getConverterNames(arg) {
  var converter = arg._converter, names = [], i, name;
  for(i = 0;i < converter.length;i++) {
    try{
      name = new converter[i]().constructor.name;
      if(name) name = name.toLowerCase();
      names.push(name);
    }catch(e){}
  }
  return names;
}

/**
 *  Convert an arguments value.
 *
 *  @param value The parsed argument value.
 *  @param arg The argument definition.
 *  @param index The index into an array (multiple only).
 */
function convert(value, arg, index) {
  var converter = getConverter(arg), i, func;
  function error(e, message, parameters) {
    if(e instanceof ArgumentTypeError) {
      if(e.code == 1) e.code = errors.ETYPE.code;
      e.key = errors.ETYPE.key;
      raise.call(this, e)
    }else{
      // pass down as uncaught exception
      throw e;
    }
  }
  function invoke(converter, fast) {
    try {
      value = converter.call(this, value, arg, index);
    }catch(e) {
      if(!fast) throw e;
      error.call(this, e);
    }
    return value;
  }
  if(Array.isArray(converter)) {
    for(i = 0;i < converter.length;i++) {
      func = getConverter(arg, converter[i]);
      try {
        return invoke.call(this, func, false);
      }catch(e) {
        // NOTE: all coercion attempts failed
        if(i == (converter.length -1)) {
          error.call(this, e, 'invalid type for %s, expected (%s)',
            [arg.names.join(' | '), getConverterNames(arg).join(', ')]);
        }
      }
    }
  }else{
    invoke.call(this, converter, true);
  }
  return value;
}

/**
 *  Coerce an argument value using an assigned converter
 *  function.
 *
 *  @param arg The argument definition.
 *  @param v The value as specified on the command line.
 */
function coerce(arg, v) {
  var type = false, i;
  var converter = getConverter(arg);
  // NOTE: we check whether the converter is one of
  // NOTE: the built in converters as they are responsible
  // NOTE: for handling array values, other custom converters
  // NOTE: are invoked for each array entry if the argument
  // NOTE: value has already been converted to an array
  var keys = Object.keys(types);
  for(i = 0;i < keys.length;i++) {
    if(types[keys[i]] === converter) {
      type = true; break;
    }
  }
  if(typeof converter == 'function' || Array.isArray(converter)) {
    if(Array.isArray(v) && !type) {
      v.forEach(function(value, index, arr) {
        arr[index] = convert.call(this, value, arg, index);
      });
    }else{
      v = convert.call(this, v, arg);
    }
  }
  return v;
}

/**
 *  Merge parsed arguments into the program.
 *
 *  @param target The target object encapsulated by
 *  the argument parsing result object.
 *  @param options An object that will receive the arguments
 *  being merged.
 */
function merge(target, options) {
  var k, v, arg, re = /^no/;
  for(k in target) {
    arg = this._arguments[k];
    //console.log('%s %s', k, arg);
    if(arg) {
      v = target[k];
      if(arg.multiple && !Array.isArray(v)) {
        v = [v];
      }else if(!arg.multiple && Array.isArray(v)) {
        raise.call(this, errors.EMULTIPLE,
          [arg.names.join(' | '), v.join(', ')], {arg: arg, value: v});
      }
      v = coerce.call(this, arg, v);
      // TODO: validate at this point?
      this[k] = options[k] = arg.value = v;
    }
  }
}

/**
 *  Validate that required arguments are present.
 */
function required() {
  var z, arg;
  for(z in this._arguments) {
    arg = this._arguments[z];
    if(!arg.optional && !this._args.options[arg.key]) {
      raise.call(this, errors.EREQUIRED, [arg.names.join(' | ')], {arg: arg});
      return true;
    }
  }
  return false;
}

/**
 *  Execute builtin handlers for help and version.
 */
function builtins() {
  var i, action, fn, arr = Object.keys(actions);
  for(i = 0;i < arr.length;i++) {
    action = arr[i];
    if(this._args.flags[action]) {
      fn = handler.call(this, action);
      fn.call(this, actions[action]);
      return true;
    }
  }
  return false;
}

/**
 *  Raise an error from an error definition or error
 *  instance.
 *
 *  @param err The error definition.
 *  @param parameters The message replacement parameters.
 *  @param data Additional error data.
 */
function raise(err, parameters, data) {
  var e;
  if(err instanceof CliError) {
    e = err;
  }else if(err instanceof ErrorDefinition) {
    // TODO: do not include this method in the stack trace
    var e = err.toError();
    e.parameters = parameters || [];
    e.key = err.key;
    e.data = data;
    if(data && data.error) e.source = data.error;
  }
  // TODO: wrap normal errors in a CliError for consistency
  this.emit('error', e, errors);
}

/**
 *  Check file permissions.
 *
 *  canExecute():
 *  checkPermission (stat, 1);
 *
 *  canRead():
 *  checkPermission (stat, 4);
 *
 *  canWrite():
 *  checkPermission (stat, 2);
 */
function permissions(stat, mask) {
  return !!(mask &
    parseInt((stat.mode & parseInt("777", 8)).toString (8)[0]));
}

/**
 *  Execute a command as an external program.
 *
 *  @param argv The program arguments.
 *  @param cmd The command to execute.
 *  @param args Array of arguments to pass to the command.
 */
function execute(argv, cmd, args) {
  var scope = this;
  var dir = this._config.bin || dirname(argv[1]);
  var bin = this._name + '-' + cmd;
  var local = path.join(dir, bin);
  var exists = fs.existsSync(local);
  var data = {bin: bin, dir: dir, local: local, args: args};
  if(!exists) {
    return raise.call(this, errors.ENOENT, [bin], data);
  }
  var stat = fs.statSync(local);
  //var perms = stat.mode & 0777;
  //console.log('%s', perms);
  //console.log('%s', check(stat, 1));
  if(!permissions(stat, 1)) {
    return raise.call(this, errors.EPERM, [bin], data);
  }
  var ps = spawn(local, args, {stdio: 'inherit'});
  //ps.on('error', function(err){
    // NOTE: keep these tests just in case the above logic is wrong
    // NOTE: or quite likely fails on windows
    //if(err.code == 'ENOENT') {
      //raise.call(scope, codes.ENOENT, null, [bin, dir, local, args]);
    //}else if (err.code == 'EACCES') {
      //raise.call(scope, codes.EPERM, null, [bin, dir, local, args]);
    //}
  //});
  ps.on('close', function (code, signal) {
    // NOTE: workaround for https://github.com/joyent/node/issues/3222
    // NOTE: assume child process exited gracefully on SIGINT
    if(signal == 'SIGINT') {
      return process.exit(0);
    }
    scope.emit('close');
    process.exit(code);
  });
  return ps;
}

/**
 *  Searches the raw arguments looking for the first argument
 *  that matches a known command and either executes the command
 *  as an external program or invokes an action associated
 *  with the command.
 *
 *  @param options An object containing all flags and option values.
 */
function command(options) {
  var z, i, raw = this._args.raw.slice(0), action, cmd, arg, ind;
  for(i = 0;i < raw.length;i++) {
    cmd = raw[i]; arg = this._commands[cmd];
    if(arg) {
      raw.splice(i, 1);
      if(!arg._action) {
        return execute.call(this, process.argv, cmd, raw);
      }else if(arg._action) {
        ind = this.args.indexOf(cmd);
        if(~ind) this.args.splice(ind, 1);
        return arg._action.call(this, arg, options, raw);
      }
    }
  }
}

/**
 *  Emits the empty event.
 */
function empty() {
  // NOTE: this little dance allows custom help and version
  // NOTE: callbacks to invoke the original implementations
  // NOTE: from empty event listeners
  var help, version, _help, _version, scope = this;
  help = _help = handler.call(this, 'help');
  version = _version = handler.call(this, 'version');
  if(help != actions.help) {
    help = function() {
      _help.call(scope, actions.help);
    }
  }
  if(version != actions.version) {
    version = function() {
      _version.call(scope, actions.version);
    }
  }
  this.emit('empty', help, version);
}

/**
 *  Default error handler for the error event.
 *
 *  @param e The error instance.
 *  @param errors Map of error definitinons.
 */
Program.prototype.error = function(e, errors) {
  var key = (e.key || '').toLowerCase();
  var trace = key == 'euncaught' ? true : false;
  e.error(trace);
  if(this._configuration.exit) e.exit();
}

/**
 *  Assigns configuration information to the program.
 *
 *  @param config The program configuration.
 */
Program.prototype.configuration = function(config) {
  this._configuration = config;
  //console.dir(config);
  return this;
}

/**
 *  Parse the supplied arguments and execute any commands
 *  found in the arguments, preferring the built in commands
 *  for help and version.
 *
 *  @param args The arguments to parse, default is process.argv.slice(2).
 *  @param options Configuration options.
 */
Program.prototype.parse = function(args, options) {
  args = args || process.argv.slice(2);
  var listeners = this.listeners('error');
  if(!listeners.length) {
    this.on('error', function(e) {
      var key = (e.key || '').toLowerCase();
      if(this.listeners(key).length) return this.emit(key, e);
      this.error(e, errors);
    })
  }
  this._config = options || {};
  var config = configuration.call(this), handled;
  this._args = parser(args, config);
  this._args.config = config;
  this.args = this._args.unparsed;
  var opts = {};
  merge.call(this, this._args.flags, opts);
  merge.call(this, this._args.options, opts);
  handled = builtins.call(this);
  if(!handled) handled = required.call(this);
  if(!args.length) return empty.call(this);
  if(!handled) return command.call(this, opts);
}

module.exports = function(package, name, description, configuration) {
  var locales = path.join(__dirname, 'lib', 'error', 'locales');
  clierr.file({locales: locales}, function (err, file, errors, lang) {
    //console.dir(err);
    //console.log('loaded %s', file);
    //console.dir(errors);
  });
  var program = cli(package, name, description);
  program.configuration(configuration || config);
  var listeners = process.listeners('uncaughtException');
  if(!listeners.length) {
    process.on('uncaughtException', function(err) {
      console.error(err);
      raise.call(program, errors.EUNCAUGHT, [err.message], {error: err});
    })
  }
  //program.parse = parse;
  clierr({name: program.name});
  return program;
}

module.exports.types = types;
<|endoftext|>