<commit_before>var fs = require('fs');
var path = require('path');
var parseURL = require('url').parse;
var reduceFunctionCall = require('reduce-function-call');
var mkdirp = require('mkdirp');
var postcss = require('postcss');
var chalk = require('chalk');

var rebasedAssets = new Array();

module.exports = postcss.plugin('postcss-assets-rebase', function(options) {

	return function(css, postcssOptions) {
		var to = postcssOptions.opts.to ? path.dirname(postcssOptions.opts.to) : '.';

		if (options && options.assetsPath) {
			css.eachDecl(function(decl) {
				if (decl.value && decl.value.indexOf('url(') > -1) {
					processDecl(decl, to, options);
				}
			})
		} else {
			console.warn(chalk.red('postcss-assets-rebase: No assets path provided, aborting'));
		}
	}
});

function processDecl(decl, to, options) {

	var dirname = (decl.source && decl.source.input) ? path.dirname(decl.source.input.file) : process.cwd();

	decl.value = reduceFunctionCall(decl.value, 'url', function(value) {
		var url = getUrl(value),
			processedUrl;

		if (isLocalImg(url)) {
			processedUrl = processUrlRebase(dirname, url, to, options);
		} else {
			processedUrl = composeUrl(url);
		}

		return processedUrl;
	});
}

function getUrl(url) {
	return url.match(/(['"]?)(.+)\1/)[2];
}

function normalizeUrl(url) {
	return (path.sep === '\\') ? url.replace(/\\/g, '\/') : url;
}

function composeUrl(url) {
	return 'url(' + normalizeUrl(url) + ')';
}

// checks if file is not local
function isLocalImg(url) {
	var notLocal = url.indexOf('data:') === 0 ||
		url.indexOf('#') === 0 ||
		/^[a-z]+:\/\//.test(url);

	return !notLocal;
}

//copy asset and place it to assets folder
function copyAsset(assetPath, contents) {
	mkdirp.sync(path.dirname(assetPath));
	if (!fs.existsSync(assetPath)) {
		fs.writeFileSync(assetPath, contents);
	}
}

function composeDuplicatedPath(assetPath, index) {
	var extname = path.extname(assetPath);
	var fileName = path.basename(assetPath, extname);
	var dirname = path.dirname(assetPath);

	return path.join(dirname, fileName + '_' + index + extname);
}

//get asset content
function getAsset(filePath) {
	if (fs.existsSync(filePath)) {
		return fs.readFileSync(filePath);
	} else {
		console.warn(chalk.yellow('postcss-assets-rebase: Can\'t read file \'' + filePath + '\', ignoring'));
	}

}

function getPostfix(url) {
	var parsedURL = parseURL(url);
	var postfix = '';

	if (parsedURL.search) {
		postfix += parsedURL.search;
	}

	if (parsedURL.hash) {
		postfix += parsedURL.hash;
	}

	return postfix;
}

function getClearUrl(url) {
	return parseURL(url).pathname;
}
//compare already rebased asset name with provided and get duplication index
function compareFileNames(rebasedPath, filePath) {
	var rebasedExtName = path.extname(rebasedPath);
	var fileExtName = path.extname(filePath);
	var rebasedBaseName = path.basename(rebasedPath, rebasedExtName);
	var fileBaseName = path.basename(filePath, fileExtName);

	var reg = new RegExp('^' + fileBaseName + '_(\\d+)$');
	var executed = reg.exec(rebasedBaseName);
	var index;

	if (rebasedBaseName === fileBaseName && rebasedExtName === fileExtName) {
		index = 1;
	} else {
		index = executed ? (parseFloat(executed[1]) + 1) : 0;
	}

	return index;
}

function getAlreadyRebasedPath(filePath) {
	for (var i = 0; i < rebasedAssets.length; i++) {
		if (rebasedAssets[i].filePath === filePath) {
			return {
				absolute: rebasedAssets[i].absoluteAssetsPath,
				relative: rebasedAssets[i].relativeAssetsPath
			};
		}
	}
}

function getDuplicationIndex(filePath) {
	var index = 0;
	rebasedAssets.forEach(function(rebasedAsset) {
		var newIndex = compareFileNames(rebasedAsset.relativeAssetsPath, filePath);
		index = (newIndex > index) ? newIndex : index;
	});
	return index;
}

function processAssetPaths(filePath, absoluteAssetsPath, relativeAssetsPath) {
	var alreadyRebasedPath = getAlreadyRebasedPath(filePath);

	if (!!alreadyRebasedPath) {
		absoluteAssetsPath = alreadyRebasedPath.absolute;
		relativeAssetsPath = alreadyRebasedPath.relative;
	} else {
		var duplicationIndex = getDuplicationIndex(absoluteAssetsPath);
		if (duplicationIndex) {
			relativeAssetsPath = composeDuplicatedPath(relativeAssetsPath, duplicationIndex);
			absoluteAssetsPath = composeDuplicatedPath(absoluteAssetsPath, duplicationIndex);
			console.warn(chalk.yellow('postcss-assets-rebase: duplicated path \'' + filePath + '\' renamed to: ' +
				relativeAssetsPath));
		}
	}

	rebasedAssets.push({
		filePath: filePath,
		absoluteAssetsPath: absoluteAssetsPath,
		relativeAssetsPath: relativeAssetsPath
	});

	return {
		relative: relativeAssetsPath,
		absolute: absoluteAssetsPath
	};
}
function processUrlRebase(dirname, url, to, options) {

	var relativeAssetsPath = '';
	var absoluteAssetsPath = '.';

	var postfix = getPostfix(url);
	var clearUrl = getClearUrl(url);

	var filePath = path.resolve(dirname, clearUrl);
	var fileName = path.basename(clearUrl);

	var assetContents = getAsset(filePath);

	if (!assetContents) {
		return composeUrl(url);
	}

	if (options.relative) {
		absoluteAssetsPath = path.resolve(to, options.assetsPath);
		relativeAssetsPath = options.assetsPath;
	} else {
		absoluteAssetsPath = path.resolve(options.assetsPath);
		relativeAssetsPath = path.relative(to, absoluteAssetsPath);
	}

	absoluteAssetsPath = path.join(absoluteAssetsPath, fileName);
	relativeAssetsPath = path.join(relativeAssetsPath, fileName);

	if (options.renameDuplicates) {
		var processedPaths = processAssetPaths(filePath, absoluteAssetsPath, relativeAssetsPath);
		relativeAssetsPath = processedPaths.relative;
		absoluteAssetsPath = processedPaths.absolute;
	}

	copyAsset(absoluteAssetsPath, assetContents);

	if (postfix) {
		relativeAssetsPath += postfix;
	}
	return composeUrl(relativeAssetsPath);
}
<commit_msg>Rename some variables<commit_after>var fs = require('fs');
var path = require('path');
var parseURL = require('url').parse;
var reduceFunctionCall = require('reduce-function-call');
var mkdirp = require('mkdirp');
var postcss = require('postcss');
var chalk = require('chalk');

var rebasedAssets = new Array();

module.exports = postcss.plugin('postcss-assets-rebase', function(options) {

	return function(css, postcssOptions) {
		var to = postcssOptions.opts.to ? path.dirname(postcssOptions.opts.to) : '.';

		if (options && options.assetsPath) {
			css.eachDecl(function(decl) {
				if (decl.value && decl.value.indexOf('url(') > -1) {
					processDecl(decl, to, options);
				}
			})
		} else {
			console.warn(chalk.red('postcss-assets-rebase: No assets path provided, aborting'));
		}
	}
});

function processDecl(decl, to, options) {

	var dirname = (decl.source && decl.source.input) ? path.dirname(decl.source.input.file) : process.cwd();

	decl.value = reduceFunctionCall(decl.value, 'url', function(value) {
		var url = getUrl(value),
			processedUrl;

		if (isLocalImg(url)) {
			processedUrl = processUrlRebase(dirname, url, to, options);
		} else {
			processedUrl = composeUrl(url);
		}

		return processedUrl;
	});
}

function getUrl(url) {
	return url.match(/(['"]?)(.+)\1/)[2];
}

function normalizeUrl(url) {
	return (path.sep === '\\') ? url.replace(/\\/g, '\/') : url;
}

function composeUrl(url) {
	return 'url(' + normalizeUrl(url) + ')';
}

// checks if file is not local
function isLocalImg(url) {
	var notLocal = url.indexOf('data:') === 0 ||
		url.indexOf('#') === 0 ||
		/^[a-z]+:\/\//.test(url);

	return !notLocal;
}

//copy asset and place it to assets folder
function copyAsset(assetPath, contents) {
	mkdirp.sync(path.dirname(assetPath));
	if (!fs.existsSync(assetPath)) {
		fs.writeFileSync(assetPath, contents);
	}
}

function composeDuplicatedPath(assetPath, index) {
	var extname = path.extname(assetPath);
	var fileName = path.basename(assetPath, extname);
	var dirname = path.dirname(assetPath);

	return path.join(dirname, fileName + '_' + index + extname);
}

//get asset content
function getAsset(filePath) {
	if (fs.existsSync(filePath)) {
		return fs.readFileSync(filePath);
	} else {
		console.warn(chalk.yellow('postcss-assets-rebase: Can\'t read file \'' + filePath + '\', ignoring'));
	}

}

function getPostfix(url) {
	var parsedURL = parseURL(url);
	var postfix = '';

	if (parsedURL.search) {
		postfix += parsedURL.search;
	}

	if (parsedURL.hash) {
		postfix += parsedURL.hash;
	}

	return postfix;
}

function getClearUrl(url) {
	return parseURL(url).pathname;
}
//compare already rebased asset name with provided and get duplication index
function compareFileNames(rebasedPath, filePath) {
	var rebasedExtName = path.extname(rebasedPath);
	var fileExtName = path.extname(filePath);
	var rebasedBaseName = path.basename(rebasedPath, rebasedExtName);
	var fileBaseName = path.basename(filePath, fileExtName);

	var reg = new RegExp('^' + fileBaseName + '_(\\d+)$');
	var executed = reg.exec(rebasedBaseName);
	var index;

	if (rebasedBaseName === fileBaseName && rebasedExtName === fileExtName) {
		index = 1;
	} else {
		index = executed ? (parseFloat(executed[1]) + 1) : 0;
	}

	return index;
}

function getAlreadyRebasedPath(filePath) {
	for (var i = 0; i < rebasedAssets.length; i++) {
		if (rebasedAssets[i].filePath === filePath) {
			return {
				absolute: rebasedAssets[i].absolute,
				relative: rebasedAssets[i].relative
			};
		}
	}
}

function getDuplicationIndex(filePath) {
	var index = 0;
	rebasedAssets.forEach(function(rebasedAsset) {
		var newIndex = compareFileNames(rebasedAsset.relative, filePath);
		index = (newIndex > index) ? newIndex : index;
	});
	return index;
}

function processAssetPaths(filePath, absoluteAssetPath, relativeAssetPath) {
	var alreadyRebasedPath = getAlreadyRebasedPath(filePath);

	if (!!alreadyRebasedPath) {
		absoluteAssetPath = alreadyRebasedPath.absolute;
		relativeAssetPath = alreadyRebasedPath.relative;
	} else {
		var duplicationIndex = getDuplicationIndex(absoluteAssetPath);
		if (duplicationIndex) {
			relativeAssetPath = composeDuplicatedPath(relativeAssetPath, duplicationIndex);
			absoluteAssetPath = composeDuplicatedPath(absoluteAssetPath, duplicationIndex);
			console.warn(chalk.yellow('postcss-assets-rebase: duplicated path \'' + filePath + '\' renamed to: ' +
				relativeAssetPath));
		}
	}

	rebasedAssets.push({
		filePath: filePath,
		absolute: absoluteAssetPath,
		relative: relativeAssetPath
	});

	return {
		relative: relativeAssetPath,
		absolute: absoluteAssetPath
	};
}
function processUrlRebase(dirname, url, to, options) {

	var relativeAssetPath = '';
	var absoluteAssetPath = '.';

	var postfix = getPostfix(url);
	var clearUrl = getClearUrl(url);

	var filePath = path.resolve(dirname, clearUrl);
	var fileName = path.basename(clearUrl);

	var assetContents = getAsset(filePath);

	if (!assetContents) {
		return composeUrl(url);
	}

	if (options.relative) {
		absoluteAssetPath = path.resolve(to, options.assetsPath);
		relativeAssetPath = options.assetsPath;
	} else {
		absoluteAssetPath = path.resolve(options.assetsPath);
		relativeAssetPath = path.relative(to, absoluteAssetPath);
	}

	absoluteAssetPath = path.join(absoluteAssetPath, fileName);
	relativeAssetPath = path.join(relativeAssetPath, fileName);

	if (options.renameDuplicates) {
		var processedPaths = processAssetPaths(filePath, absoluteAssetPath, relativeAssetPath);
		relativeAssetPath = processedPaths.relative;
		absoluteAssetPath = processedPaths.absolute;
	}

	copyAsset(absoluteAssetPath, assetContents);

	if (postfix) {
		relativeAssetPath += postfix;
	}

	return composeUrl(relativeAssetPath);
}
<|endoftext|>


<commit_before>module.exports = {
  '.react-tabs [role=tablist]': {
    'border-bottom': '1px solid #aaa',
    'margin': '0 0 10px',
    'padding': '0'
  },

  '.react-tabs [role=tab]': {
    'display': 'inline-block',
    'border': '1px solid transparent',
    'border-bottom': 'none',
    'bottom': '-1px',
    'position': 'relative',
    'list-style': 'none',
    'padding': '6px 12px',
    'cursor': 'pointer',
    'position': 'relative'
  },

  '.react-tabs [role=tab][aria-selected=true]': {
    'background': '#fff',
    'border-color': '#aaa',
    'border-radius': '5px 5px 0 0',
    '-moz-border-radius': '5px 5px 0 0',
    '-webkit-border-radius': '5px 5px 0 0'
  },

  '.react-tabs [role=tab]:focus': {
    'box-shadow': '0 0 5px hsl(208, 99%, 50%)',
    'border-color': 'hsl(208, 99%, 50%)',
    'outline': 'none'
  },

  '.react-tabs [role=tab]:focus:after': {
    'content': '""',
    'position': 'absolute',
    'height': '5px',
    'left': '-4px',
    'right': '-4px',
    'bottom': '-5px',
    'background': '#fff'
  }
};
<commit_msg>remove duplicate object property from styles hash<commit_after>module.exports = {
  '.react-tabs [role=tablist]': {
    'border-bottom': '1px solid #aaa',
    'margin': '0 0 10px',
    'padding': '0'
  },

  '.react-tabs [role=tab]': {
    'display': 'inline-block',
    'border': '1px solid transparent',
    'border-bottom': 'none',
    'bottom': '-1px',
    'position': 'relative',
    'list-style': 'none',
    'padding': '6px 12px',
    'cursor': 'pointer',
  },

  '.react-tabs [role=tab][aria-selected=true]': {
    'background': '#fff',
    'border-color': '#aaa',
    'border-radius': '5px 5px 0 0',
    '-moz-border-radius': '5px 5px 0 0',
    '-webkit-border-radius': '5px 5px 0 0'
  },

  '.react-tabs [role=tab]:focus': {
    'box-shadow': '0 0 5px hsl(208, 99%, 50%)',
    'border-color': 'hsl(208, 99%, 50%)',
    'outline': 'none'
  },

  '.react-tabs [role=tab]:focus:after': {
    'content': '""',
    'position': 'absolute',
    'height': '5px',
    'left': '-4px',
    'right': '-4px',
    'bottom': '-5px',
    'background': '#fff'
  }
};
<|endoftext|>


<commit_before>/*!
 * assemble-streams <https://github.com/jonschlinkert/assemble-streams>
 *
 * Copyright (c) 2015, Jon Schlinkert.
 * Licensed under the MIT License.
 */

'use strict';

module.exports = function(options) {
  var handle = require('assemble-handle');
  var through = require('through2');
  var src = require('src-stream');

  return function fn(app) {
    if (this.isRegistered('streams')) return;

    /**
     * Push a view collection into a vinyl stream.
     *
     * ```js
     * app.toStream('posts', function(file) {
     *   return file.path !== 'index.hbs';
     * })
     * ```
     * @name .toStream
     * @param {String} `collection` Name of the collection to push into the stream.
     * @param {Function} Optionally pass a filter function to use for filtering views.
     * @return {Stream}
     * @api public
     */

    app.mixin('toStream', function (name, filterFn) {
      var stream = through.obj();
      stream.setMaxListeners(0);

      if (typeof name === 'undefined' && !this.isCollection) {
        process.nextTick(stream.end.bind(stream));
        return src(stream);
      }

      var views;
      if (this.isApp && name) {
        views = this.getViews(name);
      } else {
        views = this.views;
      }

      setImmediate(function () {
        for (var key in views) {
          if (!filter(key, views[key], filterFn)) {
            continue;
          }
          stream.write(views[key]);
        }
        stream.end();
      });

      return src(stream).pipe(handle(this, 'onStream'));
    });

    if (app.isApp) {
      return fn;
    }
  };
};

function filter(key, view, fn) {
  if (typeof fn === 'function') {
    return fn(key, view);
  }
  return true;
}
<commit_msg>passing entire stream created after piping to `handle` to `src-stream` to ensure any files piped into `.toStream` are passed through correctly.<commit_after>/*!
 * assemble-streams <https://github.com/jonschlinkert/assemble-streams>
 *
 * Copyright (c) 2015, Jon Schlinkert.
 * Licensed under the MIT License.
 */

'use strict';

module.exports = function(options) {
  var handle = require('assemble-handle');
  var through = require('through2');
  var src = require('src-stream');

  return function fn(app) {
    if (this.isRegistered('streams')) return;

    /**
     * Push a view collection into a vinyl stream.
     *
     * ```js
     * app.toStream('posts', function(file) {
     *   return file.path !== 'index.hbs';
     * })
     * ```
     * @name .toStream
     * @param {String} `collection` Name of the collection to push into the stream.
     * @param {Function} Optionally pass a filter function to use for filtering views.
     * @return {Stream}
     * @api public
     */

    app.mixin('toStream', function (name, filterFn) {
      var stream = through.obj();
      stream.setMaxListeners(0);

      if (typeof name === 'undefined' && !this.isCollection) {
        process.nextTick(stream.end.bind(stream));
        return src(stream);
      }

      var views;
      if (this.isApp && name) {
        views = this.getViews(name);
      } else {
        views = this.views;
      }

      setImmediate(function () {
        for (var key in views) {
          if (!filter(key, views[key], filterFn)) {
            continue;
          }
          stream.write(views[key]);
        }
        stream.end();
      });

      return src(stream.pipe(handle(this, 'onStream')));
    });

    if (app.isApp) {
      return fn;
    }
  };
};

function filter(key, view, fn) {
  if (typeof fn === 'function') {
    return fn(key, view);
  }
  return true;
}
<|endoftext|>


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

require('dotenv').config({ path: `${ process.env.PWD }/.env` })

const standardChangelog = require('standard-changelog')
    , conventionalGithubReleaser = require('conventional-github-releaser')
    , bump = require('bump-regex')
    , inquirer = require('inquirer')
    , fs = require('fs')
    , q = require('q')
    , exec = require('child_process').exec
    , concatStream = require('concat-stream')

const PACKAGE_PATH = `${ process.env.PWD }/package.json`
    , CHANGELOG_PATH = `${ process.env.PWD }/CHANGELOG.md`
    , RC_PREID = 'rc'

const VERSION = require(PACKAGE_PATH).version

function get_all_versions() {
    const opts = {
        str: fs.readFileSync(PACKAGE_PATH).toString()
    }
    return q.all([
        q.nfcall(bump, Object.assign({ type: 'prerelease', preid: RC_PREID }, opts)),
        q.nfcall(bump, Object.assign({ type: 'patch' }, opts)),
        q.nfcall(bump, Object.assign({ type: 'minor' }, opts)),
        q.nfcall(bump, Object.assign({ type: 'major'}, opts))
    ])
    .spread((rc, patch, minor, major) => {
        return { rc, patch, minor, major }
    })
}

function prompt(versions) {
    return inquirer.prompt([
        {
            name: "version",
            type: "list",
            choices: [{
                name: `release-candidate (${ versions.rc.new })`,
                value: versions.rc
            }, {
                name: `patch (${ versions.patch.new })`,
                value: versions.patch
            }, {
                name: `minor (${ versions.minor.new })`,
                value: versions.minor
            }, {
                name: `major (${ versions.major.new })`,
                value: versions.major
            }, {
                name: `cancel`,
                value: null
            }],
            default: versions.patch,
            message: "What kind of release is it?"
        }
    ])
    .then(({ version }) => {
        if (!version) process.exit(0)
        return version
    })
}

function bump_version(version) {
    return q.nfcall(fs.writeFile, PACKAGE_PATH, version.str)
    .then(() => version)
}

function changelog(version) {
    if (version.preid === RC_PREID) return version
    let defer = q.defer()
    standardChangelog.createIfMissing(CHANGELOG_PATH)
    let file = fs.readFileSync(CHANGELOG_PATH)
    standardChangelog()
        .pipe(concatStream({ encoding: 'buffer'}, (data) => {
            fs.writeFileSync(CHANGELOG_PATH, Buffer.concat([data, file]))
            defer.resolve(version)
        }))

    return defer.promise
}

function git_commit(version) {
    let defer = q.defer()
    exec([
        'git add package.json CHANGELOG.md',
        `git commit -a -m "chore(release): v${ version.new }"`
    ].join(' && '), (err) => {
        if (err) return defer.reject(err)
        defer.resolve(version)
    })
    return defer.promise
}

function git_push(version) {
    let defer = q.defer()
    exec('git push', (err) => {
        if (err) return defer.reject(err)
        defer.resolve(version)
    })
    return defer.promise
}

function git_tag(version) {
    if (version.preid === RC_PREID) return version
    let defer = q.defer()
    exec([
        `git tag ${ version.new }`,
        'git push --tags'
    ].join(' && '), (err) => {
        if (err) return defer.reject(err)
        defer.resolve(version)
    })
    return defer.promise
}

function github_release(version) {
    if (version.preid === RC_PREID) return version
    if (!process.env.GITHUB_OAUTH_TOKEN) {
        console.log('Cannot run conventionalGithubReleaser. You must add a .env file with a GITHUB_OAUTH_TOKEN key')
        return version
    }
    const GITHUB_AUTH = {
        type: 'oauth',
        token: process.env.GITHUB_OAUTH_TOKEN
    }
    return q.nfcall(conventionalGithubReleaser, GITHUB_AUTH, { preset: 'angular' })
}

function notify(msg, optional) {
    return (version) => {
        if (optional && version.preid === RC_PREID) return version
        console.log(msg.replace('$$version', version.new))
        return version
    }
}

get_all_versions()
.then(prompt)
.then(notify('- Update package.json with version: $$version'))
.then(bump_version)
.then(notify('- Update changelog', true))
.then(changelog)
.then(notify('- git commit'))
.then(git_commit)
.then(notify('- git push'))
.then(git_push)
.then(notify('- git tag', true))
.then(git_tag)
.then(notify('- Github release', true))
.then(github_release)
.catch((err) => console.log(err))
<commit_msg>fix: Fetch tags before create new one<commit_after>#! /usr/bin/env node

require('dotenv').config({ path: `${ process.env.PWD }/.env` })

const standardChangelog = require('standard-changelog')
    , conventionalGithubReleaser = require('conventional-github-releaser')
    , bump = require('bump-regex')
    , inquirer = require('inquirer')
    , fs = require('fs')
    , q = require('q')
    , exec = require('child_process').exec
    , concatStream = require('concat-stream')

const PACKAGE_PATH = `${ process.env.PWD }/package.json`
    , CHANGELOG_PATH = `${ process.env.PWD }/CHANGELOG.md`
    , RC_PREID = 'rc'

const VERSION = require(PACKAGE_PATH).version

function get_all_versions() {
    const opts = {
        str: fs.readFileSync(PACKAGE_PATH).toString()
    }
    return q.all([
        q.nfcall(bump, Object.assign({ type: 'prerelease', preid: RC_PREID }, opts)),
        q.nfcall(bump, Object.assign({ type: 'patch' }, opts)),
        q.nfcall(bump, Object.assign({ type: 'minor' }, opts)),
        q.nfcall(bump, Object.assign({ type: 'major'}, opts))
    ])
    .spread((rc, patch, minor, major) => {
        return { rc, patch, minor, major }
    })
}

function prompt(versions) {
    return inquirer.prompt([
        {
            name: "version",
            type: "list",
            choices: [{
                name: `release-candidate (${ versions.rc.new })`,
                value: versions.rc
            }, {
                name: `patch (${ versions.patch.new })`,
                value: versions.patch
            }, {
                name: `minor (${ versions.minor.new })`,
                value: versions.minor
            }, {
                name: `major (${ versions.major.new })`,
                value: versions.major
            }, {
                name: `cancel`,
                value: null
            }],
            default: versions.patch,
            message: "What kind of release is it?"
        }
    ])
    .then(({ version }) => {
        if (!version) process.exit(0)
        return version
    })
}

function bump_version(version) {
    return q.nfcall(fs.writeFile, PACKAGE_PATH, version.str)
    .then(() => version)
}

function changelog(version) {
    if (version.preid === RC_PREID) return version
    let defer = q.defer()
    standardChangelog.createIfMissing(CHANGELOG_PATH)
    let file = fs.readFileSync(CHANGELOG_PATH)
    standardChangelog()
        .pipe(concatStream({ encoding: 'buffer'}, (data) => {
            fs.writeFileSync(CHANGELOG_PATH, Buffer.concat([data, file]))
            defer.resolve(version)
        }))

    return defer.promise
}

function git_commit(version) {
    let defer = q.defer()
    exec([
        'git add package.json CHANGELOG.md',
        `git commit -a -m "chore(release): v${ version.new }"`
    ].join(' && '), (err) => {
        if (err) return defer.reject(err)
        defer.resolve(version)
    })
    return defer.promise
}

function git_push(version) {
    let defer = q.defer()
    exec('git push', (err) => {
        if (err) return defer.reject(err)
        defer.resolve(version)
    })
    return defer.promise
}

function git_tag(version) {
    if (version.preid === RC_PREID) return version
    let defer = q.defer()
    exec([
        'git fetch --tags',
        `git tag ${ version.new }`,
        'git push --tags'
    ].join(' && '), (err) => {
        if (err) return defer.reject(err)
        defer.resolve(version)
    })
    return defer.promise
}

function github_release(version) {
    if (version.preid === RC_PREID) return version
    if (!process.env.GITHUB_OAUTH_TOKEN) {
        console.log('Cannot run conventionalGithubReleaser. You must add a .env file with a GITHUB_OAUTH_TOKEN key')
        return version
    }
    const GITHUB_AUTH = {
        type: 'oauth',
        token: process.env.GITHUB_OAUTH_TOKEN
    }
    return q.nfcall(conventionalGithubReleaser, GITHUB_AUTH, { preset: 'angular' })
}

function notify(msg, optional) {
    return (version) => {
        if (optional && version.preid === RC_PREID) return version
        console.log(msg.replace('$$version', version.new))
        return version
    }
}

get_all_versions()
.then(prompt)
.then(notify('- Update package.json with version: $$version'))
.then(bump_version)
.then(notify('- Update changelog', true))
.then(changelog)
.then(notify('- git commit'))
.then(git_commit)
.then(notify('- git push'))
.then(git_push)
.then(notify('- git tag', true))
.then(git_tag)
.then(notify('- Github release', true))
.then(github_release)
.catch((err) => console.log(err))
<|endoftext|>


<commit_before>var exec = require('child_process').execSync;

module.exports = {
  blocks: {
    run: {
      process: function(block) {
        console.log("Encountered run", block);
        // console.log("++++++++++++++++++++++++");
        // console.log("here is the block", block);
        // console.log("++++++++++++++++++++++++");
        var regexToExtractRunnable = /(?:\`{2,})(bash)(?:\s+)([^]*?)(?:\s+)(?:\`{2,})/g;
        var runnable = regexToExtractRunnable.exec(block.body);
        var language = runnable[1];
        var body = runnable[2];
        if (language === "bash") {
          exec(body);
        } else {
          throw "Currently unable to handle language '" + language + "'";
        }
        return block.body;
      }
    },
    // hide: {
    //   process: function(block) {
    //     console.log("hiding", block);
    //     return "";
    //   }
    // },
    patch: {
      process: function(block) {
        console.log("Encountered patch", block);
        return block.body;
      }
    }
  },
  hooks: {
    init: function(page) {
      console.log("HOOKS: init");
      return page;
    },
    finish: function(page) {
      console.log("HOOKS: finish");
      return page;
    },
    "finish:before": function(page) {
      console.log("HOOKS: finish:before");
      return page;
    },
    // Deprecated:
    page: function(page) {
      console.log("HOOKS: page");
      return page;
    },
    // Deprecated:
    "page:before": function(page) {
      console.log("HOOKS: page:before");
      return page;
    }
    // "page:before": function(page) {
    //   console.log("-------------------------");
    //   console.log("page in markrundown plugin is:", page);
    //   console.log("page.type in markrundown plugin is:", page.type);
    //   console.log("page.sections in markrundown plugin is:", page.sections);
    //   console.log("-------------------------");
    //   return page;
    // }
  }
}<commit_msg>begin work on applying patch with 'git apply' via stdin<commit_after>var exec = require('child_process').execSync;

module.exports = {
  blocks: {
    run: {
      process: function(block) {
        // console.log("Encountered run", block, this);
        // console.log("++++++++++++++++++++++++");
        // console.log("here is the block", block);
        // console.log("++++++++++++++++++++++++");
        var regexToExtractRunnable = /(?:\`{2,})(bash)(?:\s+)([^]*?)(?:\s+)(?:\`{2,})/g;
        var runnable = regexToExtractRunnable.exec(block.body);
        var language = runnable[1];
        var body = runnable[2];
        if (language === "bash") {
          exec(body);
        } else {
          throw "Currently unable to handle language '" + language + "'";
        }
        return block.body;
      }
    },
    // hide: {
    //   process: function(block) {
    //     console.log("hiding", block);
    //     return "";
    //   }
    // },
    patch: {
      process: function(block) {
        var regexToExtractPatch = /(?:\`{2,})(?:\s+)([^]*?)(?:\s+)(?:\`{2,})/g;
        var patch = regexToExtractPatch.exec(block.body)[1];

        function stripEscapedChars(patch) {
          var stripped = patch.replace(/\\-/g, '-').replace(/\\[+]/g, '+');
          return stripped;
        }

        patch = stripEscapedChars(patch);

        var gitApplyCmd = "git apply --directory=build/hello-world - <<< '\n" + patch + "'\n";
        exec(gitApplyCmd);
        return block.body;
      }
    }
  },
  hooks: {
    init: function(page) {
      console.log("HOOKS: init");
      return page;
    },
    finish: function(page) {
      console.log("HOOKS: finish");
      return page;
    },
    "finish:before": function(page) {
      console.log("HOOKS: finish:before");
      return page;
    },
    // Deprecated:
    page: function(page) {
      console.log("HOOKS: page");
      return page;
    },
    // Deprecated:
    "page:before": function(page) {
      console.log("HOOKS: page:before");
      return page;
    }
    // "page:before": function(page) {
    //   console.log("-------------------------");
    //   console.log("page in markrundown plugin is:", page);
    //   console.log("page.type in markrundown plugin is:", page.type);
    //   console.log("page.sections in markrundown plugin is:", page.sections);
    //   console.log("-------------------------");
    //   return page;
    // }
  }
}<|endoftext|>


<commit_before>/**
 * Created by gaurav on 17/5/16.
 */

/**
 * A simple storage engine
 * */
function CloudinaryStorage (opts) {
  if(opts && opts.cloudinary){
    this.cloudinary = opts.cloudinary;
  }else{
    throw new Error('Expected opts.cloudinary to be a configured cloudinary object.');
  }
  var paramTemplate = {
    remove: null,
    upload: null
  }
  switch (typeof opts.params) {
    case 'function': this.getParams = opts.params; break;
    case 'undefined': this.getParams = function () {return paramTemplate;};break;
    default: throw new TypeError('Expected opts.key to be undefined or function')
  }
}

CloudinaryStorage.prototype._handleFile = function _handleFile (req, file, cb) {
  var cloudinaryStream = this.cloudinary.uploader.upload_stream(function(result) {
      if(!result || result.error){
        return cb(result.error.message);
      }
      cb(null, result)
    } , this.getParams().upload);
  file.stream.pipe(cloudinaryStream);
};

CloudinaryStorage.prototype._removeFile = function _removeFile (req, file, cb) {

  this.cloudinary.v2.uploader.destroy(file.public_id, this.getParams().remove, function (err, result) {
    if(err){
      return cb(err);
    }
    return cb(result);
  });
}

module.exports = function (opts) {
  opts = opts || {};
  if(!opts.cloudinary){
    throw new Error('Cloudinary object should be passed');
  }
  return new CloudinaryStorage(opts)
};
<commit_msg>make it backwards compatible<commit_after>/**
 * Created by gaurav on 17/5/16.
 */

/**
 * A simple storage engine
 * */
function CloudinaryStorage (opts) {
  if(opts && opts.cloudinary){
    // Checking to see if opts.cloudinary.cloudinary is present for backwards compatibility
    // even though opts.cloudinary is the correct way to pass.
    this.cloudinary = opts.cloudinary.cloudinary ? opts.cloudinary.cloudinary : opts.cloudinary;
  }else{
    throw new Error('Expected opts.cloudinary to be a configured cloudinary object.');
  }
  var paramTemplate = {
    remove: null,
    upload: null
  }
  switch (typeof opts.params) {
    case 'function': this.getParams = opts.params; break;
    case 'undefined': this.getParams = function () {return paramTemplate;};break;
    default: throw new TypeError('Expected opts.key to be undefined or function')
  }
}

CloudinaryStorage.prototype._handleFile = function _handleFile (req, file, cb) {
  var cloudinaryStream = this.cloudinary.uploader.upload_stream(function(result) {
      if(!result || result.error){
        return cb(result.error.message);
      }
      cb(null, result)
    } , this.getParams().upload);
  file.stream.pipe(cloudinaryStream);
};

CloudinaryStorage.prototype._removeFile = function _removeFile (req, file, cb) {

  this.cloudinary.v2.uploader.destroy(file.public_id, this.getParams().remove, function (err, result) {
    if(err){
      return cb(err);
    }
    return cb(result);
  });
}

module.exports = function (opts) {
  opts = opts || {};
  if(!opts.cloudinary){
    throw new Error('Cloudinary object should be passed');
  }
  return new CloudinaryStorage(opts)
};
<|endoftext|>


<commit_before>var config = require('histograph-config');
var schemas = require('histograph-schemas');
var fuzzyDates = require('fuzzy-dates');
var Graphmalizer = require('graphmalizer-core');
var H = require('highland');
var Redis = require('redis');
var redisClient = Redis.createClient(config.redis.port, config.redis.host);

// Convert any ID, URI, URN to Histograph URN
var normalize = require('histograph-uri-normalizer').normalize;

var elasticsearch = require('elasticsearch');
var esClient = new elasticsearch.Client({
  host: config.elasticsearch.host + ':' + config.elasticsearch.port
});

// Create a stream from Redis queue
var redis = H(function redisGenerator(push, next) {

  // Function called on each Redis message (or timeout)
  function redisCallback(err, data) {
    // handle error
    if (err) {
      push(err);
      next();
      return;
    }

    // attempt parse or error
    try {
      var d = JSON.parse(data[1]);
      push(null, d);
      next();
    }
    catch (e) {
      push(e);
      next();
    }
  }

  // blocking pull from Redis
  redisClient.blpop(config.redis.queue, 0, redisCallback);
});

var ACTION_MAP = {
  add: 'add',
  update: 'add',
  delete: 'remove'
};

function toGraphmalizer(msg) {
  function norm(x) {
    if (x) {
      return normalize(x, msg.dataset);
    }

    return undefined;
  }

  var d = msg.data || {};

  // dataset is a top-level attribute that we want copied into the 'data' attribute
  d.dataset = msg.dataset;

  return {
    operation: ACTION_MAP[msg.action],

    dataset: d.dataset,

    // some old data uses `label` instead of `type`
    type: d.type,

    // nodes are identified with id's or URI's, we don't care
    id: norm(d.id || d.uri),

    // formalize source/target id's
    source: norm(d.from),
    target: norm(d.to),

    data: stringifyObjectFields(d)
  };
}

// when passed an object, every field that contains an object
// is converted into a JSON-string (*mutates in place*)
function stringifyObjectFields(obj) {
  // convert objects to JSONified strings
  var d = JSON.parse(JSON.stringify(obj));

  if (typeof (d) === 'object') {
    Object.keys(d).forEach(function(k) {
      var v = d[k];
      if (typeof (v) === 'object') {
        d[k] = JSON.stringify(v);
      }
    });
  }

  return d;
}

// Index into elasticsearch

// calling c.fn without 2nd argument yields a promise
var index = esClient.index.bind(esClient);
var remove = esClient.delete.bind(esClient);

var OP_MAP = {
  add: index,
  remove: remove
};

// index documents into elasticsearch
function toElastic(data) {
  // select appropriate ES operation
  var operation = OP_MAP[data.operation];

  // Normalize fuzzy dates (if present)
  if (data.data.validSince) {
    data.data.validSince = fuzzyDates.convert(data.data.validSince);
  }

  if (data.data.validUntil) {
    data.data.validUntil = fuzzyDates.convert(data.data.validUntil);
  }

  // replace string version with original
  try {
    data.data.geometry = JSON.parse(data.data.geometry) ;
  } catch (_) {
  }

  var opts = {
    index: data.dataset,
    type: data.type,
    id: data.id,
    body: data.data
  };

  // run it, returns a stream
  return H(operation(opts));
}

function logError(err) {
  console.error(err.stack || err);
}

var commands = redis
    .errors(logError)
    .map(toGraphmalizer);

var neo4jAuth;
if (config.neo4j.user && config.neo4j.password) {
  neo4jAuth = config.neo4j.user + ':' + config.neo4j.password;
}

var gconf = {
  types: schemas.graphmalizer.types,
  Neo4J: {
    hostname: config.neo4j.host,
    port: config.neo4j.port,
    auth: neo4jAuth
  },
  batchSize: config.core.batchSize,
  batchTimeout: config.core.batchTimeout
};

var graphmalizer = new Graphmalizer(gconf);

graphmalizer.register(commands)
    .map(function(d) {
      // only index nodes into elasticsearch
      if (d.request.parameters.structure === 'node') {
        return toElastic(d.request.parameters);
      }

      return H([]);
    })
    .series()
    .errors(logError)
    .each(function() {
      process.stdout.write('.');
    });

console.log(config.logo.join('\n'));
<commit_msg>@bertspaan @bertspaan @bertspaan...<commit_after>var config = require('histograph-config');
var schemas = require('histograph-schemas');
var fuzzyDates = require('fuzzy-dates');
var Graphmalizer = require('graphmalizer-core');
var H = require('highland');
var Redis = require('redis');
var redisClient = Redis.createClient(config.redis.port, config.redis.host);

// Convert any ID, URI, URN to Histograph URN
var normalize = require('histograph-uri-normalizer').normalize;

var elasticsearch = require('elasticsearch');
var esClient = new elasticsearch.Client({
  host: config.elasticsearch.host + ':' + config.elasticsearch.port
});

// Create a stream from Redis queue
var redis = H(function redisGenerator(push, next) {

  // Function called on each Redis message (or timeout)
  function redisCallback(err, data) {
    // handle error
    if (err) {
      push(err);
      next();
      return;
    }

    // attempt parse or error
    try {
      var d = JSON.parse(data[1]);
      push(null, d);
      next();
    }
    catch (e) {
      push(e);
      next();
    }
  }

  // blocking pull from Redis
  redisClient.blpop(config.redis.queue, 0, redisCallback);
});

var ACTION_MAP = {
  add: 'add',
  update: 'add',
  delete: 'remove'
};

function toGraphmalizer(msg) {
  function norm(x) {
    if (x) {
      return normalize(x, msg.dataset);
    }

    return undefined;
  }

  var d = msg.data || {};

  // dataset is a top-level attribute that we want copied into the 'data' attribute
  d.dataset = msg.dataset;

  return {
    operation: ACTION_MAP[msg.action],

    dataset: d.dataset,

    // some old data uses `label` instead of `type`
    type: d.type,

    // nodes are identified with id's or URI's, we don't care
    id: norm(d.id || d.uri),

    // formalize source/target id's
    source: norm(d.from),
    target: norm(d.to),

    data: stringifyObjectFields(d)
  };
}

// when passed an object, every field that contains an object
// is converted into a JSON-string (*mutates in place*)
function stringifyObjectFields(obj) {
  // convert objects to JSONified strings
  var d = JSON.parse(JSON.stringify(obj));

  if (typeof (d) === 'object') {
    Object.keys(d).forEach(function(k) {
      var v = d[k];
      if (typeof (v) === 'object') {
        d[k] = JSON.stringify(v);
      }
    });
  }

  return d;
}

// Index into elasticsearch

// calling c.fn without 2nd argument yields a promise
var index = esClient.index.bind(esClient);
var remove = esClient.delete.bind(esClient);

var OP_MAP = {
  add: index,
  remove: remove
};

// index documents into elasticsearch
function toElastic(data) {
  // select appropriate ES operation
  var operation = OP_MAP[data.operation];

  // Normalize fuzzy dates (if present)
  if (data.data.validSince) {
    data.data.validSince = fuzzyDates.convert(data.data.validSince);
  }

  if (data.data.validUntil) {
    data.data.validUntil = fuzzyDates.convert(data.data.validUntil);
  }

  // replace string version with original
  try {
    data.data.geometry = JSON.parse(data.data.geometry) ;
  } catch (_) {
  }

  var opts = {
    index: data.dataset,
    type: data.type,
    id: data.id,
    body: data.data
  };

  // run it, returns a stream
  return H(operation(opts));
}

function logError(err) {
  console.error(err.stack || err);
}

var commands = redis
    .errors(logError)
    .map(toGraphmalizer);

var neo4jAuth;
if (config.neo4j.user && config.neo4j.password) {
  neo4jAuth = config.neo4j.user + ':' + config.neo4j.password;
}

var gconf = {
  types: schemas.graphmalizer,
  Neo4J: {
    hostname: config.neo4j.host,
    port: config.neo4j.port,
    auth: neo4jAuth
  },
  batchSize: config.core.batchSize,
  batchTimeout: config.core.batchTimeout
};

var graphmalizer = new Graphmalizer(gconf);

graphmalizer.register(commands)
    .map(function(d) {
      // only index nodes into elasticsearch
      if (d.request.parameters.structure === 'node') {
        return toElastic(d.request.parameters);
      }

      return H([]);
    })
    .series()
    .errors(logError)
    .each(function() {
      process.stdout.write('.');
    });

console.log(config.logo.join('\n'));
<|endoftext|>


<commit_before>var qs = require('querystring');
var iconv = require('iconv-lite');
var vm = require('vm');
var util = require('../util');
var extend = require('util')._extend;
var Transform = require('pipestream').Transform;
var WhistleTransform = util.WhistleTransform;
var ReplacePatternTransform = util.ReplacePatternTransform;
var ReplaceStringTransform = util.ReplaceStringTransform;
var FileWriterTransform = util.FileWriterTransform;
var MAX_REQ_SIZE = 256 * 1024;
var REQ_TYPE = {
		urlencoded: 'application/x-www-form-urlencoded',
		form: 'application/x-www-form-urlencoded',
		json: 'application/json',
		xml: 'text/xml',
		text: 'text/plain',
		upload: 'multipart/form-data',
		multipart: 'multipart/form-data',
		defaultType: 'application/octet-stream'
};

/**
 * 处理请求数据
 *
 * @param req：method、body、headers，top，bottom，speed、delay，charset,timeout
 * @param data
 */
function handleReq(req, data) {
	req.method = data.method || req.method;
	req.timeout = parseInt(data.timeout, 10);
	extend(req.headers, data.headers);
	var method = req.method = typeof req.method != 'string' ? 'GET' : req.method.toUpperCase();
	if (!util.hasRequestBody(method)) {
		delete data.top;
		delete data.bottom;
		delete data.body;
	} else if (data.top || data.bottom || data.body) {
		delete req.headers['content-length'];
	}

	!util.isEmptyObject(data) && req.add(new WhistleTransform(data));
}

function handleCors(data, cors) {
	if (!cors) {
		return;
	}

	if (cors.origin !== undefined) {
		util.setHeader(data, 'origin', cors.origin);
	}

	if (cors.method !== undefined) {
		util.setHeader(data, 'access-control-request-method', cors.method);
	}

	if (cors.headers !== undefined) {
		util.setHeader(data, 'access-control-request-headers', cors.headers);
	}
}

function handleAuth(data, auth) {
	if (!auth) {
		return;
	}

	var basic = [];
	auth.username != null && basic.push(auth.username);
	auth.password != null && basic.push(auth.password);
	if (basic = basic.join(':')) {
		util.setHeader(data, 'authorization', 'Basic ' + new Buffer(basic).toString('base64'));
	}
}

function handleCookies(data, cookies, curCookies) {
	var list = cookies && Object.keys(cookies);
	if (list && list.length) {
		var result = {};
		if (curCookies && typeof curCookies == 'string') {
			curCookies.split(/;\s*/g)
					.forEach(function(cookie) {
						var index = cookie.indexOf('=');
						if (index == -1) {
							result[cookie] = null;
						} else {
							result[cookie.substring(0, index)] = cookie.substring(index + 1);
						}
					});
		}

		list.forEach(function(name) {
			var value = cookies[name];
			value = value && typeof value == 'object' ? value.value : value;
			result[util.encodeURIComponent(name)] = value ? util.encodeURIComponent(value) : value;
		});

		cookies = Object.keys(result).map(function(name) {
			var value = result[name];
			return name + (value == null ? '' : '=' + value);
		}).join('; ');
		util.setHeader(data, 'cookie', cookies);
	}
}

function handleParams(req, params) {
	var _params = params;
	if (!(params = params && qs.stringify(params))) {
		return;
	}

	if (!req.method || /^GET$/i.test(req.method)) {
		req.options.search = util.replaceUrlQueryString(req.options.search, params);
		req.options.path = util.replaceUrlQueryString(req.options.path, params);
		req.options.href = util.replaceUrlQueryString(req.options.href, params);
	} else if (util.isUrlEncoded(req)) {
		delete req.headers['content-length'];
		var transform = new Transform();
		var buffer, interrupt;
		transform._transform = function(chunk, encoding, callback) {
			if (chunk) {
				if (!interrupt) {
					buffer = buffer ? Buffer.concat([buffer, chunk]) : chunk;
					chunk = null;
					if (buffer.length > MAX_REQ_SIZE) {
						interrupt = true;
						chunk = buffer;
						buffer = null;
					}
				}
			} else if (buffer) {
				var body = buffer + '';
				var isGBK = body.indexOf('�') == -1;
				if (isGBK) {
					body = iconv.decode(buffer, 'GB18030');
					body = util.replaceQueryString(body, params);
					chunk = iconv.encode(body, 'GB18030');
				} else {
					chunk = new Buffer(body);
				}
				buffer = null;
			} else {
				chunk = new Buffer(params);
			}

			callback(null, chunk);
		};
		req.add(transform);
	} else if (util.isUploadForm(req)) {
		delete req.headers['content-length'];
		//TODO:
	}
}

function removeDisableProps(req) {
	var disable = req.disable;
	var headers = req.headers;

	if (disable.ua) {
		delete headers['user-agent'];
	}

	if (disable.cookie || disable.cookies ||
			disable.reqCookie || disable.reqCookies) {
		delete headers.cookie;
	}

	if (disable.referer) {
		delete headers.referer;
	}

	if (disable.cache) {
		delete headers['if-modified-since'];
		delete headers['if-none-match'];
		delete headers['last-modified'];
		delete headers.etag;

		headers['pragma'] = 'no-cache';
		headers['cache-control'] = 'no-cache';
	}
}

function handleReplace(req, replacement) {
	if (!replacement) {
		return;
	}

	var type = req.headers['content-type'];
	type = util.isUrlEncoded(req) ? 'FORM' : util.getContentType(type);
	if (!type || type == 'IMG') {
		return;
	}

	Object.keys(replacement).forEach(function(pattern) {
		var value = replacement[pattern];
		if (util.isOriginalRegExp(pattern) && (pattern = util.toOriginalRegExp(pattern))) {
			req.addTextTransform(new ReplacePatternTransform(pattern, value));
		} else if (pattern) {
			req.addTextTransform(new ReplaceStringTransform(pattern, value));
		}
	});
}

module.exports = function(req, res, next) {
	var reqRules = req.rules;
	util.parseRuleJson([reqRules.req, reqRules.reqHeaders, reqRules.reqCookies,
	                    reqRules.auth, reqRules.params, reqRules.reqCors, reqRules.reqReplace],
			function(data, headers, cookies, auth, params, cors, replacement) {
		if (reqRules.head && reqRules.head.req) {
			data = extend(reqRules.head.req, data);
		}
		data = data || {};
		if (headers) {
			data.headers =  extend(data.headers || {}, headers);
		}

		if (data.headers) {
			data.headers = util.lowerCaseify(data.headers);
		}

		var method = util.getMatcherValue(reqRules.method);
		if (method) {
			data.method = method;
		}

		var type = util.getMatcherValue(reqRules.reqType);
		if (type) {
			type = type.indexOf('/') != -1 ? type : (REQ_TYPE[type] || REQ_TYPE.defaultType);
			util.setHeader(data, 'content-type', type);
		}

		var referer = util.getMatcherValue(reqRules.referer);
		if (referer) {
			util.setHeader(data, 'referer', referer);
		}

		var ua = util.getMatcherValue(reqRules.ua);
		if (ua) {
			util.setHeader(data, 'user-agent', ua);
		}

		var reqDelay = util.getMatcherValue(reqRules.reqDelay);
		reqDelay = reqDelay && parseInt(reqDelay, 10);
		if (reqDelay > 0) {
			data.delay = reqDelay;
		}

		var reqSpeed = util.getMatcherValue(reqRules.reqSpeed);
		reqSpeed = reqSpeed && parseFloat(reqSpeed);
		if (reqSpeed > 0) {
			data.speed = reqSpeed;
		}

		handleCookies(data, cookies, req.headers.cookie);
		handleAuth(data, auth);
		handleCors(data, cors);

		util.readInjectFiles(data, function(data) {
			util.getRuleValue([reqRules.reqBody, reqRules.reqPrepend, reqRules.reqAppend],
				function(reqBody, reqPrepend, reqAppend) {
					if (reqBody) {
						data.body = reqBody;
					}

					if (reqPrepend) {
						data.top = reqPrepend;
					}

					if (reqAppend) {
						data.append = reqAppend;
					}

					handleReq(req, data);
					handleParams(req, params);
					util.removeUnsupportsHeaders(req.headers);
					removeDisableProps(req);
					handleReplace(req, replacement);
					util.getFileWriter(util.hasRequestBody(req) ? util.getRuleFile(reqRules.reqWrite) : null, function(writer) {
						if (writer) {
							req.add(new FileWriterTransform(writer, req));
						}
						next();
					});
				});
		});
	});
};<commit_msg>util.hasRequestBody(req)<commit_after>var qs = require('querystring');
var iconv = require('iconv-lite');
var vm = require('vm');
var util = require('../util');
var extend = require('util')._extend;
var Transform = require('pipestream').Transform;
var WhistleTransform = util.WhistleTransform;
var ReplacePatternTransform = util.ReplacePatternTransform;
var ReplaceStringTransform = util.ReplaceStringTransform;
var FileWriterTransform = util.FileWriterTransform;
var MAX_REQ_SIZE = 256 * 1024;
var REQ_TYPE = {
		urlencoded: 'application/x-www-form-urlencoded',
		form: 'application/x-www-form-urlencoded',
		json: 'application/json',
		xml: 'text/xml',
		text: 'text/plain',
		upload: 'multipart/form-data',
		multipart: 'multipart/form-data',
		defaultType: 'application/octet-stream'
};

/**
 * 处理请求数据
 *
 * @param req：method、body、headers，top，bottom，speed、delay，charset,timeout
 * @param data
 */
function handleReq(req, data) {
	req.method = data.method || req.method;
	req.timeout = parseInt(data.timeout, 10);
	extend(req.headers, data.headers);
	var method = req.method = typeof req.method != 'string' ? 'GET' : req.method.toUpperCase();
	if (!util.hasRequestBody(method)) {
		delete data.top;
		delete data.bottom;
		delete data.body;
	} else if (data.top || data.bottom || data.body) {
		delete req.headers['content-length'];
	}

	!util.isEmptyObject(data) && req.add(new WhistleTransform(data));
}

function handleCors(data, cors) {
	if (!cors) {
		return;
	}

	if (cors.origin !== undefined) {
		util.setHeader(data, 'origin', cors.origin);
	}

	if (cors.method !== undefined) {
		util.setHeader(data, 'access-control-request-method', cors.method);
	}

	if (cors.headers !== undefined) {
		util.setHeader(data, 'access-control-request-headers', cors.headers);
	}
}

function handleAuth(data, auth) {
	if (!auth) {
		return;
	}

	var basic = [];
	auth.username != null && basic.push(auth.username);
	auth.password != null && basic.push(auth.password);
	if (basic = basic.join(':')) {
		util.setHeader(data, 'authorization', 'Basic ' + new Buffer(basic).toString('base64'));
	}
}

function handleCookies(data, cookies, curCookies) {
	var list = cookies && Object.keys(cookies);
	if (list && list.length) {
		var result = {};
		if (curCookies && typeof curCookies == 'string') {
			curCookies.split(/;\s*/g)
					.forEach(function(cookie) {
						var index = cookie.indexOf('=');
						if (index == -1) {
							result[cookie] = null;
						} else {
							result[cookie.substring(0, index)] = cookie.substring(index + 1);
						}
					});
		}

		list.forEach(function(name) {
			var value = cookies[name];
			value = value && typeof value == 'object' ? value.value : value;
			result[util.encodeURIComponent(name)] = value ? util.encodeURIComponent(value) : value;
		});

		cookies = Object.keys(result).map(function(name) {
			var value = result[name];
			return name + (value == null ? '' : '=' + value);
		}).join('; ');
		util.setHeader(data, 'cookie', cookies);
	}
}

function handleParams(req, params) {
	var _params = params;
	if (!(params = params && qs.stringify(params))) {
		return;
	}

	if (!req.method || /^GET$/i.test(req.method)) {
		req.options.search = util.replaceUrlQueryString(req.options.search, params);
		req.options.path = util.replaceUrlQueryString(req.options.path, params);
		req.options.href = util.replaceUrlQueryString(req.options.href, params);
	} else if (util.isUrlEncoded(req)) {
		delete req.headers['content-length'];
		var transform = new Transform();
		var buffer, interrupt;
		transform._transform = function(chunk, encoding, callback) {
			if (chunk) {
				if (!interrupt) {
					buffer = buffer ? Buffer.concat([buffer, chunk]) : chunk;
					chunk = null;
					if (buffer.length > MAX_REQ_SIZE) {
						interrupt = true;
						chunk = buffer;
						buffer = null;
					}
				}
			} else if (buffer) {
				var body = buffer + '';
				var isGBK = body.indexOf('�') == -1;
				if (isGBK) {
					body = iconv.decode(buffer, 'GB18030');
					body = util.replaceQueryString(body, params);
					chunk = iconv.encode(body, 'GB18030');
				} else {
					chunk = new Buffer(body);
				}
				buffer = null;
			} else {
				chunk = new Buffer(params);
			}

			callback(null, chunk);
		};
		req.add(transform);
	} else if (util.isUploadForm(req)) {
		delete req.headers['content-length'];
		//TODO:
	}
}

function removeDisableProps(req) {
	var disable = req.disable;
	var headers = req.headers;

	if (disable.ua) {
		delete headers['user-agent'];
	}

	if (disable.cookie || disable.cookies ||
			disable.reqCookie || disable.reqCookies) {
		delete headers.cookie;
	}

	if (disable.referer) {
		delete headers.referer;
	}

	if (disable.cache) {
		delete headers['if-modified-since'];
		delete headers['if-none-match'];
		delete headers['last-modified'];
		delete headers.etag;

		headers['pragma'] = 'no-cache';
		headers['cache-control'] = 'no-cache';
	}
}

function handleReplace(req, replacement) {
	if (!util.hasRequestBody(req) || !replacement) {
		return;
	}

	var type = req.headers['content-type'];
	type = util.isUrlEncoded(req) ? 'FORM' : util.getContentType(type);
	if (!type || type == 'IMG') {
		return;
	}

	Object.keys(replacement).forEach(function(pattern) {
		var value = replacement[pattern];
		if (util.isOriginalRegExp(pattern) && (pattern = util.toOriginalRegExp(pattern))) {
			req.addTextTransform(new ReplacePatternTransform(pattern, value));
		} else if (pattern) {
			req.addTextTransform(new ReplaceStringTransform(pattern, value));
		}
	});
}

module.exports = function(req, res, next) {
	var reqRules = req.rules;
	util.parseRuleJson([reqRules.req, reqRules.reqHeaders, reqRules.reqCookies,
	                    reqRules.auth, reqRules.params, reqRules.reqCors, reqRules.reqReplace],
			function(data, headers, cookies, auth, params, cors, replacement) {
		if (reqRules.head && reqRules.head.req) {
			data = extend(reqRules.head.req, data);
		}
		data = data || {};
		if (headers) {
			data.headers =  extend(data.headers || {}, headers);
		}

		if (data.headers) {
			data.headers = util.lowerCaseify(data.headers);
		}

		var method = util.getMatcherValue(reqRules.method);
		if (method) {
			data.method = method;
		}

		var type = util.getMatcherValue(reqRules.reqType);
		if (type) {
			type = type.indexOf('/') != -1 ? type : (REQ_TYPE[type] || REQ_TYPE.defaultType);
			util.setHeader(data, 'content-type', type);
		}

		var referer = util.getMatcherValue(reqRules.referer);
		if (referer) {
			util.setHeader(data, 'referer', referer);
		}

		var ua = util.getMatcherValue(reqRules.ua);
		if (ua) {
			util.setHeader(data, 'user-agent', ua);
		}

		var reqDelay = util.getMatcherValue(reqRules.reqDelay);
		reqDelay = reqDelay && parseInt(reqDelay, 10);
		if (reqDelay > 0) {
			data.delay = reqDelay;
		}

		var reqSpeed = util.getMatcherValue(reqRules.reqSpeed);
		reqSpeed = reqSpeed && parseFloat(reqSpeed);
		if (reqSpeed > 0) {
			data.speed = reqSpeed;
		}

		handleCookies(data, cookies, req.headers.cookie);
		handleAuth(data, auth);
		handleCors(data, cors);

		util.readInjectFiles(data, function(data) {
			util.getRuleValue([reqRules.reqBody, reqRules.reqPrepend, reqRules.reqAppend],
				function(reqBody, reqPrepend, reqAppend) {
					if (reqBody) {
						data.body = reqBody;
					}

					if (reqPrepend) {
						data.top = reqPrepend;
					}

					if (reqAppend) {
						data.append = reqAppend;
					}

					handleReq(req, data);
					handleParams(req, params);
					util.removeUnsupportsHeaders(req.headers);
					removeDisableProps(req);
					handleReplace(req, replacement);
					util.getFileWriter(util.hasRequestBody(req) ? util.getRuleFile(reqRules.reqWrite) : null, function(writer) {
						if (writer) {
							req.add(new FileWriterTransform(writer, req));
						}
						next();
					});
				});
		});
	});
};<|endoftext|>


<commit_before>var url = require('url'),
    querystring = require('querystring'),
    crypto = require('crypto'),
    events = require('events'),
    emitter = new events.EventEmitter(),
    xml2js = require('xml2js');

var Wechat = function(token) {
  if (!(this instanceof Wechat)) {
    return new Wechat(token);
  }
  this.token = token;
  this.res = null;
}

//检验 token
Wechat.prototype.checkSignature = function(req, res) {
  if (req.method === 'GET') {
    var queryObj = querystring.parse(url.parse(req.url).query);
    var signature = queryObj.signature,
        timestamp = queryObj.timestamp,
        nonce = queryObj.nonce,
        echostr = queryObj.echostr;

    var sha1 = crypto.createHash('sha1'),
        sha1Str = sha1.update([this.token, timestamp, nonce].sort().join('')).digest('hex');

        res.writeHead(200, {'Content-Type': 'text/plain'});
        res.end((sha1Str === signature) ? echostr : '');
        return res;
  }
}

//预处理器
Wechat.prototype.handler = function(req, res) {
  var xml = '';
  var self = this;
  self.res = res;

  req.setEncoding('utf8');
  req.on('data', function (chunk) {
    xml += chunk;
  });

  req.on('end', function() {
    self.toJSON(xml);
  });
}

//解析器
Wechat.prototype.toJSON = function(xml) {
  var msg = {};
  xml2js.parseString(xml, function (err, result) {
    var data = result.xml;

    msg.ToUserName = data.ToUserName[0];
    msg.FromUserName = data.FromUserName[0];
    msg.CreateTime = data.CreateTime[0];
    msg.MsgType = data.MsgType[0];

    switch(msg.MsgType) {
      case 'text' :
        msg.Content = data.Content[0];
        msg.MsgId = data.MsgId[0];

        emitter.emit("text", msg);
        break;

      case 'image' :
        msg.PicUrl = data.PicUrl[0];
        msg.MsgId = data.MsgId[0];
        msg.MediaId = data.MediaId[0];

        emitter.emit("image", msg);
        break;

      case 'voice' :
        msg.MediaId = data.MediaId[0];
        msg.Format = data.Format[0];
        msg.MsgId = data.MsgId[0];

        emitter.emit("voice", msg);
        break;

      case 'video' :
        msg.MediaId = data.MediaId[0];
        msg.ThumbMediaId = data.ThumbMediaId[0];
        msg.MsgId = data.MsgId[0];

        emitter.emit("video", msg);
        break;

      case 'location' :
        msg.Location_X = data.Location_X[0];
        msg.Location_Y = data.Location_Y[0];
        msg.Scale = data.Scale[0];
        msg.Label = data.Label[0];
        msg.MsgId = data.MsgId[0];

        emitter.emit("location", msg);
        break;

      case 'link' :
        msg.Title = data.Title[0];
        msg.Description = data.Description[0];
        msg.Url = data.Url[0];
        msg.MsgId = data.MsgId[0];

        emitter.emit("link", msg);
        break;

      case 'event' :
        msg.Event = data.Event[0];
        msg.EventKey = data.EventKey[0];

        emitter.emit("event", msg);
        break;
    }
  });
  return msg;
}

//监听文本信息
Wechat.prototype.text = function(callback) {
  emitter.on("text", callback);
  return this;
}

//监听图片信息
Wechat.prototype.image = function(callback) {
  emitter.on("image", callback);
  return this;
}

//监听地址信息
Wechat.prototype.location = function(callback) {
  emitter.on("location", callback);
  return this;
}

//监听链接信息
Wechat.prototype.link = function(callback) {
  emitter.on("link", callback);
  return this;
}

//监听事件信息
Wechat.prototype.event = function(callback) {
  emitter.on("event", callback);
  return this;
}

//监听语音信息
Wechat.prototype.voice = function(callback) {
  emitter.on("voice", callback);
  return this;
}

//监听视频信息
Wechat.prototype.video = function(callback) {
  emitter.on("video", callback);
  return this;
}

//监听所有信息
Wechat.prototype.all = function(callback) {
  emitter.on("text", callback);
  emitter.on("image", callback);
  emitter.on("location", callback);
  emitter.on("link", callback);
  emitter.on("event", callback);
  emitter.on("voice", callback);
  emitter.on("video", callback);

  return this;
}

//将 js 组装成 xml
Wechat.prototype.toXML = function(data) {
  //自动检测 MsgType
  var MsgType = "";
  if (!data.MsgType) {
    if (data.hasOwnProperty("Content")) MsgType = "text";
    if (data.hasOwnProperty("MusicUrl")) MsgType = "music";
    if (data.hasOwnProperty("Articles")) MsgType = "news";
  } else {
    MsgType = data.MsgType;
  }

  var msg = "" +
      "<xml>" +
      "<ToUserName><![CDATA[" + data.ToUserName + "]]></ToUserName>" +
      "<FromUserName><![CDATA[" + data.FromUserName + "]]></FromUserName>" +
      "<CreateTime>" + Date.now()/1000 + "</CreateTime>" +
      "<MsgType><![CDATA[" + MsgType + "]]></MsgType>";

  switch(MsgType) {
    case 'text' :
      msg += "" +
        "<Content><![CDATA[" + (data.Content || '') + "]]></Content>" +
        "</xml>";
      return msg;

    case 'image' :
      msg += "" +
        "<Image>" +
        "<MediaId><![CDATA[" + data.MediaId +"]]></MediaId>" +
        "</Image>" +
        "</xml>";

    case 'voice' :
      msg += "" +
        "<Voice>" +
        "<MediaId><![CDATA[" + data.MediaId +"]]></MediaId>" +
        "<Title><![CDATA[" + data.Title +"]]></Title>" +
        "<Description><![CDATA[" + data.Description +"]]></Description>" +
        "</Voice>" +
        "</xml>";

    case 'video' :
      msg += "" +
        "<Video>" +
        "<MediaId><![CDATA[" + data.MediaId +"]]></MediaId>" +
        "</Video>" +
        "</xml>";

    case 'music' :
      msg += "" +
        "<Music>" +
        "<Title><![CDATA[" + (data.Title || '') + "]]></Title>" +
        "<Description><![CDATA[" + (data.Description || '') + "]]></Description>" +
        "<MusicUrl><![CDATA[" + (data.MusicUrl || '') + "]]></MusicUrl>" +
        "<HQMusicUrl><![CDATA[" + (data.HQMusicUrl || data.MusicUrl || '') + "]]></HQMusicUrl>" +
        "<ThumbMediaId><![CDATA[" + (data.ThumbMediaId || '') + "]]></ThumbMediaId>" +
        "</Music>" +
        "</xml>";
      return msg;

    case 'news' :
      var ArticlesStr = "";
      var ArticleCount = data.Articles.length;
      for (var i in data.Articles) {
        ArticlesStr += "" +
          "<item>" +
          "<Title><![CDATA[" + (data.Articles[i].Title || '') + "]]></Title>" +
          "<Description><![CDATA[" + (data.Articles[i].Description || '') + "]]></Description>" +
          "<PicUrl><![CDATA[" + (data.Articles[i].PicUrl || '') + "]]></PicUrl>" +
          "<Url><![CDATA[" + (data.Articles[i].Url ||'') + "]]></Url>" +
          "</item>";
      }

      msg += "<ArticleCount>" + ArticleCount + "</ArticleCount><Articles>" + ArticlesStr + "</Articles></xml>";
      return msg;
  }
}

//回复消息
Wechat.prototype.send = function(data) {
  this.res.writeHead(200, {'Content-Type': 'text/plain'});
  this.res.end(this.toXML(data));
  return this;
}

module.exports = Wechat;<commit_msg>解决消息重复相应的bug<commit_after>var url = require('url'),
    querystring = require('querystring'),
    crypto = require('crypto'),
    events = require('events'),
    emitter = new events.EventEmitter(),
    xml2js = require('xml2js');

var Wechat = function(token) {
  if (!(this instanceof Wechat)) {
    return new Wechat(token);
  }
  this.token = token;
  this.res = null;
}

//检验 token
Wechat.prototype.checkSignature = function(req, res) {
  if (req.method === 'GET') {
    var queryObj = querystring.parse(url.parse(req.url).query);
    var signature = queryObj.signature,
        timestamp = queryObj.timestamp,
        nonce = queryObj.nonce,
        echostr = queryObj.echostr;

    var sha1 = crypto.createHash('sha1'),
        sha1Str = sha1.update([this.token, timestamp, nonce].sort().join('')).digest('hex');

        res.writeHead(200, {'Content-Type': 'text/plain'});
        res.end((sha1Str === signature) ? echostr : '');
        return res;
  }
}

//预处理器
Wechat.prototype.handler = function(req, res) {
  var xml = '';
  var self = this;
  self.res = res;

  req.setEncoding('utf8');
  req.on('data', function (chunk) {
    xml += chunk;
  });

  req.on('end', function() {
    self.toJSON(xml);
  });

  /**
   * clear all listening events to avoid repeat triggers
   */
  emitter.removeAllListeners('text');
  emitter.removeAllListeners('voice');
  emitter.removeAllListeners('event');
}

//解析器
Wechat.prototype.toJSON = function(xml) {
  var msg = {};
  xml2js.parseString(xml, function (err, result) {
    var data = result.xml;

    msg.ToUserName = data.ToUserName[0];
    msg.FromUserName = data.FromUserName[0];
    msg.CreateTime = data.CreateTime[0];
    msg.MsgType = data.MsgType[0];

    switch(msg.MsgType) {
      case 'text' :
        msg.Content = data.Content[0];
        msg.MsgId = data.MsgId[0];

        emitter.emit("text", msg);
        break;

      case 'image' :
        msg.PicUrl = data.PicUrl[0];
        msg.MsgId = data.MsgId[0];
        msg.MediaId = data.MediaId[0];

        emitter.emit("image", msg);
        break;

      case 'voice' :
        msg.MediaId = data.MediaId[0];
        msg.Format = data.Format[0];
        msg.MsgId = data.MsgId[0];

        emitter.emit("voice", msg);
        break;

      case 'video' :
        msg.MediaId = data.MediaId[0];
        msg.ThumbMediaId = data.ThumbMediaId[0];
        msg.MsgId = data.MsgId[0];

        emitter.emit("video", msg);
        break;

      case 'location' :
        msg.Location_X = data.Location_X[0];
        msg.Location_Y = data.Location_Y[0];
        msg.Scale = data.Scale[0];
        msg.Label = data.Label[0];
        msg.MsgId = data.MsgId[0];

        emitter.emit("location", msg);
        break;

      case 'link' :
        msg.Title = data.Title[0];
        msg.Description = data.Description[0];
        msg.Url = data.Url[0];
        msg.MsgId = data.MsgId[0];

        emitter.emit("link", msg);
        break;

      case 'event' :
        msg.Event = data.Event[0];
        msg.EventKey = data.EventKey[0];

        emitter.emit("event", msg);
        break;
    }
  });
  return msg;
}

//监听文本信息
Wechat.prototype.text = function(callback) {
  emitter.once("text", callback);
  return this;
}

//监听图片信息
Wechat.prototype.image = function(callback) {
  emitter.once("image", callback);
  return this;
}

//监听地址信息
Wechat.prototype.location = function(callback) {
  emitter.once("location", callback);
  return this;
}

//监听链接信息
Wechat.prototype.link = function(callback) {
  emitter.once("link", callback);
  return this;
}

//监听事件信息
Wechat.prototype.event = function(callback) {
  emitter.once("event", callback);
  return this;
}

//监听语音信息
Wechat.prototype.voice = function(callback) {
  emitter.once("voice", callback);
  return this;
}

//监听视频信息
Wechat.prototype.video = function(callback) {
  emitter.once("video", callback);
  return this;
}

//监听所有信息
Wechat.prototype.all = function(callback) {
  emitter.once("text", callback);
  emitter.once("image", callback);
  emitter.once("location", callback);
  emitter.once("link", callback);
  emitter.once("event", callback);
  emitter.once("voice", callback);
  emitter.once("video", callback);

  return this;
}

//将 js 组装成 xml
Wechat.prototype.toXML = function(data) {
  //自动检测 MsgType
  var MsgType = "";
  if (!data.MsgType) {
    if (data.hasOwnProperty("Content")) MsgType = "text";
    if (data.hasOwnProperty("MusicUrl")) MsgType = "music";
    if (data.hasOwnProperty("Articles")) MsgType = "news";
  } else {
    MsgType = data.MsgType;
  }

  var msg = "" +
      "<xml>" +
      "<ToUserName><![CDATA[" + data.ToUserName + "]]></ToUserName>" +
      "<FromUserName><![CDATA[" + data.FromUserName + "]]></FromUserName>" +
      "<CreateTime>" + Date.now()/1000 + "</CreateTime>" +
      "<MsgType><![CDATA[" + MsgType + "]]></MsgType>";

  switch(MsgType) {
    case 'text' :
      msg += "" +
        "<Content><![CDATA[" + (data.Content || '') + "]]></Content>" +
        "</xml>";
      return msg;

    case 'image' :
      msg += "" +
        "<Image>" +
        "<MediaId><![CDATA[" + data.MediaId +"]]></MediaId>" +
        "</Image>" +
        "</xml>";

    case 'voice' :
      msg += "" +
        "<Voice>" +
        "<MediaId><![CDATA[" + data.MediaId +"]]></MediaId>" +
        "<Title><![CDATA[" + data.Title +"]]></Title>" +
        "<Description><![CDATA[" + data.Description +"]]></Description>" +
        "</Voice>" +
        "</xml>";

    case 'video' :
      msg += "" +
        "<Video>" +
        "<MediaId><![CDATA[" + data.MediaId +"]]></MediaId>" +
        "</Video>" +
        "</xml>";

    case 'music' :
      msg += "" +
        "<Music>" +
        "<Title><![CDATA[" + (data.Title || '') + "]]></Title>" +
        "<Description><![CDATA[" + (data.Description || '') + "]]></Description>" +
        "<MusicUrl><![CDATA[" + (data.MusicUrl || '') + "]]></MusicUrl>" +
        "<HQMusicUrl><![CDATA[" + (data.HQMusicUrl || data.MusicUrl || '') + "]]></HQMusicUrl>" +
        "<ThumbMediaId><![CDATA[" + (data.ThumbMediaId || '') + "]]></ThumbMediaId>" +
        "</Music>" +
        "</xml>";
      return msg;

    case 'news' :
      var ArticlesStr = "";
      var ArticleCount = data.Articles.length;
      for (var i in data.Articles) {
        ArticlesStr += "" +
          "<item>" +
          "<Title><![CDATA[" + (data.Articles[i].Title || '') + "]]></Title>" +
          "<Description><![CDATA[" + (data.Articles[i].Description || '') + "]]></Description>" +
          "<PicUrl><![CDATA[" + (data.Articles[i].PicUrl || '') + "]]></PicUrl>" +
          "<Url><![CDATA[" + (data.Articles[i].Url ||'') + "]]></Url>" +
          "</item>";
      }

      msg += "<ArticleCount>" + ArticleCount + "</ArticleCount><Articles>" + ArticlesStr + "</Articles></xml>";
      return msg;
  }
}

//回复消息
Wechat.prototype.send = function(data) {
  this.res.writeHead(200, {'Content-Type': 'text/plain'});
  this.res.end(this.toXML(data));
  return this;
}

module.exports = Wechat;<|endoftext|>


<commit_before>/**
 * express-slicer
 *
 * Copyright(c) 2013 André König <akoenig@posteo.de>
 * MIT Licensed
 *
 */

'use strict';

var util = require('util');

/**
 * A slicer middleware for ExpressJS.
 *
 * Extracts data out of response objects and sends them as partial
 * JSON responses (see: http://googlecode.blogspot.de/2010/03/making-apis-faster-introducing-partial.html)
 *
 * Example:
 *
 *     http://host/api/persons?fields=firstName,lastName
 *
 * Returns only objects with the attributes firstName and lastName.
 *
 */
function ExpressSlicer () {}

/**
 * @private
 *
 * Extracts the respective fields out of a given object.
 *
 * @param {object} obj The object from which the fields should be extracted.
 * @param {array} fields The fields that should be extracted
 *
 * @return {object} The stripped object.
 *
 */
ExpressSlicer.prototype.$$extractFields = function $$extractFields (obj, fields) {
    var i = fields.length - 1,
        extract,
        field;

    for (i; i >= 0; i = i - 1) {
        field = fields[i];

        if (obj.hasOwnProperty(field)) {
            // Lazy creation
            if (!extract) {
                 extract = {};
            }

            extract[field] = obj[field];
        }
    }

    // If no field matched, return the full object.
    if (!extract) {
        extract = obj;
    }

    return extract;
};

/**
 * @private
 *
 * The dispatcher function that prepares the slicable object(s).
 *
 * @param {array||object} slicables An array or one single object from which the fields should be extracted.
 * @param {array} fields The fields that should be extracted.
 * @return {array|object} The single sliced object or the array with sliced objects.
 *
 */
ExpressSlicer.prototype.$$slice = function $$slice (slicables, fields) {
    var i;

    fields = fields || '';
    fields = fields.split(',');

    if (!util.isArray(slicables)) {
        slicables = [slicables];
    }

    i = slicables.length - 1;

    for (i; i >= 0; i = i - 1) {
        slicables[i] = this.$$extractFields(slicables[i], fields);
    }

    if (1 === slicables.length) {
        return slicables[0];
    } else {
        return slicables;
    }
};

/**
 * @private
 *
 * Wrapper that entangles the res.json function of ExpressJs
 *
 * @return {function} The original res.json function from ExpressJS
 *
 */
ExpressSlicer.prototype.$$entangle = function $$entangle (func) {
    var self = this;

    // Wraps the express json functionality
    return function json () {

        var args = Array.prototype.slice.call(arguments),
            fields = this.req.query.fields,
            slicable;

        if (2 === args.length) {

            // Is: res.json(slicable, statusCode);
            if ('number' === typeof args[1]) {
                slicable = args[0];

                func.apply(this, [args[1], self.$$slice(slicable, fields)]);

            // Is: res.json(statusCode, slicable);
            } else {
                slicable = args[1];

                func.apply(this, [args[0], self.$$slice(slicable, fields)]);
            }

        // Is: res.json(slicable);
        } else {
            slicable = args[0];

            func.apply(this, [self.$$slice(slicable, fields)]);
        }
    };
};

/**
 * The ExpressJS middleware wrapper
 *
 */
ExpressSlicer.prototype.middleware = function middleware (req, res, next) {
    res.json = this.$$entangle(res.json.bind(res));

    next();
};

/**
 * Creates a new ExpressSlicer instance and returns
 * the middleware for ExpressJS.
 *
 * @return {function} Middleware function for ExpressJS.
 *
 */
module.exports = function init () {
    var slicer = new ExpressSlicer();

    return slicer.middleware.bind(slicer);
};<commit_msg>Source code formatting.<commit_after>/**
 * express-slicer
 *
 * Copyright(c) 2013 André König <akoenig@posteo.de>
 * MIT Licensed
 *
 */

'use strict';

var util = require('util');

/**
 * A slicer middleware for ExpressJS.
 *
 * Extracts data out of response objects and sends them as partial
 * JSON responses (see: http://googlecode.blogspot.de/2010/03/making-apis-faster-introducing-partial.html)
 *
 * Example:
 *
 *     http://host/api/persons?fields=firstName,lastName
 *
 * Returns only objects with the attributes firstName and lastName.
 *
 */
function ExpressSlicer () {}

/**
 * @private
 *
 * Extracts the respective fields out of a given object.
 *
 * @param {object} obj The object from which the fields should be extracted.
 * @param {array} fields The fields that should be extracted
 *
 * @return {object} The stripped object.
 *
 */
ExpressSlicer.prototype.$$extractFields = function $$extractFields (obj, fields) {
    var i = fields.length - 1,
        extract,
        field;

    for (i; i >= 0; i = i - 1) {
        field = fields[i];

        if (obj.hasOwnProperty(field)) {
            // Lazy creation
            if (!extract) {
                 extract = {};
            }

            extract[field] = obj[field];
        }
    }

    // If no field matched, return the full object.
    if (!extract) {
        extract = obj;
    }

    return extract;
};

/**
 * @private
 *
 * The dispatcher function that prepares the slicable object(s).
 *
 * @param {array||object} slicables An array or one single object from which the fields should be extracted.
 * @param {array} fields The fields that should be extracted.
 *
 * @return {array|object} The single sliced object or the array with sliced objects.
 *
 */
ExpressSlicer.prototype.$$slice = function $$slice (slicables, fields) {
    var i;

    fields = fields || '';
    fields = fields.split(',');

    if (!util.isArray(slicables)) {
        slicables = [slicables];
    }

    i = slicables.length - 1;

    for (i; i >= 0; i = i - 1) {
        slicables[i] = this.$$extractFields(slicables[i], fields);
    }

    if (1 === slicables.length) {
        return slicables[0];
    } else {
        return slicables;
    }
};

/**
 * @private
 *
 * Wrapper that entangles the res.json function of ExpressJs
 *
 * @return {function} The original res.json function from ExpressJS
 *
 */
ExpressSlicer.prototype.$$entangle = function $$entangle (func) {
    var self = this;

    // Wraps the express json functionality
    return function json () {

        var args = Array.prototype.slice.call(arguments),
            fields = this.req.query.fields,
            slicable;

        if (2 === args.length) {

            // Is: res.json(slicable, statusCode);
            if ('number' === typeof args[1]) {
                slicable = args[0];

                func.apply(this, [args[1], self.$$slice(slicable, fields)]);

            // Is: res.json(statusCode, slicable);
            } else {
                slicable = args[1];

                func.apply(this, [args[0], self.$$slice(slicable, fields)]);
            }

        // Is: res.json(slicable);
        } else {
            slicable = args[0];

            func.apply(this, [self.$$slice(slicable, fields)]);
        }
    };
};

/**
 * The ExpressJS middleware wrapper
 *
 */
ExpressSlicer.prototype.middleware = function middleware (req, res, next) {
    res.json = this.$$entangle(res.json.bind(res));

    next();
};

/**
 * Creates a new ExpressSlicer instance and returns
 * the middleware for ExpressJS.
 *
 * @return {function} Middleware function for ExpressJS.
 *
 */
module.exports = function init () {
    var slicer = new ExpressSlicer();

    return slicer.middleware.bind(slicer);
};<|endoftext|>


<commit_before>// Mise en place des en tetes
const discord = require('discord.js')
const client = new discord.Client()

// On start le bot
client.on('ready', () => {
  client.user.setGame('+inv | Pour plus d\'aide +help', 'https://www.twitch.tv/the_commentary', 0)
  console.log('-------------------------------------')
  console.log('    [!] ComaBot connecté [!]')
  console.log('-------------------------------------')
})
// Create an event listener for new guild members

/* Partie Ping */
const ping = require('./module/ping.js')
ping(client)

/* Partie Avatar */
const avatar = require('./module/avatar.js')
avatar(client)

/* Partie Musique */
const music = require('./discord.js-music-v11')
music(client)

/* Partie Message Aux Gens */
const message1 = require('./module/message_personne.js')
message1(client)

/* Partie Say */
const say = require('./module/say.js')
say(client)

/* Partie cpasmoi
const cpasmoi = require('./module/cpasmoi.js')
cpasmoi(client) */

/* Partie Verif Role
const verifrole = require('./module/verifrole.js')
verifrole(client) */

/* Partie Help */
const help = require('./module/help.js')
help(client)

/* Partie Admini 1
const Admini1 = require('./module/admini1.js')
Admini1(client) */

/* Partie Teste1
const test1 = require('./module/test1.js')
test1(client) */

var dt = process.env.TOKEN || process.argv[2]

if (!dt) {
  console.log('')
}

client.login(dt)
<commit_msg>Added Files<commit_after>// Mise en place des en tetes
const discord = require('discord.js')
const client = new discord.Client()

// On start le bot
client.on('ready', () => {
  client.user.setGame('+inv | Pour plus d\'aide +help', 'https://www.twitch.tv/the_commentary', 0)
  console.log('-------------------------------------')
  console.log('    [!] ComaBot connecté [!]')
  console.log('-------------------------------------')
})
// Create an event listener for new guild members

/* Partie Ping */
const ping = require('./module/ping.js')
ping(client)

/* Partie Avatar */
const avatar = require('./module/avatar.js')
avatar(client)

/* Partie Musique */
const music = require('./discord.js-music-v11')
music(client)

/* Partie Message Aux Gens */
const message1 = require('./module/message_personne.js')
message1(client)

/* Partie Say */
const say = require('./module/say.js')
say(client)

/* Partie cpasmoi
const cpasmoi = require('./module/cpasmoi.js')
cpasmoi(client) */

/* Partie Verif Role
const verifrole = require('./module/verifrole.js')
verifrole(client) */

/* Partie Help */
const help = require('./module/help.js')
help(client)

/* Partie Admini 1 */
const Admini1 = require('./module/admini1.js')
Admini1(client)

/* Partie Teste1
const test1 = require('./module/test1.js')
test1(client) */

var dt = process.env.TOKEN || process.argv[2]

if (!dt) {
  console.log('')
}

client.login(dt)
<|endoftext|>


<commit_before>'use strict';

/**
 * Regular expression for matching base64 encoded strings
 *
 * @param {Object} opts
 * @api public
 */

module.exports = function (opts) {
	opts = opts || {};
	var regex = '(?:[A-Za-z0-9+\/]{4}\\n?)*(?:[A-Za-z0-9+\/]{2}==|[A-Za-z0-9+\/]{3}=)';

	return opts.exact ? new RegExp('(?:^' + regex + '$)') :
						new RegExp('(?:^|\\s)' + regex);
};
<commit_msg>Add `global` flag<commit_after>'use strict';

/**
 * Regular expression for matching base64 encoded strings
 *
 * @param {Object} opts
 * @api public
 */

module.exports = function (opts) {
	opts = opts || {};
	var regex = '(?:[A-Za-z0-9+\/]{4}\\n?)*(?:[A-Za-z0-9+\/]{2}==|[A-Za-z0-9+\/]{3}=)';

	return opts.exact ? new RegExp('(?:^' + regex + '$)') :
						new RegExp('(?:^|\\s)' + regex, 'g');
};
<|endoftext|>


<commit_before>module.exports = require('./lib/bolt');<commit_msg>Updated the lib reference<commit_after>module.exports = require('./lib/usain');<|endoftext|>


<commit_before>var async = require('async');
var exec = require('child_process').exec;
var fs = require('fs');
var q = require('q');
var util = require('util');
var uglify = require('uglify-js');
var wiredep = require('wiredep');

var Cache = require('./lib/cache.js');

var repoPatt = /^[A-Za-z]+\/.+$/;

function App() {
  var manifest = require('./manifest.json');
  for (var prop in manifest) {
    this[prop] = manifest[prop];
  }
  this.routes = require('./routes.js');
  this.pkg = require('./package.json');
  this.bower = require('./bower.json');
  return this;
}

var app = new App();

App.prototype.init = function (srv, callback) {
  var self = this;
  self.srv = srv;
  return callback();
};

App.prototype.finally = function (callback) {
  var self = this;
  self.srv.cache = new Cache();
  self.srv.cache.init(self.srv.manager.apps);
  self.installBowerDep()
  .then(function () {
    self.injectDep();
    return self.injectNgMod();
  })
  .then(function () {
    return self.injectRoutes();
  })
  .then(function () {
    return self.minify();
  })
  .then(function () {
    return callback();
  })
};

App.prototype.installBowerDep = function () {
  var self = this;
  var d = q.defer();
  if (process.env.verbose) console.log('Building list of bower dependencies.');
  var bowerDeps = self.bower.dependencies;
  var bowerDepsList = [];
  for (var app in self.srv.manager.apps) {
    if (self.srv.manager.apps[app].bower && self.srv.manager.apps[app].bower.dependencies) {
      for (var dep in self.srv.manager.apps[app].bower.dependencies) {
        if (typeof bowerDeps[dep] !== 'undefined')
          continue;
        bowerDeps[dep] = self.srv.manager.apps[app].bower.dependencies[dep];
      }
    }
  }
  for (var name in bowerDeps) {
    if (repoPatt.test(bowerDeps[name]))
      bowerDepsList.push(bowerDeps[name]);
    else
      bowerDepsList.push(name + '#' + bowerDeps[name]);
  }
  if (process.env.verbose) console.log('Installing bower dependencies.');
  var bower = exec(['bower', 'install', '--quiet', '--allow-root'].concat(bowerDepsList).join(' '));
  bower.on('close', function (code) {
    if (code !== 0) {
      var e = new Error('Failed to install bower dependencies.');
      e.data = bowerDepsList;
      return d.reject(e);
    }
    if (process.env.verbose && bowerDepsList.length > 0) console.log('Bower packages installed:\n' + bowerDepsList.join(' '));
    return d.resolve();
  });
  return d.promise;
};

App.prototype.injectDep = function () {
  var self = this;
  if (process.env.verbose) console.log('Injecting bower dependencies.');
  wiredep({
    directory: process.cwd() + '/static/components',
    bowerJson: self.bower,
    src: [process.cwd() + '/static/index.html'],
    cwd: process.cwd(),
    dependencies: true,
    exclude: ['es5-shim', 'json3', 'bootstrap.js', 'jquery']
  });
  if (process.env.verbose) console.log('Bower dependencies injected.');
};

App.prototype.injectNgMod = function () {
  var self = this;
  var d = q.defer();
  var ngMods = ['ui.bootstrap', 'ngProgress', 'ngAnimate', 'ngRoute', 'ngTouch'];
  if (process.env.verbose) console.log('Building angular module dependencies.');
  for (var app in self.srv.manager.apps) {
    if (self.srv.manager.apps[app].ui && self.srv.manager.apps[app].ui.ngmod) {
      for (var i = 0; i < self.srv.manager.apps[app].ui.ngmod.length; i++) {
        if (ngMods.indexOf(self.srv.manager.apps[app].ui.ngmod[i]) >= 0)
          continue;
        ngMods.push(self.srv.manager.apps[app].ui.ngmod[i]);
      }
    }
  }
  if (process.env.verbose) console.log('Injecting angular module dependencies.');
  fs.readFile(process.cwd() + '/static/js/application.js', 'utf-8', function (err, content) {
    var patt = /\/\*<!-- Ng Mod Inject\*\/.*\/\*--!>\*\//;
    var replace = '[\'' + ngMods.join('\', \'') + '\']';
    if (err) d.reject(err);
    if (typeof content === 'string') {
      var result = content.replace(patt, replace);
      fs.writeFile(process.cwd() + '/static/js/application.js', result, 'utf-8', function (err) {
        if (err) d.reject(err);
        else {
          if (process.env.verbose) console.log('Angular module injected.');
          d.resolve();
        }
      });
    } else d.reject(new Error('Content is not string.'));
  });
  return d.promise;
};

App.prototype.injectRoutes = function () {
  var self = this;
  var d = q.defer();
  var views = [];
  if (process.env.verbose) console.log('Building angular route list.');
  for (var app in self.srv.manager.apps) {
    if (self.srv.manager.apps[app].ui && self.srv.manager.apps[app].ui.views) {
      for (var path in self.srv.manager.apps[app].ui.views) {
        views.push({
          path: self.srv.manager.apps[app].path + path,
          url: self.srv.manager.apps[app].path + self.srv.manager.apps[app].ui.views[path].url,
          ctrl: self.srv.manager.apps[app].ui.views[path].ctrl
        });
      }
    }
  }
  if (process.env.verbose) console.log('Injecting angular routes.');
  fs.readFile(process.cwd() + '/static/js/application.js', 'utf-8', function (err, content) {
    var patt = /\/\*<!-- Ng Route Inject --!>\*\//;
    var template = '.when(\'%s\', {templateUrl: \'%s\', controller: \'%s\'})';
    var replace = '';
    for (var i = 0; i < views.length; i++)
      replace += util.format(template, views[i].path, views[i].url, views[i].ctrl);
    if (err) d.reject(err);
    if (typeof content === 'string') {
      var result = content.replace(patt, replace);
      fs.writeFile(process.cwd() + '/static/js/application.js', result, 'utf-8', function (err) {
        if (err) d.reject(err);
        else {
          if (process.env.verbose) console.log('Angular routes injected.');
          d.resolve();
        }
      });
    } else d.reject(new Error('Content is not string.'));
  });
  return d.promise;
}

App.prototype.minify = function () {
  var self = this;
  var d = q.defer();
  var files = [];
  if (process.env.verbose) console.log('Building list of application scripts.');
  for (var app in self.srv.manager.apps) {
    if (self.srv.manager.apps[app].ui && self.srv.manager.apps[app].ui.scripts) {
      var basepath = process.cwd() + '/node_modules/' + self.srv.manager.apps[app].name + '/' + self.srv.manager.apps[app].static + '/';
      if (typeof self.srv.manager.apps[app].ui.scripts === 'string')
        files.push(basepath + self.srv.manager.apps[app].ui.scripts);
      else if (self.srv.manager.apps[app].ui.scripts instanceof Array)
        for (var i = 0; i < self.srv.manager.apps[app].ui.scripts.length; i++) {
          files.push(basepath + self.srv.manager.apps[app].ui.scripts[i]);
        }
    }
  }
  if (process.env.verbose) console.log('Minifying application scripts.');
  var appMin = uglify.minify([process.cwd() + '/static/js/application.js'], {
    warnings: true,
    outSourceMap: 'application.min.js.map'
  });
  var toWrite = [
    {
      path: process.cwd() + '/static/js/application.min.js',
      content: appMin.code
    },
    {
      path: process.cwd() + '/static/js/application.min.js.map',
      content: appMin.map
    }
  ];
  if (files.length > 0) {
    var ctrlMin = uglify.minify([process.cwd() + '/static/js/controllers.js'].concat(files), {
      warnings: true,
      outSourceMap: 'controllers.min.js.map'
    });
    toWrite.push({
      path: process.cwd() + '/static/js/controllers.min.js',
      content: ctrlMin.code
    });
    toWrite.push({
      path: process.cwd() + '/static/js/controllers.min.js.map',
      content: ctrlMin.map
    });
  }
  if (process.env.verbose) console.log('Saving minified application scripts.');
  async.each(toWrite, function (item, callback) {
    fs.writeFile(item.path, item.content, callback);
  }, function (err) {
    if (err) d.reject();
    else {
      if (process.env.verbose) console.log('Minified application scripts saved.');
      d.resolve();
    }
  });
  return d.promise;
};

module.exports = app;
<commit_msg>Fixed js source map<commit_after>var async = require('async');
var cluster = require('cluster');
var exec = require('child_process').exec;
var fs = require('fs');
var q = require('q');
var util = require('util');
var uglify = require('uglify-js');
var wiredep = require('wiredep');

var Cache = require('./lib/cache.js');

var repoPatt = /^[A-Za-z]+\/.+$/;

function App() {
  var manifest = require('./manifest.json');
  for (var prop in manifest) {
    this[prop] = manifest[prop];
  }
  this.routes = require('./routes.js');
  this.pkg = require('./package.json');
  this.bower = require('./bower.json');
  return this;
}

var app = new App();

App.prototype.init = function (srv, callback) {
  var self = this;
  self.srv = srv;
  return callback();
};

App.prototype.finally = function (callback) {
  var self = this;
  self.srv.cache = new Cache();
  self.srv.cache.init(self.srv.manager.apps);
  if (cluster.isWorker)
    return callback();
  self.installBowerDep()
  .then(function () {
    self.injectDep();
    return self.injectNgMod();
  })
  .then(function () {
    return self.injectRoutes();
  })
  .then(function () {
    return self.minify();
  })
  .then(function () {
    return callback();
  })
};

App.prototype.installBowerDep = function () {
  var self = this;
  var d = q.defer();
  if (process.env.verbose) console.log('Building list of bower dependencies.');
  var bowerDeps = self.bower.dependencies;
  var bowerDepsList = [];
  for (var app in self.srv.manager.apps) {
    if (self.srv.manager.apps[app].bower && self.srv.manager.apps[app].bower.dependencies) {
      for (var dep in self.srv.manager.apps[app].bower.dependencies) {
        if (typeof bowerDeps[dep] !== 'undefined')
          continue;
        bowerDeps[dep] = self.srv.manager.apps[app].bower.dependencies[dep];
      }
    }
  }
  for (var name in bowerDeps) {
    if (repoPatt.test(bowerDeps[name]))
      bowerDepsList.push(bowerDeps[name]);
    else
      bowerDepsList.push(name + '#' + bowerDeps[name]);
  }
  if (process.env.verbose) console.log('Installing bower dependencies.');
  var bower = exec(['bower', 'install', '--quiet', '--allow-root'].concat(bowerDepsList).join(' '));
  bower.on('close', function (code) {
    if (code !== 0) {
      var e = new Error('Failed to install bower dependencies.');
      e.data = bowerDepsList;
      return d.reject(e);
    }
    if (process.env.verbose && bowerDepsList.length > 0) console.log('Bower packages installed:\n' + bowerDepsList.join(' '));
    return d.resolve();
  });
  return d.promise;
};

App.prototype.injectDep = function () {
  var self = this;
  if (process.env.verbose) console.log('Injecting bower dependencies.');
  wiredep({
    directory: process.cwd() + '/static/components',
    bowerJson: self.bower,
    src: [process.cwd() + '/static/index.html'],
    cwd: process.cwd(),
    dependencies: true,
    exclude: ['es5-shim', 'json3', 'bootstrap.js', 'jquery']
  });
  if (process.env.verbose) console.log('Bower dependencies injected.');
};

App.prototype.injectNgMod = function () {
  var self = this;
  var d = q.defer();
  var ngMods = ['ui.bootstrap', 'ngProgress', 'ngAnimate', 'ngRoute', 'ngTouch'];
  if (process.env.verbose) console.log('Building angular module dependencies.');
  for (var app in self.srv.manager.apps) {
    if (self.srv.manager.apps[app].ui && self.srv.manager.apps[app].ui.ngmod) {
      for (var i = 0; i < self.srv.manager.apps[app].ui.ngmod.length; i++) {
        if (ngMods.indexOf(self.srv.manager.apps[app].ui.ngmod[i]) >= 0)
          continue;
        ngMods.push(self.srv.manager.apps[app].ui.ngmod[i]);
      }
    }
  }
  if (process.env.verbose) console.log('Injecting angular module dependencies.');
  fs.readFile(process.cwd() + '/static/js/application.js', 'utf-8', function (err, content) {
    var patt = /\/\*<!-- Ng Mod Inject\*\/.*\/\*--!>\*\//;
    var replace = '[\'' + ngMods.join('\', \'') + '\']';
    if (err) d.reject(err);
    if (typeof content === 'string') {
      var result = content.replace(patt, replace);
      fs.writeFile(process.cwd() + '/static/js/application.js', result, 'utf-8', function (err) {
        if (err) d.reject(err);
        else {
          if (process.env.verbose) console.log('Angular module injected.');
          d.resolve();
        }
      });
    } else d.reject(new Error('Content is not string.'));
  });
  return d.promise;
};

App.prototype.injectRoutes = function () {
  var self = this;
  var d = q.defer();
  var views = [];
  if (process.env.verbose) console.log('Building angular route list.');
  for (var app in self.srv.manager.apps) {
    if (self.srv.manager.apps[app].ui && self.srv.manager.apps[app].ui.views) {
      for (var path in self.srv.manager.apps[app].ui.views) {
        views.push({
          path: self.srv.manager.apps[app].path + path,
          url: self.srv.manager.apps[app].path + self.srv.manager.apps[app].ui.views[path].url,
          ctrl: self.srv.manager.apps[app].ui.views[path].ctrl
        });
      }
    }
  }
  if (process.env.verbose) console.log('Injecting angular routes.');
  fs.readFile(process.cwd() + '/static/js/application.js', 'utf-8', function (err, content) {
    var patt = /\/\*<!-- Ng Route Inject --!>\*\//;
    var template = '.when(\'%s\', {templateUrl: \'%s\', controller: \'%s\'})';
    var replace = '';
    for (var i = 0; i < views.length; i++)
      replace += util.format(template, views[i].path, views[i].url, views[i].ctrl);
    if (err) d.reject(err);
    if (typeof content === 'string') {
      var result = content.replace(patt, replace);
      fs.writeFile(process.cwd() + '/static/js/application.js', result, 'utf-8', function (err) {
        if (err) d.reject(err);
        else {
          if (process.env.verbose) console.log('Angular routes injected.');
          d.resolve();
        }
      });
    } else d.reject(new Error('Content is not string.'));
  });
  return d.promise;
}

App.prototype.minify = function () {
  var self = this;
  var d = q.defer();
  var files = [];
  if (process.env.verbose) console.log('Building list of application scripts.');
  for (var app in self.srv.manager.apps) {
    if (self.srv.manager.apps[app].ui && self.srv.manager.apps[app].ui.scripts) {
      var basepath = process.cwd() + '/static' + self.srv.manager.apps[app].path + '/';
      if (typeof self.srv.manager.apps[app].ui.scripts === 'string')
        files.push(basepath + self.srv.manager.apps[app].ui.scripts);
      else if (self.srv.manager.apps[app].ui.scripts instanceof Array)
        for (var i = 0; i < self.srv.manager.apps[app].ui.scripts.length; i++) {
          files.push(basepath + self.srv.manager.apps[app].ui.scripts[i]);
        }
    }
  }
  if (process.env.verbose) console.log('Minifying application scripts.');
  var appMin = uglify.minify(['./static/js/application.js'], {
    outSourceMap: 'application.min.js.map'
  });
  var patt = /"sources".+"names"/;
  var appReplace = '"sources":["application.js"],"names"';
  var toWrite = [
    {
      path: process.cwd() + '/static/js/application.min.js',
      content: appMin.code
    },
    {
      path: process.cwd() + '/static/js/application.min.js.map',
      content: appMin.map.replace(patt, appReplace)
    }
  ];
  if (files.length > 0) {
    var ctrlMin = uglify.minify([process.cwd() + '/static/js/controllers.js'].concat(files), {
      outSourceMap: 'controllers.min.js.map'
    });
    var ctrlReplace = [];
    for (var l = 0; l < files.length; l++)
      ctrlReplace.push(files[l].replace(/^.*\/static/, ''));
    ctrlReplace = '"sources":["' + ctrlReplace.join('", "') + '"],"names"';
    toWrite.push({
      path: process.cwd() + '/static/js/controllers.min.js',
      content: ctrlMin.code
    });
    toWrite.push({
      path: process.cwd() + '/static/js/controllers.min.js.map',
      content: ctrlMin.map.replace(patt, ctrlReplace)
    });
  }
  if (process.env.verbose) console.log('Saving minified application scripts.');
  async.each(toWrite, function (item, callback) {
    fs.writeFile(item.path, item.content, callback);
  }, function (err) {
    if (err) d.reject();
    else {
      if (process.env.verbose) console.log('Minified application scripts saved.');
      d.resolve();
    }
  });
  return d.promise;
};

module.exports = app;
<|endoftext|>